github.com/zmap/zcrypto@v0.0.0-20240512203510-0fef58d9a9db/x509/revocation/ocsp/ocsp.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses
     6  // are signed messages attesting to the validity of a certificate for a small
     7  // period of time. This is used to manage revocation for X.509 certificates.
     8  package ocsp
     9  
    10  import (
    11  	"crypto"
    12  	"crypto/ecdsa"
    13  	"crypto/elliptic"
    14  	"crypto/rand"
    15  	"crypto/rsa"
    16  	_ "crypto/sha1"
    17  	_ "crypto/sha256"
    18  	_ "crypto/sha512"
    19  	"errors"
    20  	"fmt"
    21  	"math/big"
    22  	"strconv"
    23  	"time"
    24  
    25  	"github.com/zmap/zcrypto/encoding/asn1"
    26  	"github.com/zmap/zcrypto/x509"
    27  	"github.com/zmap/zcrypto/x509/pkix"
    28  	"github.com/zmap/zcrypto/x509/revocation/crl"
    29  )
    30  
    31  var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1})
    32  
    33  // ResponseStatus contains the result of an OCSP request. See
    34  // https://tools.ietf.org/html/rfc6960#section-2.3
    35  type ResponseStatus int
    36  
    37  const (
    38  	Success       ResponseStatus = 0
    39  	Malformed     ResponseStatus = 1
    40  	InternalError ResponseStatus = 2
    41  	TryLater      ResponseStatus = 3
    42  	// Status code four is unused in OCSP. See
    43  	// https://tools.ietf.org/html/rfc6960#section-4.2.1
    44  	SignatureRequired ResponseStatus = 5
    45  	Unauthorized      ResponseStatus = 6
    46  )
    47  
    48  func (r ResponseStatus) String() string {
    49  	switch r {
    50  	case Success:
    51  		return "success"
    52  	case Malformed:
    53  		return "malformed"
    54  	case InternalError:
    55  		return "internal error"
    56  	case TryLater:
    57  		return "try later"
    58  	case SignatureRequired:
    59  		return "signature required"
    60  	case Unauthorized:
    61  		return "unauthorized"
    62  	default:
    63  		return "unknown OCSP status: " + strconv.Itoa(int(r))
    64  	}
    65  }
    66  
    67  // ResponseError is an error that may be returned by ParseResponse to indicate
    68  // that the response itself is an error, not just that it's indicating that a
    69  // certificate is revoked, unknown, etc.
    70  type ResponseError struct {
    71  	Status ResponseStatus
    72  }
    73  
    74  func (r ResponseError) Error() string {
    75  	return "ocsp: error from server: " + r.Status.String()
    76  }
    77  
    78  // These are internal structures that reflect the ASN.1 structure of an OCSP
    79  // response. See RFC 2560, section 4.2.
    80  
    81  type certID struct {
    82  	HashAlgorithm pkix.AlgorithmIdentifier
    83  	NameHash      []byte
    84  	IssuerKeyHash []byte
    85  	SerialNumber  *big.Int
    86  }
    87  
    88  // https://tools.ietf.org/html/rfc2560#section-4.1.1
    89  type ocspRequest struct {
    90  	TBSRequest tbsRequest
    91  }
    92  
    93  type tbsRequest struct {
    94  	Version       int              `asn1:"explicit,tag:0,default:0,optional"`
    95  	RequestorName pkix.RDNSequence `asn1:"explicit,tag:1,optional"`
    96  	RequestList   []request
    97  }
    98  
    99  type request struct {
   100  	Cert certID
   101  }
   102  
   103  type responseASN1 struct {
   104  	Status   asn1.Enumerated
   105  	Response responseBytes `asn1:"explicit,tag:0,optional"`
   106  }
   107  
   108  type responseBytes struct {
   109  	ResponseType asn1.ObjectIdentifier
   110  	Response     []byte
   111  }
   112  
   113  type basicResponse struct {
   114  	TBSResponseData    responseData
   115  	SignatureAlgorithm pkix.AlgorithmIdentifier
   116  	Signature          asn1.BitString
   117  	Certificates       []asn1.RawValue `asn1:"explicit,tag:0,optional"`
   118  }
   119  
   120  type responseData struct {
   121  	Raw            asn1.RawContent
   122  	Version        int `asn1:"optional,default:0,explicit,tag:0"`
   123  	RawResponderID asn1.RawValue
   124  	ProducedAt     time.Time `asn1:"generalized"`
   125  	Responses      []singleResponse
   126  }
   127  
   128  type singleResponse struct {
   129  	CertID           certID
   130  	Good             asn1.Flag        `asn1:"tag:0,optional"`
   131  	Revoked          revokedInfo      `asn1:"tag:1,optional"`
   132  	Unknown          asn1.Flag        `asn1:"tag:2,optional"`
   133  	ThisUpdate       time.Time        `asn1:"generalized"`
   134  	NextUpdate       time.Time        `asn1:"generalized,explicit,tag:0,optional"`
   135  	SingleExtensions []pkix.Extension `asn1:"explicit,tag:1,optional"`
   136  }
   137  
   138  type revokedInfo struct {
   139  	RevocationTime time.Time       `asn1:"generalized"`
   140  	Reason         asn1.Enumerated `asn1:"explicit,tag:0,optional"`
   141  }
   142  
   143  var (
   144  	oidSignatureMD2WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
   145  	oidSignatureMD5WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
   146  	oidSignatureSHA1WithRSA     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
   147  	oidSignatureSHA256WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
   148  	oidSignatureSHA384WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
   149  	oidSignatureSHA512WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
   150  	oidSignatureDSAWithSHA1     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
   151  	oidSignatureDSAWithSHA256   = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
   152  	oidSignatureECDSAWithSHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
   153  	oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
   154  	oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
   155  	oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
   156  )
   157  
   158  var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{
   159  	crypto.SHA1:   asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}),
   160  	crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}),
   161  	crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}),
   162  	crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}),
   163  }
   164  
   165  // TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
   166  var signatureAlgorithmDetails = []struct {
   167  	algo       x509.SignatureAlgorithm
   168  	oid        asn1.ObjectIdentifier
   169  	pubKeyAlgo x509.PublicKeyAlgorithm
   170  	hash       crypto.Hash
   171  }{
   172  	{x509.MD2WithRSA, oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */},
   173  	{x509.MD5WithRSA, oidSignatureMD5WithRSA, x509.RSA, crypto.MD5},
   174  	{x509.SHA1WithRSA, oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
   175  	{x509.SHA256WithRSA, oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256},
   176  	{x509.SHA384WithRSA, oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384},
   177  	{x509.SHA512WithRSA, oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512},
   178  	{x509.DSAWithSHA1, oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1},
   179  	{x509.DSAWithSHA256, oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256},
   180  	{x509.ECDSAWithSHA1, oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1},
   181  	{x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256},
   182  	{x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384},
   183  	{x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512},
   184  }
   185  
   186  // TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
   187  func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
   188  	var pubType x509.PublicKeyAlgorithm
   189  
   190  	switch pub := pub.(type) {
   191  	case *rsa.PublicKey:
   192  		pubType = x509.RSA
   193  		hashFunc = crypto.SHA256
   194  		sigAlgo.Algorithm = oidSignatureSHA256WithRSA
   195  		sigAlgo.Parameters = asn1.RawValue{
   196  			Tag: 5,
   197  		}
   198  
   199  	case *ecdsa.PublicKey:
   200  		pubType = x509.ECDSA
   201  
   202  		switch pub.Curve {
   203  		case elliptic.P224(), elliptic.P256():
   204  			hashFunc = crypto.SHA256
   205  			sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
   206  		case elliptic.P384():
   207  			hashFunc = crypto.SHA384
   208  			sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
   209  		case elliptic.P521():
   210  			hashFunc = crypto.SHA512
   211  			sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
   212  		default:
   213  			err = errors.New("x509: unknown elliptic curve")
   214  		}
   215  
   216  	default:
   217  		err = errors.New("x509: only RSA and ECDSA keys supported")
   218  	}
   219  
   220  	if err != nil {
   221  		return
   222  	}
   223  
   224  	if requestedSigAlgo == 0 {
   225  		return
   226  	}
   227  
   228  	found := false
   229  	for _, details := range signatureAlgorithmDetails {
   230  		if details.algo == requestedSigAlgo {
   231  			if details.pubKeyAlgo != pubType {
   232  				err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
   233  				return
   234  			}
   235  			sigAlgo.Algorithm, hashFunc = details.oid, details.hash
   236  			if hashFunc == 0 {
   237  				err = errors.New("x509: cannot sign with hash function requested")
   238  				return
   239  			}
   240  			found = true
   241  			break
   242  		}
   243  	}
   244  
   245  	if !found {
   246  		err = errors.New("x509: unknown SignatureAlgorithm")
   247  	}
   248  
   249  	return
   250  }
   251  
   252  // TODO(agl): this is taken from crypto/x509 and so should probably be exported
   253  // from crypto/x509 or crypto/x509/pkix.
   254  func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.SignatureAlgorithm {
   255  	for _, details := range signatureAlgorithmDetails {
   256  		if oid.Equal(details.oid) {
   257  			return details.algo
   258  		}
   259  	}
   260  	return x509.UnknownSignatureAlgorithm
   261  }
   262  
   263  // TODO(rlb): This is not taken from crypto/x509, but it's of the same general form.
   264  func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
   265  	for hash, oid := range hashOIDs {
   266  		if oid.Equal(target) {
   267  			return hash
   268  		}
   269  	}
   270  	return crypto.Hash(0)
   271  }
   272  
   273  func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier {
   274  	for hash, oid := range hashOIDs {
   275  		if hash == target {
   276  			return oid
   277  		}
   278  	}
   279  	return nil
   280  }
   281  
   282  // This is the exposed reflection of the internal OCSP structures.
   283  
   284  // The status values that can be expressed in OCSP.  See RFC 6960.
   285  const (
   286  	// Good means that the certificate is valid.
   287  	Good = iota
   288  	// Revoked means that the certificate has been deliberately revoked.
   289  	Revoked
   290  	// Unknown means that the OCSP responder doesn't know about the certificate.
   291  	Unknown
   292  	// ServerFailed is unused and was never used (see
   293  	// https://go-review.googlesource.com/#/c/18944). ParseResponse will
   294  	// return a ResponseError when an error response is parsed.
   295  	ServerFailed
   296  )
   297  
   298  // The enumerated reasons for revoking a certificate.  See RFC 5280.
   299  const (
   300  	Unspecified          = 0
   301  	KeyCompromise        = 1
   302  	CACompromise         = 2
   303  	AffiliationChanged   = 3
   304  	Superseded           = 4
   305  	CessationOfOperation = 5
   306  	CertificateHold      = 6
   307  
   308  	RemoveFromCRL      = 8
   309  	PrivilegeWithdrawn = 9
   310  	AACompromise       = 10
   311  )
   312  
   313  // Request represents an OCSP request. See RFC 6960.
   314  type Request struct {
   315  	HashAlgorithm  crypto.Hash
   316  	IssuerNameHash []byte
   317  	IssuerKeyHash  []byte
   318  	SerialNumber   *big.Int
   319  }
   320  
   321  // Marshal marshals the OCSP request to ASN.1 DER encoded form.
   322  func (req *Request) Marshal() ([]byte, error) {
   323  	hashAlg := getOIDFromHashAlgorithm(req.HashAlgorithm)
   324  	if hashAlg == nil {
   325  		return nil, errors.New("Unknown hash algorithm")
   326  	}
   327  	return asn1.Marshal(ocspRequest{
   328  		tbsRequest{
   329  			Version: 0,
   330  			RequestList: []request{
   331  				{
   332  					Cert: certID{
   333  						pkix.AlgorithmIdentifier{
   334  							Algorithm:  hashAlg,
   335  							Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
   336  						},
   337  						req.IssuerNameHash,
   338  						req.IssuerKeyHash,
   339  						req.SerialNumber,
   340  					},
   341  				},
   342  			},
   343  		},
   344  	})
   345  }
   346  
   347  // Response represents an OCSP response containing a single SingleResponse. See
   348  // RFC 6960.
   349  type Response struct {
   350  	// Status is one of {Good, Revoked, Unknown}
   351  	Status                                        int
   352  	SerialNumber                                  *big.Int
   353  	IsRevoked                                     bool // set to true if CertificateStatus is "revoked"
   354  	ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
   355  	RevocationReason                              crl.RevocationReasonCode
   356  	Certificate                                   *x509.Certificate
   357  	// TBSResponseData contains the raw bytes of the signed response. If
   358  	// Certificate is nil then this can be used to verify Signature.
   359  	TBSResponseData    []byte
   360  	Signature          []byte
   361  	SignatureAlgorithm x509.SignatureAlgorithm
   362  
   363  	// IssuerHash is the hash used to compute the IssuerNameHash and IssuerKeyHash.
   364  	// Valid values are crypto.SHA1, crypto.SHA256, crypto.SHA384, and crypto.SHA512.
   365  	// If zero, the default is crypto.SHA1.
   366  	IssuerHash crypto.Hash
   367  
   368  	// RawResponderName optionally contains the DER-encoded subject of the
   369  	// responder certificate. Exactly one of RawResponderName and
   370  	// ResponderKeyHash is set.
   371  	RawResponderName []byte
   372  	// ResponderKeyHash optionally contains the SHA-1 hash of the
   373  	// responder's public key. Exactly one of RawResponderName and
   374  	// ResponderKeyHash is set.
   375  	ResponderKeyHash []byte
   376  
   377  	// Extensions contains raw X.509 extensions from the singleExtensions field
   378  	// of the OCSP response. When parsing certificates, this can be used to
   379  	// extract non-critical extensions that are not parsed by this package. When
   380  	// marshaling OCSP responses, the Extensions field is ignored, see
   381  	// ExtraExtensions.
   382  	Extensions []pkix.Extension
   383  
   384  	// ExtraExtensions contains extensions to be copied, raw, into any marshaled
   385  	// OCSP response (in the singleExtensions field). Values override any
   386  	// extensions that would otherwise be produced based on the other fields. The
   387  	// ExtraExtensions field is not populated when parsing certificates, see
   388  	// Extensions.
   389  	ExtraExtensions []pkix.Extension
   390  }
   391  
   392  // These are pre-serialized error responses for the various non-success codes
   393  // defined by OCSP. The Unauthorized code in particular can be used by an OCSP
   394  // responder that supports only pre-signed responses as a response to requests
   395  // for certificates with unknown status. See RFC 5019.
   396  var (
   397  	MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01}
   398  	InternalErrorErrorResponse    = []byte{0x30, 0x03, 0x0A, 0x01, 0x02}
   399  	TryLaterErrorResponse         = []byte{0x30, 0x03, 0x0A, 0x01, 0x03}
   400  	SigRequredErrorResponse       = []byte{0x30, 0x03, 0x0A, 0x01, 0x05}
   401  	UnauthorizedErrorResponse     = []byte{0x30, 0x03, 0x0A, 0x01, 0x06}
   402  )
   403  
   404  // CheckSignatureFrom checks that the signature in resp is a valid signature
   405  // from issuer. This should only be used if resp.Certificate is nil. Otherwise,
   406  // the OCSP response contained an intermediate certificate that created the
   407  // signature. That signature is checked by ParseResponse and only
   408  // resp.Certificate remains to be validated.
   409  func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error {
   410  	return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature)
   411  }
   412  
   413  // ParseError results from an invalid OCSP response.
   414  type ParseError string
   415  
   416  func (p ParseError) Error() string {
   417  	return string(p)
   418  }
   419  
   420  // ParseRequest parses an OCSP request in DER form. It only supports
   421  // requests for a single certificate. Signed requests are not supported.
   422  // If a request includes a signature, it will result in a ParseError.
   423  func ParseRequest(bytes []byte) (*Request, error) {
   424  	var req ocspRequest
   425  	rest, err := asn1.Unmarshal(bytes, &req)
   426  	if err != nil {
   427  		return nil, err
   428  	}
   429  	if len(rest) > 0 {
   430  		return nil, ParseError("trailing data in OCSP request")
   431  	}
   432  
   433  	if len(req.TBSRequest.RequestList) == 0 {
   434  		return nil, ParseError("OCSP request contains no request body")
   435  	}
   436  	innerRequest := req.TBSRequest.RequestList[0]
   437  
   438  	hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm)
   439  	if hashFunc == crypto.Hash(0) {
   440  		return nil, ParseError("OCSP request uses unknown hash function")
   441  	}
   442  
   443  	return &Request{
   444  		HashAlgorithm:  hashFunc,
   445  		IssuerNameHash: innerRequest.Cert.NameHash,
   446  		IssuerKeyHash:  innerRequest.Cert.IssuerKeyHash,
   447  		SerialNumber:   innerRequest.Cert.SerialNumber,
   448  	}, nil
   449  }
   450  
   451  // ParseResponse parses an OCSP response in DER form. The response must contain
   452  // only one certificate status. To parse the status of a specific certificate
   453  // from a response which may contain multiple statuses, use ParseResponseForCert
   454  // instead.
   455  //
   456  // If the response contains an embedded certificate, then that certificate will
   457  // be used to verify the response signature. If the response contains an
   458  // embedded certificate and issuer is not nil, then issuer will be used to verify
   459  // the signature on the embedded certificate.
   460  //
   461  // If the response does not contain an embedded certificate and issuer is not
   462  // nil, then issuer will be used to verify the response signature.
   463  //
   464  // Invalid responses and parse failures will result in a ParseError.
   465  // Error responses will result in a ResponseError.
   466  func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
   467  	return ParseResponseForCert(bytes, nil, issuer)
   468  }
   469  
   470  // ParseResponseForCert acts identically to ParseResponse, except it supports
   471  // parsing responses that contain multiple statuses. If the response contains
   472  // multiple statuses and cert is not nil, then ParseResponseForCert will return
   473  // the first status which contains a matching serial, otherwise it will return an
   474  // error. If cert is nil, then the first status in the response will be returned.
   475  func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
   476  	var resp responseASN1
   477  	rest, err := asn1.Unmarshal(bytes, &resp)
   478  	if err != nil {
   479  		return nil, err
   480  	}
   481  	if len(rest) > 0 {
   482  		return nil, ParseError("trailing data in OCSP response")
   483  	}
   484  
   485  	if status := ResponseStatus(resp.Status); status != Success {
   486  		return nil, ResponseError{status}
   487  	}
   488  
   489  	if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
   490  		return nil, ParseError("bad OCSP response type")
   491  	}
   492  
   493  	var basicResp basicResponse
   494  	rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
   495  	if err != nil {
   496  		return nil, err
   497  	}
   498  	if len(rest) > 0 {
   499  		return nil, ParseError("trailing data in OCSP response")
   500  	}
   501  
   502  	if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
   503  		return nil, ParseError("OCSP response contains bad number of responses")
   504  	}
   505  
   506  	var singleResp singleResponse
   507  	if cert == nil {
   508  		singleResp = basicResp.TBSResponseData.Responses[0]
   509  	} else {
   510  		match := false
   511  		for _, resp := range basicResp.TBSResponseData.Responses {
   512  			if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
   513  				singleResp = resp
   514  				match = true
   515  				break
   516  			}
   517  		}
   518  		if !match {
   519  			return nil, ParseError("no response matching the supplied certificate")
   520  		}
   521  	}
   522  
   523  	ret := &Response{
   524  		TBSResponseData:    basicResp.TBSResponseData.Raw,
   525  		Signature:          basicResp.Signature.RightAlign(),
   526  		SignatureAlgorithm: getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm),
   527  		Extensions:         singleResp.SingleExtensions,
   528  		SerialNumber:       singleResp.CertID.SerialNumber,
   529  		ProducedAt:         basicResp.TBSResponseData.ProducedAt,
   530  		ThisUpdate:         singleResp.ThisUpdate,
   531  		NextUpdate:         singleResp.NextUpdate,
   532  	}
   533  
   534  	// Handle the ResponderID CHOICE tag. ResponderID can be flattened into
   535  	// TBSResponseData once https://go-review.googlesource.com/34503 has been
   536  	// released.
   537  	rawResponderID := basicResp.TBSResponseData.RawResponderID
   538  	switch rawResponderID.Tag {
   539  	case 1: // Name
   540  		var rdn pkix.RDNSequence
   541  		if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &rdn); err != nil || len(rest) != 0 {
   542  			return nil, ParseError("invalid responder name")
   543  		}
   544  		ret.RawResponderName = rawResponderID.Bytes
   545  	case 2: // KeyHash
   546  		if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &ret.ResponderKeyHash); err != nil || len(rest) != 0 {
   547  			return nil, ParseError("invalid responder key hash")
   548  		}
   549  	default:
   550  		return nil, ParseError("invalid responder id tag")
   551  	}
   552  
   553  	if len(basicResp.Certificates) > 0 {
   554  		// Responders should only send a single certificate (if they
   555  		// send any) that connects the responder's certificate to the
   556  		// original issuer. We accept responses with multiple
   557  		// certificates due to a number responders sending them[1], but
   558  		// ignore all but the first.
   559  		//
   560  		// [1] https://github.com/golang/go/issues/21527
   561  		ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
   562  		if err != nil {
   563  			return nil, err
   564  		}
   565  
   566  		if err := ret.CheckSignatureFrom(ret.Certificate); err != nil {
   567  			return nil, ParseError("bad signature on embedded certificate: " + err.Error())
   568  		}
   569  
   570  		if issuer != nil {
   571  			if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil {
   572  				return nil, ParseError("bad OCSP signature: " + err.Error())
   573  			}
   574  		}
   575  	} else if issuer != nil {
   576  		if err := ret.CheckSignatureFrom(issuer); err != nil {
   577  			return nil, ParseError("bad OCSP signature: " + err.Error())
   578  		}
   579  	}
   580  
   581  	for _, ext := range singleResp.SingleExtensions {
   582  		if ext.Critical {
   583  			return nil, ParseError("unsupported critical extension")
   584  		}
   585  	}
   586  
   587  	for h, oid := range hashOIDs {
   588  		if singleResp.CertID.HashAlgorithm.Algorithm.Equal(oid) {
   589  			ret.IssuerHash = h
   590  			break
   591  		}
   592  	}
   593  	if ret.IssuerHash == 0 {
   594  		return nil, ParseError("unsupported issuer hash algorithm")
   595  	}
   596  
   597  	switch {
   598  	case bool(singleResp.Good):
   599  		ret.Status = Good
   600  		ret.IsRevoked = false
   601  	case bool(singleResp.Unknown):
   602  		ret.Status = Unknown
   603  		ret.IsRevoked = false
   604  	default:
   605  		ret.Status = Revoked
   606  		ret.IsRevoked = true
   607  		ret.RevokedAt = singleResp.Revoked.RevocationTime
   608  		ret.RevocationReason = crl.RevocationReasonCode(singleResp.Revoked.Reason)
   609  	}
   610  
   611  	return ret, nil
   612  }
   613  
   614  // RequestOptions contains options for constructing OCSP requests.
   615  type RequestOptions struct {
   616  	// Hash contains the hash function that should be used when
   617  	// constructing the OCSP request. If zero, SHA-1 will be used.
   618  	Hash crypto.Hash
   619  }
   620  
   621  func (opts *RequestOptions) hash() crypto.Hash {
   622  	if opts == nil || opts.Hash == 0 {
   623  		// SHA-1 is nearly universally used in OCSP.
   624  		return crypto.SHA1
   625  	}
   626  	return opts.Hash
   627  }
   628  
   629  // CreateRequest returns a DER-encoded, OCSP request for the status of cert. If
   630  // opts is nil then sensible defaults are used.
   631  func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) {
   632  	hashFunc := opts.hash()
   633  
   634  	// OCSP seems to be the only place where these raw hash identifiers are
   635  	// used. I took the following from
   636  	// http://msdn.microsoft.com/en-us/library/ff635603.aspx
   637  	_, ok := hashOIDs[hashFunc]
   638  	if !ok {
   639  		return nil, x509.ErrUnsupportedAlgorithm
   640  	}
   641  
   642  	if !hashFunc.Available() {
   643  		return nil, x509.ErrUnsupportedAlgorithm
   644  	}
   645  	h := opts.hash().New()
   646  
   647  	var publicKeyInfo struct {
   648  		Algorithm pkix.AlgorithmIdentifier
   649  		PublicKey asn1.BitString
   650  	}
   651  	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
   652  		return nil, err
   653  	}
   654  
   655  	h.Write(publicKeyInfo.PublicKey.RightAlign())
   656  	issuerKeyHash := h.Sum(nil)
   657  
   658  	h.Reset()
   659  	h.Write(issuer.RawSubject)
   660  	issuerNameHash := h.Sum(nil)
   661  
   662  	req := &Request{
   663  		HashAlgorithm:  hashFunc,
   664  		IssuerNameHash: issuerNameHash,
   665  		IssuerKeyHash:  issuerKeyHash,
   666  		SerialNumber:   cert.SerialNumber,
   667  	}
   668  	return req.Marshal()
   669  }
   670  
   671  // CreateResponse returns a DER-encoded OCSP response with the specified contents.
   672  // The fields in the response are populated as follows:
   673  //
   674  // The responder cert is used to populate the responder's name field, and the
   675  // certificate itself is provided alongside the OCSP response signature.
   676  //
   677  // The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields.
   678  //
   679  // The template is used to populate the SerialNumber, Status, RevokedAt,
   680  // RevocationReason, ThisUpdate, and NextUpdate fields.
   681  //
   682  // If template.IssuerHash is not set, SHA1 will be used.
   683  //
   684  // The ProducedAt date is automatically set to the current date, to the nearest minute.
   685  func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) {
   686  	var publicKeyInfo struct {
   687  		Algorithm pkix.AlgorithmIdentifier
   688  		PublicKey asn1.BitString
   689  	}
   690  	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
   691  		return nil, err
   692  	}
   693  
   694  	if template.IssuerHash == 0 {
   695  		template.IssuerHash = crypto.SHA1
   696  	}
   697  	hashOID := getOIDFromHashAlgorithm(template.IssuerHash)
   698  	if hashOID == nil {
   699  		return nil, errors.New("unsupported issuer hash algorithm")
   700  	}
   701  
   702  	if !template.IssuerHash.Available() {
   703  		return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash)
   704  	}
   705  	h := template.IssuerHash.New()
   706  	h.Write(publicKeyInfo.PublicKey.RightAlign())
   707  	issuerKeyHash := h.Sum(nil)
   708  
   709  	h.Reset()
   710  	h.Write(issuer.RawSubject)
   711  	issuerNameHash := h.Sum(nil)
   712  
   713  	innerResponse := singleResponse{
   714  		CertID: certID{
   715  			HashAlgorithm: pkix.AlgorithmIdentifier{
   716  				Algorithm:  hashOID,
   717  				Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
   718  			},
   719  			NameHash:      issuerNameHash,
   720  			IssuerKeyHash: issuerKeyHash,
   721  			SerialNumber:  template.SerialNumber,
   722  		},
   723  		ThisUpdate:       template.ThisUpdate.UTC(),
   724  		NextUpdate:       template.NextUpdate.UTC(),
   725  		SingleExtensions: template.ExtraExtensions,
   726  	}
   727  
   728  	switch template.Status {
   729  	case Good:
   730  		innerResponse.Good = true
   731  	case Unknown:
   732  		innerResponse.Unknown = true
   733  	case Revoked:
   734  		innerResponse.Revoked = revokedInfo{
   735  			RevocationTime: template.RevokedAt.UTC(),
   736  			Reason:         asn1.Enumerated(template.RevocationReason),
   737  		}
   738  	}
   739  
   740  	rawResponderID := asn1.RawValue{
   741  		Class:      2, // context-specific
   742  		Tag:        1, // Name (explicit tag)
   743  		IsCompound: true,
   744  		Bytes:      responderCert.RawSubject,
   745  	}
   746  	tbsResponseData := responseData{
   747  		Version:        0,
   748  		RawResponderID: rawResponderID,
   749  		ProducedAt:     time.Now().Truncate(time.Minute).UTC(),
   750  		Responses:      []singleResponse{innerResponse},
   751  	}
   752  
   753  	tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
   754  	if err != nil {
   755  		return nil, err
   756  	}
   757  
   758  	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
   759  	if err != nil {
   760  		return nil, err
   761  	}
   762  
   763  	responseHash := hashFunc.New()
   764  	responseHash.Write(tbsResponseDataDER)
   765  	signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
   766  	if err != nil {
   767  		return nil, err
   768  	}
   769  
   770  	response := basicResponse{
   771  		TBSResponseData:    tbsResponseData,
   772  		SignatureAlgorithm: signatureAlgorithm,
   773  		Signature: asn1.BitString{
   774  			Bytes:     signature,
   775  			BitLength: 8 * len(signature),
   776  		},
   777  	}
   778  	if template.Certificate != nil {
   779  		response.Certificates = []asn1.RawValue{
   780  			{FullBytes: template.Certificate.Raw},
   781  		}
   782  	}
   783  	responseDER, err := asn1.Marshal(response)
   784  	if err != nil {
   785  		return nil, err
   786  	}
   787  
   788  	return asn1.Marshal(responseASN1{
   789  		Status: asn1.Enumerated(Success),
   790  		Response: responseBytes{
   791  			ResponseType: idPKIXOCSPBasic,
   792  			Response:     responseDER,
   793  		},
   794  	})
   795  }