Simplify processing logic for unhandled critical extension

This commit is contained in:
Herman Slatman 2023-03-14 09:48:44 +01:00
parent e1c7e8f00b
commit 213b31bc2c
No known key found for this signature in database
GPG key ID: F4D8A44EA0A75A4F
3 changed files with 16 additions and 22 deletions

View file

@ -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")

3
go.mod
View file

@ -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

2
go.sum
View file

@ -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=