Skip to content

Commit

Permalink
attestationreport: validation result refactoring
Browse files Browse the repository at this point in the history
use error codes instead of strings for easier result
processing. Add methods to print attestation errors.

Signed-off-by: Simon Ott <[email protected]>
  • Loading branch information
smo4201 committed Feb 19, 2024
1 parent e2735bf commit 88a1357
Show file tree
Hide file tree
Showing 11 changed files with 901 additions and 483 deletions.
291 changes: 160 additions & 131 deletions attestationreport/attestationreport.go

Large diffs are not rendered by default.

35 changes: 21 additions & 14 deletions attestationreport/cbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,27 @@ func (s CborSerializer) VerifyToken(data []byte, roots []*x509.Certificate) (Tok

x5Chain, okConv := sig.Headers.Unprotected[cose.HeaderLabelX5Chain].([]interface{})
if !okConv {
msg := fmt.Sprintf("failed to parse x5c header: %v", err)
result.SignatureCheck[i].CertChainCheck.setFalse(&msg)
log.Warnf("failed to parse x5c header: %v", err)
result.SignatureCheck[i].CertChainCheck.Success = false
result.SignatureCheck[i].CertChainCheck.ErrorCode = ParseX5C
ok = false
continue
}
certChain := make([]*x509.Certificate, 0, len(x5Chain))
for _, rawCert := range x5Chain {
cert, okCert := rawCert.([]byte)
if !okCert {
msg := "failed to decode certificate chain"
result.SignatureCheck[i].CertChainCheck.setFalse(&msg)
log.Warnf("failed to decode certificate chain")
result.SignatureCheck[i].CertChainCheck.Success = false
result.SignatureCheck[i].CertChainCheck.ErrorCode = DecodeCertChain
ok = false
continue
}
x509Cert, err := x509.ParseCertificate(cert)
if err != nil {
msg := fmt.Sprintf("failed to parse leaf certificate: %v", err)
result.SignatureCheck[i].CertChainCheck.setFalse(&msg)
log.Warnf("failed to parse leaf certificate: %v", err)
result.SignatureCheck[i].CertChainCheck.Success = false
result.SignatureCheck[i].CertChainCheck.ErrorCode = ParseCert
ok = false
continue
}
Expand All @@ -173,8 +176,9 @@ func (s CborSerializer) VerifyToken(data []byte, roots []*x509.Certificate) (Tok

x509Chains, err := internal.VerifyCertChain(certChain, roots)
if err != nil {
msg := fmt.Sprintf("failed to verify certificate chain: %v", err)
result.SignatureCheck[i].CertChainCheck.setFalse(&msg)
log.Warnf("failed to verify certificate chain: %v", err)
result.SignatureCheck[i].CertChainCheck.Success = false
result.SignatureCheck[i].CertChainCheck.ErrorCode = VerifyCertChain
ok = false
continue
}
Expand All @@ -192,17 +196,19 @@ func (s CborSerializer) VerifyToken(data []byte, roots []*x509.Certificate) (Tok

publicKey, okKey := certChain[0].PublicKey.(*ecdsa.PublicKey)
if !okKey {
msg := fmt.Sprintf("Failed to extract public key from certificate: %v", err)
result.SignatureCheck[i].SignCheck.setFalse(&msg)
log.Warnf("Failed to extract public key from certificate: %v", err)
result.SignatureCheck[i].SignCheck.Success = false
result.SignatureCheck[i].SignCheck.ErrorCode = ExtractPubKey
ok = false
continue
}

// create a verifier from a trusted private key
verifier, err := cose.NewVerifier(cose.AlgorithmES256, publicKey)
if err != nil {
msg := fmt.Sprintf("Failed to create verifier: %v", err)
result.SignatureCheck[i].SignCheck.setFalse(&msg)
log.Warnf("Failed to create verifier: %v", err)
result.SignatureCheck[i].SignCheck.Success = false
result.SignatureCheck[i].SignCheck.ErrorCode = Internal
ok = false
continue
}
Expand All @@ -212,10 +218,11 @@ func (s CborSerializer) VerifyToken(data []byte, roots []*x509.Certificate) (Tok

err = msgToVerify.Verify(nil, verifiers...)
if err != nil {
msg := fmt.Sprintf("Error verifying cbor signature: %v", err)
log.Warnf("Error verifying cbor signature: %v", err)
// Can only be set for all signatures here
for i := range result.SignatureCheck {
result.SignatureCheck[i].SignCheck.setFalse(&msg)
result.SignatureCheck[i].SignCheck.Success = false
result.SignatureCheck[i].SignCheck.ErrorCode = VerifySignature
}
return result, nil, false
} else {
Expand Down
62 changes: 27 additions & 35 deletions attestationreport/iat.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"crypto/ecdsa"
"crypto/x509"
"encoding/hex"
"fmt"

"github.com/Fraunhofer-AISEC/cmc/internal"
"github.com/veraison/go-cose"
Expand Down Expand Up @@ -60,14 +59,14 @@ func verifyIasMeasurements(iasM Measurement, nonce []byte, referenceValues []Ref
log.Tracef("Parsing %v certificates", len(iasM.Certs))
certs, err := internal.ParseCertsDer(iasM.Certs)
if err != nil {
msg := fmt.Sprintf("failed to parse IAS certificates: %v", err)
result.Summary.setFalse(&msg)
log.Tracef("failed to parse IAS certificates: %v", err)
result.Summary.SetErr(ParseEvidence)
return result, false
}

if len(referenceValues) == 0 {
msg := "Could not find IAS Reference Value"
result.Summary.setFalse(&msg)
log.Tracef("Could not find IAS Reference Value")
result.Summary.SetErr(RefValNotPresent)
return result, false
}
s := CborSerializer{}
Expand All @@ -76,19 +75,19 @@ func verifyIasMeasurements(iasM Measurement, nonce []byte, referenceValues []Ref

iatresult, payload, ok := verifyIat(iasM.Evidence, certs[0])
if !ok {
msg := "IAS signature verification failed"
result.Summary.setFalse(&msg)
log.Tracef("IAS signature verification failed")
result.Summary.SetErr(VerifySignature)
return result, false
}
result.Signature = iatresult
result.Signature.SignCheck = iatresult

log.Trace("Unmarshalling CBOR IAT")

iat := &Iat{}
err = s.Unmarshal(payload, iat)
if err != nil {
msg := fmt.Sprintf("Failed to unmarshal IAT: %v", err)
result.Summary.setFalse(&msg)
log.Tracef("Failed to unmarshal IAT: %v", err)
result.Summary.SetErr(ParseEvidence)
return result, false
}

Expand All @@ -98,8 +97,10 @@ func verifyIasMeasurements(iasM Measurement, nonce []byte, referenceValues []Ref
if bytes.Equal(nonce, iat.AuthChallenge) {
result.Freshness.Success = true
} else {
msg := fmt.Sprintf("Nonces mismatch: Supplied Nonce = %v, IAT Nonce = %v)", hex.EncodeToString(nonce), hex.EncodeToString(iat.AuthChallenge))
result.Freshness.setFalse(&msg)
log.Tracef("Nonces mismatch: Supplied Nonce = %v, IAT Nonce = %v)", hex.EncodeToString(nonce), hex.EncodeToString(iat.AuthChallenge))
result.Freshness.Success = false
result.Freshness.Expected = hex.EncodeToString(nonce)
result.Freshness.Got = hex.EncodeToString(iat.AuthChallenge)
ok = false
}

Expand All @@ -108,8 +109,8 @@ func verifyIasMeasurements(iasM Measurement, nonce []byte, referenceValues []Ref
// Verify certificate chain
x509Chains, err := internal.VerifyCertChain(certs, cas)
if err != nil {
msg := fmt.Sprintf("Failed to verify certificate chain: %v", err)
result.Signature.CertChainCheck.setFalse(&msg)
log.Tracef("Failed to verify certificate chain: %v", err)
result.Signature.CertChainCheck.SetErr(VerifyCertChain)
ok = false
} else {
result.Signature.CertChainCheck.Success = true
Expand All @@ -132,8 +133,8 @@ func verifyIasMeasurements(iasM Measurement, nonce []byte, referenceValues []Ref
for _, ver := range referenceValues {
log.Tracef("Found reference value %v: %v", ver.Name, hex.EncodeToString(ver.Sha256))
if ver.Type != "IAS Reference Value" {
msg := fmt.Sprintf("IAS Reference Value invalid type %v", ver.Type)
result.Summary.setFalse(&msg)
log.Tracef("IAS Reference Value invalid type %v", ver.Type)
result.Summary.SetErr(RefValType)
return result, false
}
found := false
Expand Down Expand Up @@ -189,43 +190,34 @@ func verifyIasMeasurements(iasM Measurement, nonce []byte, referenceValues []Ref
return result, ok
}

func verifyIat(data []byte, cert *x509.Certificate) (SignatureResult, []byte, bool) {

result := SignatureResult{
CertChainCheck: Result{Success: true},
}
func verifyIat(data []byte, cert *x509.Certificate) (Result, []byte, bool) {

// create a Sign1Message from a raw COSE_Sign payload
var msgToVerify cose.Sign1Message
err := msgToVerify.UnmarshalCBOR(data)
if err != nil {
log.Warnf("error unmarshalling cose: %v", err)
return result, nil, false
log.Tracef("error unmarshalling cose: %v", err)
return Result{Success: false, ErrorCode: ParseEvidence}, nil, false
}

publicKey, okKey := cert.PublicKey.(*ecdsa.PublicKey)
if !okKey {
msg := fmt.Sprintf("Failed to extract public key from certificate: %v", err)
result.SignCheck.setFalse(&msg)
return result, nil, false
log.Tracef("Failed to extract public key from certificate: %v", err)
return Result{Success: false, ErrorCode: ExtractPubKey}, nil, false
}

// create a verifier from a trusted private key
verifier, err := cose.NewVerifier(cose.AlgorithmES256, publicKey)
if err != nil {
msg := fmt.Sprintf("Failed to create verifier: %v", err)
result.SignCheck.setFalse(&msg)
return result, nil, false
log.Tracef("Failed to create verifier: %v", err)
return Result{Success: false, ErrorCode: Internal}, nil, false
}

err = msgToVerify.Verify(nil, verifier)
if err != nil {
msg := fmt.Sprintf("Failed to verify COSE token: %v", err)
result.SignCheck.setFalse(&msg)
return result, nil, false
log.Tracef("Failed to verify COSE token: %v", err)
return Result{Success: false, ErrorCode: VerifySignature}, nil, false
}

result.SignCheck.Success = true

return result, msgToVerify.Payload, true
return Result{Success: true}, msgToVerify.Payload, true
}
Loading

0 comments on commit 88a1357

Please sign in to comment.