Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wip #170

Merged
merged 2 commits into from
Feb 19, 2024
Merged

Wip #170

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading