From 20bfa10a4323d73120a33688eb9ccfe168bb65fb Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 28 Sep 2022 12:49:30 -0700 Subject: [PATCH] Use more shared error messages --- Src/Fido2/AttestationFormat/AndroidKey.cs | 4 +-- Src/Fido2/AttestationFormat/Apple.cs | 2 +- Src/Fido2/AttestationFormat/Packed.cs | 2 +- Src/Fido2/AttestationFormat/Tpm.cs | 2 +- Src/Fido2/Fido2ErrorMessages.cs | 5 +++ Test/Attestation/AndroidKey.cs | 32 ++++++++++++------- Test/Attestation/Apple.cs | 38 ++++++++++++++--------- Test/Attestation/Packed.cs | 16 ++++++---- Test/Attestation/Tpm.cs | 13 ++++---- 9 files changed, 70 insertions(+), 44 deletions(-) diff --git a/Src/Fido2/AttestationFormat/AndroidKey.cs b/Src/Fido2/AttestationFormat/AndroidKey.cs index 330b855e..799ea648 100644 --- a/Src/Fido2/AttestationFormat/AndroidKey.cs +++ b/Src/Fido2/AttestationFormat/AndroidKey.cs @@ -143,7 +143,7 @@ public override (AttestationType, X509Certificate2[]) Verify() // 2. Verify that sig is a valid signature over the concatenation of authenticatorData and clientDataHash // using the attestation public key in attestnCert with the algorithm specified in alg if (!(X5c is CborArray { Length: > 0 } x5cArray)) - throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, "Malformed x5c in android-key attestation"); + throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, Fido2ErrorMessages.MalformedX5c_AndroidKeyAttestation); if (Alg is not CborInteger) throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, "Invalid android-key attestation algorithm"); @@ -166,7 +166,7 @@ public override (AttestationType, X509Certificate2[]) Verify() } else { - throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, "Malformed x5c in android-key attestation"); + throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, Fido2ErrorMessages.MalformedX5c_AndroidKeyAttestation); } } diff --git a/Src/Fido2/AttestationFormat/Apple.cs b/Src/Fido2/AttestationFormat/Apple.cs index 0af6e575..b04aab05 100644 --- a/Src/Fido2/AttestationFormat/Apple.cs +++ b/Src/Fido2/AttestationFormat/Apple.cs @@ -45,7 +45,7 @@ public override (AttestationType, X509Certificate2[]) Verify() // 1. Verify that attStmt is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the contained fields. if (!(X5c is CborArray { Length: >= 2 } x5cArray && x5cArray[0] is CborByteString { Length: > 0 })) { - throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, "Malformed x5c in Apple attestation"); + throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, Fido2ErrorMessages.MalformedX5c_AppleAttestation); } // 2. Verify x5c is a valid certificate chain starting from the credCert to the Apple WebAuthn root certificate. diff --git a/Src/Fido2/AttestationFormat/Packed.cs b/Src/Fido2/AttestationFormat/Packed.cs index c86d13aa..2cb1c4cc 100644 --- a/Src/Fido2/AttestationFormat/Packed.cs +++ b/Src/Fido2/AttestationFormat/Packed.cs @@ -97,7 +97,7 @@ public override (AttestationType, X509Certificate2[]?) Verify() // 2bii. Subject field MUST contain C, O, OU, CN // OU must match "Authenticator Attestation" if (!IsValidPackedAttnCertSubject(attestnCert.Subject)) - throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, "Invalid attestation cert subject"); + throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, Fido2ErrorMessages.InvalidAttestationCertSubject); // 2biii. If the related attestation root certificate is used for multiple authenticator models, // the Extension OID 1.3.6.1.4.1.45724.1.1.4 (id-fido-gen-ce-aaguid) MUST be present, containing the AAGUID as a 16-byte OCTET STRING diff --git a/Src/Fido2/AttestationFormat/Tpm.cs b/Src/Fido2/AttestationFormat/Tpm.cs index fbe5817e..40f5a551 100644 --- a/Src/Fido2/AttestationFormat/Tpm.cs +++ b/Src/Fido2/AttestationFormat/Tpm.cs @@ -138,7 +138,7 @@ public override (AttestationType, X509Certificate2[]) Verify() } else { - throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, "Malformed x5c in TPM attestation"); + throw new Fido2VerificationException(Fido2ErrorCode.InvalidAttestation, Fido2ErrorMessages.MalformedX5c_TpmAttestation); } } diff --git a/Src/Fido2/Fido2ErrorMessages.cs b/Src/Fido2/Fido2ErrorMessages.cs index a645fdee..ec7a8aed 100644 --- a/Src/Fido2/Fido2ErrorMessages.cs +++ b/Src/Fido2/Fido2ErrorMessages.cs @@ -26,7 +26,12 @@ internal static class Fido2ErrorMessages public static readonly string InvalidCoseAlgorithmValue = "Unrecognized COSE algorithm value"; public static readonly string NonUniqueCredentialId = "CredentialId is not unique to this user"; public static readonly string MissingAttestationType = "Missing attestation type"; + public static readonly string InvalidAttestationCertSubject = "Invalid attestation cert subject"; public static readonly string UnimplementedAlgorithm_Ecdaa_Packed = "ECDAA support for packed attestation is not yet implemented"; public static readonly string UnimplementedAlgorithm_Ecdaa_Tpm = "ECDAA support for TPM attestation is not yet implemented"; + + public static readonly string MalformedX5c_AndroidKeyAttestation = "Malformed x5c in android-key attestation"; + public static readonly string MalformedX5c_AppleAttestation = "Malformed x5c in Apple attestation"; + public static readonly string MalformedX5c_TpmAttestation = "Malformed x5c in TPM attestation"; } diff --git a/Test/Attestation/AndroidKey.cs b/Test/Attestation/AndroidKey.cs index 7fcc8d30..f8a48890 100644 --- a/Test/Attestation/AndroidKey.cs +++ b/Test/Attestation/AndroidKey.cs @@ -122,38 +122,46 @@ public async Task TestAndroidKeySigByteStringZeroLen() } [Fact] - public void TestAndroidKeyMissingX5c() + public async Task TestAndroidKeyMissingX5c() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", CborNull.Instance); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in android-key attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AndroidKeyAttestation, ex.Message); } [Fact] - public void TestAndroidKeyX5cNotArray() + public async Task TestAndroidKeyX5cNotArray() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", new CborTextString("boomerang")); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in android-key attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AndroidKeyAttestation, ex.Message); } [Fact] - public void TestAndroidKeyX5cValueNotByteString() + public async Task TestAndroidKeyX5cValueNotByteString() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", new CborTextString("x")); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in android-key attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AndroidKeyAttestation, ex.Message); } [Fact] - public void TestAndroidKeyX5cValueZeroLengthByteString() + public async Task TestAndroidKeyX5cValueZeroLengthByteString() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", new CborArray { Array.Empty() }); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in android-key attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AndroidKeyAttestation, ex.Message); } [Fact] diff --git a/Test/Attestation/Apple.cs b/Test/Attestation/Apple.cs index 9c68daa4..1ed3bc96 100644 --- a/Test/Attestation/Apple.cs +++ b/Test/Attestation/Apple.cs @@ -76,49 +76,57 @@ public Apple() } [Fact] - public void TestAppleMissingX5c() + public async Task TestAppleMissingX5c() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", CborNull.Instance); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in Apple attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AppleAttestation, ex.Message); } [Fact] - public void TestAppleX5cNotArray() + public async Task TestAppleX5cNotArray() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", new CborTextString("boomerang")); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in Apple attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AppleAttestation, ex.Message); } [Fact] - public void TestAppleX5cCountNotOne() + public async Task TestAppleX5cCountNotOne() { var emptyX5c = new CborArray { new byte[0], new byte[0] }; var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", emptyX5c); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in Apple attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AppleAttestation, ex.Message); } [Fact] - public void TestAppleX5cValueNotByteString() + public async Task TestAppleX5cValueNotByteString() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", new CborTextString("x")); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in Apple attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AppleAttestation, ex.Message); } [Fact] - public void TestAppleX5cValueZeroLengthByteString() + public async Task TestAppleX5cValueZeroLengthByteString() { var attStmt = (CborMap)_attestationObject["attStmt"]; attStmt.Set("x5c", new CborArray { new byte[0] }); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in Apple attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_AppleAttestation, ex.Message); } [Fact] diff --git a/Test/Attestation/Packed.cs b/Test/Attestation/Packed.cs index 8d397985..7d7c9655 100644 --- a/Test/Attestation/Packed.cs +++ b/Test/Attestation/Packed.cs @@ -816,7 +816,7 @@ public void TestFullAttCertNotV3() } [Fact] - public void TestFullAttCertSubject() + public async Task TestFullAttCertSubject() { var (type, alg, curve) = Fido2Tests._validCOSEParameters[0]; X509Certificate2 attestnCert; @@ -860,8 +860,10 @@ public void TestFullAttCertSubject() { "x5c", x5c } }); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Invalid attestation cert subject", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal(Fido2ErrorMessages.InvalidAttestationCertSubject, ex.Message); } [Fact] @@ -917,7 +919,7 @@ public async void TestAttCertSubjectCommaAsync() } [Fact] - public void TestFullAttCertAaguidNotMatchAuthdata() + public async Task TestFullAttCertAaguidNotMatchAuthdata() { var (type, alg, curve) = Fido2Tests._validCOSEParameters[0]; X509Certificate2 attestnCert; @@ -964,8 +966,10 @@ public void TestFullAttCertAaguidNotMatchAuthdata() { "x5c", x5c } }); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("aaguid present in packed attestation cert exts but does not match aaguid from authData", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + + Assert.Equal(Fido2ErrorCode.InvalidAttestation, ex.Code); + Assert.Equal("aaguid present in packed attestation cert exts but does not match aaguid from authData", ex.Message); } [Fact] diff --git a/Test/Attestation/Tpm.cs b/Test/Attestation/Tpm.cs index 376a95c8..c295b895 100644 --- a/Test/Attestation/Tpm.cs +++ b/Test/Attestation/Tpm.cs @@ -6,6 +6,7 @@ using Fido2NetLib; using Fido2NetLib.Cbor; +using Fido2NetLib.Exceptions; using Fido2NetLib.Objects; using static Fido2NetLib.DataHelper; @@ -3647,7 +3648,7 @@ public void TestTPMX5cCountZero() } [Fact] - public void TestTPMX5cValuesNull() + public async Task TestTPMX5cValuesNull() { var (type, alg, _) = Fido2Tests._validCOSEParameters[3]; @@ -3740,8 +3741,8 @@ public void TestTPMX5cValuesNull() { "pubArea", pubArea } }); - var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in TPM attestation", ex.Result.Message); + var ex = await Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_TpmAttestation, ex.Message); } [Fact] @@ -3840,7 +3841,7 @@ public void TestTPMX5cValuesCountZero() var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in TPM attestation", ex.Result.Message); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_TpmAttestation, ex.Result.Message); } [Fact] @@ -3938,7 +3939,7 @@ public void TestTPMFirstX5cValueNotByteString() }); var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in TPM attestation", ex.Result.Message); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_TpmAttestation, ex.Result.Message); } [Fact] @@ -4036,7 +4037,7 @@ public void TestTPMFirstX5cValueByteStringZeroLen() }); var ex = Assert.ThrowsAsync(() => MakeAttestationResponseAsync()); - Assert.Equal("Malformed x5c in TPM attestation", ex.Result.Message); + Assert.Equal(Fido2ErrorMessages.MalformedX5c_TpmAttestation, ex.Result.Message); } [Fact]