cli/third-party/github.com/letsencrypt/boulder/cmd/ceremony/ocsp.go
2025-05-30 12:50:20 -04:00

69 lines
1.9 KiB
Go

package main
import (
"crypto"
"crypto/x509"
"encoding/base64"
"errors"
"fmt"
"time"
"golang.org/x/crypto/ocsp"
)
func generateOCSPResponse(signer crypto.Signer, issuer, delegatedIssuer, cert *x509.Certificate, thisUpdate, nextUpdate time.Time, status int) ([]byte, error) {
err := cert.CheckSignatureFrom(issuer)
if err != nil {
return nil, fmt.Errorf("invalid signature on certificate from issuer: %s", err)
}
signingCert := issuer
if delegatedIssuer != nil {
signingCert = delegatedIssuer
err := delegatedIssuer.CheckSignatureFrom(issuer)
if err != nil {
return nil, fmt.Errorf("invalid signature on delegated issuer from issuer: %s", err)
}
gotOCSPEKU := false
for _, eku := range delegatedIssuer.ExtKeyUsage {
if eku == x509.ExtKeyUsageOCSPSigning {
gotOCSPEKU = true
break
}
}
if !gotOCSPEKU {
return nil, errors.New("delegated issuer certificate doesn't contain OCSPSigning extended key usage")
}
}
if nextUpdate.Before(thisUpdate) {
return nil, errors.New("thisUpdate must be before nextUpdate")
}
if thisUpdate.Before(signingCert.NotBefore) {
return nil, errors.New("thisUpdate is before signing certificate's notBefore")
} else if nextUpdate.After(signingCert.NotAfter) {
return nil, errors.New("nextUpdate is after signing certificate's notAfter")
}
template := ocsp.Response{
SerialNumber: cert.SerialNumber,
ThisUpdate: thisUpdate,
NextUpdate: nextUpdate,
Status: status,
}
if delegatedIssuer != nil {
template.Certificate = delegatedIssuer
}
resp, err := ocsp.CreateResponse(issuer, signingCert, template, signer)
if err != nil {
return nil, fmt.Errorf("failed to create response: %s", err)
}
encodedResp := make([]byte, base64.StdEncoding.EncodedLen(len(resp))+1)
base64.StdEncoding.Encode(encodedResp, resp)
encodedResp[len(encodedResp)-1] = '\n'
return encodedResp, nil
}