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/
|
/.idea/
|
||||||
/cacertocsp
|
/cacertocsp
|
||||||
/config.yaml
|
/config.yaml
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -34,6 +35,8 @@ import (
|
||||||
"golang.org/x/crypto/ocsp"
|
"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
|
// CertificateIssuer is an abstraction for the OCSP responder that knows certificates of a specific CA
|
||||||
type CertificateIssuer struct {
|
type CertificateIssuer struct {
|
||||||
responderCertificate *x509.Certificate
|
responderCertificate *x509.Certificate
|
||||||
|
@ -156,7 +159,16 @@ func WithIssuer(issuer *CertificateIssuer) Option {
|
||||||
func (o *OcspSource) Response(r *ocsp.Request) ([]byte, http.Header, error) {
|
func (o *OcspSource) Response(r *ocsp.Request) ([]byte, http.Header, error) {
|
||||||
issuer, err := o.getIssuer(r.IssuerKeyHash, r.HashAlgorithm)
|
issuer, err := o.getIssuer(r.IssuerKeyHash, r.HashAlgorithm)
|
||||||
if err != nil {
|
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)
|
response, err := issuer.LookupResponse(r.SerialNumber)
|
||||||
|
@ -177,7 +189,7 @@ func (o *OcspSource) getIssuer(keyHash []byte, algorithm crypto.Hash) (*Certific
|
||||||
return issuer, nil
|
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
|
// 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()
|
wg.Wait()
|
||||||
logrus.Info("stopped OCSP source background tasks")
|
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 {
|
if response, ok := o.content[serial]; ok {
|
||||||
return response
|
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
|
// 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{
|
response := ocsp.Response{
|
||||||
Status: 0,
|
|
||||||
SerialNumber: serialNumber,
|
SerialNumber: serialNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue