ocsp: use asn1.Enumerated for revocation reason
In the initial patch enabling generation of OCSP responses, the Reason field in the revokedInfo struct used for serializing responses was set to type int. That type maps to the ASN.1 type INTEGER, not ENUMERATED, as required by RFC 6960. As a result, if you serialize an OCSP resonse with the Reason field populated, then it will be rejected as malformed by compliant OCSP parsers. This patch changes the type of the Reason field in revokedInfo to asn1.Enumerated. It leaves the RevocationReason field in the public Response struct as int, and converts between the two. The patch also adds constant for the defined revocation reasons. Change-Id: I97205319503f447cde12d9a0bb0bd1a8db7a66ee Reviewed-on: https://go-review.googlesource.com/13964 Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
committed by
Adam Langley
parent
81bf7719a6
commit
287a1d87db
+20
-4
@@ -94,8 +94,8 @@ type singleResponse struct {
|
||||
}
|
||||
|
||||
type revokedInfo struct {
|
||||
RevocationTime time.Time `asn1:"generalized"`
|
||||
Reason int `asn1:"explicit,tag:0,optional"`
|
||||
RevocationTime time.Time `asn1:"generalized"`
|
||||
Reason asn1.Enumerated `asn1:"explicit,tag:0,optional"`
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -230,6 +230,7 @@ func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
|
||||
|
||||
// This is the exposed reflection of the internal OCSP structures.
|
||||
|
||||
// The status values that can be expressed in OCSP. See RFC 6960.
|
||||
const (
|
||||
// Good means that the certificate is valid.
|
||||
Good = iota
|
||||
@@ -241,6 +242,21 @@ const (
|
||||
ServerFailed = iota
|
||||
)
|
||||
|
||||
// The enumerated reasons for revoking a certificate. See RFC 5280.
|
||||
const (
|
||||
Unspecified = iota
|
||||
KeyCompromise = iota
|
||||
CACompromise = iota
|
||||
AffiliationChanged = iota
|
||||
Superseded = iota
|
||||
CessationOfOperation = iota
|
||||
CertificateHold = iota
|
||||
_ = iota
|
||||
RemoveFromCRL = iota
|
||||
PrivilegeWithdrawn = iota
|
||||
AACompromise = iota
|
||||
)
|
||||
|
||||
// Request represents an OCSP request. See RFC 2560.
|
||||
type Request struct {
|
||||
HashAlgorithm crypto.Hash
|
||||
@@ -399,7 +415,7 @@ func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
|
||||
default:
|
||||
ret.Status = Revoked
|
||||
ret.RevokedAt = r.Revoked.RevocationTime
|
||||
ret.RevocationReason = r.Revoked.Reason
|
||||
ret.RevocationReason = int(r.Revoked.Reason)
|
||||
}
|
||||
|
||||
ret.ProducedAt = basicResp.TBSResponseData.ProducedAt
|
||||
@@ -530,7 +546,7 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
|
||||
case Revoked:
|
||||
innerResponse.Revoked = revokedInfo{
|
||||
RevocationTime: template.RevokedAt.UTC(),
|
||||
Reason: template.RevocationReason,
|
||||
Reason: asn1.Enumerated(template.RevocationReason),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -26,9 +26,9 @@ func TestOCSPDecode(t *testing.T) {
|
||||
}
|
||||
|
||||
expected := Response{
|
||||
Status: 0,
|
||||
Status: Good,
|
||||
SerialNumber: big.NewInt(0x1d0fa),
|
||||
RevocationReason: 0,
|
||||
RevocationReason: Unspecified,
|
||||
ThisUpdate: time.Date(2010, 7, 7, 15, 1, 5, 0, time.UTC),
|
||||
NextUpdate: time.Date(2010, 7, 7, 18, 35, 17, 0, time.UTC),
|
||||
}
|
||||
@@ -171,7 +171,7 @@ func TestOCSPResponse(t *testing.T) {
|
||||
ThisUpdate: thisUpdate,
|
||||
NextUpdate: nextUpdate,
|
||||
RevokedAt: thisUpdate,
|
||||
RevocationReason: 1, // keyCompromise
|
||||
RevocationReason: KeyCompromise,
|
||||
Certificate: responder,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user