Example #1
0
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")
}
Example #2
0
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
}