1  
     2  
     3  
     4  
     5  
     6  
     7  
     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  	"crypto/x509"
    20  	"crypto/x509/pkix"
    21  	"encoding/asn1"
    22  	"errors"
    23  	"fmt"
    24  	"math/big"
    25  	"strconv"
    26  	"time"
    27  )
    28  
    29  var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1})
    30  
    31  
    32  
    33  type ResponseStatus int
    34  
    35  const (
    36  	Success       ResponseStatus = 0
    37  	Malformed     ResponseStatus = 1
    38  	InternalError ResponseStatus = 2
    39  	TryLater      ResponseStatus = 3
    40  	
    41  	
    42  	SignatureRequired ResponseStatus = 5
    43  	Unauthorized      ResponseStatus = 6
    44  )
    45  
    46  func (r ResponseStatus) String() string {
    47  	switch r {
    48  	case Success:
    49  		return "success"
    50  	case Malformed:
    51  		return "malformed"
    52  	case InternalError:
    53  		return "internal error"
    54  	case TryLater:
    55  		return "try later"
    56  	case SignatureRequired:
    57  		return "signature required"
    58  	case Unauthorized:
    59  		return "unauthorized"
    60  	default:
    61  		return "unknown OCSP status: " + strconv.Itoa(int(r))
    62  	}
    63  }
    64  
    65  
    66  
    67  
    68  type ResponseError struct {
    69  	Status ResponseStatus
    70  }
    71  
    72  func (r ResponseError) Error() string {
    73  	return "ocsp: error from server: " + r.Status.String()
    74  }
    75  
    76  
    77  
    78  
    79  type certID struct {
    80  	HashAlgorithm pkix.AlgorithmIdentifier
    81  	NameHash      []byte
    82  	IssuerKeyHash []byte
    83  	SerialNumber  *big.Int
    84  }
    85  
    86  
    87  type ocspRequest struct {
    88  	TBSRequest tbsRequest
    89  }
    90  
    91  type tbsRequest struct {
    92  	Version       int              `asn1:"explicit,tag:0,default:0,optional"`
    93  	RequestorName pkix.RDNSequence `asn1:"explicit,tag:1,optional"`
    94  	RequestList   []request
    95  }
    96  
    97  type request struct {
    98  	Cert certID
    99  }
   100  
   101  type responseASN1 struct {
   102  	Status   asn1.Enumerated
   103  	Response responseBytes `asn1:"explicit,tag:0,optional"`
   104  }
   105  
   106  type responseBytes struct {
   107  	ResponseType asn1.ObjectIdentifier
   108  	Response     []byte
   109  }
   110  
   111  type basicResponse struct {
   112  	TBSResponseData    responseData
   113  	SignatureAlgorithm pkix.AlgorithmIdentifier
   114  	Signature          asn1.BitString
   115  	Certificates       []asn1.RawValue `asn1:"explicit,tag:0,optional"`
   116  }
   117  
   118  type responseData struct {
   119  	Raw            asn1.RawContent
   120  	Version        int `asn1:"optional,default:0,explicit,tag:0"`
   121  	RawResponderID asn1.RawValue
   122  	ProducedAt     time.Time `asn1:"generalized"`
   123  	Responses      []singleResponse
   124  }
   125  
   126  type singleResponse struct {
   127  	CertID           certID
   128  	Good             asn1.Flag        `asn1:"tag:0,optional"`
   129  	Revoked          revokedInfo      `asn1:"tag:1,optional"`
   130  	Unknown          asn1.Flag        `asn1:"tag:2,optional"`
   131  	ThisUpdate       time.Time        `asn1:"generalized"`
   132  	NextUpdate       time.Time        `asn1:"generalized,explicit,tag:0,optional"`
   133  	SingleExtensions []pkix.Extension `asn1:"explicit,tag:1,optional"`
   134  }
   135  
   136  type revokedInfo struct {
   137  	RevocationTime time.Time       `asn1:"generalized"`
   138  	Reason         asn1.Enumerated `asn1:"explicit,tag:0,optional"`
   139  }
   140  
   141  var (
   142  	oidSignatureMD2WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
   143  	oidSignatureMD5WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
   144  	oidSignatureSHA1WithRSA     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
   145  	oidSignatureSHA256WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
   146  	oidSignatureSHA384WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
   147  	oidSignatureSHA512WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
   148  	oidSignatureDSAWithSHA1     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
   149  	oidSignatureDSAWithSHA256   = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
   150  	oidSignatureECDSAWithSHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
   151  	oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
   152  	oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
   153  	oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
   154  )
   155  
   156  var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{
   157  	crypto.SHA1:   asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}),
   158  	crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}),
   159  	crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}),
   160  	crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}),
   161  }
   162  
   163  
   164  var signatureAlgorithmDetails = []struct {
   165  	algo       x509.SignatureAlgorithm
   166  	oid        asn1.ObjectIdentifier
   167  	pubKeyAlgo x509.PublicKeyAlgorithm
   168  	hash       crypto.Hash
   169  }{
   170  	{x509.MD2WithRSA, oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) },
   171  	{x509.MD5WithRSA, oidSignatureMD5WithRSA, x509.RSA, crypto.MD5},
   172  	{x509.SHA1WithRSA, oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
   173  	{x509.SHA256WithRSA, oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256},
   174  	{x509.SHA384WithRSA, oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384},
   175  	{x509.SHA512WithRSA, oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512},
   176  	{x509.DSAWithSHA1, oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1},
   177  	{x509.DSAWithSHA256, oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256},
   178  	{x509.ECDSAWithSHA1, oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1},
   179  	{x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256},
   180  	{x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384},
   181  	{x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512},
   182  }
   183  
   184  
   185  func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
   186  	var pubType x509.PublicKeyAlgorithm
   187  
   188  	switch pub := pub.(type) {
   189  	case *rsa.PublicKey:
   190  		pubType = x509.RSA
   191  		hashFunc = crypto.SHA256
   192  		sigAlgo.Algorithm = oidSignatureSHA256WithRSA
   193  		sigAlgo.Parameters = asn1.RawValue{
   194  			Tag: 5,
   195  		}
   196  
   197  	case *ecdsa.PublicKey:
   198  		pubType = x509.ECDSA
   199  
   200  		switch pub.Curve {
   201  		case elliptic.P224(), elliptic.P256():
   202  			hashFunc = crypto.SHA256
   203  			sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
   204  		case elliptic.P384():
   205  			hashFunc = crypto.SHA384
   206  			sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
   207  		case elliptic.P521():
   208  			hashFunc = crypto.SHA512
   209  			sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
   210  		default:
   211  			err = errors.New("x509: unknown elliptic curve")
   212  		}
   213  
   214  	default:
   215  		err = errors.New("x509: only RSA and ECDSA keys supported")
   216  	}
   217  
   218  	if err != nil {
   219  		return
   220  	}
   221  
   222  	if requestedSigAlgo == 0 {
   223  		return
   224  	}
   225  
   226  	found := false
   227  	for _, details := range signatureAlgorithmDetails {
   228  		if details.algo == requestedSigAlgo {
   229  			if details.pubKeyAlgo != pubType {
   230  				err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
   231  				return
   232  			}
   233  			sigAlgo.Algorithm, hashFunc = details.oid, details.hash
   234  			if hashFunc == 0 {
   235  				err = errors.New("x509: cannot sign with hash function requested")
   236  				return
   237  			}
   238  			found = true
   239  			break
   240  		}
   241  	}
   242  
   243  	if !found {
   244  		err = errors.New("x509: unknown SignatureAlgorithm")
   245  	}
   246  
   247  	return
   248  }
   249  
   250  
   251  
   252  func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.SignatureAlgorithm {
   253  	for _, details := range signatureAlgorithmDetails {
   254  		if oid.Equal(details.oid) {
   255  			return details.algo
   256  		}
   257  	}
   258  	return x509.UnknownSignatureAlgorithm
   259  }
   260  
   261  
   262  func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
   263  	for hash, oid := range hashOIDs {
   264  		if oid.Equal(target) {
   265  			return hash
   266  		}
   267  	}
   268  	return crypto.Hash(0)
   269  }
   270  
   271  func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier {
   272  	for hash, oid := range hashOIDs {
   273  		if hash == target {
   274  			return oid
   275  		}
   276  	}
   277  	return nil
   278  }
   279  
   280  
   281  
   282  
   283  const (
   284  	
   285  	Good = iota
   286  	
   287  	Revoked
   288  	
   289  	Unknown
   290  	
   291  	
   292  	
   293  	ServerFailed
   294  )
   295  
   296  
   297  const (
   298  	Unspecified          = 0
   299  	KeyCompromise        = 1
   300  	CACompromise         = 2
   301  	AffiliationChanged   = 3
   302  	Superseded           = 4
   303  	CessationOfOperation = 5
   304  	CertificateHold      = 6
   305  
   306  	RemoveFromCRL      = 8
   307  	PrivilegeWithdrawn = 9
   308  	AACompromise       = 10
   309  )
   310  
   311  
   312  type Request struct {
   313  	HashAlgorithm  crypto.Hash
   314  	IssuerNameHash []byte
   315  	IssuerKeyHash  []byte
   316  	SerialNumber   *big.Int
   317  }
   318  
   319  
   320  func (req *Request) Marshal() ([]byte, error) {
   321  	hashAlg := getOIDFromHashAlgorithm(req.HashAlgorithm)
   322  	if hashAlg == nil {
   323  		return nil, errors.New("Unknown hash algorithm")
   324  	}
   325  	return asn1.Marshal(ocspRequest{
   326  		tbsRequest{
   327  			Version: 0,
   328  			RequestList: []request{
   329  				{
   330  					Cert: certID{
   331  						pkix.AlgorithmIdentifier{
   332  							Algorithm:  hashAlg,
   333  							Parameters: asn1.RawValue{Tag: 5 },
   334  						},
   335  						req.IssuerNameHash,
   336  						req.IssuerKeyHash,
   337  						req.SerialNumber,
   338  					},
   339  				},
   340  			},
   341  		},
   342  	})
   343  }
   344  
   345  
   346  
   347  type Response struct {
   348  	Raw []byte
   349  
   350  	
   351  	Status                                        int
   352  	SerialNumber                                  *big.Int
   353  	ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
   354  	RevocationReason                              int
   355  	Certificate                                   *x509.Certificate
   356  	
   357  	
   358  	TBSResponseData    []byte
   359  	Signature          []byte
   360  	SignatureAlgorithm x509.SignatureAlgorithm
   361  
   362  	
   363  	
   364  	
   365  	IssuerHash crypto.Hash
   366  
   367  	
   368  	
   369  	
   370  	RawResponderName []byte
   371  	
   372  	
   373  	
   374  	ResponderKeyHash []byte
   375  
   376  	
   377  	
   378  	
   379  	
   380  	
   381  	Extensions []pkix.Extension
   382  
   383  	
   384  	
   385  	
   386  	
   387  	
   388  	ExtraExtensions []pkix.Extension
   389  }
   390  
   391  
   392  
   393  
   394  
   395  var (
   396  	MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01}
   397  	InternalErrorErrorResponse    = []byte{0x30, 0x03, 0x0A, 0x01, 0x02}
   398  	TryLaterErrorResponse         = []byte{0x30, 0x03, 0x0A, 0x01, 0x03}
   399  	SigRequredErrorResponse       = []byte{0x30, 0x03, 0x0A, 0x01, 0x05}
   400  	UnauthorizedErrorResponse     = []byte{0x30, 0x03, 0x0A, 0x01, 0x06}
   401  )
   402  
   403  
   404  
   405  
   406  
   407  
   408  func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error {
   409  	return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature)
   410  }
   411  
   412  
   413  type ParseError string
   414  
   415  func (p ParseError) Error() string {
   416  	return string(p)
   417  }
   418  
   419  
   420  
   421  
   422  func ParseRequest(bytes []byte) (*Request, error) {
   423  	var req ocspRequest
   424  	rest, err := asn1.Unmarshal(bytes, &req)
   425  	if err != nil {
   426  		return nil, err
   427  	}
   428  	if len(rest) > 0 {
   429  		return nil, ParseError("trailing data in OCSP request")
   430  	}
   431  
   432  	if len(req.TBSRequest.RequestList) == 0 {
   433  		return nil, ParseError("OCSP request contains no request body")
   434  	}
   435  	innerRequest := req.TBSRequest.RequestList[0]
   436  
   437  	hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm)
   438  	if hashFunc == crypto.Hash(0) {
   439  		return nil, ParseError("OCSP request uses unknown hash function")
   440  	}
   441  
   442  	return &Request{
   443  		HashAlgorithm:  hashFunc,
   444  		IssuerNameHash: innerRequest.Cert.NameHash,
   445  		IssuerKeyHash:  innerRequest.Cert.IssuerKeyHash,
   446  		SerialNumber:   innerRequest.Cert.SerialNumber,
   447  	}, nil
   448  }
   449  
   450  
   451  
   452  
   453  
   454  
   455  
   456  
   457  
   458  
   459  
   460  
   461  
   462  
   463  
   464  
   465  func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
   466  	return ParseResponseForCert(bytes, nil, issuer)
   467  }
   468  
   469  
   470  
   471  
   472  
   473  
   474  func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
   475  	var resp responseASN1
   476  	rest, err := asn1.Unmarshal(bytes, &resp)
   477  	if err != nil {
   478  		return nil, err
   479  	}
   480  	if len(rest) > 0 {
   481  		return nil, ParseError("trailing data in OCSP response")
   482  	}
   483  
   484  	if status := ResponseStatus(resp.Status); status != Success {
   485  		return nil, ResponseError{status}
   486  	}
   487  
   488  	if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
   489  		return nil, ParseError("bad OCSP response type")
   490  	}
   491  
   492  	var basicResp basicResponse
   493  	rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
   494  	if err != nil {
   495  		return nil, err
   496  	}
   497  	if len(rest) > 0 {
   498  		return nil, ParseError("trailing data in OCSP response")
   499  	}
   500  
   501  	if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
   502  		return nil, ParseError("OCSP response contains bad number of responses")
   503  	}
   504  
   505  	var singleResp singleResponse
   506  	if cert == nil {
   507  		singleResp = basicResp.TBSResponseData.Responses[0]
   508  	} else {
   509  		match := false
   510  		for _, resp := range basicResp.TBSResponseData.Responses {
   511  			if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
   512  				singleResp = resp
   513  				match = true
   514  				break
   515  			}
   516  		}
   517  		if !match {
   518  			return nil, ParseError("no response matching the supplied certificate")
   519  		}
   520  	}
   521  
   522  	ret := &Response{
   523  		Raw:                bytes,
   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  	
   535  	
   536  	
   537  	rawResponderID := basicResp.TBSResponseData.RawResponderID
   538  	switch rawResponderID.Tag {
   539  	case 1: 
   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: 
   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  		
   555  		
   556  		
   557  		
   558  		
   559  		
   560  		
   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  	case bool(singleResp.Unknown):
   601  		ret.Status = Unknown
   602  	default:
   603  		ret.Status = Revoked
   604  		ret.RevokedAt = singleResp.Revoked.RevocationTime
   605  		ret.RevocationReason = int(singleResp.Revoked.Reason)
   606  	}
   607  
   608  	return ret, nil
   609  }
   610  
   611  
   612  type RequestOptions struct {
   613  	
   614  	
   615  	Hash crypto.Hash
   616  }
   617  
   618  func (opts *RequestOptions) hash() crypto.Hash {
   619  	if opts == nil || opts.Hash == 0 {
   620  		
   621  		return crypto.SHA1
   622  	}
   623  	return opts.Hash
   624  }
   625  
   626  
   627  
   628  func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) {
   629  	hashFunc := opts.hash()
   630  
   631  	
   632  	
   633  	
   634  	_, ok := hashOIDs[hashFunc]
   635  	if !ok {
   636  		return nil, x509.ErrUnsupportedAlgorithm
   637  	}
   638  
   639  	if !hashFunc.Available() {
   640  		return nil, x509.ErrUnsupportedAlgorithm
   641  	}
   642  	h := opts.hash().New()
   643  
   644  	var publicKeyInfo struct {
   645  		Algorithm pkix.AlgorithmIdentifier
   646  		PublicKey asn1.BitString
   647  	}
   648  	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
   649  		return nil, err
   650  	}
   651  
   652  	h.Write(publicKeyInfo.PublicKey.RightAlign())
   653  	issuerKeyHash := h.Sum(nil)
   654  
   655  	h.Reset()
   656  	h.Write(issuer.RawSubject)
   657  	issuerNameHash := h.Sum(nil)
   658  
   659  	req := &Request{
   660  		HashAlgorithm:  hashFunc,
   661  		IssuerNameHash: issuerNameHash,
   662  		IssuerKeyHash:  issuerKeyHash,
   663  		SerialNumber:   cert.SerialNumber,
   664  	}
   665  	return req.Marshal()
   666  }
   667  
   668  
   669  
   670  
   671  
   672  
   673  
   674  
   675  
   676  
   677  
   678  
   679  
   680  
   681  
   682  func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) {
   683  	var publicKeyInfo struct {
   684  		Algorithm pkix.AlgorithmIdentifier
   685  		PublicKey asn1.BitString
   686  	}
   687  	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
   688  		return nil, err
   689  	}
   690  
   691  	if template.IssuerHash == 0 {
   692  		template.IssuerHash = crypto.SHA1
   693  	}
   694  	hashOID := getOIDFromHashAlgorithm(template.IssuerHash)
   695  	if hashOID == nil {
   696  		return nil, errors.New("unsupported issuer hash algorithm")
   697  	}
   698  
   699  	if !template.IssuerHash.Available() {
   700  		return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash)
   701  	}
   702  	h := template.IssuerHash.New()
   703  	h.Write(publicKeyInfo.PublicKey.RightAlign())
   704  	issuerKeyHash := h.Sum(nil)
   705  
   706  	h.Reset()
   707  	h.Write(issuer.RawSubject)
   708  	issuerNameHash := h.Sum(nil)
   709  
   710  	innerResponse := singleResponse{
   711  		CertID: certID{
   712  			HashAlgorithm: pkix.AlgorithmIdentifier{
   713  				Algorithm:  hashOID,
   714  				Parameters: asn1.RawValue{Tag: 5 },
   715  			},
   716  			NameHash:      issuerNameHash,
   717  			IssuerKeyHash: issuerKeyHash,
   718  			SerialNumber:  template.SerialNumber,
   719  		},
   720  		ThisUpdate:       template.ThisUpdate.UTC(),
   721  		NextUpdate:       template.NextUpdate.UTC(),
   722  		SingleExtensions: template.ExtraExtensions,
   723  	}
   724  
   725  	switch template.Status {
   726  	case Good:
   727  		innerResponse.Good = true
   728  	case Unknown:
   729  		innerResponse.Unknown = true
   730  	case Revoked:
   731  		innerResponse.Revoked = revokedInfo{
   732  			RevocationTime: template.RevokedAt.UTC(),
   733  			Reason:         asn1.Enumerated(template.RevocationReason),
   734  		}
   735  	}
   736  
   737  	rawResponderID := asn1.RawValue{
   738  		Class:      2, 
   739  		Tag:        1, 
   740  		IsCompound: true,
   741  		Bytes:      responderCert.RawSubject,
   742  	}
   743  	tbsResponseData := responseData{
   744  		Version:        0,
   745  		RawResponderID: rawResponderID,
   746  		ProducedAt:     time.Now().Truncate(time.Minute).UTC(),
   747  		Responses:      []singleResponse{innerResponse},
   748  	}
   749  
   750  	tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
   751  	if err != nil {
   752  		return nil, err
   753  	}
   754  
   755  	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
   756  	if err != nil {
   757  		return nil, err
   758  	}
   759  
   760  	responseHash := hashFunc.New()
   761  	responseHash.Write(tbsResponseDataDER)
   762  	signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
   763  	if err != nil {
   764  		return nil, err
   765  	}
   766  
   767  	response := basicResponse{
   768  		TBSResponseData:    tbsResponseData,
   769  		SignatureAlgorithm: signatureAlgorithm,
   770  		Signature: asn1.BitString{
   771  			Bytes:     signature,
   772  			BitLength: 8 * len(signature),
   773  		},
   774  	}
   775  	if template.Certificate != nil {
   776  		response.Certificates = []asn1.RawValue{
   777  			{FullBytes: template.Certificate.Raw},
   778  		}
   779  	}
   780  	responseDER, err := asn1.Marshal(response)
   781  	if err != nil {
   782  		return nil, err
   783  	}
   784  
   785  	return asn1.Marshal(responseASN1{
   786  		Status: asn1.Enumerated(Success),
   787  		Response: responseBytes{
   788  			ResponseType: idPKIXOCSPBasic,
   789  			Response:     responseDER,
   790  		},
   791  	})
   792  }
   793  
View as plain text