This reverts commit 6454513ded
.
We actually need to wait 90 days to ensure the issuerID field of the
certificateStatus table is non-nil for all extant certificates.
This commit is contained in:
parent
325bba3a6f
commit
0b0917cea6
121
ca/ca.go
121
ca/ca.go
|
@ -7,6 +7,7 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
|
@ -36,8 +37,8 @@ import (
|
|||
corepb "github.com/letsencrypt/boulder/core/proto"
|
||||
csrlib "github.com/letsencrypt/boulder/csr"
|
||||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
"github.com/letsencrypt/boulder/features"
|
||||
"github.com/letsencrypt/boulder/goodkey"
|
||||
"github.com/letsencrypt/boulder/issuercerts"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
sapb "github.com/letsencrypt/boulder/sa/proto"
|
||||
)
|
||||
|
@ -115,9 +116,11 @@ const (
|
|||
type CertificateAuthorityImpl struct {
|
||||
rsaProfile string
|
||||
ecdsaProfile string
|
||||
// A map from issuer cert common name to an internalIssuer struct
|
||||
issuers map[string]*internalIssuer
|
||||
// A map from issuer ID to internalIssuer
|
||||
idToIssuer map[issuercerts.ID]*internalIssuer
|
||||
// The issuer that will be used for issuance (as opposed to OCSP signing)
|
||||
idToIssuer map[int64]*internalIssuer
|
||||
// The common name of the default issuer cert
|
||||
defaultIssuer *internalIssuer
|
||||
sa certificateStorage
|
||||
pa core.PolicyAuthority
|
||||
|
@ -163,12 +166,11 @@ func makeInternalIssuers(
|
|||
issuers []Issuer,
|
||||
policy *cfsslConfig.Signing,
|
||||
lifespanOCSP time.Duration,
|
||||
) (map[issuercerts.ID]*internalIssuer, error) {
|
||||
) (map[string]*internalIssuer, error) {
|
||||
if len(issuers) == 0 {
|
||||
return nil, errors.New("No issuers specified.")
|
||||
}
|
||||
internalIssuers := make(map[issuercerts.ID]*internalIssuer)
|
||||
cns := make(map[string]bool)
|
||||
internalIssuers := make(map[string]*internalIssuer)
|
||||
for _, iss := range issuers {
|
||||
if iss.Cert == nil || iss.Signer == nil {
|
||||
return nil, errors.New("Issuer with nil cert or signer specified.")
|
||||
|
@ -179,11 +181,10 @@ func makeInternalIssuers(
|
|||
}
|
||||
|
||||
cn := iss.Cert.Subject.CommonName
|
||||
if cns[cn] {
|
||||
if internalIssuers[cn] != nil {
|
||||
return nil, errors.New("Multiple issuer certs with the same CommonName are not supported")
|
||||
}
|
||||
id := issuercerts.FromCert(iss.Cert).ID()
|
||||
internalIssuers[id] = &internalIssuer{
|
||||
internalIssuers[cn] = &internalIssuer{
|
||||
cert: iss.Cert,
|
||||
eeSigner: eeSigner,
|
||||
ocspSigner: iss.Signer,
|
||||
|
@ -192,8 +193,16 @@ func makeInternalIssuers(
|
|||
return internalIssuers, nil
|
||||
}
|
||||
|
||||
// idForIssuer generates a stable ID for an issuer certificate. This
|
||||
// is used for identifying which issuer issued a certificate in the
|
||||
// certificateStatus table.
|
||||
func idForIssuer(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 in the issuers slice), and can sign OCSP
|
||||
// from a single issuer (the first first in the issuers slice), and can sign OCSP
|
||||
// for any of the issuer certificates provided.
|
||||
func NewCertificateAuthorityImpl(
|
||||
config ca_config.CAConfig,
|
||||
|
@ -242,7 +251,7 @@ func NewCertificateAuthorityImpl(
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultIssuer := internalIssuers[issuercerts.FromCert(issuers[0].Cert).ID()]
|
||||
defaultIssuer := internalIssuers[issuers[0].Cert.Subject.CommonName]
|
||||
|
||||
rsaProfile := config.RSAProfile
|
||||
ecdsaProfile := config.ECDSAProfile
|
||||
|
@ -292,6 +301,7 @@ func NewCertificateAuthorityImpl(
|
|||
ca = &CertificateAuthorityImpl{
|
||||
sa: sa,
|
||||
pa: pa,
|
||||
issuers: internalIssuers,
|
||||
defaultIssuer: defaultIssuer,
|
||||
rsaProfile: rsaProfile,
|
||||
ecdsaProfile: ecdsaProfile,
|
||||
|
@ -309,9 +319,9 @@ func NewCertificateAuthorityImpl(
|
|||
signErrorCounter: signErrorCounter,
|
||||
}
|
||||
|
||||
ca.idToIssuer = make(map[issuercerts.ID]*internalIssuer)
|
||||
for _, ii := range internalIssuers {
|
||||
id := issuercerts.FromCert(ii.cert).ID()
|
||||
ca.idToIssuer = make(map[int64]*internalIssuer)
|
||||
for _, ii := range ca.issuers {
|
||||
id := idForIssuer(ii.cert)
|
||||
ca.idToIssuer[id] = ii
|
||||
}
|
||||
|
||||
|
@ -423,33 +433,48 @@ var ocspStatusToCode = map[string]int{
|
|||
func (ca *CertificateAuthorityImpl) GenerateOCSP(ctx context.Context, req *caPB.GenerateOCSPRequest) (*caPB.OCSPResponse, error) {
|
||||
var issuer *internalIssuer
|
||||
var serial *big.Int
|
||||
if req.IssuerID == nil {
|
||||
return nil, fmt.Errorf("no issuerID provided")
|
||||
}
|
||||
if req.Serial == nil {
|
||||
return nil, fmt.Errorf("no serial provided")
|
||||
}
|
||||
// Once the feature is enabled we need to support both RPCs that include
|
||||
// IssuerID and those that don't as we still need to be able to update rows
|
||||
// that didn't have an IssuerID set when they were created. Once this feature
|
||||
// has been enabled for a full OCSP lifetime cycle we can remove this
|
||||
// functionality.
|
||||
serialInt, err := core.StringToSerial(*req.Serial)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serial = serialInt
|
||||
var ok bool
|
||||
issuer, ok = ca.idToIssuer[issuercerts.ID(*req.IssuerID)]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("This CA doesn't have an issuer cert with ID %d", *req.IssuerID)
|
||||
}
|
||||
exists, err := ca.sa.SerialExists(ctx, &sapb.Serial{Serial: req.Serial})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !*exists.Exists {
|
||||
return nil, fmt.Errorf("GenerateOCSP was asked to sign OCSP for certification with unknown serial %q", *req.Serial)
|
||||
if features.Enabled(features.StoreIssuerInfo) && req.IssuerID != nil {
|
||||
serialInt, err := core.StringToSerial(*req.Serial)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
serial = serialInt
|
||||
var ok bool
|
||||
issuer, ok = ca.idToIssuer[*req.IssuerID]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("This CA doesn't have an issuer cert with ID %d", *req.IssuerID)
|
||||
}
|
||||
exists, err := ca.sa.SerialExists(ctx, &sapb.Serial{Serial: req.Serial})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !*exists.Exists {
|
||||
return nil, fmt.Errorf("GenerateOCSP was asked to sign OCSP for certification with unknown serial %q", *req.Serial)
|
||||
}
|
||||
} else {
|
||||
cert, err := x509.ParseCertificate(req.CertDER)
|
||||
if err != nil {
|
||||
ca.log.AuditErr(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serial = cert.SerialNumber
|
||||
cn := cert.Issuer.CommonName
|
||||
issuer = ca.issuers[cn]
|
||||
if issuer == nil {
|
||||
return nil, fmt.Errorf("This CA doesn't have an issuer cert with CommonName %q", cn)
|
||||
}
|
||||
err = cert.CheckSignatureFrom(issuer.cert)
|
||||
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.",
|
||||
core.SerialToString(cert.SerialNumber), cn, err)
|
||||
}
|
||||
}
|
||||
|
||||
now := ca.clk.Now().Truncate(time.Hour)
|
||||
|
@ -498,16 +523,10 @@ func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// we currently only use one issuer, in the future when we support multiple
|
||||
// the issuer will need to be derived from issueReq
|
||||
issuerID := int64(issuercerts.FromCert(ca.defaultIssuer.cert).ID())
|
||||
|
||||
status := string(core.OCSPStatusGood)
|
||||
ocspResp, err := ca.GenerateOCSP(ctx, &caPB.GenerateOCSPRequest{
|
||||
Serial: &serialHex,
|
||||
CertDER: precertDER,
|
||||
Status: &status,
|
||||
IssuerID: &issuerID,
|
||||
CertDER: precertDER,
|
||||
Status: &status,
|
||||
})
|
||||
if err != nil {
|
||||
err = berrors.InternalServerError(err.Error())
|
||||
|
@ -516,13 +535,17 @@ func (ca *CertificateAuthorityImpl) IssuePrecertificate(ctx context.Context, iss
|
|||
}
|
||||
|
||||
req := &sapb.AddCertificateRequest{
|
||||
Der: precertDER,
|
||||
RegID: ®ID,
|
||||
Ocsp: ocspResp.Response,
|
||||
Issued: &nowNanos,
|
||||
IssuerID: &issuerID,
|
||||
Der: precertDER,
|
||||
RegID: ®ID,
|
||||
Ocsp: ocspResp.Response,
|
||||
Issued: &nowNanos,
|
||||
}
|
||||
|
||||
// we currently only use one issuer, in the future when we support multiple
|
||||
// the issuer will need to be derived from issueReq
|
||||
issuerID := idForIssuer(ca.defaultIssuer.cert)
|
||||
req.IssuerID = &issuerID
|
||||
|
||||
_, err = ca.sa.AddPrecertificate(ctx, req)
|
||||
if err != nil {
|
||||
ca.orphanCount.With(prometheus.Labels{"type": "precert"}).Inc()
|
||||
|
|
|
@ -39,7 +39,6 @@ import (
|
|||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
"github.com/letsencrypt/boulder/features"
|
||||
"github.com/letsencrypt/boulder/goodkey"
|
||||
"github.com/letsencrypt/boulder/issuercerts"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
"github.com/letsencrypt/boulder/policy"
|
||||
|
@ -493,16 +492,10 @@ func TestOCSP(t *testing.T) {
|
|||
test.AssertNotError(t, err, "Failed to issue")
|
||||
parsedCert, err := x509.ParseCertificate(cert.DER)
|
||||
test.AssertNotError(t, err, "Failed to parse cert")
|
||||
|
||||
caCertIssuerID := int64(issuercerts.FromCert(caCert).ID())
|
||||
serial := core.SerialToString(parsedCert.SerialNumber)
|
||||
status := string(core.OCSPStatusGood)
|
||||
|
||||
ocspResp, err := ca.GenerateOCSP(ctx, &caPB.GenerateOCSPRequest{
|
||||
IssuerID: &caCertIssuerID,
|
||||
Serial: &serial,
|
||||
CertDER: cert.DER,
|
||||
Status: &status,
|
||||
CertDER: cert.DER,
|
||||
Status: &status,
|
||||
})
|
||||
test.AssertNotError(t, err, "Failed to generate OCSP")
|
||||
parsed, err := ocsp.ParseResponse(ocspResp.Response, caCert)
|
||||
|
@ -511,6 +504,13 @@ func TestOCSP(t *testing.T) {
|
|||
test.AssertEquals(t, parsed.RevocationReason, 0)
|
||||
test.AssertEquals(t, parsed.SerialNumber.Cmp(parsedCert.SerialNumber), 0)
|
||||
|
||||
// Test that signatures are checked.
|
||||
_, err = ca.GenerateOCSP(ctx, &caPB.GenerateOCSPRequest{
|
||||
CertDER: append(cert.DER, byte(0)),
|
||||
Status: &status,
|
||||
})
|
||||
test.AssertError(t, err, "Generated OCSP for cert with bad signature")
|
||||
|
||||
// Load multiple issuers, including the old issuer, and ensure OCSP is still
|
||||
// signed correctly.
|
||||
newIssuerCert, err := core.LoadCert("../test/test-ca2.pem")
|
||||
|
@ -543,16 +543,14 @@ func TestOCSP(t *testing.T) {
|
|||
parsedNewCert, err := x509.ParseCertificate(newCert.DER)
|
||||
test.AssertNotError(t, err, "Failed to parse newCert")
|
||||
|
||||
newIssuerID := int64(issuercerts.FromCert(newIssuers[0].Cert).ID())
|
||||
newSerial := core.SerialToString(parsedNewCert.SerialNumber)
|
||||
err = parsedNewCert.CheckSignatureFrom(newIssuerCert)
|
||||
t.Logf("check sig: %s", err)
|
||||
|
||||
// ocspResp2 is a second OCSP response for `cert` (issued by caCert), and
|
||||
// should be signed by caCert.
|
||||
ocspResp2, err := ca.GenerateOCSP(ctx, &caPB.GenerateOCSPRequest{
|
||||
IssuerID: &newIssuerID,
|
||||
Serial: &newSerial,
|
||||
CertDER: append([]byte(nil), cert.DER...),
|
||||
Status: &status,
|
||||
CertDER: append([]byte(nil), cert.DER...),
|
||||
Status: &status,
|
||||
})
|
||||
test.AssertNotError(t, err, "Failed to sign second OCSP response")
|
||||
_, err = ocsp.ParseResponse(ocspResp2.Response, caCert)
|
||||
|
@ -561,10 +559,8 @@ func TestOCSP(t *testing.T) {
|
|||
// newCertOcspResp is an OCSP response for `newCert` (issued by newIssuer),
|
||||
// and should be signed by newIssuer.
|
||||
newCertOcspResp, err := ca.GenerateOCSP(ctx, &caPB.GenerateOCSPRequest{
|
||||
IssuerID: &newIssuerID,
|
||||
Serial: &newSerial,
|
||||
CertDER: newCert.DER,
|
||||
Status: &status,
|
||||
CertDER: newCert.DER,
|
||||
Status: &status,
|
||||
})
|
||||
test.AssertNotError(t, err, "Failed to generate OCSP")
|
||||
parsedNewCertOcspResp, err := ocsp.ParseResponse(newCertOcspResp.Response, newIssuerCert)
|
||||
|
@ -1257,6 +1253,7 @@ func TestIssuePrecertificateLinting(t *testing.T) {
|
|||
func TestGenerateOCSPWithIssuerID(t *testing.T) {
|
||||
testCtx := setup(t)
|
||||
sa := &mockSA{}
|
||||
_ = features.Set(map[string]bool{"StoreIssuerInfo": true})
|
||||
ca, err := NewCertificateAuthorityImpl(
|
||||
testCtx.caConfig,
|
||||
sa,
|
||||
|
@ -1269,7 +1266,7 @@ func TestGenerateOCSPWithIssuerID(t *testing.T) {
|
|||
nil)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
|
||||
// req contains bad IssuerID
|
||||
// GenerateOCSP with feature enabled + req contains bad IssuerID
|
||||
issuerID := int64(666)
|
||||
serial := "DEADDEADDEADDEADDEADDEADDEADDEADDEAD"
|
||||
status := string(core.OCSPStatusGood)
|
||||
|
@ -1280,8 +1277,8 @@ func TestGenerateOCSPWithIssuerID(t *testing.T) {
|
|||
})
|
||||
test.AssertError(t, err, "GenerateOCSP didn't fail with invalid IssuerID")
|
||||
|
||||
// req contains good IssuerID
|
||||
issuerID = int64(issuercerts.FromCert(ca.defaultIssuer.cert).ID())
|
||||
// GenerateOCSP with feature enabled + req contains good IssuerID
|
||||
issuerID = idForIssuer(ca.defaultIssuer.cert)
|
||||
_, err = ca.GenerateOCSP(context.Background(), &caPB.GenerateOCSPRequest{
|
||||
IssuerID: &issuerID,
|
||||
Serial: &serial,
|
||||
|
@ -1289,7 +1286,7 @@ func TestGenerateOCSPWithIssuerID(t *testing.T) {
|
|||
})
|
||||
test.AssertNotError(t, err, "GenerateOCSP failed")
|
||||
|
||||
// req doesn't contain IssuerID or Serial
|
||||
// GenerateOCSP with feature enabled + req doesn't contain IssuerID
|
||||
issueReq := caPB.IssueCertificateRequest{Csr: CNandSANCSR, RegistrationID: &arbitraryRegID}
|
||||
cert, err := ca.IssuePrecertificate(ctx, &issueReq)
|
||||
test.AssertNotError(t, err, "Failed to issue")
|
||||
|
@ -1297,5 +1294,5 @@ func TestGenerateOCSPWithIssuerID(t *testing.T) {
|
|||
CertDER: cert.DER,
|
||||
Status: &status,
|
||||
})
|
||||
test.AssertError(t, err, "Expected error from GenerateOCSP")
|
||||
test.AssertNotError(t, err, "GenerateOCSP failed")
|
||||
}
|
||||
|
|
|
@ -20,11 +20,9 @@ import (
|
|||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
corepb "github.com/letsencrypt/boulder/core/proto"
|
||||
"github.com/letsencrypt/boulder/db"
|
||||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
"github.com/letsencrypt/boulder/features"
|
||||
bgrpc "github.com/letsencrypt/boulder/grpc"
|
||||
"github.com/letsencrypt/boulder/issuercerts"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
sapb "github.com/letsencrypt/boulder/sa/proto"
|
||||
|
@ -53,15 +51,10 @@ type config struct {
|
|||
// to the original issued date. It should match the value used in
|
||||
// `test/config/ca.json` for the CA "backdate" value.
|
||||
Backdate cmd.ConfigDuration
|
||||
// A list of issuer certificates. Orphaned certificates from the logs will be
|
||||
// matched against these when determining which issuer ID to enter into the
|
||||
// certificateStatus table.
|
||||
IssuerFiles []string
|
||||
Features map[string]bool
|
||||
Features map[string]bool
|
||||
}
|
||||
|
||||
type certificateStorage interface {
|
||||
AddSerial(context.Context, *sapb.AddSerialRequest) (*corepb.Empty, error)
|
||||
AddCertificate(context.Context, []byte, int64, []byte, *time.Time) (string, error)
|
||||
AddPrecertificate(ctx context.Context, req *sapb.AddCertificateRequest) (*corepb.Empty, error)
|
||||
GetCertificate(ctx context.Context, serial string) (core.Certificate, error)
|
||||
|
@ -82,28 +75,17 @@ const (
|
|||
certOrphan
|
||||
// precertOrphan indicates an orphaned precertificate type
|
||||
precertOrphan
|
||||
// certOrphanAlreadyExists indicates an orphaned final certificate that
|
||||
// already exists in the DB.
|
||||
certOrphanAlreadyExists
|
||||
// precertOrphanAlreadyExists indicates an orphaned precertificate that
|
||||
// already exists in the DB.
|
||||
precertOrphanAlreadyExists
|
||||
)
|
||||
|
||||
// String returns a human representation of the orphanType.
|
||||
// This is used both for printing orphanTypes and (in the case of certOrphan and
|
||||
// precertOrphan) to figure out what to search for when parsing logs.
|
||||
// Invalid orphanTypes are stringified as "unknown."
|
||||
// String returns a human representation of the orphanType and the expected
|
||||
// label in the orphaning message for that type, or "unknown" if it isn't
|
||||
// a known orphan type.
|
||||
func (t orphanType) String() string {
|
||||
switch t {
|
||||
case certOrphan:
|
||||
return "certificate"
|
||||
case precertOrphan:
|
||||
return "precertificate"
|
||||
case certOrphanAlreadyExists:
|
||||
return "certificate (already exists in DB)"
|
||||
case precertOrphanAlreadyExists:
|
||||
return "precertificate (already exists in DB)"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
|
@ -115,6 +97,8 @@ var (
|
|||
errAlreadyExists = fmt.Errorf("Certificate already exists in DB")
|
||||
)
|
||||
|
||||
var backdateDuration time.Duration
|
||||
|
||||
// orphanTypeForCert returns precertOrphan if the certificate has the RFC 6962
|
||||
// CT poison extension, or certOrphan if it does not. If the certificate is nil
|
||||
// unknownOrphan is returned.
|
||||
|
@ -149,16 +133,13 @@ func checkDER(sai certificateStorage, der []byte) (*x509.Certificate, orphanType
|
|||
switch orphanTyp {
|
||||
case certOrphan:
|
||||
_, err = sai.GetCertificate(ctx, orphanSerial)
|
||||
if err == nil {
|
||||
return nil, certOrphanAlreadyExists, errAlreadyExists
|
||||
}
|
||||
case precertOrphan:
|
||||
_, err = sai.GetPrecertificate(ctx, &sapb.Serial{Serial: &orphanSerial})
|
||||
if err == nil {
|
||||
return nil, precertOrphanAlreadyExists, errAlreadyExists
|
||||
}
|
||||
default:
|
||||
return nil, unknownOrphan, errors.New("unknown orphan type")
|
||||
err = errors.New("unknown orphan type")
|
||||
}
|
||||
if err == nil {
|
||||
return nil, orphanTyp, errAlreadyExists
|
||||
}
|
||||
if berrors.Is(err, berrors.NotFound) {
|
||||
return orphan, orphanTyp, nil
|
||||
|
@ -172,7 +153,7 @@ func checkDER(sai certificateStorage, der []byte) (*x509.Certificate, orphanType
|
|||
// is true if the orphan was successfully added to the DB. As part of adding an
|
||||
// orphan to the DB, it requests a fresh OCSP response from the CA to store
|
||||
// alongside the precertificate/certificate.
|
||||
func (of *orphanFinder) storeParsedLogLine(line string) (found bool, added bool, typ orphanType) {
|
||||
func storeParsedLogLine(sa certificateStorage, ca ocspGenerator, logger blog.Logger, line string) (found bool, added bool, typ orphanType) {
|
||||
ctx := context.Background()
|
||||
|
||||
// The log line should contain a label indicating it is a cert or a precert
|
||||
|
@ -189,77 +170,78 @@ func (of *orphanFinder) storeParsedLogLine(line string) (found bool, added bool,
|
|||
// Extract and decode the orphan DER
|
||||
derStr := derOrphan.FindStringSubmatch(line)
|
||||
if len(derStr) <= 1 {
|
||||
of.logger.AuditErrf("Didn't match regex for cert: %s", line)
|
||||
logger.AuditErrf("Didn't match regex for cert: %s", line)
|
||||
return true, false, unknownOrphan
|
||||
}
|
||||
der, err := hex.DecodeString(derStr[1])
|
||||
if err != nil {
|
||||
of.logger.AuditErrf("Couldn't decode hex: %s, [%s]", err, line)
|
||||
logger.AuditErrf("Couldn't decode hex: %s, [%s]", err, line)
|
||||
return true, false, unknownOrphan
|
||||
}
|
||||
// Parse the DER, determine the orphan type, and ensure it doesn't already
|
||||
// exist in the DB
|
||||
cert, typ, err := checkDER(sa, der)
|
||||
if err != nil {
|
||||
logFunc := logger.Errf
|
||||
if err == errAlreadyExists {
|
||||
logFunc = logger.Infof
|
||||
}
|
||||
logFunc("%s, [%s]", err, line)
|
||||
return true, false, typ
|
||||
}
|
||||
// extract the regID
|
||||
regStr := regOrphan.FindStringSubmatch(line)
|
||||
if len(regStr) <= 1 {
|
||||
of.logger.AuditErrf("regID variable is empty, [%s]", line)
|
||||
logger.AuditErrf("regID variable is empty, [%s]", line)
|
||||
return true, false, typ
|
||||
}
|
||||
regID, err := strconv.ParseInt(regStr[1], 10, 64)
|
||||
if err != nil {
|
||||
of.logger.AuditErrf("Couldn't parse regID: %s, [%s]", err, line)
|
||||
logger.AuditErrf("Couldn't parse regID: %s, [%s]", err, line)
|
||||
return true, false, typ
|
||||
}
|
||||
|
||||
typ, err = of.storeDER(ctx, regID, der)
|
||||
response, err := generateOCSP(ctx, ca, der)
|
||||
if err != nil {
|
||||
of.logger.AuditErrf("Failed to store certificate: %s, [%s]", err, line)
|
||||
logger.AuditErrf("Couldn't generate OCSP: %s, [%s]", err, line)
|
||||
return true, false, typ
|
||||
}
|
||||
if typ == certOrphanAlreadyExists || typ == precertOrphanAlreadyExists {
|
||||
return true, false, typ
|
||||
} else {
|
||||
return true, true, typ
|
||||
// We use `cert.NotBefore` as the issued date to avoid the SA tagging this
|
||||
// certificate with an issued date of the current time when we know it was an
|
||||
// orphan issued in the past. Because certificates are backdated we need to
|
||||
// add the backdate duration to find the true issued time.
|
||||
issuedDate := cert.NotBefore.Add(backdateDuration)
|
||||
switch typ {
|
||||
case certOrphan:
|
||||
_, err = sa.AddCertificate(ctx, der, regID, response, &issuedDate)
|
||||
case precertOrphan:
|
||||
issued := issuedDate.UnixNano()
|
||||
_, err = sa.AddPrecertificate(ctx, &sapb.AddCertificateRequest{
|
||||
Der: der,
|
||||
RegID: ®ID,
|
||||
Ocsp: response,
|
||||
Issued: &issued,
|
||||
})
|
||||
default:
|
||||
// Shouldn't happen but be defensive anyway
|
||||
err = errors.New("unknown orphan type")
|
||||
}
|
||||
if err != nil {
|
||||
logger.AuditErrf("Failed to store certificate: %s, [%s]", err, line)
|
||||
return true, false, typ
|
||||
}
|
||||
return true, true, typ
|
||||
}
|
||||
|
||||
func (of *orphanFinder) findIssuerID(der []byte) (issuercerts.ID, error) {
|
||||
cert, err := x509.ParseCertificate(der)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for _, issuer := range of.issuers {
|
||||
if err := cert.CheckSignatureFrom(issuer.Cert); err == nil {
|
||||
return issuer.ID(), nil
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("no issuer found")
|
||||
}
|
||||
|
||||
func (of *orphanFinder) generateOCSP(ctx context.Context, certDER []byte) ([]byte, error) {
|
||||
func generateOCSP(ctx context.Context, ca ocspGenerator, certDER []byte) ([]byte, error) {
|
||||
// generate a fresh OCSP response
|
||||
statusGood := string(core.OCSPStatusGood)
|
||||
zeroInt32 := int32(0)
|
||||
zeroInt64 := int64(0)
|
||||
|
||||
cert, err := x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
issuerID, err := of.findIssuerID(certDER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
issuerIDInt := int64(issuerID)
|
||||
|
||||
serial := core.SerialToString(cert.SerialNumber)
|
||||
|
||||
ocspResponse, err := of.ocspCA.GenerateOCSP(ctx, &capb.GenerateOCSPRequest{
|
||||
ocspResponse, err := ca.GenerateOCSP(ctx, &capb.GenerateOCSPRequest{
|
||||
CertDER: certDER,
|
||||
Status: &statusGood,
|
||||
Reason: &zeroInt32,
|
||||
RevokedAt: &zeroInt64,
|
||||
IssuerID: &issuerIDInt,
|
||||
Serial: &serial,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -267,70 +249,30 @@ func (of *orphanFinder) generateOCSP(ctx context.Context, certDER []byte) ([]byt
|
|||
return ocspResponse.Response, nil
|
||||
}
|
||||
|
||||
type orphanFinder struct {
|
||||
logger blog.Logger
|
||||
sa certificateStorage
|
||||
ocspCA capb.OCSPGeneratorClient
|
||||
issuers []*issuercerts.Issuer
|
||||
backdateDuration time.Duration
|
||||
}
|
||||
|
||||
func setup(configFile string) (*orphanFinder, error) {
|
||||
func setup(configFile string) (blog.Logger, core.StorageAuthority, capb.OCSPGeneratorClient) {
|
||||
configJSON, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading config: %s", err)
|
||||
}
|
||||
|
||||
cmd.FailOnError(err, "Failed to read config file")
|
||||
var conf config
|
||||
err = json.Unmarshal(configJSON, &conf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing config: %s", err)
|
||||
}
|
||||
|
||||
cmd.FailOnError(err, "Failed to parse config file")
|
||||
err = features.Set(conf.Features)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setting feature flags: %s", err)
|
||||
}
|
||||
|
||||
cmd.FailOnError(err, "Failed to set feature flags")
|
||||
logger := cmd.NewLogger(conf.Syslog)
|
||||
|
||||
tlsConfig, err := conf.TLS.Load()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading TLS config: %s", err)
|
||||
}
|
||||
cmd.FailOnError(err, "TLS config")
|
||||
|
||||
clientMetrics := bgrpc.NewClientMetrics(metrics.NoopRegisterer)
|
||||
saConn, err := bgrpc.ClientSetup(conf.SAService, tlsConfig, clientMetrics, cmd.Clock())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setting up SA connection: %s", err)
|
||||
}
|
||||
|
||||
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
|
||||
sac := bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(saConn))
|
||||
caConn, err := bgrpc.ClientSetup(conf.OCSPGeneratorService, tlsConfig, clientMetrics, cmd.Clock())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("setting up OCSP CA connection: %s", err)
|
||||
}
|
||||
|
||||
caConn, err := bgrpc.ClientSetup(conf.OCSPGeneratorService, tlsConfig, clientMetrics, cmd.Clock())
|
||||
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to CA")
|
||||
cac := capb.NewOCSPGeneratorClient(caConn)
|
||||
|
||||
issuers, err := loadIssuers(conf.IssuerFiles)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &orphanFinder{logger, sac, cac, issuers, conf.Backdate.Duration}, nil
|
||||
}
|
||||
|
||||
func loadIssuers(filenames []string) ([]*issuercerts.Issuer, error) {
|
||||
var issuers []*issuercerts.Issuer
|
||||
for _, filename := range filenames {
|
||||
issuer, err := issuercerts.FromFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading %s: %s", filename, err)
|
||||
}
|
||||
issuers = append(issuers, issuer)
|
||||
}
|
||||
return issuers, nil
|
||||
backdateDuration = conf.Backdate.Duration
|
||||
return logger, sac, cac
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -360,13 +302,11 @@ func main() {
|
|||
|
||||
switch command {
|
||||
case "parse-ca-log":
|
||||
logger, sa, ca := setup(*configFile)
|
||||
if *logPath == "" {
|
||||
usage()
|
||||
}
|
||||
|
||||
orphanFinder, err := setup(*configFile)
|
||||
cmd.FailOnError(err, "setup")
|
||||
|
||||
logData, err := ioutil.ReadFile(*logPath)
|
||||
cmd.FailOnError(err, "Failed to read log file")
|
||||
|
||||
|
@ -375,7 +315,7 @@ func main() {
|
|||
if line == "" {
|
||||
continue
|
||||
}
|
||||
found, added, typ := orphanFinder.storeParsedLogLine(line)
|
||||
found, added, typ := storeParsedLogLine(sa, ca, logger, line)
|
||||
var foundStat, addStat *int64
|
||||
switch typ {
|
||||
case certOrphan:
|
||||
|
@ -385,7 +325,7 @@ func main() {
|
|||
foundStat = &precertOrphansFound
|
||||
addStat = &precertOrphansAdded
|
||||
default:
|
||||
orphanFinder.logger.Errf("Found orphan type %s", typ)
|
||||
logger.Errf("Found orphan type %s", typ)
|
||||
continue
|
||||
}
|
||||
if found {
|
||||
|
@ -395,85 +335,42 @@ func main() {
|
|||
}
|
||||
}
|
||||
}
|
||||
orphanFinder.logger.Infof("Found %d certificate orphans and added %d to the database", certOrphansFound, certOrphansAdded)
|
||||
orphanFinder.logger.Infof("Found %d precertificate orphans and added %d to the database", precertOrphansFound, precertOrphansAdded)
|
||||
logger.Infof("Found %d certificate orphans and added %d to the database", certOrphansFound, certOrphansAdded)
|
||||
logger.Infof("Found %d precertificate orphans and added %d to the database", precertOrphansFound, precertOrphansAdded)
|
||||
|
||||
case "parse-der":
|
||||
ctx := context.Background()
|
||||
_, sa, ca := setup(*configFile)
|
||||
if *derPath == "" || *regID == 0 {
|
||||
usage()
|
||||
}
|
||||
|
||||
orphanFinder, err := setup(*configFile)
|
||||
cmd.FailOnError(err, "setup")
|
||||
|
||||
der, err := ioutil.ReadFile(*derPath)
|
||||
cmd.FailOnError(err, "Failed to read DER file")
|
||||
_, err = orphanFinder.storeDER(context.Background(), *regID, der)
|
||||
cmd.FailOnError(err, "storing DER")
|
||||
cert, typ, err := checkDER(sa, der)
|
||||
cmd.FailOnError(err, "Pre-AddCertificate checks failed")
|
||||
// Because certificates are backdated we need to add the backdate duration
|
||||
// to find the true issued time.
|
||||
issuedDate := cert.NotBefore.Add(1 * backdateDuration)
|
||||
response, err := generateOCSP(ctx, ca, der)
|
||||
cmd.FailOnError(err, "Generating OCSP")
|
||||
|
||||
switch typ {
|
||||
case certOrphan:
|
||||
_, err = sa.AddCertificate(ctx, der, *regID, response, &issuedDate)
|
||||
case precertOrphan:
|
||||
issued := issuedDate.UnixNano()
|
||||
_, err = sa.AddPrecertificate(ctx, &sapb.AddCertificateRequest{
|
||||
Der: der,
|
||||
RegID: regID,
|
||||
Ocsp: response,
|
||||
Issued: &issued,
|
||||
})
|
||||
default:
|
||||
err = errors.New("unknown orphan type")
|
||||
}
|
||||
cmd.FailOnError(err, "Failed to add certificate to database")
|
||||
|
||||
default:
|
||||
usage()
|
||||
}
|
||||
}
|
||||
|
||||
func (of *orphanFinder) storeDER(ctx context.Context, regID int64, der []byte) (orphanType, error) {
|
||||
cert, typ, err := checkDER(of.sa, der)
|
||||
if err != nil {
|
||||
if err == errAlreadyExists {
|
||||
of.logger.Infof("%s", err)
|
||||
return typ, nil
|
||||
} else {
|
||||
return unknownOrphan, err
|
||||
}
|
||||
}
|
||||
// Because certificates are backdated we need to add the backdate duration
|
||||
// to find the true issued time.
|
||||
issuedDate := cert.NotBefore.Add(of.backdateDuration)
|
||||
issuedDateNanos := issuedDate.UnixNano()
|
||||
notAfter := cert.NotAfter.UnixNano()
|
||||
serial := core.SerialToString(cert.SerialNumber)
|
||||
|
||||
// The CA's GenerateOCSP method will return error if the serial is not in the
|
||||
// serials table, so add it in case it doesn't exist (for instance this
|
||||
// happens during integration testing). However, if the serial already exists
|
||||
// ignore the error.
|
||||
_, err = of.sa.AddSerial(ctx, &sapb.AddSerialRequest{
|
||||
RegID: ®ID,
|
||||
Serial: &serial,
|
||||
Created: &issuedDateNanos,
|
||||
Expires: ¬After,
|
||||
})
|
||||
if err != nil && !db.IsDuplicate(err) {
|
||||
return unknownOrphan, err
|
||||
}
|
||||
|
||||
response, err := of.generateOCSP(ctx, der)
|
||||
if err != nil {
|
||||
return unknownOrphan, fmt.Errorf("generating OCSP: %s", err)
|
||||
}
|
||||
|
||||
switch typ {
|
||||
case certOrphan:
|
||||
_, err = of.sa.AddCertificate(ctx, der, regID, response, &issuedDate)
|
||||
if err != nil {
|
||||
return unknownOrphan, fmt.Errorf("adding certificate: %s", err)
|
||||
}
|
||||
case precertOrphan:
|
||||
issuerID, err := of.findIssuerID(der)
|
||||
cmd.FailOnError(err, "finding issuerID")
|
||||
issuerIDInt := int64(issuerID)
|
||||
_, err = of.sa.AddPrecertificate(ctx, &sapb.AddCertificateRequest{
|
||||
Der: der,
|
||||
RegID: ®ID,
|
||||
Ocsp: response,
|
||||
Issued: &issuedDateNanos,
|
||||
IssuerID: &issuerIDInt,
|
||||
})
|
||||
if err != nil {
|
||||
return unknownOrphan, fmt.Errorf("adding precertificate: %s", err)
|
||||
}
|
||||
default:
|
||||
return unknownOrphan, errors.New("unknown orphan type")
|
||||
}
|
||||
return typ, nil
|
||||
}
|
||||
|
|
|
@ -29,10 +29,6 @@ type mockSA struct {
|
|||
clk clock.FakeClock
|
||||
}
|
||||
|
||||
func (m *mockSA) AddSerial(ctx context.Context, req *sapb.AddSerialRequest) (*corepb.Empty, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockSA) AddCertificate(ctx context.Context, der []byte, regID int64, _ []byte, issued *time.Time) (string, error) {
|
||||
parsed, err := x509.ParseCertificate(der)
|
||||
if err != nil {
|
||||
|
@ -113,29 +109,18 @@ func checkNoErrors(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func mustLoadCert(filename string) *x509.Certificate {
|
||||
cert, err := core.LoadCert(filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cert
|
||||
}
|
||||
|
||||
func TestParseLine(t *testing.T) {
|
||||
fc := clock.NewFake()
|
||||
fc.Set(time.Date(2015, 3, 4, 5, 0, 0, 0, time.UTC))
|
||||
sa := &mockSA{}
|
||||
ca := &mockCA{}
|
||||
issuers, err := loadIssuers([]string{"testdata/minica1.pem", "testdata/minica2.pem"})
|
||||
test.AssertNotError(t, err, "loading issuers")
|
||||
|
||||
backdateDuration := time.Hour
|
||||
of := orphanFinder{log, sa, ca, issuers, backdateDuration}
|
||||
// Set an example backdate duration (this is normally read from config)
|
||||
backdateDuration = time.Hour
|
||||
|
||||
testCert := mustLoadCert("testdata/example.com/cert.pem")
|
||||
testCertDERHex := hex.EncodeToString(testCert.Raw)
|
||||
testPreCert := mustLoadCert("testdata/example.com/precert.pem")
|
||||
testPreCertDERHex := hex.EncodeToString(testPreCert.Raw)
|
||||
testCertDER := "3082045b30820343a003020102021300ffa0160630d618b2eb5c0510824b14274856300d06092a864886f70d01010b0500301f311d301b06035504030c146861707079206861636b65722066616b65204341301e170d3135313030333035323130305a170d3136303130313035323130305a3018311630140603550403130d6578616d706c652e636f2e626e30820122300d06092a864886f70d01010105000382010f003082010a02820101009ea3f1d21fade5596e36a6a77095a94758e4b72466b7444ada4f7c4cf6fde9b1d470b93b65c1fdd896917f248ccae49b57c80dc21c64b010699432130d059d2d8392346e8a179c7c947835549c64a7a5680c518faf0a5cbea48e684fca6304775c8fa9239c34f1d5cb2d063b098bd1c17183c7521efc884641b2f0b41402ac87c7076848d4347cef59dd5a9c174ad25467db933c95ef48c578ba762f527b21666a198fb5e1fe2d8299b4dceb1791e96ad075e3ecb057c776d764fad8f0829d43c32ddf985a3a36fade6966cec89468721a1ec47ab38eac8da4514060ded51d283a787b7c69971bda01f49f76baa41b1f9b4348aa4279e0fa55645d6616441f0d0203010001a382019530820191300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff04023000301d0603551d0e04160414369d0c100452b9eb3ffe7ae852e9e839a3ae5adb301f0603551d23041830168014fb784f12f96015832c9f177f3419b32e36ea4189306a06082b06010505070101045e305c302606082b06010505073001861a687474703a2f2f6c6f63616c686f73743a343030322f6f637370303206082b060105050730028626687474703a2f2f6c6f63616c686f73743a343030302f61636d652f6973737565722d6365727430180603551d110411300f820d6578616d706c652e636f2e626e30270603551d1f0420301e301ca01aa0188616687474703a2f2f6578616d706c652e636f6d2f63726c30630603551d20045c305a300a060667810c0102013000304c06032a03043045302206082b060105050702011616687474703a2f2f6578616d706c652e636f6d2f637073301f06082b0601050507020230130c11446f20576861742054686f752057696c74300d06092a864886f70d01010b05000382010100bbb4b994971cafa2e56e2258db46d88bfb361d8bfcd75521c03174e471eaa9f3ff2e719059bb57cc064079496d8550577c127baa84a18e792ddd36bf4f7b874b6d40d1d14288c15d38e4d6be25eb7805b1c3756b3735702eb4585d1886bc8af2c14086d3ce506e55184913c83aaaa8dfe6160bd035e42cda6d97697ed3ee3124c9bf9620a9fe6602191c1b746533c1d4a30023bbe902cb4aa661901177ed924eb836c94cc062dd0ce439c4ece9ee1dfe0499a42cbbcb2ea7243c59f4df4fdd7058229bacf9a640632dbd776b21633137b2df1c41f0765a66f448777aeec7ed4c0cdeb9d8a2356ff813820a287e11d52efde1aa543b4ef2ee992a7a9d5ccf7da4"
|
||||
|
||||
testPreCertDER := "308204553082033da003020102021203e1dea6f3349009a90e0306dbb39c3e7ca2300d06092a864886f70d01010b0500304a310b300906035504061302555331163014060355040a130d4c6574277320456e6372797074312330210603550403131a4c6574277320456e637279707420417574686f72697479205833301e170d3139313031363132353431375a170d3230303131343132353431375a30133111300f060355040313086a756e74732e696f30820122300d06092a864886f70d01010105000382010f003082010a0282010100c91926403839aadbf2a73af4f85e3884df553880c7e9d11943121b941f284a2c805b6329a93d7fb2357c1298d811cfce61faa863c334149f948ff52a55a516e56b2d31d137b1d0319f2aabdea0e9d5e8630b54d7e53597e094c323e24a7ec1ab0db5d85651a641ec3fd7841fe5cbc675315c49b714238ead757e55409fd68c4b48d42f14c2124d381800fd2ec417ed7f363b00ab23aaddaf9113d5cf889bbf391431bffb91d425d11a1e79318b7007b8e75cc56633662c3d6c58175b5cab6225aa495361b1124642f19584820d215f23f46bd9fafa3341a0f7f387bf7cdecbccd7fcbcb3e917becb41562771e579884a0d8a1b170536f82ba90b398e9a6932150203010001a382016a30820166300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff04023000301d0603551d0e041604144d14d73117ca7f5a27394ed590b0d037eb5888a2301f0603551d23041830168014a84a6a63047dddbae6d139b7a64565eff3a8eca1306f06082b0601050507010104633061302e06082b060105050730018622687474703a2f2f6f6373702e696e742d78332e6c657473656e63727970742e6f7267302f06082b060105050730028623687474703a2f2f636572742e696e742d78332e6c657473656e63727970742e6f72672f30130603551d11040c300a82086a756e74732e696f304c0603551d20044530433008060667810c0102013037060b2b0601040182df130101013028302606082b06010505070201161a687474703a2f2f6370732e6c657473656e63727970742e6f72673013060a2b06010401d6790204030101ff04020500300d06092a864886f70d01010b0500038201010035f9d6620874966f2aa400f069c5f601dc11083f5859a15d20e9b1d2f9d87d3756a71a03cee0ab2a69b5173a4395b698163ba60394167c9eb4b66d20d9b3a76bf94995288e8d15c70bee969f77a71147718803e73df0a7832c1fcae1e3138601ebc61725bc7505c6d1e5b0eaf7797e09161d71e37d76370dc489312b1bf0600d1c952f846edb810c284c0d831f27481a8f2220ad178c87d8c4688023fa3798293dc9fdffa9e5b885a8107d8a2480226cd5f9121d6d7ea83b10292371ad6757e7729b27136a064f2901822b4f0ea52f8149a17860e37d3dc925488b1ba4aa26ef51e60de024e67e3d5e04ac97d8bd79a003e668ea2e1bd1c0b9d77c7cf7bfdc32"
|
||||
|
||||
logLine := func(typ orphanType, der, regID, orderID string) string {
|
||||
return fmt.Sprintf(
|
||||
|
@ -177,16 +162,16 @@ func TestParseLine(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Name: "Valid cert in line",
|
||||
LogLine: logLine(certOrphan, testCertDERHex, "1001", "0"),
|
||||
LogLine: logLine(certOrphan, testCertDER, "1001", "0"),
|
||||
ExpectFound: true,
|
||||
ExpectAdded: true,
|
||||
ExpectAddedDER: testCertDERHex,
|
||||
ExpectAddedDER: testCertDER,
|
||||
ExpectRegID: 1001,
|
||||
ExpectNoErrors: true,
|
||||
},
|
||||
{
|
||||
Name: "Already inserted cert in line",
|
||||
LogLine: logLine(certOrphan, testCertDERHex, "1001", "0"),
|
||||
LogLine: logLine(certOrphan, testCertDER, "1001", "0"),
|
||||
ExpectFound: true,
|
||||
// ExpectAdded is false because we have already added this cert in the
|
||||
// previous "Valid cert in line" test case.
|
||||
|
@ -209,16 +194,16 @@ func TestParseLine(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Name: "Valid precert in line",
|
||||
LogLine: logLine(precertOrphan, testPreCertDERHex, "9999", "0"),
|
||||
LogLine: logLine(precertOrphan, testPreCertDER, "9999", "0"),
|
||||
ExpectFound: true,
|
||||
ExpectAdded: true,
|
||||
ExpectAddedDER: testPreCertDERHex,
|
||||
ExpectAddedDER: testPreCertDER,
|
||||
ExpectRegID: 9999,
|
||||
ExpectNoErrors: true,
|
||||
},
|
||||
{
|
||||
Name: "Already inserted precert in line",
|
||||
LogLine: logLine(precertOrphan, testPreCertDERHex, "1001", "0"),
|
||||
LogLine: logLine(precertOrphan, testPreCertDER, "1001", "0"),
|
||||
ExpectFound: true,
|
||||
// ExpectAdded is false because we have already added this cert in the
|
||||
// previous "Valid cert in line" test case.
|
||||
|
@ -227,7 +212,7 @@ func TestParseLine(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Name: "Unknown orphan type",
|
||||
LogLine: logLine(unknownOrphan, testPreCertDERHex, "1001", "0"),
|
||||
LogLine: logLine(unknownOrphan, testPreCertDER, "1001", "0"),
|
||||
ExpectFound: false,
|
||||
ExpectAdded: false,
|
||||
ExpectNoErrors: false,
|
||||
|
@ -237,8 +222,7 @@ func TestParseLine(t *testing.T) {
|
|||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
log.Clear()
|
||||
found, added, typ := of.storeParsedLogLine(tc.LogLine)
|
||||
t.Logf("%s", log.GetAllMatching(".*"))
|
||||
found, added, typ := storeParsedLogLine(sa, ca, log, tc.LogLine)
|
||||
test.AssertEquals(t, found, tc.ExpectFound)
|
||||
test.AssertEquals(t, added, tc.ExpectAdded)
|
||||
logs := log.GetAllMatching("ERR:")
|
||||
|
@ -286,12 +270,9 @@ func TestNotOrphan(t *testing.T) {
|
|||
fc.Set(time.Date(2015, 3, 4, 5, 0, 0, 0, time.UTC))
|
||||
sa := &mockSA{}
|
||||
ca := &mockCA{}
|
||||
issuers, err := loadIssuers([]string{"../../test/test-ca.pem", "../../test/test-ca2.pem"})
|
||||
test.AssertNotError(t, err, "loading issuers")
|
||||
of := orphanFinder{log, sa, ca, issuers, time.Hour}
|
||||
|
||||
log.Clear()
|
||||
found, added, typ := of.storeParsedLogLine("cert=fakeout")
|
||||
found, added, typ := storeParsedLogLine(sa, ca, log, "cert=fakeout")
|
||||
test.AssertEquals(t, found, false)
|
||||
test.AssertEquals(t, added, false)
|
||||
test.AssertEquals(t, typ, unknownOrphan)
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDMDCCAhigAwIBAgIIR8kD33NctSkwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgNTU5MzdmMB4XDTIwMDYwNDIyMjY1NFoXDTIyMDcw
|
||||
NDIyMjY1NFowFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDOxrD2fSEKlqiLEst5Ysg0qjrldebpcR7bFqS0fO2q
|
||||
gwtJ6lo+kCwacnjoUKar2cWqC+FlqkGnW/Htdb7H0kFnMdXM26iMNMcLuN3SmWDw
|
||||
JzqMmZ9OAB7zYxy0ePu5EOFMPSvx3tK/7LP3YAj32Xbmf/fCRuAqCwbEqxptzoCP
|
||||
rUqAN/1jfcf0MKqojrBRN0iRgTw5DpjW3RhNew7ngzvcgqroqyEXUE5/BCwRGPqr
|
||||
xluhW7OxVX4OGEboW4KOvDbrVpmnUe8VcKlNV9L5HwkL29xc/AJOrFsiElNGVAvW
|
||||
kY60+wH5xf+dWSA1RBdAm4JWShg81R0gdes3KRreqW6RAgMBAAGjeDB2MA4GA1Ud
|
||||
DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T
|
||||
AQH/BAIwADAfBgNVHSMEGDAWgBS5uijpDluYTxcU27MKGYqPixX8MDAWBgNVHREE
|
||||
DzANggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAqZWk3H9yqwrKZQ/F
|
||||
dbtIqrbp7dLEolhcBmyVLIjAFJc/CvaciRgzBMsDBfG3o2sspu/WIngUbHPGHXK+
|
||||
yWmVHBOtB63U6hlXk7GFeMsoyomT/dNM6bET+1E8xpXHR0VnlF/YDytUzcglrNcu
|
||||
VpGC56i5ZpyKl5+XQ+Q0pnpt3npymvkJcWXCUisSSGmOsCf5CA9O/A83nPAMlC1I
|
||||
bM7hzOXdxrMYZFSbo1PQKPWuzsgToVNN5Vk22uphxaH9rWoKW2I3BAaVGKqvyoma
|
||||
bI4oIj4aevoUiYOKVV+t1rKqvdgCcx9QMPWf85Od0n0Sg/8oTwydNtg7XQ0Sj90d
|
||||
SWWW/Q==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA41Af7nGW3cnU+ckGRCp/k9Ks0S8im7zLftuxnYLHXlgf1+Kr
|
||||
PYxR+T5asULgUW7YDADVd5omUKjo3Lg6srTgBtpsynTrhBZOqANy/caM1CpE+Ao+
|
||||
g6GYzIyzBozPi0+1mQ4q/5fxlAT+XROxsORwBr5Se6qaTyy6Da7NIjNndLQ6JeyL
|
||||
uLRMCq9TjjYXmU/BiqbbWhnGuvztau938MVDKmYva2h2icmyQ5Y9rcgKbSrM29az
|
||||
3lFM19xzdkgUVvEqJ3U6SDu8eH9dyfBFSwQZov+hAypzFeSahypugREmD6Iot23i
|
||||
34+BnhMx6Y1ABBY951br6J36c/5yj4npwxngqwIDAQABAoIBAG6/iO8pVHG2dhdE
|
||||
w9LOSd4BlMVOC7SI5TRnYT/2iaADm3AZNYkFJqMiqBkZFiVWtdgTR+2/os9FnD59
|
||||
W8vZqBRusvZoxJ5UJ/pfw9S0ucRc28FlbFPBlaqDGm4kiLG9IiLx7i0dIEwXqr46
|
||||
bCZdBd+jNpid5BSTHAqykasKFGucwBDOMXrUO92arPYwTdbGL3NorYzkcVLfkGgU
|
||||
r4FiH4/3UwY/hLYy3/632305E+EFcbGfaRf/wB1lA3xMZ781K5GWqdjaicJeer5S
|
||||
gamMyTFpxgLlvT8DQMSvOmiLSdTh2FF3+LwwZ8jJHQlldDkFhKkr7y7z2H56x/wJ
|
||||
Sj6Bx1ECgYEA5AaT8f0P8KftytxhmRIuupyWyKI5tCZK+nqWnHcLVESLzjq73CWE
|
||||
rlVKuLcFgw6WoQioxr7LeI/LVJd046pFXhsfnoTSFQiioAcZ6xtUlUioWONpeKv3
|
||||
w7Dkua8KC6yKWdUnk4VfRhVJtKCJY9Z+a6QkbWeiUEPfiivsI2ckCXcCgYEA/zMp
|
||||
0uwBkDTkLmTqafpv4sIPvqZZWBkvktPT9kDmpb7Ano9PFC4rqY92+Qh9eRC74mRJ
|
||||
ua/1wM5Fe+1vDPvH4mEDh4frY5G59+G+MAN5Kw1M+c2n/o+STpJImZQigQa3rywI
|
||||
nxPRPbCDyU2tZujmnsjL9okKW3w2hhJO6X5jL20CgYEAqaKnH2hnGl6jjb4jsU+Q
|
||||
ie2CUyI0kWvHbc4TC7WYLQmNhE+3gBA9Q8BaBU7K//OzZXteq/Q2xKsc1gKSx+fd
|
||||
ESRWgoRHEbTJ3wlJY9mCNEjITNBpn4c3nFKV5fltHMAwcKIdfibDeQzPN1wSub5R
|
||||
cFy9aNKnMtU7kLwaQUAy1AMCgYEAzukcr/bKDbHUkAkiRmrW7HOLcHhPWC6Tc+hr
|
||||
ou1cFGZkpiprY2FL5V58h81qbg4zR4soe3U/O+QCUkhgEZbSqakew3RgVYqBzYkq
|
||||
OqOWSmGuV5t26d5eMXZJhrukfhiENXLuSow2yl2jfEOOpDGRSoxjUrApxaMgUfPm
|
||||
J0piAMECgYBs9LWkADgigbjLmiHkyViAVXnjKC+C4U+G+lTlldIxaRKlmUl6iAeF
|
||||
9mtQVtUm1fHPYE9NBiXb/GMddafOpoHIj1zfJbdWRLRQEevhk7PYfefO6mOK7b2g
|
||||
oLNTG4WVgQKPQX+Q111wLvKWpIsOA03gOWEyZTLP45UroAGfh/N88Q==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,20 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDRzCCAi+gAwIBAgIIfWdzK08iuGwwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgNTU5MzdmMB4XDTIwMDYwNDIyMzI1N1oXDTIyMDcw
|
||||
NDIyMzI1N1owFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDjUB/ucZbdydT5yQZEKn+T0qzRLyKbvMt+27Gdgsde
|
||||
WB/X4qs9jFH5PlqxQuBRbtgMANV3miZQqOjcuDqytOAG2mzKdOuEFk6oA3L9xozU
|
||||
KkT4Cj6DoZjMjLMGjM+LT7WZDir/l/GUBP5dE7Gw5HAGvlJ7qppPLLoNrs0iM2d0
|
||||
tDol7Iu4tEwKr1OONheZT8GKpttaGca6/O1q73fwxUMqZi9raHaJybJDlj2tyApt
|
||||
Kszb1rPeUUzX3HN2SBRW8SondTpIO7x4f13J8EVLBBmi/6EDKnMV5JqHKm6BESYP
|
||||
oii3beLfj4GeEzHpjUAEFj3nVuvonfpz/nKPienDGeCrAgMBAAGjgY4wgYswDgYD
|
||||
VR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNV
|
||||
HRMBAf8EAjAAMB8GA1UdIwQYMBaAFLm6KOkOW5hPFxTbswoZio+LFfwwMBYGA1Ud
|
||||
EQQPMA2CC2V4YW1wbGUuY29tMBMGCisGAQQB1nkCBAMBAf8EAgUAMA0GCSqGSIb3
|
||||
DQEBCwUAA4IBAQBULgckk9GWazkbu2eholA8ORoPx4d8kPHmoskIG7sz8sFxo87j
|
||||
pIO0nbNN9iZABQ6v3JYMqc40Z+b2Sc4DJqkFQcoYOnZ8YVGQhNP/tjmKBcOM/eQb
|
||||
/FFL1xqILFt/WofVXfnpgiyqVbQPwYeRsqBpwqnL/EMx7rtET+dmKDsqJSwUhtEw
|
||||
vXvnkusxGnlvz8Eqj6WX2xWZfk1oBG+bUQJLBVirY4OX7eXMpKX66FXDBCMgPrdn
|
||||
pf1yuULU69AbqDJBJ5N9q6w6H9KTJDzvM+EclxObuT84wcEoWpF0055EVnBKHKoG
|
||||
7VAIWpdVUzibqgQEVX5FiqWMNEdzhfKVSHex
|
||||
-----END CERTIFICATE-----
|
|
@ -1,20 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDODCCAiCgAwIBAgIII8rbZbTIezIwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgMjljMWM5MB4XDTIwMDYwNDIyMzMzOFoXDTIyMDcw
|
||||
NDIyMzMzOFowGjEYMBYGA1UEAxMPbGV0c2VuY3J5cHQub3JnMIIBIjANBgkqhkiG
|
||||
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA684jaKhaEskHRr2pQ5ST7bFjBVx8jStcNZ2Y
|
||||
NuF7qjLYfVFHhZqrshiyphm0V8k/clQFiVUpE+bY37Q/dzH4vPZw02OKIR2KR4kQ
|
||||
Bi7wXY/HxiQ405PBbOmQhGbmsYnSatkPsgAWTXcE0cJGkSTkO1PX1Z/rFfEZvFac
|
||||
JlBO6guwCjJZakAHKiUV9pfJ3CU/OeNW7ep3DLPtSP2dxBRXyMoMSObjv4dG3yD8
|
||||
HDHiAPbRhvabV2PXSIi9WcGGacNwvCMgMMwjarkFTQGBQmXhIV/Eq2zT/r3IK69R
|
||||
swc7BtUjHXtFoyhWRCRaX2u5Lhs2o9dc2OvPmAqeCvF0hNHfXwIDAQABo3wwejAO
|
||||
BgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwG
|
||||
A1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU43XymR5OQ/ghn7nvl2oiI/eOosMwGgYD
|
||||
VR0RBBMwEYIPbGV0c2VuY3J5cHQub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQBQUW/d
|
||||
9hy4ZwKVbtyjm3/gbc8WwV/OqW9mG0Zg7nNUf0s107zathX4JEoodlDHKqTjV8+v
|
||||
VJMJB4n3AwyVaUC3FmSnBieEEfDKhurk2dzY3qBGPdxZBfW1HAxvUEgn/0S8p4tr
|
||||
WjR1nLLxObKxG58i9UhlSeOsKTefJl6oIC1ChgDq8hInUSrRPwROE5PMpmwAnAHM
|
||||
yeaz6Tv4cBRMgB1TDUXKpgDKl1GZaegAqsptzMZSJkBwzv9ZmAcpDpeNqreA4D9+
|
||||
vfGum/oZwLPRSOfitow5+jXc92jmZu2SHP45MdXZSX6RzfEe+Lb5BCYLJaDVJLrb
|
||||
vCzz79LbGdPpawer
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA684jaKhaEskHRr2pQ5ST7bFjBVx8jStcNZ2YNuF7qjLYfVFH
|
||||
hZqrshiyphm0V8k/clQFiVUpE+bY37Q/dzH4vPZw02OKIR2KR4kQBi7wXY/HxiQ4
|
||||
05PBbOmQhGbmsYnSatkPsgAWTXcE0cJGkSTkO1PX1Z/rFfEZvFacJlBO6guwCjJZ
|
||||
akAHKiUV9pfJ3CU/OeNW7ep3DLPtSP2dxBRXyMoMSObjv4dG3yD8HDHiAPbRhvab
|
||||
V2PXSIi9WcGGacNwvCMgMMwjarkFTQGBQmXhIV/Eq2zT/r3IK69Rswc7BtUjHXtF
|
||||
oyhWRCRaX2u5Lhs2o9dc2OvPmAqeCvF0hNHfXwIDAQABAoIBAFC+aF+I7jbqgURW
|
||||
42PRt4m3qQmH7tpEE7IEQb/hHABeosTelRgJq2szi9DWkmtQ7RnP7YlmEMfQz0hi
|
||||
pyzAfsTtuhqYRg8q11PBeiwz3HidKDIP6yl/ucb6f1LnDW2TnOqbYwV3hCuIaq0M
|
||||
0i8XK9Oo1QpAVTZRNZfJLHTuIOeA6r0COQfGzbW69D8NbWoy7PvFEaTQKlnXSbUJ
|
||||
NqjHO640KGRIWZXsd0S3UkX/DC/ZtqEi2RCgsMpXidogvfWE8Yzrms/0F/H7q1wG
|
||||
fVu7kPbRowiAzZSQQsu/MmC0wvdQJSb5Tw4JOCXGsDXYQdigR2D7B001SP7LIyw/
|
||||
yBzkhekCgYEA8J4uEgZeRmTfovTlks8ulMhFXB1oB2jEmxqyccwbgbwOhM+hPWQe
|
||||
qfKTsH43ZtM00CwFz4HzT8dWCRUfORHcf6+iHsT76N/M8VIS/x4c0su93Po8xY+4
|
||||
tJGvLag8U+oosTNl3uSuhNxl6TVx582PHp3/Vn1LLOj/dPbfo2pn2yMCgYEA+uEy
|
||||
bCsnPjzZvPOCOp01vKGTDtBCvr3BK7AF1tsfiYWfJsbwRrNQ02TIQwju7E9ayHSU
|
||||
ZEIFUKf4E+zm7gd0yLZ6DMbe44M0HRweTV4CV9pJHuRxwJhFmCiqS+bYaclIOR04
|
||||
EalbahX5t3DP8ZruLVdBgi+KnccOJlA2IoAynJUCgYAZVF1/MkJsYKQWMHeWW88I
|
||||
hIigqMvRs9q2hTnxts3Se2x/2KedodOEim+3raHBZkxx+aBm9sQZSt+otxuBU3sF
|
||||
ygRj/tKR8jVN1hj/2DiqjB4hjAontfh4sbliMgqfvs+nz8RSkXo5rEXiJekmwMHn
|
||||
NDSz8x6dzK1Pr8ldF491RwKBgH06NZoKvE7zvtfzUNkDKhSbLjWhvP9K5oZxGakS
|
||||
vZ4+pZ+Mg9k2nqy2TMQxTFmGjtEqZ/vXfKGzBkCj6u17qU6azzdbeVxlXHj/VRzX
|
||||
RSInIoKaEzHIkEyQV9kFRJchUry3mgou2COPDpQDari11hepy1g5dN6mwqhbN3pn
|
||||
NVw1AoGBAOTiKFh94yEjHuqNSSyNFD1CFJqlG09+fQmNFXBe4mPmfVneWJ0+ZpwW
|
||||
x3bOCVkPJo0/vnfEdo7GJnhSLHaEMj2SoPlqYJPV/J0LfWSLWflroQKlAIOLW80y
|
||||
gjVKoceqaddS7OsxNx0aeVyvaSo1d+ygmucZD7htNsG86S+JoOtO
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEA5m04f98iiXYlnX6JeYouJGcIgeuBamHFwfPUNymGFLCSh05S
|
||||
Gww2YjhlMhahsSJiHGqIbowYrivKOoSJrYzMksxX6pjolg3MI35m86wYAg+pqEHh
|
||||
ofeDcT+fPoTw5svsyO86fDWw2a4DLHX7znUS66pSJnaPHvXEErz6Npqt/9yjKbAw
|
||||
hZxL15TSApJkj8PusDxZ9/C5X6Csy2HGn2rKd9tRUEQAYE1wBKU6aHQ4AhKtzQAQ
|
||||
+FNu+Hd9IOvAKIo/DatL16k9k4gspbKcJp5nPwDr9JaSczfkU96uOkdL72+LxcaX
|
||||
9q4sIusOXcvABBacpsnkmaam5fHORAcUEHGMSwIDAQABAoIBACnixrdvzy5fnJzR
|
||||
aJoARTz2wbQkJCU7WqBT+0p/sNDH/Aq+cOxbvvMBv1tog8HYNy9lKiG2M7JNYXhb
|
||||
qU8z3ef9XynU28qS/X2iN4Kp0L9nK3bbavFvNaR7ZS4PKl85yHQKEH6Nn/UhzY/i
|
||||
boBsBaFzF3XIbWG6WQby9STB30k38N/QnDbsb2OJK03sJB9Buhz169gZ61oK/zs1
|
||||
bd3hUDX3ZeI/XLZCKTbejj7+xe67u+HKvrRxjfJdPRBmb1ZPCb7YDLEegKvyPgun
|
||||
SPhip0iAHLHpXZGem4dimfUrppyy2/Xi05aaZwbyyLIWumGPsEZa8FyF7isaVCla
|
||||
VRqcZmECgYEA9FuP/+Qrz78VGdiAIEblLAeZ90ZVbzMiyKTVTG6WmK6jvaJreZZY
|
||||
FdE2MTcAsn+m9MNhnJQn2tGo7jhca+kqkLWjAkMiG5xsJH4zm8n7471mLhQwt2lw
|
||||
871kjjDzbm+8PTAIaGWAz9jucbgxbu3UxA1Td48MvqFsgDwVSDdeV3ECgYEA8We9
|
||||
ueRHMon+FDNH1pL3yYq+ANTwl4OUZ+rhdxbzvRKRYhb8oQ6Ib254JRMAMN/XWT/N
|
||||
E0yiUbr97rx5lnYItp6mahbw8xv8l+s2RM/TG5TfKK1RITjVopqZpG+Uz196Y7xX
|
||||
iyUASMTznZhbPG3+7rX5XYQuMFzr8+QXDHILmXsCgYAICt9xb6QVgVeDc0G8TjkK
|
||||
uvFRVypGr6ssaWhvzI/+VHklK6xX4x/hD/K1qfbG6Taoham3ypSJOi9SL96y2ojB
|
||||
HIlR8L21pO9WQCUYsows0bYEPDviPYEvNIOTvn60ms7aQLN2JCkaLiyi54oQ+Zjw
|
||||
HvQpUjb8Kznz+oZEyzW6sQKBgCTpjPwwqKZUrVIfaTupK1RY76am6MbyKq4dHy6b
|
||||
hteBUFOkWiqyUzBevuZEWoIeqAoQlGYAEM3Yft2TWjAkij6KUb3lFiDGRcBhCeJJ
|
||||
uOj9wYWxwrcGvrvnUdjv6twuqEM52FUBamK2It4VHtZFp3aOwruG650fiEC5vsB7
|
||||
a8SjAoGBALlUvePHaZs0/dUluJv2wwkgpy9fmc8hnvwopOpRDcujB6mW16bw80qe
|
||||
EKMJSx3z7R3mNYnbtujn8xAIxpO4AVX1glZImp0C45PGNw2Kvry7FB3coy26YTJp
|
||||
hcACUhfVkl9vJkje7sJZyyv9hIOaX+fVhQeZrTOoSHmz9vkH0Uir
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,20 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDSzCCAjOgAwIBAgIIVZN/5ReT87wwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgNTU5MzdmMCAXDTIwMDYwNDIyMjY1NFoYDzIxMjAw
|
||||
NjA0MjMyNjU0WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA1NTkzN2YwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmbTh/3yKJdiWdfol5ii4kZwiB
|
||||
64FqYcXB89Q3KYYUsJKHTlIbDDZiOGUyFqGxImIcaohujBiuK8o6hImtjMySzFfq
|
||||
mOiWDcwjfmbzrBgCD6moQeGh94NxP58+hPDmy+zI7zp8NbDZrgMsdfvOdRLrqlIm
|
||||
do8e9cQSvPo2mq3/3KMpsDCFnEvXlNICkmSPw+6wPFn38LlfoKzLYcafasp321FQ
|
||||
RABgTXAEpTpodDgCEq3NABD4U274d30g68Aoij8Nq0vXqT2TiCylspwmnmc/AOv0
|
||||
lpJzN+RT3q46R0vvb4vFxpf2riwi6w5dy8AEFpymyeSZpqbl8c5EBxQQcYxLAgMB
|
||||
AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||
BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBS5uijpDluYTxcU
|
||||
27MKGYqPixX8MDAfBgNVHSMEGDAWgBS5uijpDluYTxcU27MKGYqPixX8MDANBgkq
|
||||
hkiG9w0BAQsFAAOCAQEAkRHRKnSQ4+c5cfJxqJ+FtivRfAgKEgGUN1RwW6Dwbe2t
|
||||
ndIqlw9IODxVxAnTCKe30g77SSormxeNIw9BALFR7gFAU5QsU6KtC8qwSwlOz4BZ
|
||||
EYGmPDIn8f+uhiwo1GRlGPko3hksWeimw+wkwKJVKGDnCr7fxqqJrfb3eit07KIx
|
||||
IVqSqH3aby92Q9owK74JJBXN8FnNoCYwRNQ3qI2ViDj+fQQpQDSJp2BDCQ2196hB
|
||||
DcPAgECC6AyxiGEvSeXNrTgWYtAjLqxTiGbshULdbDop8AMFCzf6ALRC3rMfKvNR
|
||||
Z8AM2ohnwVlfiz6G19JFKp3lNqLegVGemLjLyX2d8A==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAp3i+84dsjNu8JwAk5j6zcfzZzhmI647NdNOK/iA8+0ycsuUu
|
||||
Hf32NkOrFoWpSfn7+Tt2kKxM8/qbG75QFDfV7tU5V96BllqGz6Kv+Gv8GWOPipHO
|
||||
qgt1HAq1nWz8OliiM/MyI+UEYQgSJlJjO6p1UnRhvSimtN3KAw+KwrRaaABpUf1E
|
||||
eBqHksKlq+TQIlr8E/+qxCmYkPUVhIPi2tiIiLLIuKopzioHqTSI8ltUYxHtuHD4
|
||||
TfFcTNvTVxYI3KN+WqUxZ2fXAPsmEjWQwrtoNioZL/OVdr0dPLtdkIgFl857OBRK
|
||||
BMnHvXmYE/ycAwUpZg4JApDZA6wQnOb3drxbDQIDAQABAoIBAB+kqffby7/luOxp
|
||||
k49Jo6BTFVhi7MMNbXa4jdesgbk95ZHLyeXy2XWxXX9Y6/7FVD3oZWO6mqOy42Hf
|
||||
mMPpNOv2r+oRaczd+AD9jWBUDwNBE5ssJ69rkMomn+BJ+nKP0r4cIoozuJsY6k0B
|
||||
Xiyk7ZwRz3HtX2pnScdARYi6iSaDNv3svzNqSpiTrThxDSCOhzbDwWxpSga+z9QM
|
||||
iIhnmX7OSsdgVAx7kAjqzqUNYBUmhHQ6dPsSXpCB/FZna3fMmaZbxZiqNtxt9nLl
|
||||
tI+9Vchg4NEg4gezTNno95708OIoenS1Dn7pYug/yJpVFxWCsg30LBrhyTOTLJl1
|
||||
iAm3rGUCgYEA3DwBnoXAK5lnha3l1wr5de/D3mL4y/GyEzP34e6WcRU9OU433+cD
|
||||
+mNpPH7DCyUlHTm+uCEnMBfLUmTCA7m4ixEnafuYOcgZF0K+s0ep1EY2H7hAMsB/
|
||||
OVTdEv3PRwarVMCazyEpqRGwwo36f7B3XxmZEhxKKV2doa7+UPYsDvMCgYEAwqsw
|
||||
Z4ewLLzhXLp9yw8+Iry+HsfhwWVL7ZpIJCGSiMZX/CpQpOQTidIRLyOw/PdqfzD3
|
||||
O90rOLzrW0rGQ7XnrLVl9su4I4uZ84DsKDoYDv3vcWT6C1qxUdfUVhxKzla6KFLP
|
||||
T+4mlYKGzlOiHW0qTDKRqHaPCqqop3AGbj6Ubf8CgYBlCtLjXBIS7srkNiihRNO3
|
||||
HE4NFfN3/mfpD4rHCaPUNh5k0FIqU98rXbjGnJH35w7kHb421F8aXZBXOQsaknbs
|
||||
tu4SXfA1cmywk1rS/ioYzi2+19X8cvzr3NehAvm6aIDq3YMpTNnES+2BFYq8UsYx
|
||||
x5jHClusJttPdu4PTyJfqQKBgB3t6/c+6Vs3fv6evZBmu4rjsedRm+f8Bvx05/qG
|
||||
Ht1ggU6HwvZXCpn57iJtPlzmPT1o7doKWwbSJO1YRbtLUF9BVHfpQlpUsEq725Mj
|
||||
u2cyq4mnmLn+K50FreO/XdDzjJN+h9kmKFB8TPWT7izQB9zHOZXJBJ0DOALmOlbg
|
||||
0DlJAoGAQrz+uu+nBwWZBhx7EGJpsbfAuwPGyxI71EIEh1A7HMv0AxvbDcy6PvFn
|
||||
eAuMBRJYqmWi/oAaXoxDgfhJBnSHD/vP+YZW7mmG07npOs8/C7CGsswwEDgf/ZtS
|
||||
ukD2mdcu4zXBnyKwkXqBZTDL5a++5QXbPYfFDtbzO8UbC5wqBM4=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,20 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDSzCCAjOgAwIBAgIIKcHJulXb3YMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE
|
||||
AxMVbWluaWNhIHJvb3QgY2EgMjljMWM5MCAXDTIwMDYwNDIyMzMzN1oYDzIxMjAw
|
||||
NjA0MjMzMzM3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAyOWMxYzkwggEi
|
||||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCneL7zh2yM27wnACTmPrNx/NnO
|
||||
GYjrjs1004r+IDz7TJyy5S4d/fY2Q6sWhalJ+fv5O3aQrEzz+psbvlAUN9Xu1TlX
|
||||
3oGWWobPoq/4a/wZY4+Kkc6qC3UcCrWdbPw6WKIz8zIj5QRhCBImUmM7qnVSdGG9
|
||||
KKa03coDD4rCtFpoAGlR/UR4GoeSwqWr5NAiWvwT/6rEKZiQ9RWEg+La2IiIssi4
|
||||
qinOKgepNIjyW1RjEe24cPhN8VxM29NXFgjco35apTFnZ9cA+yYSNZDCu2g2Khkv
|
||||
85V2vR08u12QiAWXzns4FEoEyce9eZgT/JwDBSlmDgkCkNkDrBCc5vd2vFsNAgMB
|
||||
AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||
BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTjdfKZHk5D+CGf
|
||||
ue+XaiIj946iwzAfBgNVHSMEGDAWgBTjdfKZHk5D+CGfue+XaiIj946iwzANBgkq
|
||||
hkiG9w0BAQsFAAOCAQEAFHfBaqEujbVCHt3NnuO/MDVs7ZU8qDpImdzTjnB50IQ1
|
||||
YM7mfK887Nm0e7Qw+hHQcZqyVMr/lwVCxXln4s7nd4gWscniicklw0mLYYKxJZfi
|
||||
sh0kxvfzRP2ohquA6g0K6gyA06xfWbar6Q4Ww8DltX+Bn5UDlE4oryVFWx8uZoNP
|
||||
49A0U0nkoaApzSKRkxTb0H/yVG6w6twr9ONT7eGHlrYaN1K/znxo4/jOgaTrzjwj
|
||||
PdWtvyxXnpe02JGAQtVp2Iw6Zfa7xxLY+c6wZrtgSKf/UPx9w7dCpsGPLK9Q2pNn
|
||||
7T6S1Kpnwq8Ko5ND3oCecW4LoRxy349vEuWEHWFeKw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,37 +0,0 @@
|
|||
// Package issuercerts defines types representing a certificate that issue other
|
||||
// certificates.
|
||||
package issuercerts
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"math/big"
|
||||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
)
|
||||
|
||||
type Issuer struct {
|
||||
Cert *x509.Certificate
|
||||
}
|
||||
type ID int64
|
||||
|
||||
// New reads an issuer certificate from a file and returns an Issuer.
|
||||
func FromFile(filename string) (*Issuer, error) {
|
||||
cert, err := core.LoadCert(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Issuer{cert}, nil
|
||||
}
|
||||
|
||||
func FromCert(cert *x509.Certificate) *Issuer {
|
||||
return &Issuer{cert}
|
||||
}
|
||||
|
||||
// idForIssuer generates a stable ID for an issuer certificate, based on a hash
|
||||
// of the issuer certificate's bytes. This is used for identifying which issuer
|
||||
// issued a certificate in the certificateStatus table.
|
||||
func (issuer *Issuer) ID() ID {
|
||||
h := sha256.Sum256(issuer.Cert.Raw)
|
||||
return ID(big.NewInt(0).SetBytes(h[:4]).Int64())
|
||||
}
|
6
ra/ra.go
6
ra/ra.go
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/letsencrypt/boulder/goodkey"
|
||||
bgrpc "github.com/letsencrypt/boulder/grpc"
|
||||
"github.com/letsencrypt/boulder/identifier"
|
||||
"github.com/letsencrypt/boulder/issuercerts"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/metrics"
|
||||
"github.com/letsencrypt/boulder/policy"
|
||||
|
@ -1655,11 +1654,7 @@ func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert
|
|||
status := string(core.OCSPStatusRevoked)
|
||||
reason := int32(code)
|
||||
revokedAt := ra.clk.Now().UnixNano()
|
||||
serial := core.SerialToString(cert.SerialNumber)
|
||||
issuerID := int64(issuercerts.FromCert(ra.issuer).ID())
|
||||
ocspResponse, err := ra.CA.GenerateOCSP(ctx, &caPB.GenerateOCSPRequest{
|
||||
Serial: &serial,
|
||||
IssuerID: &issuerID,
|
||||
CertDER: cert.Raw,
|
||||
Status: &status,
|
||||
Reason: &reason,
|
||||
|
@ -1668,6 +1663,7 @@ func (ra *RegistrationAuthorityImpl) revokeCertificate(ctx context.Context, cert
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serial := core.SerialToString(cert.SerialNumber)
|
||||
// for some reason we use int32 and int64 for the reason in different
|
||||
// protobuf messages, so we have to re-cast it here.
|
||||
reason64 := int64(reason)
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
"stdoutlevel": 7,
|
||||
"stdoutlevel": 7
|
||||
},
|
||||
"issuerFiles": [
|
||||
"/tmp/intermediate-cert-rsa-a.pem",
|
||||
"/tmp/intermediate-cert-rsa-b.pem"
|
||||
],
|
||||
|
||||
"tls": {
|
||||
"caCertFile": "test/grpc-creds/minica.pem",
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
"stdoutlevel": 7,
|
||||
"stdoutlevel": 7
|
||||
},
|
||||
"issuerFiles": [
|
||||
"/tmp/intermediate-cert-rsa-a.pem",
|
||||
"/tmp/intermediate-cert-rsa-b.pem"
|
||||
],
|
||||
|
||||
"tls": {
|
||||
"caCertFile": "test/grpc-creds/minica.pem",
|
||||
|
|
Loading…
Reference in New Issue