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.
8package ocsp // import "golang.org/x/crypto/ocsp"
9
10import (
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
29var 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
33type ResponseStatus int
34
35const (
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
46func (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 it's indicating that a
67// certificate is revoked, unknown, etc.
68type ResponseError struct {
69	Status ResponseStatus
70}
71
72func (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
79type 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
87type ocspRequest struct {
88	TBSRequest tbsRequest
89}
90
91type 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
97type request struct {
98	Cert certID
99}
100
101type responseASN1 struct {
102	Status   asn1.Enumerated
103	Response responseBytes `asn1:"explicit,tag:0,optional"`
104}
105
106type responseBytes struct {
107	ResponseType asn1.ObjectIdentifier
108	Response     []byte
109}
110
111type basicResponse struct {
112	TBSResponseData    responseData
113	SignatureAlgorithm pkix.AlgorithmIdentifier
114	Signature          asn1.BitString
115	Certificates       []asn1.RawValue `asn1:"explicit,tag:0,optional"`
116}
117
118type 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
126type 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
136type revokedInfo struct {
137	RevocationTime time.Time       `asn1:"generalized"`
138	Reason         asn1.Enumerated `asn1:"explicit,tag:0,optional"`
139}
140
141var (
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
156var 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
164var 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
185func 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.
252func 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.
262func 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
271func 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.
283const (
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.
297const (
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// Request represents an OCSP request. See RFC 6960.
312type 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.
320func (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.
347type 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.
393var (
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.
406func (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.
411type ParseError string
412
413func (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.
420func 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. The response must contain
449// only one certificate status. To parse the status of a specific certificate
450// from a response which may contain multiple statuses, use ParseResponseForCert
451// instead.
452//
453// If the response contains an embedded certificate, then that certificate will
454// be used to verify the response signature. If the response contains an
455// embedded certificate and issuer is not nil, then issuer will be used to verify
456// the signature on the embedded certificate.
457//
458// If the response does not contain an embedded certificate and issuer is not
459// nil, then issuer will be used to verify the response signature.
460//
461// Invalid responses and parse failures will result in a ParseError.
462// Error responses will result in a ResponseError.
463func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
464	return ParseResponseForCert(bytes, nil, issuer)
465}
466
467// ParseResponseForCert acts identically to ParseResponse, except it supports
468// parsing responses that contain multiple statuses. If the response contains
469// multiple statuses and cert is not nil, then ParseResponseForCert will return
470// the first status which contains a matching serial, otherwise it will return an
471// error. If cert is nil, then the first status in the response will be returned.
472func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
473	var resp responseASN1
474	rest, err := asn1.Unmarshal(bytes, &resp)
475	if err != nil {
476		return nil, err
477	}
478	if len(rest) > 0 {
479		return nil, ParseError("trailing data in OCSP response")
480	}
481
482	if status := ResponseStatus(resp.Status); status != Success {
483		return nil, ResponseError{status}
484	}
485
486	if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
487		return nil, ParseError("bad OCSP response type")
488	}
489
490	var basicResp basicResponse
491	rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
492	if err != nil {
493		return nil, err
494	}
495	if len(rest) > 0 {
496		return nil, ParseError("trailing data in OCSP response")
497	}
498
499	if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 {
500		return nil, ParseError("OCSP response contains bad number of responses")
501	}
502
503	var singleResp singleResponse
504	if cert == nil {
505		singleResp = basicResp.TBSResponseData.Responses[0]
506	} else {
507		match := false
508		for _, resp := range basicResp.TBSResponseData.Responses {
509			if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
510				singleResp = resp
511				match = true
512				break
513			}
514		}
515		if !match {
516			return nil, ParseError("no response matching the supplied certificate")
517		}
518	}
519
520	ret := &Response{
521		TBSResponseData:    basicResp.TBSResponseData.Raw,
522		Signature:          basicResp.Signature.RightAlign(),
523		SignatureAlgorithm: getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm),
524		Extensions:         singleResp.SingleExtensions,
525		SerialNumber:       singleResp.CertID.SerialNumber,
526		ProducedAt:         basicResp.TBSResponseData.ProducedAt,
527		ThisUpdate:         singleResp.ThisUpdate,
528		NextUpdate:         singleResp.NextUpdate,
529	}
530
531	// Handle the ResponderID CHOICE tag. ResponderID can be flattened into
532	// TBSResponseData once https://go-review.googlesource.com/34503 has been
533	// released.
534	rawResponderID := basicResp.TBSResponseData.RawResponderID
535	switch rawResponderID.Tag {
536	case 1: // Name
537		var rdn pkix.RDNSequence
538		if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &rdn); err != nil || len(rest) != 0 {
539			return nil, ParseError("invalid responder name")
540		}
541		ret.RawResponderName = rawResponderID.Bytes
542	case 2: // KeyHash
543		if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &ret.ResponderKeyHash); err != nil || len(rest) != 0 {
544			return nil, ParseError("invalid responder key hash")
545		}
546	default:
547		return nil, ParseError("invalid responder id tag")
548	}
549
550	if len(basicResp.Certificates) > 0 {
551		// Responders should only send a single certificate (if they
552		// send any) that connects the responder's certificate to the
553		// original issuer. We accept responses with multiple
554		// certificates due to a number responders sending them[1], but
555		// ignore all but the first.
556		//
557		// [1] https://github.com/golang/go/issues/21527
558		ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
559		if err != nil {
560			return nil, err
561		}
562
563		if err := ret.CheckSignatureFrom(ret.Certificate); err != nil {
564			return nil, ParseError("bad signature on embedded certificate: " + err.Error())
565		}
566
567		if issuer != nil {
568			if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil {
569				return nil, ParseError("bad OCSP signature: " + err.Error())
570			}
571		}
572	} else if issuer != nil {
573		if err := ret.CheckSignatureFrom(issuer); err != nil {
574			return nil, ParseError("bad OCSP signature: " + err.Error())
575		}
576	}
577
578	for _, ext := range singleResp.SingleExtensions {
579		if ext.Critical {
580			return nil, ParseError("unsupported critical extension")
581		}
582	}
583
584	for h, oid := range hashOIDs {
585		if singleResp.CertID.HashAlgorithm.Algorithm.Equal(oid) {
586			ret.IssuerHash = h
587			break
588		}
589	}
590	if ret.IssuerHash == 0 {
591		return nil, ParseError("unsupported issuer hash algorithm")
592	}
593
594	switch {
595	case bool(singleResp.Good):
596		ret.Status = Good
597	case bool(singleResp.Unknown):
598		ret.Status = Unknown
599	default:
600		ret.Status = Revoked
601		ret.RevokedAt = singleResp.Revoked.RevocationTime
602		ret.RevocationReason = int(singleResp.Revoked.Reason)
603	}
604
605	return ret, nil
606}
607
608// RequestOptions contains options for constructing OCSP requests.
609type RequestOptions struct {
610	// Hash contains the hash function that should be used when
611	// constructing the OCSP request. If zero, SHA-1 will be used.
612	Hash crypto.Hash
613}
614
615func (opts *RequestOptions) hash() crypto.Hash {
616	if opts == nil || opts.Hash == 0 {
617		// SHA-1 is nearly universally used in OCSP.
618		return crypto.SHA1
619	}
620	return opts.Hash
621}
622
623// CreateRequest returns a DER-encoded, OCSP request for the status of cert. If
624// opts is nil then sensible defaults are used.
625func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) {
626	hashFunc := opts.hash()
627
628	// OCSP seems to be the only place where these raw hash identifiers are
629	// used. I took the following from
630	// http://msdn.microsoft.com/en-us/library/ff635603.aspx
631	_, ok := hashOIDs[hashFunc]
632	if !ok {
633		return nil, x509.ErrUnsupportedAlgorithm
634	}
635
636	if !hashFunc.Available() {
637		return nil, x509.ErrUnsupportedAlgorithm
638	}
639	h := opts.hash().New()
640
641	var publicKeyInfo struct {
642		Algorithm pkix.AlgorithmIdentifier
643		PublicKey asn1.BitString
644	}
645	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
646		return nil, err
647	}
648
649	h.Write(publicKeyInfo.PublicKey.RightAlign())
650	issuerKeyHash := h.Sum(nil)
651
652	h.Reset()
653	h.Write(issuer.RawSubject)
654	issuerNameHash := h.Sum(nil)
655
656	req := &Request{
657		HashAlgorithm:  hashFunc,
658		IssuerNameHash: issuerNameHash,
659		IssuerKeyHash:  issuerKeyHash,
660		SerialNumber:   cert.SerialNumber,
661	}
662	return req.Marshal()
663}
664
665// CreateResponse returns a DER-encoded OCSP response with the specified contents.
666// The fields in the response are populated as follows:
667//
668// The responder cert is used to populate the responder's name field, and the
669// certificate itself is provided alongside the OCSP response signature.
670//
671// The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields.
672//
673// The template is used to populate the SerialNumber, Status, RevokedAt,
674// RevocationReason, ThisUpdate, and NextUpdate fields.
675//
676// If template.IssuerHash is not set, SHA1 will be used.
677//
678// The ProducedAt date is automatically set to the current date, to the nearest minute.
679func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) {
680	var publicKeyInfo struct {
681		Algorithm pkix.AlgorithmIdentifier
682		PublicKey asn1.BitString
683	}
684	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
685		return nil, err
686	}
687
688	if template.IssuerHash == 0 {
689		template.IssuerHash = crypto.SHA1
690	}
691	hashOID := getOIDFromHashAlgorithm(template.IssuerHash)
692	if hashOID == nil {
693		return nil, errors.New("unsupported issuer hash algorithm")
694	}
695
696	if !template.IssuerHash.Available() {
697		return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash)
698	}
699	h := template.IssuerHash.New()
700	h.Write(publicKeyInfo.PublicKey.RightAlign())
701	issuerKeyHash := h.Sum(nil)
702
703	h.Reset()
704	h.Write(issuer.RawSubject)
705	issuerNameHash := h.Sum(nil)
706
707	innerResponse := singleResponse{
708		CertID: certID{
709			HashAlgorithm: pkix.AlgorithmIdentifier{
710				Algorithm:  hashOID,
711				Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
712			},
713			NameHash:      issuerNameHash,
714			IssuerKeyHash: issuerKeyHash,
715			SerialNumber:  template.SerialNumber,
716		},
717		ThisUpdate:       template.ThisUpdate.UTC(),
718		NextUpdate:       template.NextUpdate.UTC(),
719		SingleExtensions: template.ExtraExtensions,
720	}
721
722	switch template.Status {
723	case Good:
724		innerResponse.Good = true
725	case Unknown:
726		innerResponse.Unknown = true
727	case Revoked:
728		innerResponse.Revoked = revokedInfo{
729			RevocationTime: template.RevokedAt.UTC(),
730			Reason:         asn1.Enumerated(template.RevocationReason),
731		}
732	}
733
734	rawResponderID := asn1.RawValue{
735		Class:      2, // context-specific
736		Tag:        1, // Name (explicit tag)
737		IsCompound: true,
738		Bytes:      responderCert.RawSubject,
739	}
740	tbsResponseData := responseData{
741		Version:        0,
742		RawResponderID: rawResponderID,
743		ProducedAt:     time.Now().Truncate(time.Minute).UTC(),
744		Responses:      []singleResponse{innerResponse},
745	}
746
747	tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
748	if err != nil {
749		return nil, err
750	}
751
752	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
753	if err != nil {
754		return nil, err
755	}
756
757	responseHash := hashFunc.New()
758	responseHash.Write(tbsResponseDataDER)
759	signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
760	if err != nil {
761		return nil, err
762	}
763
764	response := basicResponse{
765		TBSResponseData:    tbsResponseData,
766		SignatureAlgorithm: signatureAlgorithm,
767		Signature: asn1.BitString{
768			Bytes:     signature,
769			BitLength: 8 * len(signature),
770		},
771	}
772	if template.Certificate != nil {
773		response.Certificates = []asn1.RawValue{
774			{FullBytes: template.Certificate.Raw},
775		}
776	}
777	responseDER, err := asn1.Marshal(response)
778	if err != nil {
779		return nil, err
780	}
781
782	return asn1.Marshal(responseASN1{
783		Status: asn1.Enumerated(Success),
784		Response: responseBytes{
785			ResponseType: idPKIXOCSPBasic,
786			Response:     responseDER,
787		},
788	})
789}
790