ocsp: add support for OCSP response extensions
Some current uses of OCSP require extensions. In particular, Certificate Transparency (RFC 6962) can use an OCSP extension to carry a Signed Certificate Timestamp. This patch adds support for OCSP extensions (in particular, singleExtensions), by adding Extensions and ExtraExtensions fields with the same semantics as in x509.Certificate. As a side-effect, trying to parse a response with a critical extension will now return an error, just like parsing a certificate. This change does not enable extensions in OCSP requests, just responses. Change-Id: I5918f26ea1bb9d1ece96e85a6bb7691c7c017467 Reviewed-on: https://go-review.googlesource.com/18202 Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
committed by
Adam Langley
parent
f18420efc3
commit
552e9d568f
+34
-10
@@ -85,12 +85,13 @@ type responseData struct {
|
||||
}
|
||||
|
||||
type singleResponse struct {
|
||||
CertID certID
|
||||
Good asn1.Flag `asn1:"tag:0,optional"`
|
||||
Revoked revokedInfo `asn1:"tag:1,optional"`
|
||||
Unknown asn1.Flag `asn1:"tag:2,optional"`
|
||||
ThisUpdate time.Time `asn1:"generalized"`
|
||||
NextUpdate time.Time `asn1:"generalized,explicit,tag:0,optional"`
|
||||
CertID certID
|
||||
Good asn1.Flag `asn1:"tag:0,optional"`
|
||||
Revoked revokedInfo `asn1:"tag:1,optional"`
|
||||
Unknown asn1.Flag `asn1:"tag:2,optional"`
|
||||
ThisUpdate time.Time `asn1:"generalized"`
|
||||
NextUpdate time.Time `asn1:"generalized,explicit,tag:0,optional"`
|
||||
SingleExtensions []pkix.Extension `asn1:"explicit,tag:1,optional"`
|
||||
}
|
||||
|
||||
type revokedInfo struct {
|
||||
@@ -257,7 +258,7 @@ const (
|
||||
AACompromise = iota
|
||||
)
|
||||
|
||||
// Request represents an OCSP request. See RFC 2560.
|
||||
// Request represents an OCSP request. See RFC 6960.
|
||||
type Request struct {
|
||||
HashAlgorithm crypto.Hash
|
||||
IssuerNameHash []byte
|
||||
@@ -265,7 +266,8 @@ type Request struct {
|
||||
SerialNumber *big.Int
|
||||
}
|
||||
|
||||
// Response represents an OCSP response. See RFC 2560.
|
||||
// Response represents an OCSP response containing a single SingleResponse. See
|
||||
// RFC 6960.
|
||||
type Response struct {
|
||||
// Status is one of {Good, Revoked, Unknown, ServerFailed}
|
||||
Status int
|
||||
@@ -278,6 +280,20 @@ type Response struct {
|
||||
TBSResponseData []byte
|
||||
Signature []byte
|
||||
SignatureAlgorithm x509.SignatureAlgorithm
|
||||
|
||||
// Extensions contains raw X.509 extensions from the singleExtensions field
|
||||
// of the OCSP response. When parsing certificates, this can be used to
|
||||
// extract non-critical extensions that are not parsed by this package. When
|
||||
// marshaling OCSP responses, the Extensions field is ignored, see
|
||||
// ExtraExtensions.
|
||||
Extensions []pkix.Extension
|
||||
|
||||
// ExtraExtensions contains extensions to be copied, raw, into any marshaled
|
||||
// OCSP response (in the singleExtensions field). Values override any
|
||||
// extensions that would otherwise be produced based on the other fields. The
|
||||
// ExtraExtensions field is not populated when parsing certificates, see
|
||||
// Extensions.
|
||||
ExtraExtensions []pkix.Extension
|
||||
}
|
||||
|
||||
// These are pre-serialized error responses for the various non-success codes
|
||||
@@ -405,6 +421,13 @@ func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
|
||||
|
||||
r := basicResp.TBSResponseData.Responses[0]
|
||||
|
||||
for _, ext := range r.SingleExtensions {
|
||||
if ext.Critical {
|
||||
return nil, ParseError("unsupported critical extension")
|
||||
}
|
||||
}
|
||||
ret.Extensions = r.SingleExtensions
|
||||
|
||||
ret.SerialNumber = r.CertID.SerialNumber
|
||||
|
||||
switch {
|
||||
@@ -534,8 +557,9 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
|
||||
IssuerKeyHash: issuerKeyHash,
|
||||
SerialNumber: template.SerialNumber,
|
||||
},
|
||||
ThisUpdate: template.ThisUpdate.UTC(),
|
||||
NextUpdate: template.NextUpdate.UTC(),
|
||||
ThisUpdate: template.ThisUpdate.UTC(),
|
||||
NextUpdate: template.NextUpdate.UTC(),
|
||||
SingleExtensions: template.ExtraExtensions,
|
||||
}
|
||||
|
||||
switch template.Status {
|
||||
|
||||
Reference in New Issue
Block a user