Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
james-d-elliott committed May 18, 2024
1 parent 21d9198 commit f113e81
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 38 deletions.
22 changes: 17 additions & 5 deletions metadata/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"github.com/google/uuid"
)

// NewMemoryProvider returns a new memory provider given a map, list of undesired AuthenticatorStatus types, and a
// conformance requirement boolean.
// NewMemoryProvider returns a new memory provider given a map, list of undesired AuthenticatorStatus types, a
// required boolean which if true will cause registrations to fail if no metadata entry is found for the attestation
// statement, and a validate boolean which determines if trust anchors should be validated by this provider during
// registration.
//
// If the undesired status slice is nil it will use a default value. You must explicitly use an empty slice to disable
// this functionality.
func NewMemoryProvider(mds map[uuid.UUID]*MetadataBLOBPayloadEntry, undesired []AuthenticatorStatus, required bool) *MemoryProvider {
func NewMemoryProvider(mds map[uuid.UUID]*MetadataBLOBPayloadEntry, undesired []AuthenticatorStatus, required, validate bool) *MemoryProvider {
if undesired == nil {
undesired = make([]AuthenticatorStatus, len(defaultUndesiredAuthenticatorStatus))

Expand All @@ -24,16 +26,26 @@ func NewMemoryProvider(mds map[uuid.UUID]*MetadataBLOBPayloadEntry, undesired []
mds: mds,
undesired: undesired,
require: required,
validate: validate,
}
}

type MemoryProvider struct {
mds map[uuid.UUID]*MetadataBLOBPayloadEntry
undesired []AuthenticatorStatus
require bool
validate bool
}

func (p *MemoryProvider) GetRequireConformance(ctx context.Context) (require bool) {
func (p *MemoryProvider) GetTrustAnchorValidation(ctx context.Context) (validate bool) {
return p.validate
}

func (p *MemoryProvider) GetAuthenticatorStatusValidation(ctx context.Context) (validate bool) {
return len(p.undesired) > 0
}

func (p *MemoryProvider) GetRequireEntry(ctx context.Context) (require bool) {
return p.require
}

Expand All @@ -51,7 +63,7 @@ func (p *MemoryProvider) GetEntry(ctx context.Context, aaguid uuid.UUID) (entry
return nil, nil
}

func (p *MemoryProvider) GetIsUndesiredAuthenticatorStatus(ctx context.Context, status AuthenticatorStatus) (isUndesiredAuthenticatorStatus bool) {
func (p *MemoryProvider) GetAuthenticatorStatusIsUndesired(ctx context.Context, status AuthenticatorStatus) (undesired bool) {
for _, s := range p.undesired {
if s == status {
return true
Expand Down
18 changes: 13 additions & 5 deletions metadata/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,22 @@ import (
)

type Provider interface {
// GetRequireConformance returns true if this provider requires conformance.
GetRequireConformance(ctx context.Context) (require bool)

// GetEntry returns a MDS3 payload entry given a AAGUID. This
GetEntry(ctx context.Context, aaguid uuid.UUID) (entry *MetadataBLOBPayloadEntry, err error)

// GetIsUndesiredAuthenticatorStatus returns true if the provided AuthenticatorStatus is not desired.
GetIsUndesiredAuthenticatorStatus(ctx context.Context, status AuthenticatorStatus) (isUndesiredAuthenticatorStatus bool)
// GetRequireEntry returns true if this provider requires an entry to exist with a AAGUID matching the attestation
// statement during registration.
GetRequireEntry(ctx context.Context) (require bool)

// GetTrustAnchorValidation returns true if trust anchor validation of attestation statements is enforced during
// registration.
GetTrustAnchorValidation(ctx context.Context) (validate bool)

// GetAuthenticatorStatusValidation returns true if this provider should validate the authenticator status reports.
GetAuthenticatorStatusValidation(ctx context.Context) (validate bool)

// GetAuthenticatorStatusIsUndesired returns true if the provided AuthenticatorStatus is not desired.
GetAuthenticatorStatusIsUndesired(ctx context.Context, status AuthenticatorStatus) (undesired bool)
}

var (
Expand Down
58 changes: 31 additions & 27 deletions protocol/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,48 +183,52 @@ func (a *AttestationObject) Verify(relyingPartyID string, clientDataHash []byte,
}

if entry == nil {
if mds.GetRequireConformance(ctx) {
if mds.GetRequireEntry(ctx) {
return ErrInvalidAttestation.WithDetails(fmt.Sprintf("AAGUID %s not found in metadata during conformance testing", aaguid.String()))
}

return nil
}

for _, s := range entry.StatusReports {
if mds.GetIsUndesiredAuthenticatorStatus(ctx, s.Status) {
return ErrInvalidAttestation.WithDetails("Authenticator with undesirable status encountered")
if mds.GetAuthenticatorStatusValidation(ctx) {
for _, s := range entry.StatusReports {
if mds.GetAuthenticatorStatusIsUndesired(ctx, s.Status) {
return ErrInvalidAttestation.WithDetails("Authenticator with undesirable status encountered")
}
}
}

if x5cs == nil {
return nil
}

var (
x5c *x509.Certificate
raw []byte
ok bool
)
if mds.GetTrustAnchorValidation(ctx) {
if x5cs == nil {
return nil
}

if len(x5cs) == 0 {
return ErrInvalidAttestation.WithDetails("Unable to parse attestation certificate from x5c").WithInfo("The attestation had no certificates")
}
var (
x5c *x509.Certificate
raw []byte
ok bool
)

if raw, ok = x5cs[0].([]byte); !ok {
return ErrInvalidAttestation.WithDetails("Unable to parse attestation certificate from x5c").WithInfo(fmt.Sprintf("The first certificate in the attestation was type '%T' but '[]byte' was expected", x5cs[0]))
}
if len(x5cs) == 0 {
return ErrInvalidAttestation.WithDetails("Unable to parse attestation certificate from x5c").WithInfo("The attestation had no certificates")
}

if x5c, err = x509.ParseCertificate(raw); err != nil {
return ErrInvalidAttestation.WithDetails("Unable to parse attestation certificate from x5c").WithInfo(fmt.Sprintf("Error returned from x509.ParseCertificate: %+v", err))
}
if raw, ok = x5cs[0].([]byte); !ok {
return ErrInvalidAttestation.WithDetails("Unable to parse attestation certificate from x5c").WithInfo(fmt.Sprintf("The first certificate in the attestation was type '%T' but '[]byte' was expected", x5cs[0]))
}

if x5c.Subject.CommonName != x5c.Issuer.CommonName {
if !entry.MetadataStatement.AttestationTypes.HasBasicFull() {
return ErrInvalidAttestation.WithDetails("Attestation with full attestation from authenticator that does not support full attestation")
if x5c, err = x509.ParseCertificate(raw); err != nil {
return ErrInvalidAttestation.WithDetails("Unable to parse attestation certificate from x5c").WithInfo(fmt.Sprintf("Error returned from x509.ParseCertificate: %+v", err))
}

if _, err = x5c.Verify(entry.MetadataStatement.Verifier()); err != nil {
return ErrInvalidAttestation.WithDetails(fmt.Sprintf("Invalid certificate chain from MDS: %v", err))
if x5c.Subject.CommonName != x5c.Issuer.CommonName {
if !entry.MetadataStatement.AttestationTypes.HasBasicFull() {
return ErrInvalidAttestation.WithDetails("Attestation with full attestation from authenticator that does not support full attestation")
}

if _, err = x5c.Verify(entry.MetadataStatement.Verifier()); err != nil {
return ErrInvalidAttestation.WithDetails(fmt.Sprintf("Invalid certificate chain from MDS: %v", err))
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion protocol/attestation_safetynet.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte, mds met
return "", nil, ErrInvalidAttestation.WithDetails("SafetyNet response with timestamp after current time")
} else if t.Before(time.Now().Add(-time.Minute)) {
// Small tolerance for pre-dated timestamps.
if mds != nil && mds.GetRequireConformance(context.Background()) {
if mds != nil && mds.GetRequireEntry(context.Background()) {
return "", nil, ErrInvalidAttestation.WithDetails("SafetyNet response with timestamp before one minute ago")
}
}
Expand Down

0 comments on commit f113e81

Please sign in to comment.