OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / ocsp / ocsp.go
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 // import "golang.org/x/crypto/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 // ResponseStatus contains the result of an OCSP request. See
32 // https://tools.ietf.org/html/rfc6960#section-2.3
33 type ResponseStatus int
34
35 const (
36         Success       ResponseStatus = 0
37         Malformed     ResponseStatus = 1
38         InternalError ResponseStatus = 2
39         TryLater      ResponseStatus = 3
40         // Status code four is unused in OCSP. See
41         // https://tools.ietf.org/html/rfc6960#section-4.2.1
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 // ResponseError is an error that may be returned by ParseResponse to indicate
66 // that the response itself is an error, not just that its indicating that a
67 // certificate is revoked, unknown, etc.
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 // These are internal structures that reflect the ASN.1 structure of an OCSP
77 // response. See RFC 2560, section 4.2.
78
79 type certID struct {
80         HashAlgorithm pkix.AlgorithmIdentifier
81         NameHash      []byte
82         IssuerKeyHash []byte
83         SerialNumber  *big.Int
84 }
85
86 // https://tools.ietf.org/html/rfc2560#section-4.1.1
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 // TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
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) /* no value for MD2 */},
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 // TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
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 // TODO(agl): this is taken from crypto/x509 and so should probably be exported
251 // from crypto/x509 or crypto/x509/pkix.
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 // TODO(rlb): This is not taken from crypto/x509, but it's of the same general form.
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 // This is the exposed reflection of the internal OCSP structures.
281
282 // The status values that can be expressed in OCSP.  See RFC 6960.
283 const (
284         // Good means that the certificate is valid.
285         Good = iota
286         // Revoked means that the certificate has been deliberately revoked.
287         Revoked
288         // Unknown means that the OCSP responder doesn't know about the certificate.
289         Unknown
290         // ServerFailed is unused and was never used (see
291         // https://go-review.googlesource.com/#/c/18944). ParseResponse will
292         // return a ResponseError when an error response is parsed.
293         ServerFailed
294 )
295
296 // The enumerated reasons for revoking a certificate.  See RFC 5280.
297 const (
298         Unspecified          = iota
299         KeyCompromise        = iota
300         CACompromise         = iota
301         AffiliationChanged   = iota
302         Superseded           = iota
303         CessationOfOperation = iota
304         CertificateHold      = iota
305         _                    = iota
306         RemoveFromCRL        = iota
307         PrivilegeWithdrawn   = iota
308         AACompromise         = iota
309 )
310
311 // Request represents an OCSP request. See RFC 6960.
312 type Request struct {
313         HashAlgorithm  crypto.Hash
314         IssuerNameHash []byte
315         IssuerKeyHash  []byte
316         SerialNumber   *big.Int
317 }
318
319 // Marshal marshals the OCSP request to ASN.1 DER encoded form.
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 /* ASN.1 NULL */},
334                                                 },
335                                                 req.IssuerNameHash,
336                                                 req.IssuerKeyHash,
337                                                 req.SerialNumber,
338                                         },
339                                 },
340                         },
341                 },
342         })
343 }
344
345 // Response represents an OCSP response containing a single SingleResponse. See
346 // RFC 6960.
347 type Response struct {
348         // Status is one of {Good, Revoked, Unknown}
349         Status                                        int
350         SerialNumber                                  *big.Int
351         ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
352         RevocationReason                              int
353         Certificate                                   *x509.Certificate
354         // TBSResponseData contains the raw bytes of the signed response. If
355         // Certificate is nil then this can be used to verify Signature.
356         TBSResponseData    []byte
357         Signature          []byte
358         SignatureAlgorithm x509.SignatureAlgorithm
359
360         // IssuerHash is the hash used to compute the IssuerNameHash and IssuerKeyHash.
361         // Valid values are crypto.SHA1, crypto.SHA256, crypto.SHA384, and crypto.SHA512.
362         // If zero, the default is crypto.SHA1.
363         IssuerHash crypto.Hash
364
365         // RawResponderName optionally contains the DER-encoded subject of the
366         // responder certificate. Exactly one of RawResponderName and
367         // ResponderKeyHash is set.
368         RawResponderName []byte
369         // ResponderKeyHash optionally contains the SHA-1 hash of the
370         // responder's public key. Exactly one of RawResponderName and
371         // ResponderKeyHash is set.
372         ResponderKeyHash []byte
373
374         // Extensions contains raw X.509 extensions from the singleExtensions field
375         // of the OCSP response. When parsing certificates, this can be used to
376         // extract non-critical extensions that are not parsed by this package. When
377         // marshaling OCSP responses, the Extensions field is ignored, see
378         // ExtraExtensions.
379         Extensions []pkix.Extension
380
381         // ExtraExtensions contains extensions to be copied, raw, into any marshaled
382         // OCSP response (in the singleExtensions field). Values override any
383         // extensions that would otherwise be produced based on the other fields. The
384         // ExtraExtensions field is not populated when parsing certificates, see
385         // Extensions.
386         ExtraExtensions []pkix.Extension
387 }
388
389 // These are pre-serialized error responses for the various non-success codes
390 // defined by OCSP. The Unauthorized code in particular can be used by an OCSP
391 // responder that supports only pre-signed responses as a response to requests
392 // for certificates with unknown status. See RFC 5019.
393 var (
394         MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01}
395         InternalErrorErrorResponse    = []byte{0x30, 0x03, 0x0A, 0x01, 0x02}
396         TryLaterErrorResponse         = []byte{0x30, 0x03, 0x0A, 0x01, 0x03}
397         SigRequredErrorResponse       = []byte{0x30, 0x03, 0x0A, 0x01, 0x05}
398         UnauthorizedErrorResponse     = []byte{0x30, 0x03, 0x0A, 0x01, 0x06}
399 )
400
401 // CheckSignatureFrom checks that the signature in resp is a valid signature
402 // from issuer. This should only be used if resp.Certificate is nil. Otherwise,
403 // the OCSP response contained an intermediate certificate that created the
404 // signature. That signature is checked by ParseResponse and only
405 // resp.Certificate remains to be validated.
406 func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error {
407         return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature)
408 }
409
410 // ParseError results from an invalid OCSP response.
411 type ParseError string
412
413 func (p ParseError) Error() string {
414         return string(p)
415 }
416
417 // ParseRequest parses an OCSP request in DER form. It only supports
418 // requests for a single certificate. Signed requests are not supported.
419 // If a request includes a signature, it will result in a ParseError.
420 func ParseRequest(bytes []byte) (*Request, error) {
421         var req ocspRequest
422         rest, err := asn1.Unmarshal(bytes, &req)
423         if err != nil {
424                 return nil, err
425         }
426         if len(rest) > 0 {
427                 return nil, ParseError("trailing data in OCSP request")
428         }
429
430         if len(req.TBSRequest.RequestList) == 0 {
431                 return nil, ParseError("OCSP request contains no request body")
432         }
433         innerRequest := req.TBSRequest.RequestList[0]
434
435         hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm)
436         if hashFunc == crypto.Hash(0) {
437                 return nil, ParseError("OCSP request uses unknown hash function")
438         }
439
440         return &Request{
441                 HashAlgorithm:  hashFunc,
442                 IssuerNameHash: innerRequest.Cert.NameHash,
443                 IssuerKeyHash:  innerRequest.Cert.IssuerKeyHash,
444                 SerialNumber:   innerRequest.Cert.SerialNumber,
445         }, nil
446 }
447
448 // ParseResponse parses an OCSP response in DER form. It only supports
449 // responses for a single certificate. If the response contains a certificate
450 // then the signature over the response is checked. If issuer is not nil then
451 // it will be used to validate the signature or embedded certificate.
452 //
453 // Invalid responses and parse failures will result in a ParseError.
454 // Error responses will result in a ResponseError.
455 func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
456         return ParseResponseForCert(bytes, nil, issuer)
457 }
458
459 // ParseResponseForCert parses an OCSP response in DER form and searches for a
460 // Response relating to cert. If such a Response is found and the OCSP response
461 // contains a certificate then the signature over the response is checked. If
462 // issuer is not nil then it will be used to validate the signature or embedded
463 // certificate.
464 //
465 // Invalid responses and parse failures will result in a ParseError.
466 // Error responses will result in a ResponseError.
467 func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
468         var resp responseASN1
469         rest, err := asn1.Unmarshal(bytes, &resp)
470         if err != nil {
471                 return nil, err
472         }
473         if len(rest) > 0 {
474                 return nil, ParseError("trailing data in OCSP response")
475         }
476
477         if status := ResponseStatus(resp.Status); status != Success {
478                 return nil, ResponseError{status}
479         }
480
481         if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
482                 return nil, ParseError("bad OCSP response type")
483         }
484
485         var basicResp basicResponse
486         rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
487         if err != nil {
488                 return nil, err
489         }
490
491         if len(basicResp.Certificates) > 1 {
492                 return nil, ParseError("OCSP response contains bad number of certificates")
493         }
494
495         if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
496                 return nil, ParseError("OCSP response contains bad number of responses")
497         }
498
499         var singleResp singleResponse
500         if cert == nil {
501                 singleResp = basicResp.TBSResponseData.Responses[0]
502         } else {
503                 match := false
504                 for _, resp := range basicResp.TBSResponseData.Responses {
505                         if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
506                                 singleResp = resp
507                                 match = true
508                                 break
509                         }
510                 }
511                 if !match {
512                         return nil, ParseError("no response matching the supplied certificate")
513                 }
514         }
515
516         ret := &Response{
517                 TBSResponseData:    basicResp.TBSResponseData.Raw,
518                 Signature:          basicResp.Signature.RightAlign(),
519                 SignatureAlgorithm: getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm),
520                 Extensions:         singleResp.SingleExtensions,
521                 SerialNumber:       singleResp.CertID.SerialNumber,
522                 ProducedAt:         basicResp.TBSResponseData.ProducedAt,
523                 ThisUpdate:         singleResp.ThisUpdate,
524                 NextUpdate:         singleResp.NextUpdate,
525         }
526
527         // Handle the ResponderID CHOICE tag. ResponderID can be flattened into
528         // TBSResponseData once https://go-review.googlesource.com/34503 has been
529         // released.
530         rawResponderID := basicResp.TBSResponseData.RawResponderID
531         switch rawResponderID.Tag {
532         case 1: // Name
533                 var rdn pkix.RDNSequence
534                 if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &rdn); err != nil || len(rest) != 0 {
535                         return nil, ParseError("invalid responder name")
536                 }
537                 ret.RawResponderName = rawResponderID.Bytes
538         case 2: // KeyHash
539                 if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &ret.ResponderKeyHash); err != nil || len(rest) != 0 {
540                         return nil, ParseError("invalid responder key hash")
541                 }
542         default:
543                 return nil, ParseError("invalid responder id tag")
544         }
545
546         if len(basicResp.Certificates) > 0 {
547                 ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
548                 if err != nil {
549                         return nil, err
550                 }
551
552                 if err := ret.CheckSignatureFrom(ret.Certificate); err != nil {
553                         return nil, ParseError("bad signature on embedded certificate: " + err.Error())
554                 }
555
556                 if issuer != nil {
557                         if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil {
558                                 return nil, ParseError("bad OCSP signature: " + err.Error())
559                         }
560                 }
561         } else if issuer != nil {
562                 if err := ret.CheckSignatureFrom(issuer); err != nil {
563                         return nil, ParseError("bad OCSP signature: " + err.Error())
564                 }
565         }
566
567         for _, ext := range singleResp.SingleExtensions {
568                 if ext.Critical {
569                         return nil, ParseError("unsupported critical extension")
570                 }
571         }
572
573         for h, oid := range hashOIDs {
574                 if singleResp.CertID.HashAlgorithm.Algorithm.Equal(oid) {
575                         ret.IssuerHash = h
576                         break
577                 }
578         }
579         if ret.IssuerHash == 0 {
580                 return nil, ParseError("unsupported issuer hash algorithm")
581         }
582
583         switch {
584         case bool(singleResp.Good):
585                 ret.Status = Good
586         case bool(singleResp.Unknown):
587                 ret.Status = Unknown
588         default:
589                 ret.Status = Revoked
590                 ret.RevokedAt = singleResp.Revoked.RevocationTime
591                 ret.RevocationReason = int(singleResp.Revoked.Reason)
592         }
593
594         return ret, nil
595 }
596
597 // RequestOptions contains options for constructing OCSP requests.
598 type RequestOptions struct {
599         // Hash contains the hash function that should be used when
600         // constructing the OCSP request. If zero, SHA-1 will be used.
601         Hash crypto.Hash
602 }
603
604 func (opts *RequestOptions) hash() crypto.Hash {
605         if opts == nil || opts.Hash == 0 {
606                 // SHA-1 is nearly universally used in OCSP.
607                 return crypto.SHA1
608         }
609         return opts.Hash
610 }
611
612 // CreateRequest returns a DER-encoded, OCSP request for the status of cert. If
613 // opts is nil then sensible defaults are used.
614 func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) {
615         hashFunc := opts.hash()
616
617         // OCSP seems to be the only place where these raw hash identifiers are
618         // used. I took the following from
619         // http://msdn.microsoft.com/en-us/library/ff635603.aspx
620         _, ok := hashOIDs[hashFunc]
621         if !ok {
622                 return nil, x509.ErrUnsupportedAlgorithm
623         }
624
625         if !hashFunc.Available() {
626                 return nil, x509.ErrUnsupportedAlgorithm
627         }
628         h := opts.hash().New()
629
630         var publicKeyInfo struct {
631                 Algorithm pkix.AlgorithmIdentifier
632                 PublicKey asn1.BitString
633         }
634         if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
635                 return nil, err
636         }
637
638         h.Write(publicKeyInfo.PublicKey.RightAlign())
639         issuerKeyHash := h.Sum(nil)
640
641         h.Reset()
642         h.Write(issuer.RawSubject)
643         issuerNameHash := h.Sum(nil)
644
645         req := &Request{
646                 HashAlgorithm:  hashFunc,
647                 IssuerNameHash: issuerNameHash,
648                 IssuerKeyHash:  issuerKeyHash,
649                 SerialNumber:   cert.SerialNumber,
650         }
651         return req.Marshal()
652 }
653
654 // CreateResponse returns a DER-encoded OCSP response with the specified contents.
655 // The fields in the response are populated as follows:
656 //
657 // The responder cert is used to populate the responder's name field, and the
658 // certificate itself is provided alongside the OCSP response signature.
659 //
660 // The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields.
661 //
662 // The template is used to populate the SerialNumber, RevocationStatus, RevokedAt,
663 // RevocationReason, ThisUpdate, and NextUpdate fields.
664 //
665 // If template.IssuerHash is not set, SHA1 will be used.
666 //
667 // The ProducedAt date is automatically set to the current date, to the nearest minute.
668 func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) {
669         var publicKeyInfo struct {
670                 Algorithm pkix.AlgorithmIdentifier
671                 PublicKey asn1.BitString
672         }
673         if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
674                 return nil, err
675         }
676
677         if template.IssuerHash == 0 {
678                 template.IssuerHash = crypto.SHA1
679         }
680         hashOID := getOIDFromHashAlgorithm(template.IssuerHash)
681         if hashOID == nil {
682                 return nil, errors.New("unsupported issuer hash algorithm")
683         }
684
685         if !template.IssuerHash.Available() {
686                 return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash)
687         }
688         h := template.IssuerHash.New()
689         h.Write(publicKeyInfo.PublicKey.RightAlign())
690         issuerKeyHash := h.Sum(nil)
691
692         h.Reset()
693         h.Write(issuer.RawSubject)
694         issuerNameHash := h.Sum(nil)
695
696         innerResponse := singleResponse{
697                 CertID: certID{
698                         HashAlgorithm: pkix.AlgorithmIdentifier{
699                                 Algorithm:  hashOID,
700                                 Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
701                         },
702                         NameHash:      issuerNameHash,
703                         IssuerKeyHash: issuerKeyHash,
704                         SerialNumber:  template.SerialNumber,
705                 },
706                 ThisUpdate:       template.ThisUpdate.UTC(),
707                 NextUpdate:       template.NextUpdate.UTC(),
708                 SingleExtensions: template.ExtraExtensions,
709         }
710
711         switch template.Status {
712         case Good:
713                 innerResponse.Good = true
714         case Unknown:
715                 innerResponse.Unknown = true
716         case Revoked:
717                 innerResponse.Revoked = revokedInfo{
718                         RevocationTime: template.RevokedAt.UTC(),
719                         Reason:         asn1.Enumerated(template.RevocationReason),
720                 }
721         }
722
723         rawResponderID := asn1.RawValue{
724                 Class:      2, // context-specific
725                 Tag:        1, // Name (explicit tag)
726                 IsCompound: true,
727                 Bytes:      responderCert.RawSubject,
728         }
729         tbsResponseData := responseData{
730                 Version:        0,
731                 RawResponderID: rawResponderID,
732                 ProducedAt:     time.Now().Truncate(time.Minute).UTC(),
733                 Responses:      []singleResponse{innerResponse},
734         }
735
736         tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
737         if err != nil {
738                 return nil, err
739         }
740
741         hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
742         if err != nil {
743                 return nil, err
744         }
745
746         responseHash := hashFunc.New()
747         responseHash.Write(tbsResponseDataDER)
748         signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
749         if err != nil {
750                 return nil, err
751         }
752
753         response := basicResponse{
754                 TBSResponseData:    tbsResponseData,
755                 SignatureAlgorithm: signatureAlgorithm,
756                 Signature: asn1.BitString{
757                         Bytes:     signature,
758                         BitLength: 8 * len(signature),
759                 },
760         }
761         if template.Certificate != nil {
762                 response.Certificates = []asn1.RawValue{
763                         asn1.RawValue{FullBytes: template.Certificate.Raw},
764                 }
765         }
766         responseDER, err := asn1.Marshal(response)
767         if err != nil {
768                 return nil, err
769         }
770
771         return asn1.Marshal(responseASN1{
772                 Status: asn1.Enumerated(Success),
773                 Response: responseBytes{
774                         ResponseType: idPKIXOCSPBasic,
775                         Response:     responseDER,
776                 },
777         })
778 }