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/x509"
18	"crypto/x509/pkix"
19	"encoding/asn1"
20	"errors"
21	"math/big"
22	"time"
23)
24
25var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1})
26
27// These are internal structures that reflect the ASN.1 structure of an OCSP
28// response. See RFC 2560, section 4.2.
29
30const (
31	ocspSuccess       = 0
32	ocspMalformed     = 1
33	ocspInternalError = 2
34	ocspTryLater      = 3
35	ocspSigRequired   = 4
36	ocspUnauthorized  = 5
37)
38
39type certID struct {
40	HashAlgorithm pkix.AlgorithmIdentifier
41	NameHash      []byte
42	IssuerKeyHash []byte
43	SerialNumber  *big.Int
44}
45
46// https://tools.ietf.org/html/rfc2560#section-4.1.1
47type ocspRequest struct {
48	TBSRequest tbsRequest
49}
50
51type tbsRequest struct {
52	Version       int              `asn1:"explicit,tag:0,default:0,optional"`
53	RequestorName pkix.RDNSequence `asn1:"explicit,tag:1,optional"`
54	RequestList   []request
55}
56
57type request struct {
58	Cert certID
59}
60
61type responseASN1 struct {
62	Status   asn1.Enumerated
63	Response responseBytes `asn1:"explicit,tag:0"`
64}
65
66type responseBytes struct {
67	ResponseType asn1.ObjectIdentifier
68	Response     []byte
69}
70
71type basicResponse struct {
72	TBSResponseData    responseData
73	SignatureAlgorithm pkix.AlgorithmIdentifier
74	Signature          asn1.BitString
75	Certificates       []asn1.RawValue `asn1:"explicit,tag:0,optional"`
76}
77
78type responseData struct {
79	Raw              asn1.RawContent
80	Version          int           `asn1:"optional,default:1,explicit,tag:0"`
81	RawResponderName asn1.RawValue `asn1:"optional,explicit,tag:1"`
82	KeyHash          []byte        `asn1:"optional,explicit,tag:2"`
83	ProducedAt       time.Time     `asn1:"generalized"`
84	Responses        []singleResponse
85}
86
87type singleResponse struct {
88	CertID     certID
89	Good       asn1.Flag   `asn1:"tag:0,optional"`
90	Revoked    revokedInfo `asn1:"explicit,tag:1,optional"`
91	Unknown    asn1.Flag   `asn1:"tag:2,optional"`
92	ThisUpdate time.Time   `asn1:"generalized"`
93	NextUpdate time.Time   `asn1:"generalized,explicit,tag:0,optional"`
94}
95
96type revokedInfo struct {
97	RevocationTime time.Time `asn1:"generalized"`
98	Reason         int       `asn1:"explicit,tag:0,optional"`
99}
100
101var (
102	oidSignatureMD2WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
103	oidSignatureMD5WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
104	oidSignatureSHA1WithRSA     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
105	oidSignatureSHA256WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
106	oidSignatureSHA384WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
107	oidSignatureSHA512WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
108	oidSignatureDSAWithSHA1     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
109	oidSignatureDSAWithSHA256   = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 4, 3, 2}
110	oidSignatureECDSAWithSHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
111	oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
112	oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
113	oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
114)
115
116var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{
117	crypto.SHA1:   asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}),
118	crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}),
119	crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}),
120	crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}),
121}
122
123// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
124var signatureAlgorithmDetails = []struct {
125	algo       x509.SignatureAlgorithm
126	oid        asn1.ObjectIdentifier
127	pubKeyAlgo x509.PublicKeyAlgorithm
128	hash       crypto.Hash
129}{
130	{x509.MD2WithRSA, oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */},
131	{x509.MD5WithRSA, oidSignatureMD5WithRSA, x509.RSA, crypto.MD5},
132	{x509.SHA1WithRSA, oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
133	{x509.SHA256WithRSA, oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256},
134	{x509.SHA384WithRSA, oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384},
135	{x509.SHA512WithRSA, oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512},
136	{x509.DSAWithSHA1, oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1},
137	{x509.DSAWithSHA256, oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256},
138	{x509.ECDSAWithSHA1, oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1},
139	{x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256},
140	{x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384},
141	{x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512},
142}
143
144// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
145func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
146	var pubType x509.PublicKeyAlgorithm
147
148	switch pub := pub.(type) {
149	case *rsa.PublicKey:
150		pubType = x509.RSA
151		hashFunc = crypto.SHA256
152		sigAlgo.Algorithm = oidSignatureSHA256WithRSA
153		sigAlgo.Parameters = asn1.RawValue{
154			Tag: 5,
155		}
156
157	case *ecdsa.PublicKey:
158		pubType = x509.ECDSA
159
160		switch pub.Curve {
161		case elliptic.P224(), elliptic.P256():
162			hashFunc = crypto.SHA256
163			sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
164		case elliptic.P384():
165			hashFunc = crypto.SHA384
166			sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
167		case elliptic.P521():
168			hashFunc = crypto.SHA512
169			sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
170		default:
171			err = errors.New("x509: unknown elliptic curve")
172		}
173
174	default:
175		err = errors.New("x509: only RSA and ECDSA keys supported")
176	}
177
178	if err != nil {
179		return
180	}
181
182	if requestedSigAlgo == 0 {
183		return
184	}
185
186	found := false
187	for _, details := range signatureAlgorithmDetails {
188		if details.algo == requestedSigAlgo {
189			if details.pubKeyAlgo != pubType {
190				err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
191				return
192			}
193			sigAlgo.Algorithm, hashFunc = details.oid, details.hash
194			if hashFunc == 0 {
195				err = errors.New("x509: cannot sign with hash function requested")
196				return
197			}
198			found = true
199			break
200		}
201	}
202
203	if !found {
204		err = errors.New("x509: unknown SignatureAlgorithm")
205	}
206
207	return
208}
209
210// TODO(agl): this is taken from crypto/x509 and so should probably be exported
211// from crypto/x509 or crypto/x509/pkix.
212func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.SignatureAlgorithm {
213	for _, details := range signatureAlgorithmDetails {
214		if oid.Equal(details.oid) {
215			return details.algo
216		}
217	}
218	return x509.UnknownSignatureAlgorithm
219}
220
221// TODO(rlb): This is not taken from crypto/x509, but it's of the same general form.
222func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
223	for hash, oid := range hashOIDs {
224		if oid.Equal(target) {
225			return hash
226		}
227	}
228	return crypto.Hash(0)
229}
230
231// This is the exposed reflection of the internal OCSP structures.
232
233const (
234	// Good means that the certificate is valid.
235	Good = iota
236	// Revoked means that the certificate has been deliberately revoked.
237	Revoked = iota
238	// Unknown means that the OCSP responder doesn't know about the certificate.
239	Unknown = iota
240	// ServerFailed means that the OCSP responder failed to process the request.
241	ServerFailed = iota
242)
243
244// Request represents an OCSP request. See RFC 2560.
245type Request struct {
246	HashAlgorithm  crypto.Hash
247	IssuerNameHash []byte
248	IssuerKeyHash  []byte
249	SerialNumber   *big.Int
250}
251
252// Response represents an OCSP response. See RFC 2560.
253type Response struct {
254	// Status is one of {Good, Revoked, Unknown, ServerFailed}
255	Status                                        int
256	SerialNumber                                  *big.Int
257	ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time
258	RevocationReason                              int
259	Certificate                                   *x509.Certificate
260	// TBSResponseData contains the raw bytes of the signed response. If
261	// Certificate is nil then this can be used to verify Signature.
262	TBSResponseData    []byte
263	Signature          []byte
264	SignatureAlgorithm x509.SignatureAlgorithm
265}
266
267// These are pre-serialized error responses for the various non-success codes
268// defined by OCSP. The Unauthorized code in particular can be used by an OCSP
269// responder that supports only pre-signed responses as a response to requests
270// for certificates with unknown status. See RFC 5019.
271var (
272	MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01}
273	InternalErrorErrorResponse    = []byte{0x30, 0x03, 0x0A, 0x01, 0x02}
274	TryLaterErrorResponse         = []byte{0x30, 0x03, 0x0A, 0x01, 0x03}
275	SigRequredErrorResponse       = []byte{0x30, 0x03, 0x0A, 0x01, 0x05}
276	UnauthorizedErrorResponse     = []byte{0x30, 0x03, 0x0A, 0x01, 0x06}
277)
278
279// CheckSignatureFrom checks that the signature in resp is a valid signature
280// from issuer. This should only be used if resp.Certificate is nil. Otherwise,
281// the OCSP response contained an intermediate certificate that created the
282// signature. That signature is checked by ParseResponse and only
283// resp.Certificate remains to be validated.
284func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error {
285	return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature)
286}
287
288// ParseError results from an invalid OCSP response.
289type ParseError string
290
291func (p ParseError) Error() string {
292	return string(p)
293}
294
295// ParseRequest parses an OCSP request in DER form. It only supports
296// requests for a single certificate. Signed requests are not supported.
297// If a request includes a signature, it will result in a ParseError.
298func ParseRequest(bytes []byte) (*Request, error) {
299	var req ocspRequest
300	rest, err := asn1.Unmarshal(bytes, &req)
301	if err != nil {
302		return nil, err
303	}
304	if len(rest) > 0 {
305		return nil, ParseError("trailing data in OCSP request")
306	}
307
308	if len(req.TBSRequest.RequestList) == 0 {
309		return nil, ParseError("OCSP request contains no request body")
310	}
311	innerRequest := req.TBSRequest.RequestList[0]
312
313	hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm)
314	if hashFunc == crypto.Hash(0) {
315		return nil, ParseError("OCSP request uses unknown hash function")
316	}
317
318	return &Request{
319		HashAlgorithm:  hashFunc,
320		IssuerNameHash: innerRequest.Cert.NameHash,
321		IssuerKeyHash:  innerRequest.Cert.IssuerKeyHash,
322		SerialNumber:   innerRequest.Cert.SerialNumber,
323	}, nil
324}
325
326// ParseResponse parses an OCSP response in DER form. It only supports
327// responses for a single certificate. If the response contains a certificate
328// then the signature over the response is checked. If issuer is not nil then
329// it will be used to validate the signature or embedded certificate. Invalid
330// signatures or parse failures will result in a ParseError.
331func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
332	var resp responseASN1
333	rest, err := asn1.Unmarshal(bytes, &resp)
334	if err != nil {
335		return nil, err
336	}
337	if len(rest) > 0 {
338		return nil, ParseError("trailing data in OCSP response")
339	}
340
341	ret := new(Response)
342	if resp.Status != ocspSuccess {
343		ret.Status = ServerFailed
344		return ret, nil
345	}
346
347	if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) {
348		return nil, ParseError("bad OCSP response type")
349	}
350
351	var basicResp basicResponse
352	rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
353	if err != nil {
354		return nil, err
355	}
356
357	if len(basicResp.Certificates) > 1 {
358		return nil, ParseError("OCSP response contains bad number of certificates")
359	}
360
361	if len(basicResp.TBSResponseData.Responses) != 1 {
362		return nil, ParseError("OCSP response contains bad number of responses")
363	}
364
365	ret.TBSResponseData = basicResp.TBSResponseData.Raw
366	ret.Signature = basicResp.Signature.RightAlign()
367	ret.SignatureAlgorithm = getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm)
368
369	if len(basicResp.Certificates) > 0 {
370		ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
371		if err != nil {
372			return nil, err
373		}
374
375		if err := ret.CheckSignatureFrom(ret.Certificate); err != nil {
376			return nil, ParseError("bad OCSP signature")
377		}
378
379		if issuer != nil {
380			if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil {
381				return nil, ParseError("bad signature on embedded certificate")
382			}
383		}
384	} else if issuer != nil {
385		if err := ret.CheckSignatureFrom(issuer); err != nil {
386			return nil, ParseError("bad OCSP signature")
387		}
388	}
389
390	r := basicResp.TBSResponseData.Responses[0]
391
392	ret.SerialNumber = r.CertID.SerialNumber
393
394	switch {
395	case bool(r.Good):
396		ret.Status = Good
397	case bool(r.Unknown):
398		ret.Status = Unknown
399	default:
400		ret.Status = Revoked
401		ret.RevokedAt = r.Revoked.RevocationTime
402		ret.RevocationReason = r.Revoked.Reason
403	}
404
405	ret.ProducedAt = basicResp.TBSResponseData.ProducedAt
406	ret.ThisUpdate = r.ThisUpdate
407	ret.NextUpdate = r.NextUpdate
408
409	return ret, nil
410}
411
412// RequestOptions contains options for constructing OCSP requests.
413type RequestOptions struct {
414	// Hash contains the hash function that should be used when
415	// constructing the OCSP request. If zero, SHA-1 will be used.
416	Hash crypto.Hash
417}
418
419func (opts *RequestOptions) hash() crypto.Hash {
420	if opts == nil || opts.Hash == 0 {
421		// SHA-1 is nearly universally used in OCSP.
422		return crypto.SHA1
423	}
424	return opts.Hash
425}
426
427// CreateRequest returns a DER-encoded, OCSP request for the status of cert. If
428// opts is nil then sensible defaults are used.
429func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) {
430	hashFunc := opts.hash()
431
432	// OCSP seems to be the only place where these raw hash identifiers are
433	// used. I took the following from
434	// http://msdn.microsoft.com/en-us/library/ff635603.aspx
435	var hashOID asn1.ObjectIdentifier
436	hashOID, ok := hashOIDs[hashFunc]
437	if !ok {
438		return nil, x509.ErrUnsupportedAlgorithm
439	}
440
441	if !hashFunc.Available() {
442		return nil, x509.ErrUnsupportedAlgorithm
443	}
444	h := opts.hash().New()
445
446	var publicKeyInfo struct {
447		Algorithm pkix.AlgorithmIdentifier
448		PublicKey asn1.BitString
449	}
450	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
451		return nil, err
452	}
453
454	h.Write(publicKeyInfo.PublicKey.RightAlign())
455	issuerKeyHash := h.Sum(nil)
456
457	h.Reset()
458	h.Write(issuer.RawSubject)
459	issuerNameHash := h.Sum(nil)
460
461	return asn1.Marshal(ocspRequest{
462		tbsRequest{
463			Version: 0,
464			RequestList: []request{
465				{
466					Cert: certID{
467						pkix.AlgorithmIdentifier{
468							Algorithm:  hashOID,
469							Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
470						},
471						issuerNameHash,
472						issuerKeyHash,
473						cert.SerialNumber,
474					},
475				},
476			},
477		},
478	})
479}
480
481// CreateResponse returns a DER-encoded OCSP response with the specified contents.
482// The fields in the response are populated as follows:
483//
484// The responder cert is used to populate the ResponderName field, and the certificate
485// itself is provided alongside the OCSP response signature.
486//
487// The issuer cert is used to puplate the IssuerNameHash and IssuerKeyHash fields.
488// (SHA-1 is used for the hash function; this is not configurable.)
489//
490// The template is used to populate the SerialNumber, RevocationStatus, RevokedAt,
491// RevocationReason, ThisUpdate, and NextUpdate fields.
492//
493// The ProducedAt date is automatically set to the current date, to the nearest minute.
494func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) {
495	var publicKeyInfo struct {
496		Algorithm pkix.AlgorithmIdentifier
497		PublicKey asn1.BitString
498	}
499	if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
500		return nil, err
501	}
502
503	h := sha1.New()
504	h.Write(publicKeyInfo.PublicKey.RightAlign())
505	issuerKeyHash := h.Sum(nil)
506
507	h.Reset()
508	h.Write(issuer.RawSubject)
509	issuerNameHash := h.Sum(nil)
510
511	innerResponse := singleResponse{
512		CertID: certID{
513			HashAlgorithm: pkix.AlgorithmIdentifier{
514				Algorithm:  hashOIDs[crypto.SHA1],
515				Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
516			},
517			NameHash:      issuerNameHash,
518			IssuerKeyHash: issuerKeyHash,
519			SerialNumber:  template.SerialNumber,
520		},
521		ThisUpdate: template.ThisUpdate.UTC(),
522		NextUpdate: template.NextUpdate.UTC(),
523	}
524
525	switch template.Status {
526	case Good:
527		innerResponse.Good = true
528	case Unknown:
529		innerResponse.Unknown = true
530	case Revoked:
531		innerResponse.Revoked = revokedInfo{
532			RevocationTime: template.RevokedAt.UTC(),
533			Reason:         template.RevocationReason,
534		}
535	}
536
537	responderName := asn1.RawValue{
538		Class:      2, // context-specific
539		Tag:        1, // explicit tag
540		IsCompound: true,
541		Bytes:      responderCert.RawSubject,
542	}
543	tbsResponseData := responseData{
544		Version:          0,
545		RawResponderName: responderName,
546		ProducedAt:       time.Now().Truncate(time.Minute).UTC(),
547		Responses:        []singleResponse{innerResponse},
548	}
549
550	tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
551	if err != nil {
552		return nil, err
553	}
554
555	hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
556	if err != nil {
557		return nil, err
558	}
559
560	responseHash := hashFunc.New()
561	responseHash.Write(tbsResponseDataDER)
562	signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
563	if err != nil {
564		return nil, err
565	}
566
567	response := basicResponse{
568		TBSResponseData:    tbsResponseData,
569		SignatureAlgorithm: signatureAlgorithm,
570		Signature: asn1.BitString{
571			Bytes:     signature,
572			BitLength: 8 * len(signature),
573		},
574	}
575	if template.Certificate != nil {
576		response.Certificates = []asn1.RawValue{
577			asn1.RawValue{FullBytes: template.Certificate.Raw},
578		}
579	}
580	responseDER, err := asn1.Marshal(response)
581	if err != nil {
582		return nil, err
583	}
584
585	return asn1.Marshal(responseASN1{
586		Status: ocspSuccess,
587		Response: responseBytes{
588			ResponseType: idPKIXOCSPBasic,
589			Response:     responseDER,
590		},
591	})
592}
593