CreateResponse returns a DER-encoded OCSP response with the specified contents. The fields in the response are populated as follows:

The responder cert is used to populate the ResponderName field, and the certificate itself is provided alongside the OCSP response signature.

The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields. (SHA-1 is used for the hash function; this is not configurable.)

The template is used to populate the SerialNumber, RevocationStatus, RevokedAt, RevocationReason, ThisUpdate, and NextUpdate fields.

The ProducedAt date is automatically set to the current date, to the nearest minute.

CreateResponse is referenced in 1 repository


func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) {
	var publicKeyInfo struct {
		Algorithm pkix.AlgorithmIdentifier
		PublicKey asn1.BitString
	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
		return nil, err

	h := sha1.New()
	issuerKeyHash := h.Sum(nil)

	issuerNameHash := h.Sum(nil)

	innerResponse := singleResponse{
		CertID: certID{
			HashAlgorithm: pkix.AlgorithmIdentifier{
				Algorithm:  hashOIDs[crypto.SHA1],
				Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
			NameHash:      issuerNameHash,
			IssuerKeyHash: issuerKeyHash,
			SerialNumber:  template.SerialNumber,
		ThisUpdate:       template.ThisUpdate.UTC(),
		NextUpdate:       template.NextUpdate.UTC(),
		SingleExtensions: template.ExtraExtensions,

	switch template.Status {
	case Good:
		innerResponse.Good = true
	case Unknown:
		innerResponse.Unknown = true
	case Revoked:
		innerResponse.Revoked = revokedInfo{
			RevocationTime: template.RevokedAt.UTC(),
			Reason:         asn1.Enumerated(template.RevocationReason),

	responderName := asn1.RawValue{
		Class:      2, // context-specific
		Tag:        1, // explicit tag
		IsCompound: true,
		Bytes:      responderCert.RawSubject,
	tbsResponseData := responseData{
		Version:          0,
		RawResponderName: responderName,
		ProducedAt:       time.Now().Truncate(time.Minute).UTC(),
		Responses:        []singleResponse{innerResponse},

	tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
	if err != nil {
		return nil, err

	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
	if err != nil {
		return nil, err

	responseHash := hashFunc.New()
	signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
	if err != nil {
		return nil, err

	response := basicResponse{
		TBSResponseData:    tbsResponseData,
		SignatureAlgorithm: signatureAlgorithm,
		Signature: asn1.BitString{
			Bytes:     signature,
			BitLength: 8 * len(signature),
	if template.Certificate != nil {
		response.Certificates = []asn1.RawValue{
			asn1.RawValue{FullBytes: template.Certificate.Raw},
	responseDER, err := asn1.Marshal(response)
	if err != nil {
		return nil, err

	return asn1.Marshal(responseASN1{
		Status: asn1.Enumerated(Success),
		Response: responseBytes{
			ResponseType: idPKIXOCSPBasic,
			Response:     responseDER,