|
|
|
@ -30,7 +30,7 @@ import (
|
|
|
|
|
"crypto/elliptic"
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"crypto/rsa"
|
|
|
|
|
_ "crypto/sha1"
|
|
|
|
|
_ "crypto/sha1" //nolint:gosec
|
|
|
|
|
_ "crypto/sha256"
|
|
|
|
|
_ "crypto/sha512"
|
|
|
|
|
"crypto/x509"
|
|
|
|
@ -45,19 +45,19 @@ import (
|
|
|
|
|
|
|
|
|
|
var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1})
|
|
|
|
|
|
|
|
|
|
// ResponseStatus contains the result of an OCSP request. See
|
|
|
|
|
// https://tools.ietf.org/html/rfc6960#section-2.3
|
|
|
|
|
// ResponseStatus contains the result of an OCSP request. See https://tools.ietf.org/html/rfc6960#section-2.3
|
|
|
|
|
type ResponseStatus int
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
Success ResponseStatus = 0
|
|
|
|
|
Malformed ResponseStatus = 1
|
|
|
|
|
InternalError ResponseStatus = 2
|
|
|
|
|
TryLater ResponseStatus = 3
|
|
|
|
|
// Status code four is unused in OCSP. See
|
|
|
|
|
// https://tools.ietf.org/html/rfc6960#section-4.2.1
|
|
|
|
|
SignatureRequired ResponseStatus = 5
|
|
|
|
|
Unauthorized ResponseStatus = 6
|
|
|
|
|
Success ResponseStatus = 0 // response has valid confirmations
|
|
|
|
|
Malformed ResponseStatus = 1 // illegal confirmation request
|
|
|
|
|
InternalError ResponseStatus = 2 // internal error in issuer
|
|
|
|
|
TryLater ResponseStatus = 3 // try again later
|
|
|
|
|
|
|
|
|
|
// Status code four is unused in OCSP. See https://tools.ietf.org/html/rfc6960#section-4.2.1
|
|
|
|
|
|
|
|
|
|
SignatureRequired ResponseStatus = 5 // must sign the request
|
|
|
|
|
Unauthorized ResponseStatus = 6 // request unauthorized
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (r ResponseStatus) String() string {
|
|
|
|
@ -115,7 +115,7 @@ type request struct {
|
|
|
|
|
Cert certID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type responseASN1 struct {
|
|
|
|
|
type ocspResponseASN1 struct {
|
|
|
|
|
Status asn1.Enumerated
|
|
|
|
|
Response responseBytes `asn1:"explicit,tag:0,optional"`
|
|
|
|
|
}
|
|
|
|
@ -200,8 +200,17 @@ var signatureAlgorithmDetails = []struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below
|
|
|
|
|
func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
|
|
|
|
|
var pubType x509.PublicKeyAlgorithm
|
|
|
|
|
//nolint:cyclop
|
|
|
|
|
func signingParamsForPublicKey(
|
|
|
|
|
pub interface{},
|
|
|
|
|
requestedSigAlgo x509.SignatureAlgorithm,
|
|
|
|
|
) (crypto.Hash, pkix.AlgorithmIdentifier, error) {
|
|
|
|
|
var (
|
|
|
|
|
pubType x509.PublicKeyAlgorithm
|
|
|
|
|
hashFunc crypto.Hash
|
|
|
|
|
sigAlgo pkix.AlgorithmIdentifier
|
|
|
|
|
err error
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
switch pub := pub.(type) {
|
|
|
|
|
case *rsa.PublicKey:
|
|
|
|
@ -234,35 +243,41 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
return 0, pkix.AlgorithmIdentifier{}, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if requestedSigAlgo == 0 {
|
|
|
|
|
return
|
|
|
|
|
return hashFunc, sigAlgo, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
found := false
|
|
|
|
|
|
|
|
|
|
for _, details := range signatureAlgorithmDetails {
|
|
|
|
|
if details.algo == requestedSigAlgo {
|
|
|
|
|
if details.pubKeyAlgo != pubType {
|
|
|
|
|
err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
|
|
|
|
|
return
|
|
|
|
|
return 0, pkix.AlgorithmIdentifier{}, errors.New(
|
|
|
|
|
"x509: requested SignatureAlgorithm does not match private key type",
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sigAlgo.Algorithm, hashFunc = details.oid, details.hash
|
|
|
|
|
if hashFunc == 0 {
|
|
|
|
|
err = errors.New("x509: cannot sign with hash function requested")
|
|
|
|
|
return
|
|
|
|
|
return 0, pkix.AlgorithmIdentifier{}, errors.New(
|
|
|
|
|
"x509: cannot sign with hash function requested",
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
found = true
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
|
err = errors.New("x509: unknown SignatureAlgorithm")
|
|
|
|
|
return 0, pkix.AlgorithmIdentifier{}, errors.New("x509: unknown SignatureAlgorithm")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
return hashFunc, sigAlgo, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO(agl): this is taken from crypto/x509 and so should probably be exported
|
|
|
|
@ -273,6 +288,7 @@ func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.SignatureAlgor
|
|
|
|
|
return details.algo
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return x509.UnknownSignatureAlgorithm
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -283,6 +299,7 @@ func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
|
|
|
|
|
return hash
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return crypto.Hash(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -292,6 +309,7 @@ func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier {
|
|
|
|
|
return oid
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -308,7 +326,7 @@ const (
|
|
|
|
|
// ServerFailed is unused and was never used (see
|
|
|
|
|
// https://go-review.googlesource.com/#/c/18944). ParseResponse will
|
|
|
|
|
// return a ResponseError when an error response is parsed.
|
|
|
|
|
ServerFailed
|
|
|
|
|
// ServerFailed
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// The enumerated reasons for revoking a certificate. See RFC 5280.
|
|
|
|
@ -340,7 +358,8 @@ func (req *Request) Marshal() ([]byte, error) {
|
|
|
|
|
if hashAlg == nil {
|
|
|
|
|
return nil, errors.New("Unknown hash algorithm")
|
|
|
|
|
}
|
|
|
|
|
return asn1.Marshal(ocspRequest{
|
|
|
|
|
|
|
|
|
|
request, err := asn1.Marshal(ocspRequest{
|
|
|
|
|
tbsRequest{
|
|
|
|
|
Version: 0,
|
|
|
|
|
RequestList: []request{
|
|
|
|
@ -358,6 +377,11 @@ func (req *Request) Marshal() ([]byte, error) {
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("could not marshal OCSP request ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return request, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Response represents an OCSP response containing a single SingleResponse. See
|
|
|
|
@ -408,13 +432,13 @@ type Response struct {
|
|
|
|
|
// defined by OCSP. The Unauthorized code in particular can be used by an OCSP
|
|
|
|
|
// responder that supports only pre-signed responses as a response to requests
|
|
|
|
|
// for certificates with unknown status. See RFC 5019.
|
|
|
|
|
var (
|
|
|
|
|
MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01}
|
|
|
|
|
InternalErrorErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x02}
|
|
|
|
|
TryLaterErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x03}
|
|
|
|
|
SigRequredErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x05}
|
|
|
|
|
UnauthorizedErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x06}
|
|
|
|
|
)
|
|
|
|
|
// var (
|
|
|
|
|
// MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01}
|
|
|
|
|
// InternalErrorErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x02}
|
|
|
|
|
// TryLaterErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x03}
|
|
|
|
|
// SigRequredErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x05}
|
|
|
|
|
// UnauthorizedErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x06}
|
|
|
|
|
// )
|
|
|
|
|
|
|
|
|
|
// CheckSignatureFrom checks that the signature in resp is a valid signature
|
|
|
|
|
// from issuer. This should only be used if resp.Certificate is nil. Otherwise,
|
|
|
|
@ -422,7 +446,11 @@ var (
|
|
|
|
|
// signature. That signature is checked by ParseResponse and only
|
|
|
|
|
// resp.Certificate remains to be validated.
|
|
|
|
|
func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error {
|
|
|
|
|
return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature)
|
|
|
|
|
if err := issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature); err != nil {
|
|
|
|
|
return fmt.Errorf("could not check signature: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ParseError results from an invalid OCSP response.
|
|
|
|
@ -437,10 +465,12 @@ func (p ParseError) Error() string {
|
|
|
|
|
// If a request includes a signature, it will result in a ParseError.
|
|
|
|
|
func ParseRequest(bytes []byte) (*Request, error) {
|
|
|
|
|
var req ocspRequest
|
|
|
|
|
|
|
|
|
|
rest, err := asn1.Unmarshal(bytes, &req)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not unmarshal OCSP request ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(rest) > 0 {
|
|
|
|
|
return nil, ParseError("trailing data in OCSP request")
|
|
|
|
|
}
|
|
|
|
@ -448,6 +478,7 @@ func ParseRequest(bytes []byte) (*Request, error) {
|
|
|
|
|
if len(req.TBSRequest.RequestList) == 0 {
|
|
|
|
|
return nil, ParseError("OCSP request contains no request body")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
innerRequest := req.TBSRequest.RequestList[0]
|
|
|
|
|
|
|
|
|
|
hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm)
|
|
|
|
@ -487,12 +518,17 @@ func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
|
|
|
|
|
// multiple statuses and cert is not nil, then ParseResponseForCert will return
|
|
|
|
|
// the first status which contains a matching serial, otherwise it will return an
|
|
|
|
|
// error. If cert is nil, then the first status in the response will be returned.
|
|
|
|
|
//
|
|
|
|
|
//nolint:gocognit, cyclop
|
|
|
|
|
func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
|
|
|
|
|
var resp responseASN1
|
|
|
|
|
var resp ocspResponseASN1
|
|
|
|
|
|
|
|
|
|
rest, err := asn1.Unmarshal(bytes, &resp)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not unmarshal OCSP response ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(rest) > 0 {
|
|
|
|
|
return nil, ParseError("trailing data in OCSP response")
|
|
|
|
|
}
|
|
|
|
@ -506,10 +542,12 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var basicResp basicResponse
|
|
|
|
|
|
|
|
|
|
rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not unmarshal basic response ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(rest) > 0 {
|
|
|
|
|
return nil, ParseError("trailing data in OCSP response")
|
|
|
|
|
}
|
|
|
|
@ -519,6 +557,7 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var singleResp singleResponse
|
|
|
|
|
|
|
|
|
|
if cert == nil {
|
|
|
|
|
singleResp = basicResp.TBSResponseData.Responses[0]
|
|
|
|
|
} else {
|
|
|
|
@ -527,6 +566,7 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 {
|
|
|
|
|
singleResp = resp
|
|
|
|
|
match = true
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -553,9 +593,11 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
switch rawResponderID.Tag {
|
|
|
|
|
case 1: // Name
|
|
|
|
|
var rdn pkix.RDNSequence
|
|
|
|
|
|
|
|
|
|
if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &rdn); err != nil || len(rest) != 0 {
|
|
|
|
|
return nil, ParseError("invalid responder name")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret.RawResponderName = rawResponderID.Bytes
|
|
|
|
|
case 2: // KeyHash
|
|
|
|
|
if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &ret.ResponderKeyHash); err != nil || len(rest) != 0 {
|
|
|
|
@ -565,7 +607,7 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
return nil, ParseError("invalid responder id tag")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(basicResp.Certificates) > 0 {
|
|
|
|
|
if len(basicResp.Certificates) > 0 { //nolint:nestif
|
|
|
|
|
// Responders should only send a single certificate (if they
|
|
|
|
|
// send any) that connects the responder's certificate to the
|
|
|
|
|
// original issuer. We accept responses with multiple
|
|
|
|
@ -575,7 +617,7 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
// [1] https://github.com/golang/go/issues/21527
|
|
|
|
|
ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not parse signer certificate: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := ret.CheckSignatureFrom(ret.Certificate); err != nil {
|
|
|
|
@ -583,7 +625,11 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if issuer != nil {
|
|
|
|
|
if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil {
|
|
|
|
|
if err := issuer.CheckSignature(
|
|
|
|
|
ret.Certificate.SignatureAlgorithm,
|
|
|
|
|
ret.Certificate.RawTBSCertificate,
|
|
|
|
|
ret.Certificate.Signature,
|
|
|
|
|
); err != nil {
|
|
|
|
|
return nil, ParseError("bad OCSP signature: " + err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -602,9 +648,11 @@ func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Respon
|
|
|
|
|
for h, oid := range hashOIDs {
|
|
|
|
|
if singleResp.CertID.HashAlgorithm.Algorithm.Equal(oid) {
|
|
|
|
|
ret.IssuerHash = h
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ret.IssuerHash == 0 {
|
|
|
|
|
return nil, ParseError("unsupported issuer hash algorithm")
|
|
|
|
|
}
|
|
|
|
@ -635,6 +683,7 @@ func (opts *RequestOptions) hash() crypto.Hash {
|
|
|
|
|
// SHA-1 is nearly universally used in OCSP.
|
|
|
|
|
return crypto.SHA1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return opts.Hash
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -654,14 +703,16 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
|
|
|
|
|
if !hashFunc.Available() {
|
|
|
|
|
return nil, x509.ErrUnsupportedAlgorithm
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h := opts.hash().New()
|
|
|
|
|
|
|
|
|
|
var publicKeyInfo struct {
|
|
|
|
|
Algorithm pkix.AlgorithmIdentifier
|
|
|
|
|
PublicKey asn1.BitString
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not unmarshal public key info ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h.Write(publicKeyInfo.PublicKey.RightAlign())
|
|
|
|
@ -677,6 +728,7 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
|
|
|
|
|
IssuerKeyHash: issuerKeyHash,
|
|
|
|
|
SerialNumber: cert.SerialNumber,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return req.Marshal()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -694,18 +746,27 @@ func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte
|
|
|
|
|
// If template.IssuerHash is not set, SHA1 will be used.
|
|
|
|
|
//
|
|
|
|
|
// The ProducedAt date is automatically set to the current date, to the nearest minute.
|
|
|
|
|
func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer, extensions []pkix.Extension) ([]byte, error) {
|
|
|
|
|
//
|
|
|
|
|
//nolint:cyclop
|
|
|
|
|
func CreateResponse(
|
|
|
|
|
issuer, responderCert *x509.Certificate,
|
|
|
|
|
template Response,
|
|
|
|
|
priv crypto.Signer,
|
|
|
|
|
extensions []pkix.Extension,
|
|
|
|
|
) ([]byte, error) {
|
|
|
|
|
var publicKeyInfo struct {
|
|
|
|
|
Algorithm pkix.AlgorithmIdentifier
|
|
|
|
|
PublicKey asn1.BitString
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not unmarshal public key info ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if template.IssuerHash == 0 {
|
|
|
|
|
template.IssuerHash = crypto.SHA1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hashOID := getOIDFromHashAlgorithm(template.IssuerHash)
|
|
|
|
|
if hashOID == nil {
|
|
|
|
|
return nil, errors.New("unsupported issuer hash algorithm")
|
|
|
|
@ -714,12 +775,15 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
|
|
|
|
|
if !template.IssuerHash.Available() {
|
|
|
|
|
return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h := template.IssuerHash.New()
|
|
|
|
|
|
|
|
|
|
h.Write(publicKeyInfo.PublicKey.RightAlign())
|
|
|
|
|
issuerKeyHash := h.Sum(nil)
|
|
|
|
|
|
|
|
|
|
h.Reset()
|
|
|
|
|
h.Write(issuer.RawSubject)
|
|
|
|
|
|
|
|
|
|
issuerNameHash := h.Sum(nil)
|
|
|
|
|
|
|
|
|
|
innerResponse := singleResponse{
|
|
|
|
@ -765,7 +829,7 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
|
|
|
|
|
|
|
|
|
|
tbsResponseDataDER, err := asn1.Marshal(tbsResponseData)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not marshal response data: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
|
|
|
|
@ -775,9 +839,10 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
|
|
|
|
|
|
|
|
|
|
responseHash := hashFunc.New()
|
|
|
|
|
responseHash.Write(tbsResponseDataDER)
|
|
|
|
|
|
|
|
|
|
signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("signing failed: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
response := basicResponse{
|
|
|
|
@ -793,16 +858,22 @@ func CreateResponse(issuer, responderCert *x509.Certificate, template Response,
|
|
|
|
|
{FullBytes: template.Certificate.Raw},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
responseDER, err := asn1.Marshal(response)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
return nil, fmt.Errorf("could not marshal OCSP data ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return asn1.Marshal(responseASN1{
|
|
|
|
|
responseStructureDER, err := asn1.Marshal(ocspResponseASN1{
|
|
|
|
|
Status: asn1.Enumerated(Success),
|
|
|
|
|
Response: responseBytes{
|
|
|
|
|
ResponseType: idPKIXOCSPBasic,
|
|
|
|
|
Response: responseDER,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("could not marshal OSCP response ASN.1: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return responseStructureDER, nil
|
|
|
|
|
}
|
|
|
|
|