ca: log cert signing using JSON objects (#7742)

This makes the log events easier to parse, and makes it easier to
consistently use the correct fields from the issuance request.

Also, reduce the number of fields that are logged on error events.
Logging just the serial and the error in most cases should suffice to
cross-reference the error with the item that we attempted to sign.

One downside is that this increases the total log size (10kB above, vs
7kB from a similar production issuance) due in part to more repetition.
For example, both the "signing cert" and "signing cert success" log
lines include the full precert DER.

Note that our long-term plan for more structured logs is to have a
unique event id to join logs on, which can avoid this repetition. But
since we don't currently have convenient ways to do that join, some
duplication (as we currently have in the logs) seems reasonable.
This commit is contained in:
Jacob Hoffman-Andrews 2024-11-04 16:54:07 -08:00 committed by GitHub
parent 1fa66781ee
commit cb56bf6beb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 62 deletions

View File

@ -15,7 +15,6 @@ import (
"fmt"
"math/big"
mrand "math/rand/v2"
"strings"
"time"
ct "github.com/google/certificate-transparency-go"
@ -51,6 +50,25 @@ const (
certType = certificateType("certificate")
)
// issuanceEvent is logged before and after issuance of precertificates and certificates.
// The `omitempty` fields are not always present.
// CSR, Precertificate, and Certificate are hex-encoded DER bytes to make it easier to
// ad-hoc search for sequences or OIDs in logs. Other data, like public key within CSR,
// is logged as base64 because it doesn't have interesting DER structure.
type issuanceEvent struct {
CSR string `json:",omitempty"`
IssuanceRequest *issuance.IssuanceRequest
Issuer string
OrderID int64
Profile string
ProfileHash string
Requester int64
Result struct {
Precertificate string `json:",omitempty"`
Certificate string `json:",omitempty"`
}
}
// Two maps of keys to Issuers. Lookup by PublicKeyAlgorithm is useful for
// determining the set of issuers which can sign a given (pre)cert, based on its
// PublicKeyAlgorithm. Lookup by NameID is useful for looking up a specific
@ -428,17 +446,22 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
return nil, err
}
names := strings.Join(issuanceReq.DNSNames, ", ")
ca.log.AuditInfof("Signing cert: issuer=[%s] serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%x] precert=[%s]",
issuer.Name(), serialHex, req.RegistrationID, names, certProfile.name, certProfile.hash, hex.EncodeToString(precert.Raw))
lintCertBytes, issuanceToken, err := issuer.Prepare(certProfile.profile, issuanceReq)
if err != nil {
ca.log.AuditErrf("Preparing cert failed: issuer=[%s] serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%x] err=[%v]",
issuer.Name(), serialHex, req.RegistrationID, names, certProfile.name, certProfile.hash, err)
ca.log.AuditErrf("Preparing cert failed: serial=[%s] err=[%v]", serialHex, err)
return nil, berrors.InternalServerError("failed to prepare certificate signing: %s", err)
}
logEvent := issuanceEvent{
IssuanceRequest: issuanceReq,
Issuer: issuer.Name(),
OrderID: req.OrderID,
Profile: certProfile.name,
ProfileHash: hex.EncodeToString(certProfile.hash[:]),
Requester: req.RegistrationID,
}
ca.log.AuditObject("Signing cert", logEvent)
_, span := ca.tracer.Start(ctx, "signing cert", trace.WithAttributes(
attribute.String("serial", serialHex),
attribute.String("issuer", issuer.Name()),
@ -448,8 +471,7 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
certDER, err := issuer.Issue(issuanceToken)
if err != nil {
ca.metrics.noteSignError(err)
ca.log.AuditErrf("Signing cert failed: issuer=[%s] serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%x] err=[%v]",
issuer.Name(), serialHex, req.RegistrationID, names, certProfile.name, certProfile.hash, err)
ca.log.AuditErrf("Signing cert failed: serial=[%s] err=[%v]", serialHex, err)
span.SetStatus(codes.Error, err.Error())
span.End()
return nil, berrors.InternalServerError("failed to sign certificate: %s", err)
@ -462,8 +484,8 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
}
ca.metrics.signatureCount.With(prometheus.Labels{"purpose": string(certType), "issuer": issuer.Name()}).Inc()
ca.log.AuditInfof("Signing cert success: issuer=[%s] serial=[%s] regID=[%d] names=[%s] certificate=[%s] certProfileName=[%s] certProfileHash=[%x]",
issuer.Name(), serialHex, req.RegistrationID, names, hex.EncodeToString(certDER), certProfile.name, certProfile.hash)
logEvent.Result.Certificate = hex.EncodeToString(certDER)
ca.log.AuditObject("Signing cert success", logEvent)
_, err = ca.sa.AddCertificate(ctx, &sapb.AddCertificateRequest{
Der: certDER,
@ -471,8 +493,7 @@ func (ca *certificateAuthorityImpl) IssueCertificateForPrecertificate(ctx contex
Issued: timestamppb.New(ca.clk.Now()),
})
if err != nil {
ca.log.AuditErrf("Failed RPC to store at SA: issuer=[%s] serial=[%s] cert=[%s] regID=[%d] orderID=[%d] certProfileName=[%s] certProfileHash=[%x] err=[%v]",
issuer.Name(), serialHex, hex.EncodeToString(certDER), req.RegistrationID, req.OrderID, certProfile.name, certProfile.hash, err)
ca.log.AuditErrf("Failed RPC to store at SA: serial=[%s] err=[%v]", serialHex, hex.EncodeToString(certDER))
return nil, err
}
@ -568,7 +589,7 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
names := csrlib.NamesFromCSR(csr)
req := &issuance.IssuanceRequest{
PublicKey: csr.PublicKey,
PublicKey: issuance.MarshalablePublicKey{PublicKey: csr.PublicKey},
SubjectKeyId: subjectKeyId,
Serial: serialBigInt.Bytes(),
DNSNames: names.SANs,
@ -579,13 +600,9 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
NotAfter: notAfter,
}
ca.log.AuditInfof("Signing precert: serial=[%s] regID=[%d] names=[%s] csr=[%s]",
serialHex, issueReq.RegistrationID, strings.Join(req.DNSNames, ", "), hex.EncodeToString(csr.Raw))
lintCertBytes, issuanceToken, err := issuer.Prepare(certProfile.profile, req)
if err != nil {
ca.log.AuditErrf("Preparing precert failed: issuer=[%s] serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%x] err=[%v]",
issuer.Name(), serialHex, issueReq.RegistrationID, strings.Join(req.DNSNames, ", "), certProfile.name, certProfile.hash, err)
ca.log.AuditErrf("Preparing precert failed: serial=[%s] err=[%v]", serialHex, err)
if errors.Is(err, linter.ErrLinting) {
ca.metrics.lintErrorCount.Inc()
}
@ -608,6 +625,17 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
return nil, nil, err
}
logEvent := issuanceEvent{
CSR: hex.EncodeToString(csr.Raw),
IssuanceRequest: req,
Issuer: issuer.Name(),
Profile: certProfile.name,
ProfileHash: hex.EncodeToString(certProfile.hash[:]),
Requester: issueReq.RegistrationID,
OrderID: issueReq.OrderID,
}
ca.log.AuditObject("Signing precert", logEvent)
_, span := ca.tracer.Start(ctx, "signing precert", trace.WithAttributes(
attribute.String("serial", serialHex),
attribute.String("issuer", issuer.Name()),
@ -617,8 +645,7 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
certDER, err := issuer.Issue(issuanceToken)
if err != nil {
ca.metrics.noteSignError(err)
ca.log.AuditErrf("Signing precert failed: issuer=[%s] serial=[%s] regID=[%d] names=[%s] certProfileName=[%s] certProfileHash=[%x] err=[%v]",
issuer.Name(), serialHex, issueReq.RegistrationID, strings.Join(req.DNSNames, ", "), certProfile.name, certProfile.hash, err)
ca.log.AuditErrf("Signing precert failed: serial=[%s] err=[%v]", serialHex, err)
span.SetStatus(codes.Error, err.Error())
span.End()
return nil, nil, berrors.InternalServerError("failed to sign precertificate: %s", err)
@ -631,8 +658,11 @@ func (ca *certificateAuthorityImpl) issuePrecertificateInner(ctx context.Context
}
ca.metrics.signatureCount.With(prometheus.Labels{"purpose": string(precertType), "issuer": issuer.Name()}).Inc()
ca.log.AuditInfof("Signing precert success: issuer=[%s] serial=[%s] regID=[%d] names=[%s] precert=[%s] certProfileName=[%s] certProfileHash=[%x]",
issuer.Name(), serialHex, issueReq.RegistrationID, strings.Join(req.DNSNames, ", "), hex.EncodeToString(certDER), certProfile.name, certProfile.hash)
logEvent.Result.Precertificate = hex.EncodeToString(certDER)
// The CSR is big and not that informative, so don't log it a second time.
logEvent.CSR = ""
ca.log.AuditObject("Signing precert success", logEvent)
return certDER, &certProfileWithID{certProfile.name, certProfile.hash, nil}, nil
}

View File

@ -332,7 +332,6 @@ func TestIssuePrecertificate(t *testing.T) {
var certDER []byte
response, err := ca.IssuePrecertificate(ctx, issueReq)
test.AssertNotError(t, err, "Failed to issue precertificate")
certDER = response.DER

View File

@ -9,6 +9,7 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/json"
"errors"
"fmt"
"math/big"
@ -153,7 +154,7 @@ func (p *Profile) GenerateValidity(now time.Time) (time.Time, time.Time) {
// requestValid verifies the passed IssuanceRequest against the profile. If the
// request doesn't match the signing profile an error is returned.
func (i *Issuer) requestValid(clk clock.Clock, prof *Profile, req *IssuanceRequest) error {
switch req.PublicKey.(type) {
switch req.PublicKey.PublicKey.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey:
default:
return errors.New("unsupported public key type")
@ -261,12 +262,36 @@ var mustStapleExt = pkix.Extension{
Value: []byte{0x30, 0x03, 0x02, 0x01, 0x05},
}
// IssuanceRequest describes a certificate issuance request
type IssuanceRequest struct {
PublicKey crypto.PublicKey
SubjectKeyId []byte
// MarshalablePublicKey is a wrapper for crypto.PublicKey with a custom JSON
// marshaller that encodes the public key as a DER-encoded SubjectPublicKeyInfo.
type MarshalablePublicKey struct {
crypto.PublicKey
}
Serial []byte
func (pk MarshalablePublicKey) MarshalJSON() ([]byte, error) {
keyDER, err := x509.MarshalPKIXPublicKey(pk.PublicKey)
if err != nil {
return nil, err
}
return json.Marshal(keyDER)
}
type HexMarshalableBytes []byte
func (h HexMarshalableBytes) MarshalJSON() ([]byte, error) {
return json.Marshal(fmt.Sprintf("%x", h))
}
// IssuanceRequest describes a certificate issuance request
//
// It can be marshaled as JSON for logging purposes, though note that sctList and precertDER
// will be omitted from the marshaled output because they are unexported.
type IssuanceRequest struct {
// PublicKey is of type MarshalablePublicKey so we can log an IssuanceRequest as a JSON object.
PublicKey MarshalablePublicKey
SubjectKeyId HexMarshalableBytes
Serial HexMarshalableBytes
NotBefore time.Time
NotAfter time.Time
@ -294,7 +319,7 @@ type IssuanceRequest struct {
type issuanceToken struct {
mu sync.Mutex
template *x509.Certificate
pubKey any
pubKey MarshalablePublicKey
// A pointer to the issuer that created this token. This token may only
// be redeemed by the same issuer.
issuer *Issuer
@ -335,7 +360,7 @@ func (i *Issuer) Prepare(prof *Profile, req *IssuanceRequest) ([]byte, *issuance
}
template.DNSNames = req.DNSNames
switch req.PublicKey.(type) {
switch req.PublicKey.PublicKey.(type) {
case *rsa.PublicKey:
if prof.omitKeyEncipherment {
template.KeyUsage = x509.KeyUsageDigitalSignature
@ -371,7 +396,7 @@ func (i *Issuer) Prepare(prof *Profile, req *IssuanceRequest) ([]byte, *issuance
// check that the tbsCertificate is properly formed by signing it
// with a throwaway key and then linting it using zlint
lintCertBytes, err := i.Linter.Check(template, req.PublicKey, prof.lints)
lintCertBytes, err := i.Linter.Check(template, req.PublicKey.PublicKey, prof.lints)
if err != nil {
return nil, nil, fmt.Errorf("tbsCertificate linting failed: %w", err)
}
@ -406,7 +431,7 @@ func (i *Issuer) Issue(token *issuanceToken) ([]byte, error) {
return nil, errors.New("tried to redeem issuance token with the wrong issuer")
}
return x509.CreateCertificate(rand.Reader, template, i.Cert.Certificate, token.pubKey, i.Signer)
return x509.CreateCertificate(rand.Reader, template, i.Cert.Certificate, token.pubKey.PublicKey, i.Signer)
}
// ContainsMustStaple returns true if the provided set of extensions includes
@ -441,7 +466,7 @@ func RequestFromPrecert(precert *x509.Certificate, scts []ct.SignedCertificateTi
return nil, errors.New("provided certificate doesn't contain the CT poison extension")
}
return &IssuanceRequest{
PublicKey: precert.PublicKey,
PublicKey: MarshalablePublicKey{precert.PublicKey},
SubjectKeyId: precert.SubjectKeyId,
Serial: precert.SerialNumber.Bytes(),
NotBefore: precert.NotBefore,

View File

@ -83,21 +83,21 @@ func TestRequestValid(t *testing.T) {
name: "unsupported key type",
issuer: &Issuer{},
profile: &Profile{},
request: &IssuanceRequest{PublicKey: &dsa.PublicKey{}},
request: &IssuanceRequest{PublicKey: MarshalablePublicKey{&dsa.PublicKey{}}},
expectedError: "unsupported public key type",
},
{
name: "inactive (rsa)",
issuer: &Issuer{},
profile: &Profile{},
request: &IssuanceRequest{PublicKey: &rsa.PublicKey{}},
request: &IssuanceRequest{PublicKey: MarshalablePublicKey{&rsa.PublicKey{}}},
expectedError: "inactive issuer cannot issue precert",
},
{
name: "inactive (ecdsa)",
issuer: &Issuer{},
profile: &Profile{},
request: &IssuanceRequest{PublicKey: &ecdsa.PublicKey{}},
request: &IssuanceRequest{PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}}},
expectedError: "inactive issuer cannot issue precert",
},
{
@ -107,7 +107,7 @@ func TestRequestValid(t *testing.T) {
},
profile: &Profile{},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: []byte{0, 1, 2, 3, 4},
},
expectedError: "unexpected subject key ID length",
@ -119,7 +119,7 @@ func TestRequestValid(t *testing.T) {
},
profile: &Profile{},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
IncludeMustStaple: true,
},
@ -132,7 +132,7 @@ func TestRequestValid(t *testing.T) {
},
profile: &Profile{},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
IncludeCTPoison: true,
sctList: []ct.SignedCertificateTimestamp{},
@ -146,7 +146,7 @@ func TestRequestValid(t *testing.T) {
},
profile: &Profile{},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now().Add(time.Hour),
NotAfter: fc.Now(),
@ -162,7 +162,7 @@ func TestRequestValid(t *testing.T) {
maxValidity: time.Minute,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now(),
NotAfter: fc.Now().Add(time.Hour - time.Second),
@ -178,7 +178,7 @@ func TestRequestValid(t *testing.T) {
maxValidity: time.Hour,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now(),
NotAfter: fc.Now().Add(time.Hour),
@ -195,7 +195,7 @@ func TestRequestValid(t *testing.T) {
maxBackdate: time.Hour,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now().Add(-time.Hour * 2),
NotAfter: fc.Now().Add(-time.Hour),
@ -212,7 +212,7 @@ func TestRequestValid(t *testing.T) {
maxBackdate: time.Hour,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now().Add(time.Hour),
NotAfter: fc.Now().Add(time.Hour * 2),
@ -228,7 +228,7 @@ func TestRequestValid(t *testing.T) {
maxValidity: time.Hour * 2,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now(),
NotAfter: fc.Now().Add(time.Hour),
@ -245,7 +245,7 @@ func TestRequestValid(t *testing.T) {
maxValidity: time.Hour * 2,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now(),
NotAfter: fc.Now().Add(time.Hour),
@ -262,7 +262,7 @@ func TestRequestValid(t *testing.T) {
maxValidity: time.Hour * 2,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now(),
NotAfter: fc.Now().Add(time.Hour),
@ -279,7 +279,7 @@ func TestRequestValid(t *testing.T) {
maxValidity: time.Hour * 2,
},
request: &IssuanceRequest{
PublicKey: &ecdsa.PublicKey{},
PublicKey: MarshalablePublicKey{&ecdsa.PublicKey{}},
SubjectKeyId: goodSKID,
NotBefore: fc.Now(),
NotAfter: fc.Now().Add(time.Hour),
@ -356,7 +356,7 @@ func TestIssue(t *testing.T) {
pk, err := tc.generateFunc()
test.AssertNotError(t, err, "failed to generate test key")
lintCertBytes, issuanceToken, err := signer.Prepare(defaultProfile(), &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -399,7 +399,7 @@ func TestIssueCommonName(t *testing.T) {
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
ir := &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com", "www.example.com"},
@ -463,7 +463,7 @@ func TestIssueOmissions(t *testing.T) {
pk, err := rsa.GenerateKey(rand.Reader, 2048)
test.AssertNotError(t, err, "failed to generate test key")
_, issuanceToken, err := signer.Prepare(prof, &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -492,7 +492,7 @@ func TestIssueCTPoison(t *testing.T) {
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
_, issuanceToken, err := signer.Prepare(defaultProfile(), &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -537,7 +537,7 @@ func TestIssueSCTList(t *testing.T) {
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
_, issuanceToken, err := signer.Prepare(enforceSCTsProfile, &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -601,7 +601,7 @@ func TestIssueMustStaple(t *testing.T) {
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
_, issuanceToken, err := signer.Prepare(defaultProfile(), &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -636,7 +636,7 @@ func TestIssueBadLint(t *testing.T) {
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
_, _, err = signer.Prepare(noSkipLintsProfile, &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example-com"},
@ -665,7 +665,7 @@ func TestIssuanceToken(t *testing.T) {
pk, err := rsa.GenerateKey(rand.Reader, 2048)
test.AssertNotError(t, err, "failed to generate test key")
_, issuanceToken, err := signer.Prepare(defaultProfile(), &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -682,7 +682,7 @@ func TestIssuanceToken(t *testing.T) {
test.AssertContains(t, err.Error(), "issuance token already redeemed")
_, issuanceToken, err = signer.Prepare(defaultProfile(), &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -712,7 +712,7 @@ func TestInvalidProfile(t *testing.T) {
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
_, _, err = signer.Prepare(defaultProfile(), &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -724,7 +724,7 @@ func TestInvalidProfile(t *testing.T) {
test.AssertError(t, err, "Invalid IssuanceRequest")
_, _, err = signer.Prepare(defaultProfile(), &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
DNSNames: []string{"example.com"},
@ -765,7 +765,7 @@ func TestMismatchedProfiles(t *testing.T) {
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "failed to generate test key")
_, issuanceToken, err := issuer1.Prepare(cnProfile, &IssuanceRequest{
PublicKey: pk.Public(),
PublicKey: MarshalablePublicKey{pk.Public()},
SubjectKeyId: goodSKID,
Serial: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9},
CommonName: "example.com",