Merge pull request #1055 from smallstep/acme-att-info

Acme attestation information
This commit is contained in:
Mariano Cano 2022-09-16 14:30:46 -07:00 committed by GitHub
commit 6cdaaf5e0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 1 deletions

View file

@ -157,6 +157,9 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
data := x509util.NewTemplateData() data := x509util.NewTemplateData()
data.SetCommonName(csr.Subject.CommonName) data.SetCommonName(csr.Subject.CommonName)
// Custom sign options passed to authority.Sign
var extraOptions []provisioner.SignOption
// TODO: support for multiple identifiers? // TODO: support for multiple identifiers?
var permanentIdentifier string var permanentIdentifier string
for i := range o.Identifiers { for i := range o.Identifiers {
@ -173,6 +176,9 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
Type: x509util.PermanentIdentifierType, Type: x509util.PermanentIdentifierType,
Value: permanentIdentifier, Value: permanentIdentifier,
}) })
extraOptions = append(extraOptions, provisioner.AttestationData{
PermanentIdentifier: permanentIdentifier,
})
} else { } else {
defaultTemplate = x509util.DefaultLeafTemplate defaultTemplate = x509util.DefaultLeafTemplate
sans, err := o.sans(csr) sans, err := o.sans(csr)
@ -193,7 +199,11 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
if err != nil { if err != nil {
return WrapErrorISE(err, "error creating template options from ACME provisioner") return WrapErrorISE(err, "error creating template options from ACME provisioner")
} }
// Build extra signing options.
signOps = append(signOps, templateOptions) signOps = append(signOps, templateOptions)
signOps = append(signOps, extraOptions...)
// Sign a new certificate. // Sign a new certificate.
certChain, err := auth.Sign(csr, provisioner.SignOptions{ certChain, err := auth.Sign(csr, provisioner.SignOptions{
NotBefore: provisioner.NewTimeDuration(o.NotBefore), NotBefore: provisioner.NewTimeDuration(o.NotBefore),

View file

@ -77,6 +77,12 @@ func (fn CertificateEnforcerFunc) Enforce(cert *x509.Certificate) error {
return fn(cert) return fn(cert)
} }
// AttestationData is a SignOption used to pass attestation information to the
// sign methods.
type AttestationData struct {
PermanentIdentifier string
}
// emailOnlyIdentity is a CertificateRequestValidator that checks that the only // emailOnlyIdentity is a CertificateRequestValidator that checks that the only
// SAN provided is the given email address. // SAN provided is the given email address.
type emailOnlyIdentity string type emailOnlyIdentity string

View file

@ -94,6 +94,7 @@ func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Sign
var prov provisioner.Interface var prov provisioner.Interface
var pInfo *casapi.ProvisionerInfo var pInfo *casapi.ProvisionerInfo
var attData provisioner.AttestationData
for _, op := range extraOpts { for _, op := range extraOpts {
switch k := op.(type) { switch k := op.(type) {
// Capture current provisioner // Capture current provisioner
@ -129,6 +130,11 @@ func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Sign
case provisioner.CertificateEnforcer: case provisioner.CertificateEnforcer:
certEnforcers = append(certEnforcers, k) certEnforcers = append(certEnforcers, k)
// Extra information from ACME attestations.
case provisioner.AttestationData:
attData = k
// TODO(mariano,areed): remove me once attData is used.
_ = attData
default: default:
return nil, errs.InternalServer("authority.Sign; invalid extra option type %T", append([]interface{}{k}, opts...)...) return nil, errs.InternalServer("authority.Sign; invalid extra option type %T", append([]interface{}{k}, opts...)...)
} }

View file

@ -14,6 +14,7 @@ import (
"io" "io"
"net" "net"
"os" "os"
"path/filepath"
"reflect" "reflect"
"testing" "testing"
"time" "time"
@ -402,6 +403,14 @@ func TestNew_real(t *testing.T) {
}) })
} }
failDefaultCredentials := true
if home, err := os.UserHomeDir(); err == nil {
file := filepath.Join(home, ".config", "gcloud", "application_default_credentials.json")
if _, err := os.Stat(file); err == nil {
failDefaultCredentials = false
}
}
type args struct { type args struct {
ctx context.Context ctx context.Context
opts apiv1.Options opts apiv1.Options
@ -412,7 +421,7 @@ func TestNew_real(t *testing.T) {
args args args args
wantErr bool wantErr bool
}{ }{
{"fail default credentials", true, args{context.Background(), apiv1.Options{CertificateAuthority: testAuthorityName}}, true}, {"fail default credentials", true, args{context.Background(), apiv1.Options{CertificateAuthority: testAuthorityName}}, failDefaultCredentials},
{"fail certificate authority", false, args{context.Background(), apiv1.Options{}}, true}, {"fail certificate authority", false, args{context.Background(), apiv1.Options{}}, true},
{"fail with credentials", false, args{context.Background(), apiv1.Options{ {"fail with credentials", false, args{context.Background(), apiv1.Options{
CertificateAuthority: testAuthorityName, CredentialsFile: "testdata/missing.json", CertificateAuthority: testAuthorityName, CredentialsFile: "testdata/missing.json",