ocsp: add Request.Marshal method
Tests that Marshaling a parsed response returns the same bytes as were parsed. Use Marshal in CreateRequest; still passes CreateRequest's golden test. Change-Id: I427ef8372d7b62c43b7718d7d90631d022377d32 Reviewed-on: https://go-review.googlesource.com/19488 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
committed by
Russ Cox
parent
7682e7e394
commit
0e69e08b8a
+43
-20
@@ -266,6 +266,15 @@ func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
|
|||||||
return crypto.Hash(0)
|
return crypto.Hash(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier {
|
||||||
|
for hash, oid := range hashOIDs {
|
||||||
|
if hash == target {
|
||||||
|
return oid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// This is the exposed reflection of the internal OCSP structures.
|
// This is the exposed reflection of the internal OCSP structures.
|
||||||
|
|
||||||
// The status values that can be expressed in OCSP. See RFC 6960.
|
// The status values that can be expressed in OCSP. See RFC 6960.
|
||||||
@@ -305,6 +314,32 @@ type Request struct {
|
|||||||
SerialNumber *big.Int
|
SerialNumber *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marshal marshals the OCSP request to ASN.1 DER encoded form.
|
||||||
|
func (req *Request) Marshal() ([]byte, error) {
|
||||||
|
hashAlg := getOIDFromHashAlgorithm(req.HashAlgorithm)
|
||||||
|
if hashAlg == nil {
|
||||||
|
return nil, errors.New("Unknown hash algorithm")
|
||||||
|
}
|
||||||
|
return asn1.Marshal(ocspRequest{
|
||||||
|
tbsRequest{
|
||||||
|
Version: 0,
|
||||||
|
RequestList: []request{
|
||||||
|
{
|
||||||
|
Cert: certID{
|
||||||
|
pkix.AlgorithmIdentifier{
|
||||||
|
Algorithm: hashAlg,
|
||||||
|
Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
|
||||||
|
},
|
||||||
|
req.IssuerNameHash,
|
||||||
|
req.IssuerKeyHash,
|
||||||
|
req.SerialNumber,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Response represents an OCSP response containing a single SingleResponse. See
|
// Response represents an OCSP response containing a single SingleResponse. See
|
||||||
// RFC 6960.
|
// RFC 6960.
|
||||||
type Response struct {
|
type Response struct {
|
||||||
@@ -512,8 +547,7 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
|
|||||||
// OCSP seems to be the only place where these raw hash identifiers are
|
// OCSP seems to be the only place where these raw hash identifiers are
|
||||||
// used. I took the following from
|
// used. I took the following from
|
||||||
// http://msdn.microsoft.com/en-us/library/ff635603.aspx
|
// http://msdn.microsoft.com/en-us/library/ff635603.aspx
|
||||||
var hashOID asn1.ObjectIdentifier
|
_, ok := hashOIDs[hashFunc]
|
||||||
hashOID, ok := hashOIDs[hashFunc]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, x509.ErrUnsupportedAlgorithm
|
return nil, x509.ErrUnsupportedAlgorithm
|
||||||
}
|
}
|
||||||
@@ -538,24 +572,13 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
|
|||||||
h.Write(issuer.RawSubject)
|
h.Write(issuer.RawSubject)
|
||||||
issuerNameHash := h.Sum(nil)
|
issuerNameHash := h.Sum(nil)
|
||||||
|
|
||||||
return asn1.Marshal(ocspRequest{
|
req := &Request{
|
||||||
tbsRequest{
|
HashAlgorithm: hashFunc,
|
||||||
Version: 0,
|
IssuerNameHash: issuerNameHash,
|
||||||
RequestList: []request{
|
IssuerKeyHash: issuerKeyHash,
|
||||||
{
|
SerialNumber: cert.SerialNumber,
|
||||||
Cert: certID{
|
}
|
||||||
pkix.AlgorithmIdentifier{
|
return req.Marshal()
|
||||||
Algorithm: hashOID,
|
|
||||||
Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */},
|
|
||||||
},
|
|
||||||
issuerNameHash,
|
|
||||||
issuerKeyHash,
|
|
||||||
cert.SerialNumber,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResponse returns a DER-encoded OCSP response with the specified contents.
|
// CreateResponse returns a DER-encoded OCSP response with the specified contents.
|
||||||
|
|||||||
@@ -159,6 +159,19 @@ func TestOCSPRequest(t *testing.T) {
|
|||||||
if got := decodedRequest.SerialNumber; got.Cmp(cert.SerialNumber) != 0 {
|
if got := decodedRequest.SerialNumber; got.Cmp(cert.SerialNumber) != 0 {
|
||||||
t.Errorf("request.SerialNumber: got %x, want %x", got, cert.SerialNumber)
|
t.Errorf("request.SerialNumber: got %x, want %x", got, cert.SerialNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
marshaledRequest, err := decodedRequest.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytes.Compare(expectedBytes, marshaledRequest) != 0 {
|
||||||
|
t.Errorf(
|
||||||
|
"Marshaled request doesn't match expected: wanted %x, got %x",
|
||||||
|
expectedBytes,
|
||||||
|
marshaledRequest,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOCSPResponse(t *testing.T) {
|
func TestOCSPResponse(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user