diff --git a/acme/challenge.go b/acme/challenge.go index 47733be7..0d9c2179 100644 --- a/acme/challenge.go +++ b/acme/challenge.go @@ -28,7 +28,6 @@ import ( "github.com/fxamacker/cbor/v2" "github.com/google/go-attestation/attest" "github.com/google/go-tpm/tpm2" - "github.com/ryboe/q" "go.step.sm/crypto/jose" "go.step.sm/crypto/keyutil" @@ -448,7 +447,6 @@ func deviceAttest01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose data, err := doTPMAttestationFormat(ctx, ch, db, jwk, &att) if err != nil { var acmeError *Error - q.Q("att error: %w", err) if errors.As(err, &acmeError) { if acmeError.Status == 500 { return acmeError @@ -494,6 +492,10 @@ func keyAuthDigest(jwk *jose.JSONWebKey, token string) ([]byte, error) { return digest[:], err } +var ( + oidSubjectAlternativeName = asn1.ObjectIdentifier{2, 5, 29, 17} +) + type tpmAttestationData struct { Certificate *x509.Certificate VerifiedChains [][]*x509.Certificate @@ -554,17 +556,10 @@ func doTPMAttestationFormat(ctx context.Context, ch *Challenge, db DB, jwk *jose unhandledCriticalExtensions := leaf.UnhandledCriticalExtensions[:0] for _, extOID := range leaf.UnhandledCriticalExtensions { switch { - case extOID.Equal(asn1.ObjectIdentifier{2, 5, 29, 17}): // Subject Alternative Name - // TODO(hs): decide when the processed extension is "OK"; permanent-identifier/hardware-module-name - for _, e := range leaf.Extensions { - if e.Id.Equal(extOID) { - // TODO(hs): validate this is in fact a valid PermanentIdentifier/HardwareModuleName - q.Q(e) - } - } - continue + case extOID.Equal(oidSubjectAlternativeName): + // allow Subject Alternative Names, including PermanentIdentifier, HardwareModuleName, TPM attributes, etc default: - // OIDs that are not in the switch remain unhandled + // OIDs that are not in the switch with explicitly allowed OIDs remain unhandled unhandledCriticalExtensions = append(unhandledCriticalExtensions, extOID) } } @@ -573,7 +568,7 @@ func doTPMAttestationFormat(ctx context.Context, ch *Challenge, db DB, jwk *jose roots, ok := prov.GetAttestationRoots() if !ok { - return nil, NewErrorISE("error getting tpm attestation root CAs") + return nil, NewErrorISE("failed getting tpm attestation root CAs") } verifiedChains, err := leaf.Verify(x509.VerifyOptions{ @@ -620,19 +615,22 @@ func doTPMAttestationFormat(ctx context.Context, ch *Challenge, db DB, jwk *jose return nil, NewError(ErrorBadAttestationStatementType, "invalid certInfo in attestation statement") } + // recreate the generated key certification parameter values and verify + // the attested key using the public key of the AK. certificationParameters := &attest.CertificationParameters{ - Public: pubArea, - CreateSignature: sig, - CreateAttestation: certInfo, + Public: pubArea, // the public key that was attested + CreateAttestation: certInfo, // the attested properties of the key + CreateSignature: sig, // signature over the attested properties } verifyOpts := attest.VerifyOpts{ - Public: leaf.PublicKey, // signature created by the AK that attested the key + Public: leaf.PublicKey, // public key of the AK that attested the key Hash: hash, } if err = certificationParameters.Verify(verifyOpts); err != nil { return nil, WrapError(ErrorBadAttestationStatementType, err, "invalid certification parameters") } + // decode the "certInfo" data tpmCertInfo, err := tpm2.DecodeAttestationData(certInfo) if err != nil { return nil, WrapError(ErrorBadAttestationStatementType, err, "failed decoding attestation data") @@ -649,6 +647,7 @@ func doTPMAttestationFormat(ctx context.Context, ch *Challenge, db DB, jwk *jose return nil, NewError(ErrorBadAttestationStatementType, "key authorization doesn not match") } + // decode the (attested) public key and determine its fingerprint pub, err := tpm2.DecodePublic(pubArea) if err != nil { return nil, WrapError(ErrorBadAttestationStatementType, err, "failed decoding pubArea") diff --git a/go.mod b/go.mod index 6a2f85ad..cdecb871 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,6 @@ require ( github.com/newrelic/go-agent/v3 v3.20.4 github.com/pkg/errors v0.9.1 github.com/rs/xid v1.4.0 - github.com/ryboe/q v1.0.17 github.com/sirupsen/logrus v1.9.0 github.com/slackhq/nebula v1.6.1 github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 @@ -116,7 +115,6 @@ require ( github.com/jackc/pgx/v4 v4.18.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/compress v1.15.11 // indirect - github.com/kr/text v0.2.0 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/miekg/pkcs11 v1.1.1 // indirect @@ -125,7 +123,6 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect diff --git a/go.sum b/go.sum index 683da771..be200090 100644 --- a/go.sum +++ b/go.sum @@ -686,8 +686,6 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/ryboe/q v1.0.17 h1:Ap34VxlzBbjFHdApe1RzvBwrYmoLa4hC5J7P643ENtU= -github.com/ryboe/q v1.0.17/go.mod h1:7wNegax8bjSyGxm9Pnsy6i8z+Uy9X8hkm7pAId9PDdg= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=