Factor out idForIssuer. (#5102)
This was already part done: There is an ID() method in issuance. This change extends that by: - Defining a type alias indicating something is an IssuerID. - Defining issuance.Certificate, which also has an ID() method, so that components that aren't the CA can load certificates and use the type system to mark them as issuers (and get their IDs). - Converting akamai-purger and ca to use the new types. - Removing idForIssuer from ca.go.
This commit is contained in:
parent
3666322817
commit
cfe943fea5
37
ca/ca.go
37
ca/ca.go
|
@ -7,7 +7,6 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
|
@ -120,7 +119,7 @@ const (
|
|||
type issuerMaps struct {
|
||||
byAlg map[x509.PublicKeyAlgorithm]*internalIssuer
|
||||
byName map[string]*internalIssuer
|
||||
byID map[int64]*internalIssuer
|
||||
byID map[issuance.IssuerID]*internalIssuer
|
||||
}
|
||||
|
||||
// CertificateAuthorityImpl represents a CA that signs certificates, CRLs, and
|
||||
|
@ -150,7 +149,7 @@ type CertificateAuthorityImpl struct {
|
|||
// Issuer represents a single issuer certificate, along with its key.
|
||||
type Issuer struct {
|
||||
Signer crypto.Signer
|
||||
Cert *x509.Certificate
|
||||
Cert *issuance.Certificate
|
||||
}
|
||||
|
||||
// localSigner is an interface describing the functions of a cfssl.local.Signer
|
||||
|
@ -164,7 +163,7 @@ type localSigner interface {
|
|||
// issuer, including the cfssl signer and OCSP signer objects.
|
||||
// TODO(#5086): Remove the ocsp-specific pieces of this as we factor OCSP out.
|
||||
type internalIssuer struct {
|
||||
cert *x509.Certificate
|
||||
cert *issuance.Certificate
|
||||
ocspSigner crypto.Signer
|
||||
|
||||
// Only one of cfsslSigner and boulderIssuer will be non-nill
|
||||
|
@ -175,7 +174,7 @@ type internalIssuer struct {
|
|||
func makeInternalIssuers(issuers []*issuance.Issuer, lifespanOCSP time.Duration) (issuerMaps, error) {
|
||||
issuersByAlg := make(map[x509.PublicKeyAlgorithm]*internalIssuer, 2)
|
||||
issuersByName := make(map[string]*internalIssuer, len(issuers))
|
||||
issuersByID := make(map[int64]*internalIssuer, len(issuers))
|
||||
issuersByID := make(map[issuance.IssuerID]*internalIssuer, len(issuers))
|
||||
for _, issuer := range issuers {
|
||||
ii := &internalIssuer{
|
||||
cert: issuer.Cert,
|
||||
|
@ -203,12 +202,12 @@ func makeCFSSLInternalIssuers(issuers []Issuer, policy *cfsslConfig.Signing, lif
|
|||
}
|
||||
issuersByAlg := make(map[x509.PublicKeyAlgorithm]*internalIssuer, len(issuers))
|
||||
issuersByName := make(map[string]*internalIssuer, len(issuers))
|
||||
issuersByID := make(map[int64]*internalIssuer, len(issuers))
|
||||
issuersByID := make(map[issuance.IssuerID]*internalIssuer, len(issuers))
|
||||
for idx, iss := range issuers {
|
||||
if iss.Cert == nil || iss.Signer == nil {
|
||||
return issuerMaps{}, errors.New("Issuer with nil cert or signer specified.")
|
||||
}
|
||||
cfsslSigner, err := local.NewSigner(iss.Signer, iss.Cert, x509.SHA256WithRSA, policy)
|
||||
cfsslSigner, err := local.NewSigner(iss.Signer, iss.Cert.Certificate, x509.SHA256WithRSA, policy)
|
||||
if err != nil {
|
||||
return issuerMaps{}, err
|
||||
}
|
||||
|
@ -235,19 +234,11 @@ func makeCFSSLInternalIssuers(issuers []Issuer, policy *cfsslConfig.Signing, lif
|
|||
issuersByAlg[x509.ECDSA] = ii
|
||||
}
|
||||
issuersByName[cn] = ii
|
||||
issuersByID[idForCert(iss.Cert)] = ii
|
||||
issuersByID[iss.Cert.ID()] = ii
|
||||
}
|
||||
return issuerMaps{issuersByAlg, issuersByName, issuersByID}, nil
|
||||
}
|
||||
|
||||
// idForCert generates a stable ID for an issuer certificate. This
|
||||
// is used for identifying which issuer issued a certificate in the
|
||||
// certificateStatus table.
|
||||
func idForCert(cert *x509.Certificate) int64 {
|
||||
h := sha256.Sum256(cert.Raw)
|
||||
return big.NewInt(0).SetBytes(h[:4]).Int64()
|
||||
}
|
||||
|
||||
// NewCertificateAuthorityImpl creates a CA instance that can sign certificates
|
||||
// from a single issuer (the first first in the issuers slice), and can sign OCSP
|
||||
// for any of the issuer certificates provided.
|
||||
|
@ -490,7 +481,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, req *capb.
|
|||
}
|
||||
serial = serialInt
|
||||
var ok bool
|
||||
issuer, ok = ca.issuers.byID[req.IssuerID]
|
||||
issuer, ok = ca.issuers.byID[issuance.IssuerID(req.IssuerID)]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("This CA doesn't have an issuer cert with ID %d", req.IssuerID)
|
||||
}
|
||||
|
@ -508,7 +499,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, req *capb.
|
|||
if issuer == nil {
|
||||
return nil, fmt.Errorf("This CA doesn't have an issuer cert with CommonName %q", cn)
|
||||
}
|
||||
err = cert.CheckSignatureFrom(issuer.cert)
|
||||
err = cert.CheckSignatureFrom(issuer.cert.Certificate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GenerateOCSP was asked to sign OCSP for cert "+
|
||||
"%s from %q, but the cert's signature was not valid: %s.",
|
||||
|
@ -528,7 +519,7 @@ func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, req *capb.
|
|||
tbsResponse.RevocationReason = int(req.Reason)
|
||||
}
|
||||
|
||||
ocspResponse, err := ocsp.CreateResponse(issuer.cert, issuer.cert, tbsResponse, issuer.ocspSigner)
|
||||
ocspResponse, err := ocsp.CreateResponse(issuer.cert.Certificate, issuer.cert.Certificate, tbsResponse, issuer.ocspSigner)
|
||||
ca.noteSignError(err)
|
||||
if err == nil {
|
||||
ca.signatureCount.With(prometheus.Labels{"purpose": "ocsp"}).Inc()
|
||||
|
@ -576,14 +567,14 @@ func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
|
|||
return nil, err
|
||||
}
|
||||
|
||||
issuerID := idForCert(issuer.cert)
|
||||
issuerID := issuer.cert.ID()
|
||||
|
||||
req := &sapb.AddCertificateRequest{
|
||||
Der: precertDER,
|
||||
RegID: regID,
|
||||
Ocsp: ocspResp.Response,
|
||||
Issued: nowNanos,
|
||||
IssuerID: issuerID,
|
||||
IssuerID: int64(issuerID),
|
||||
}
|
||||
|
||||
_, err = ca.sa.AddPrecertificate(ctx, req)
|
||||
|
@ -600,7 +591,7 @@ func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
|
|||
RegID: regID,
|
||||
OCSPResp: ocspResp.Response,
|
||||
Precert: true,
|
||||
IssuerID: issuerID,
|
||||
IssuerID: int64(issuerID),
|
||||
})
|
||||
}
|
||||
return nil, err
|
||||
|
@ -694,7 +685,7 @@ func (ca *CertificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
|
|||
ca.log.AuditInfof("Signing success: serial=[%s] names=[%s] csr=[%s] certificate=[%s]",
|
||||
serialHex, strings.Join(precert.DNSNames, ", "), hex.EncodeToString(req.DER),
|
||||
hex.EncodeToString(certDER))
|
||||
err = ca.storeCertificate(ctx, req.RegistrationID, req.OrderID, precert.SerialNumber, certDER, idForCert(issuer.cert))
|
||||
err = ca.storeCertificate(ctx, req.RegistrationID, req.OrderID, precert.SerialNumber, certDER, int64(issuer.cert.ID()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ func (m *mockSA) GetCertificate(ctx context.Context, serial string) (core.Certif
|
|||
}
|
||||
|
||||
var caKey crypto.Signer
|
||||
var caCert *x509.Certificate
|
||||
var caCert *issuance.Certificate
|
||||
var ctx = context.Background()
|
||||
|
||||
func init() {
|
||||
|
@ -180,7 +180,7 @@ func init() {
|
|||
if err != nil {
|
||||
panic(fmt.Sprintf("Unable to parse %s: %s", caKeyFile, err))
|
||||
}
|
||||
caCert, err = core.LoadCert(caCertFile)
|
||||
caCert, err = issuance.LoadCertificate(caCertFile)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Unable to parse %s: %s", caCertFile, err))
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ func issueCertificateSubTestValidityUsesCAClock(t *testing.T, i *TestCertificate
|
|||
func TestMultipleIssuers(t *testing.T) {
|
||||
testCtx := setup(t)
|
||||
// Load multiple issuers, and ensure the first one in the list is used.
|
||||
newIssuerCert, err := core.LoadCert("../test/test-ca2.pem")
|
||||
newIssuerCert, err := issuance.LoadCertificate("../test/test-ca2.pem")
|
||||
test.AssertNotError(t, err, "Failed to load new cert")
|
||||
newIssuers := []Issuer{
|
||||
{
|
||||
|
@ -511,7 +511,7 @@ func TestMultipleIssuers(t *testing.T) {
|
|||
cert, err := x509.ParseCertificate(issuedCert.DER)
|
||||
test.AssertNotError(t, err, "Certificate failed to parse")
|
||||
// Verify cert was signed by newIssuerCert, not caCert.
|
||||
err = cert.CheckSignatureFrom(newIssuerCert)
|
||||
err = cert.CheckSignatureFrom(newIssuerCert.Certificate)
|
||||
test.AssertNotError(t, err, "Certificate failed signature validation")
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ func TestOCSP(t *testing.T) {
|
|||
Status: status,
|
||||
})
|
||||
test.AssertNotError(t, err, "Failed to generate OCSP")
|
||||
parsed, err := ocsp.ParseResponse(ocspResp.Response, caCert)
|
||||
parsed, err := ocsp.ParseResponse(ocspResp.Response, caCert.Certificate)
|
||||
test.AssertNotError(t, err, "Failed to parse validate OCSP")
|
||||
test.AssertEquals(t, parsed.Status, 0)
|
||||
test.AssertEquals(t, parsed.RevocationReason, 0)
|
||||
|
@ -565,7 +565,7 @@ func TestOCSP(t *testing.T) {
|
|||
|
||||
// Load multiple issuers, including the old issuer, and ensure OCSP is still
|
||||
// signed correctly.
|
||||
newIssuerCert, err := core.LoadCert("../test/test-ca2.pem")
|
||||
newIssuerCert, err := issuance.LoadCertificate("../test/test-ca2.pem")
|
||||
test.AssertNotError(t, err, "Failed to load new cert")
|
||||
newIssuers := []Issuer{
|
||||
{
|
||||
|
@ -603,7 +603,7 @@ func TestOCSP(t *testing.T) {
|
|||
parsedNewCert, err := x509.ParseCertificate(newCert.DER)
|
||||
test.AssertNotError(t, err, "Failed to parse newCert")
|
||||
|
||||
err = parsedNewCert.CheckSignatureFrom(newIssuerCert)
|
||||
err = parsedNewCert.CheckSignatureFrom(newIssuerCert.Certificate)
|
||||
t.Logf("check sig: %s", err)
|
||||
|
||||
// ocspResp2 is a second OCSP response for `cert` (issued by caCert), and
|
||||
|
@ -613,7 +613,7 @@ func TestOCSP(t *testing.T) {
|
|||
Status: status,
|
||||
})
|
||||
test.AssertNotError(t, err, "Failed to sign second OCSP response")
|
||||
_, err = ocsp.ParseResponse(ocspResp2.Response, caCert)
|
||||
_, err = ocsp.ParseResponse(ocspResp2.Response, caCert.Certificate)
|
||||
test.AssertNotError(t, err, "Failed to parse / validate second OCSP response")
|
||||
|
||||
// newCertOcspResp is an OCSP response for `newCert` (issued by newIssuer),
|
||||
|
@ -623,7 +623,7 @@ func TestOCSP(t *testing.T) {
|
|||
Status: status,
|
||||
})
|
||||
test.AssertNotError(t, err, "Failed to generate OCSP")
|
||||
parsedNewCertOcspResp, err := ocsp.ParseResponse(newCertOcspResp.Response, newIssuerCert)
|
||||
parsedNewCertOcspResp, err := ocsp.ParseResponse(newCertOcspResp.Response, newIssuerCert.Certificate)
|
||||
test.AssertNotError(t, err, "Failed to parse / validate OCSP for newCert")
|
||||
test.AssertEquals(t, parsedNewCertOcspResp.Status, 0)
|
||||
test.AssertEquals(t, parsedNewCertOcspResp.RevocationReason, 0)
|
||||
|
@ -1396,7 +1396,7 @@ func TestGenerateOCSPWithIssuerID(t *testing.T) {
|
|||
// GenerateOCSP with feature enabled + req contains good IssuerID
|
||||
rsaIssuer := ca.issuers.byAlg[x509.RSA]
|
||||
_, err = ca.GenerateOCSP(context.Background(), &capb.GenerateOCSPRequest{
|
||||
IssuerID: idForCert(rsaIssuer.cert),
|
||||
IssuerID: int64(rsaIssuer.cert.ID()),
|
||||
Serial: "DEADDEADDEADDEADDEADDEADDEADDEADDEAD",
|
||||
Status: string(core.OCSPStatusGood),
|
||||
})
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
capb "github.com/letsencrypt/boulder/ca/proto"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/goodkey"
|
||||
"github.com/letsencrypt/boulder/issuance"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
"github.com/letsencrypt/boulder/mocks"
|
||||
|
@ -54,7 +55,18 @@ func TestRevokeBatch(t *testing.T) {
|
|||
ra := ra.NewRegistrationAuthorityImpl(fc,
|
||||
log,
|
||||
metrics.NoopRegisterer,
|
||||
1, goodkey.KeyPolicy{}, 100, true, 300*24*time.Hour, 7*24*time.Hour, nil, nil, 0, nil, nil, &x509.Certificate{})
|
||||
1,
|
||||
goodkey.KeyPolicy{},
|
||||
100,
|
||||
true,
|
||||
300*24*time.Hour,
|
||||
7*24*time.Hour,
|
||||
nil,
|
||||
nil,
|
||||
0,
|
||||
nil,
|
||||
nil,
|
||||
&issuance.Certificate{Certificate: &x509.Certificate{}})
|
||||
ra.SA = ssa
|
||||
ra.CA = &mockCA{}
|
||||
|
||||
|
|
|
@ -124,13 +124,13 @@ func loadCFSSLIssuers(configs []IssuerConfig) ([]ca.Issuer, error) {
|
|||
return issuers, nil
|
||||
}
|
||||
|
||||
func loadCFSSLIssuer(issuerConfig IssuerConfig) (crypto.Signer, *x509.Certificate, error) {
|
||||
cert, err := core.LoadCert(issuerConfig.CertFile)
|
||||
func loadCFSSLIssuer(issuerConfig IssuerConfig) (crypto.Signer, *issuance.Certificate, error) {
|
||||
cert, err := issuance.LoadCertificate(issuerConfig.CertFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
signer, err := loadCFSSLSigner(issuerConfig, cert)
|
||||
signer, err := loadCFSSLSigner(issuerConfig, cert.Certificate)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -13,12 +12,12 @@ import (
|
|||
akamaipb "github.com/letsencrypt/boulder/akamai/proto"
|
||||
capb "github.com/letsencrypt/boulder/ca/proto"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/ctpolicy"
|
||||
"github.com/letsencrypt/boulder/ctpolicy/ctconfig"
|
||||
"github.com/letsencrypt/boulder/features"
|
||||
"github.com/letsencrypt/boulder/goodkey"
|
||||
bgrpc "github.com/letsencrypt/boulder/grpc"
|
||||
"github.com/letsencrypt/boulder/issuance"
|
||||
"github.com/letsencrypt/boulder/policy"
|
||||
pubpb "github.com/letsencrypt/boulder/publisher/proto"
|
||||
"github.com/letsencrypt/boulder/ra"
|
||||
|
@ -158,13 +157,11 @@ func main() {
|
|||
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to Publisher")
|
||||
pubc := bgrpc.NewPublisherClientWrapper(pubpb.NewPublisherClient(conn))
|
||||
|
||||
var apc akamaipb.AkamaiPurgerClient
|
||||
var issuerCert *x509.Certificate
|
||||
apConn, err := bgrpc.ClientSetup(c.RA.AkamaiPurgerService, tlsConfig, clientMetrics, clk)
|
||||
cmd.FailOnError(err, "Unable to create a Akamai Purger client")
|
||||
apc = akamaipb.NewAkamaiPurgerClient(apConn)
|
||||
apc := akamaipb.NewAkamaiPurgerClient(apConn)
|
||||
|
||||
issuerCert, err = core.LoadCert(c.RA.IssuerCertPath)
|
||||
issuerCert, err := issuance.LoadCertificate(c.RA.IssuerCertPath)
|
||||
cmd.FailOnError(err, "Failed to load issuer certificate")
|
||||
|
||||
// Boulder's components assume that there will always be CT logs configured.
|
||||
|
|
|
@ -87,24 +87,32 @@ type IssuerLoc struct {
|
|||
}
|
||||
|
||||
// LoadIssuer loads a signer (private key) and certificate from the locations specified.
|
||||
func LoadIssuer(location IssuerLoc) (*x509.Certificate, crypto.Signer, error) {
|
||||
cert, err := core.LoadCert(location.CertFile)
|
||||
func LoadIssuer(location IssuerLoc) (*Certificate, crypto.Signer, error) {
|
||||
issuerCert, err := LoadCertificate(location.CertFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
signer, err := loadSigner(location, cert)
|
||||
signer, err := loadSigner(location, issuerCert)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if !core.KeyDigestEquals(signer.Public(), cert.PublicKey) {
|
||||
if !core.KeyDigestEquals(signer.Public(), issuerCert.PublicKey) {
|
||||
return nil, nil, fmt.Errorf("Issuer key did not match issuer cert %s", location.CertFile)
|
||||
}
|
||||
return cert, signer, err
|
||||
return issuerCert, signer, err
|
||||
}
|
||||
|
||||
func loadSigner(location IssuerLoc, cert *x509.Certificate) (crypto.Signer, error) {
|
||||
func LoadCertificate(path string) (*Certificate, error) {
|
||||
cert, err := core.LoadCert(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Certificate{cert}, nil
|
||||
}
|
||||
|
||||
func loadSigner(location IssuerLoc, cert *Certificate) (crypto.Signer, error) {
|
||||
if location.File != "" {
|
||||
keyBytes, err := ioutil.ReadFile(location.File)
|
||||
if err != nil {
|
||||
|
@ -325,10 +333,26 @@ func (p *Profile) generateTemplate(clk clock.Clock) *x509.Certificate {
|
|||
return template
|
||||
}
|
||||
|
||||
// Certificate embeds an *x509.Certificate and represent the added semantics
|
||||
// that this certificate can be used for issuance. It also provides the .ID()
|
||||
// method, which returns an internal issuer ID for this certificate.
|
||||
type Certificate struct {
|
||||
*x509.Certificate
|
||||
}
|
||||
|
||||
type IssuerID int64
|
||||
|
||||
// ID provides a stable ID for an issuer's certificate. This is used for
|
||||
// identifying which issuer issued a certificate in the certificateStatus table.
|
||||
func (ic *Certificate) ID() IssuerID {
|
||||
h := sha256.Sum256(ic.Raw)
|
||||
return IssuerID(big.NewInt(0).SetBytes(h[:4]).Int64())
|
||||
}
|
||||
|
||||
// Issuer is capable of issuing new certificates
|
||||
// TODO(#5086): make Cert and Signer private when they're no longer needed by ca.internalIssuer
|
||||
type Issuer struct {
|
||||
Cert *x509.Certificate
|
||||
Cert *Certificate
|
||||
Signer crypto.Signer
|
||||
Profile *Profile
|
||||
Linter *lint.Linter
|
||||
|
@ -337,7 +361,7 @@ type Issuer struct {
|
|||
|
||||
// NewIssuer constructs an Issuer on the heap, verifying that the profile
|
||||
// is well-formed.
|
||||
func NewIssuer(cert *x509.Certificate, signer crypto.Signer, profile *Profile, linter *lint.Linter, clk clock.Clock) (*Issuer, error) {
|
||||
func NewIssuer(cert *Certificate, signer crypto.Signer, profile *Profile, linter *lint.Linter, clk clock.Clock) (*Issuer, error) {
|
||||
switch k := cert.PublicKey.(type) {
|
||||
case *rsa.PublicKey:
|
||||
profile.sigAlg = x509.SHA256WithRSA
|
||||
|
@ -395,9 +419,8 @@ func (i *Issuer) Name() string {
|
|||
|
||||
// ID provides a stable ID for an issuer's certificate. This is used for
|
||||
// identifying which issuer issued a certificate in the certificateStatus table.
|
||||
func (i *Issuer) ID() int64 {
|
||||
h := sha256.Sum256(i.Cert.Raw)
|
||||
return big.NewInt(0).SetBytes(h[:4]).Int64()
|
||||
func (i *Issuer) ID() IssuerID {
|
||||
return i.Cert.ID()
|
||||
}
|
||||
|
||||
var ctPoisonExt = pkix.Extension{
|
||||
|
@ -526,12 +549,12 @@ func (i *Issuer) Issue(req *IssuanceRequest) ([]byte, error) {
|
|||
|
||||
// check that the tbsCertificate is properly formed by signing it
|
||||
// with a throwaway key and then linting it using zlint
|
||||
err = i.Linter.LintTBS(template, i.Cert, req.PublicKey)
|
||||
err = i.Linter.LintTBS(template, i.Cert.Certificate, req.PublicKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tbsCertificate linting failed: %w", err)
|
||||
}
|
||||
|
||||
return x509.CreateCertificate(rand.Reader, template, i.Cert, req.PublicKey, i.Signer)
|
||||
return x509.CreateCertificate(rand.Reader, template, i.Cert.Certificate, req.PublicKey, i.Signer)
|
||||
}
|
||||
|
||||
func ContainsMustStaple(extensions []pkix.Extension) bool {
|
||||
|
|
|
@ -52,7 +52,7 @@ func defaultProfile() *Profile {
|
|||
return p
|
||||
}
|
||||
|
||||
var issuerCert *x509.Certificate
|
||||
var issuerCert *Certificate
|
||||
var issuerSigner *ecdsa.PrivateKey
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
@ -72,8 +72,9 @@ func TestMain(m *testing.M) {
|
|||
}
|
||||
issuer, err := x509.CreateCertificate(rand.Reader, template, template, tk.Public(), tk)
|
||||
cmd.FailOnError(err, "failed to generate test issuer")
|
||||
issuerCert, err = x509.ParseCertificate(issuer)
|
||||
cert, err := x509.ParseCertificate(issuer)
|
||||
cmd.FailOnError(err, "failed to parse test issuer")
|
||||
issuerCert = &Certificate{cert}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
|
@ -422,8 +423,10 @@ func TestNewIssuer(t *testing.T) {
|
|||
|
||||
func TestNewIssuerUnsupportedKeyType(t *testing.T) {
|
||||
_, err := NewIssuer(
|
||||
&x509.Certificate{
|
||||
PublicKey: &ed25519.PublicKey{},
|
||||
&Certificate{
|
||||
&x509.Certificate{
|
||||
PublicKey: &ed25519.PublicKey{},
|
||||
},
|
||||
},
|
||||
&ed25519.PrivateKey{},
|
||||
defaultProfile(),
|
||||
|
@ -436,11 +439,13 @@ func TestNewIssuerUnsupportedKeyType(t *testing.T) {
|
|||
|
||||
func TestNewIssuerNoCertSign(t *testing.T) {
|
||||
_, err := NewIssuer(
|
||||
&x509.Certificate{
|
||||
PublicKey: &ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
&Certificate{
|
||||
&x509.Certificate{
|
||||
PublicKey: &ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
},
|
||||
KeyUsage: 0,
|
||||
},
|
||||
KeyUsage: 0,
|
||||
},
|
||||
issuerSigner,
|
||||
defaultProfile(),
|
||||
|
@ -453,11 +458,13 @@ func TestNewIssuerNoCertSign(t *testing.T) {
|
|||
|
||||
func TestNewIssuerNoDigitalSignature(t *testing.T) {
|
||||
_, err := NewIssuer(
|
||||
&x509.Certificate{
|
||||
PublicKey: &ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
&Certificate{
|
||||
&x509.Certificate{
|
||||
PublicKey: &ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
},
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
},
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
},
|
||||
issuerSigner,
|
||||
defaultProfile(),
|
||||
|
@ -473,11 +480,13 @@ func TestNewIssuerOCSPOnly(t *testing.T) {
|
|||
p.useForRSALeaves = false
|
||||
p.useForECDSALeaves = false
|
||||
_, err := NewIssuer(
|
||||
&x509.Certificate{
|
||||
PublicKey: &ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
&Certificate{
|
||||
&x509.Certificate{
|
||||
PublicKey: &ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
},
|
||||
issuerSigner,
|
||||
p,
|
||||
|
@ -530,7 +539,7 @@ func TestIssue(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Issue failed")
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
test.AssertNotError(t, err, "failed to parse certificate")
|
||||
err = cert.CheckSignatureFrom(issuerCert)
|
||||
err = cert.CheckSignatureFrom(issuerCert.Certificate)
|
||||
test.AssertNotError(t, err, "signature validation failed")
|
||||
test.AssertDeepEquals(t, cert.DNSNames, []string{"example.com"})
|
||||
test.AssertEquals(t, cert.Subject.CommonName, "example.com")
|
||||
|
@ -563,7 +572,7 @@ func TestIssueRSA(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Issue failed")
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
test.AssertNotError(t, err, "failed to parse certificate")
|
||||
err = cert.CheckSignatureFrom(issuerCert)
|
||||
err = cert.CheckSignatureFrom(issuerCert.Certificate)
|
||||
test.AssertNotError(t, err, "signature validation failed")
|
||||
test.AssertByteEquals(t, cert.SerialNumber.Bytes(), []byte{1, 2, 3, 4, 5, 6, 7, 8})
|
||||
test.AssertDeepEquals(t, cert.PublicKey, pk.Public())
|
||||
|
@ -593,7 +602,7 @@ func TestIssueCTPoison(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Issue failed")
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
test.AssertNotError(t, err, "failed to parse certificate")
|
||||
err = cert.CheckSignatureFrom(issuerCert)
|
||||
err = cert.CheckSignatureFrom(issuerCert.Certificate)
|
||||
test.AssertNotError(t, err, "signature validation failed")
|
||||
test.AssertByteEquals(t, cert.SerialNumber.Bytes(), []byte{1, 2, 3, 4, 5, 6, 7, 8})
|
||||
test.AssertDeepEquals(t, cert.PublicKey, pk.Public())
|
||||
|
@ -625,7 +634,7 @@ func TestIssueSCTList(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Issue failed")
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
test.AssertNotError(t, err, "failed to parse certificate")
|
||||
err = cert.CheckSignatureFrom(issuerCert)
|
||||
err = cert.CheckSignatureFrom(issuerCert.Certificate)
|
||||
test.AssertNotError(t, err, "signature validation failed")
|
||||
test.AssertByteEquals(t, cert.SerialNumber.Bytes(), []byte{1, 2, 3, 4, 5, 6, 7, 8})
|
||||
test.AssertDeepEquals(t, cert.PublicKey, pk.Public())
|
||||
|
@ -658,7 +667,7 @@ func TestIssueMustStaple(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Issue failed")
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
test.AssertNotError(t, err, "failed to parse certificate")
|
||||
err = cert.CheckSignatureFrom(issuerCert)
|
||||
err = cert.CheckSignatureFrom(issuerCert.Certificate)
|
||||
test.AssertNotError(t, err, "signature validation failed")
|
||||
test.AssertByteEquals(t, cert.SerialNumber.Bytes(), []byte{1, 2, 3, 4, 5, 6, 7, 8})
|
||||
test.AssertDeepEquals(t, cert.PublicKey, pk.Public())
|
||||
|
|
7
ra/ra.go
7
ra/ra.go
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/letsencrypt/boulder/goodkey"
|
||||
bgrpc "github.com/letsencrypt/boulder/grpc"
|
||||
"github.com/letsencrypt/boulder/identifier"
|
||||
"github.com/letsencrypt/boulder/issuance"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
"github.com/letsencrypt/boulder/policy"
|
||||
|
@ -75,7 +76,7 @@ type RegistrationAuthorityImpl struct {
|
|||
reuseValidAuthz bool
|
||||
orderLifetime time.Duration
|
||||
|
||||
issuer *x509.Certificate
|
||||
issuer *issuance.Certificate
|
||||
purger akamaipb.AkamaiPurgerClient
|
||||
|
||||
ctpolicy *ctpolicy.CTPolicy
|
||||
|
@ -106,7 +107,7 @@ func NewRegistrationAuthorityImpl(
|
|||
orderLifetime time.Duration,
|
||||
ctp *ctpolicy.CTPolicy,
|
||||
purger akamaipb.AkamaiPurgerClient,
|
||||
issuer *x509.Certificate,
|
||||
issuer *issuance.Certificate,
|
||||
) *RegistrationAuthorityImpl {
|
||||
ctpolicyResults := prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
|
@ -1708,7 +1709,7 @@ func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert
|
|||
return err
|
||||
}
|
||||
}
|
||||
purgeURLs, err := akamai.GeneratePurgeURLs(cert.Raw, ra.issuer)
|
||||
purgeURLs, err := akamai.GeneratePurgeURLs(cert.Raw, ra.issuer.Certificate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import (
|
|||
"github.com/letsencrypt/boulder/goodkey"
|
||||
bgrpc "github.com/letsencrypt/boulder/grpc"
|
||||
"github.com/letsencrypt/boulder/identifier"
|
||||
"github.com/letsencrypt/boulder/issuance"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
"github.com/letsencrypt/boulder/mocks"
|
||||
|
@ -3900,7 +3901,7 @@ func TestRevocationAddBlockedKey(t *testing.T) {
|
|||
test.AssertNotError(t, err, "x509.CreateCertificate failed")
|
||||
cert, err := x509.ParseCertificate(der)
|
||||
test.AssertNotError(t, err, "x509.ParseCertificate failed")
|
||||
ra.issuer = cert
|
||||
ra.issuer = &issuance.Certificate{Certificate: cert}
|
||||
|
||||
err = ra.RevokeCertificateWithReg(context.Background(), *cert, ocsp.Unspecified, 0)
|
||||
test.AssertNotError(t, err, "RevokeCertificateWithReg failed")
|
||||
|
|
Loading…
Reference in New Issue