Ensure RFC-6960 compliance
This commit is contained in:
parent
62962b695b
commit
fe6c63ff4b
3 changed files with 30 additions and 4 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
*.der
|
||||
/.idea/
|
||||
/cacertocsp
|
||||
/config.yaml
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
@ -34,6 +35,8 @@ import (
|
|||
"golang.org/x/crypto/ocsp"
|
||||
)
|
||||
|
||||
var unknownIssuer = errors.New("issuer key hash does not match any of the known issuers")
|
||||
|
||||
// CertificateIssuer is an abstraction for the OCSP responder that knows certificates of a specific CA
|
||||
type CertificateIssuer struct {
|
||||
responderCertificate *x509.Certificate
|
||||
|
@ -156,7 +159,16 @@ func WithIssuer(issuer *CertificateIssuer) Option {
|
|||
func (o *OcspSource) Response(r *ocsp.Request) ([]byte, http.Header, error) {
|
||||
issuer, err := o.getIssuer(r.IssuerKeyHash, r.HashAlgorithm)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot answer request: %v", err)
|
||||
if errors.Is(err, unknownIssuer) {
|
||||
logrus.Infof("received request for unknown issuer key hash %s", hex.EncodeToString(r.IssuerKeyHash))
|
||||
issuer = o.getDefaultIssuer()
|
||||
response, err := issuer.buildUnknownResponse(r.SerialNumber)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("could not build OCSP response: %v", err)
|
||||
}
|
||||
return response, nil, nil
|
||||
}
|
||||
return nil, nil, fmt.Errorf("cannot answer request: %w", err)
|
||||
}
|
||||
|
||||
response, err := issuer.LookupResponse(r.SerialNumber)
|
||||
|
@ -177,7 +189,7 @@ func (o *OcspSource) getIssuer(keyHash []byte, algorithm crypto.Hash) (*Certific
|
|||
return issuer, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("issuer key hash does not match any of the known issuers")
|
||||
return nil, unknownIssuer
|
||||
}
|
||||
|
||||
// BackgroundTasks delegates background task handling to the CertificateIssuer instances of the OcspSource
|
||||
|
@ -195,3 +207,7 @@ func (o *OcspSource) BackgroundTasks(ctx context.Context) {
|
|||
wg.Wait()
|
||||
logrus.Info("stopped OCSP source background tasks")
|
||||
}
|
||||
|
||||
func (o *OcspSource) getDefaultIssuer() *CertificateIssuer {
|
||||
return o.issuers[0]
|
||||
}
|
||||
|
|
|
@ -102,7 +102,17 @@ func (o *OpenSSLCertDB) LookupResponseTemplate(number *big.Int) *ocsp.Response {
|
|||
if response, ok := o.content[serial]; ok {
|
||||
return response
|
||||
}
|
||||
return nil
|
||||
// RFC https://datatracker.ietf.org/doc/html/rfc6960#section-2.2 states that certificates we cannot answer for
|
||||
// should be marked as good. This would allow a CRL as sole certificate source.
|
||||
//
|
||||
// We might change this to an unknown response when we have a more accurate certificate source like an API or an
|
||||
// up-to-date openssl index.txt.
|
||||
logrus.Debugf("received request for certificate %s that is not in our data source", serial)
|
||||
response := &ocsp.Response{
|
||||
Status: ocsp.Good,
|
||||
SerialNumber: number,
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
// WatchChanges creates file system monitoring for the index.txt file of the OpenSSLCertDB
|
||||
|
@ -172,7 +182,6 @@ func parseLine(line string) (string, *ocsp.Response) {
|
|||
}
|
||||
|
||||
response := ocsp.Response{
|
||||
Status: 0,
|
||||
SerialNumber: serialNumber,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue