func TestCheckSignature(t *testing.T) { // Based on a submission to the aviator log goodSigBytes, err := base64.StdEncoding.DecodeString("BAMASDBGAiEAknaySJVdB3FqG9bUKHgyu7V9AdEabpTc71BELUp6/iECIQDObrkwlQq6Azfj5XOA5E12G/qy/WuRn97z7qMSXXc82Q==") test.AssertNotError(t, err, "Couldn't decode signature") testReceipt := core.SignedCertificateTimestamp{ Signature: goodSigBytes, } // Good signature err = testReceipt.CheckSignature() test.AssertNotError(t, err, "Valid signature check failed") // Invalid signature (too short, trailing garbage) testReceipt.Signature = goodSigBytes[1:] err = testReceipt.CheckSignature() test.AssertError(t, err, "Invalid signature check failed") testReceipt.Signature = append(goodSigBytes, []byte{0, 0, 1}...) err = testReceipt.CheckSignature() test.AssertError(t, err, "Invalid signature check failed") }
func (pub *PublisherImpl) submitToCTLog(serial string, jsonSubmission []byte, log LogDescription) error { done := false var sct core.SignedCertificateTimestamp backoff := pub.submissionBackoff var retries int for retries = 0; retries <= pub.submissionRetries; retries++ { if retries > 0 { time.Sleep(backoff) } resp, err := postJSON(pub.client, fmt.Sprintf("%s%s", log.URI, "/ct/v1/add-chain"), jsonSubmission, &sct) if err != nil { // Retry the request, log the error pub.log.Warning(fmt.Sprintf("Error POSTing JSON to CT log submission endpoint [%s]: %s", log.URI, err)) backoff = pub.submissionBackoff continue } else if resp.StatusCode == http.StatusRequestTimeout || resp.StatusCode == http.StatusServiceUnavailable { // Retry the request after either the configured backoff period or the period // specified by the Retry-After header backoff = pub.submissionBackoff if seconds, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil { backoff = time.Second * time.Duration(seconds) } continue } else if resp.StatusCode != http.StatusOK { // If we hit an otherwise unexpected status code break the loop and return // an error immediately return fmt.Errorf("Unexpected status code returned from CT log: %d", resp.StatusCode) } done = true break } if !done { err := fmt.Errorf( "Unable to submit certificate to CT log [Serial: %s, Log URI: %s, Retries: %d]", serial, log.URI, retries, ) return err } if err := sct.CheckSignature(); err != nil { return err } pub.log.Debug(fmt.Sprintf( "Submitted certificate to CT log [Serial: %s, Log URI: %s, Retries: %d, Signature: %x]", serial, log.URI, retries, sct.Signature, )) // Set certificate serial and add SCT to DB sct.CertificateSerial = serial err := pub.SA.AddSCTReceipt(sct) if err != nil { if _, ok := err.(sa.ErrDuplicateReceipt); ok { pub.log.Warning(fmt.Sprintf( "SCT receipt for [Serial: %s, Log URI: %s] already exists in database", serial, log.URI, )) return nil } else if err != nil { err = fmt.Errorf( "Error adding SCT receipt for [%s to %s]: %s", sct.CertificateSerial, log.URI, err, ) return err } } pub.log.Info(fmt.Sprintf( "Stored SCT receipt from CT log submission [Serial: %s, Log URI: %s]", serial, log.URI, )) return nil }