Skip to content

Commit 735a90d

Browse files
committed
Added new test cases for invalid signature and for inaccessiable JWKS.
1 parent fd27f5d commit 735a90d

3 files changed

Lines changed: 89 additions & 11 deletions

File tree

SmartHealthCard.Test/SmartHealthCardDecoderTest.cs

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
using SmartHealthCard.Test.Serializers;
44
using SmartHealthCard.Test.Support;
55
using SmartHealthCard.Token;
6+
using SmartHealthCard.Token.Exceptions;
67
using SmartHealthCard.Token.Model.Shc;
78
using SmartHealthCard.Token.Providers;
89
using System;
910
using System.Collections.Generic;
1011
using System.Security.Cryptography.X509Certificates;
12+
using System.Threading.Tasks;
1113
using Xunit;
1214

1315
namespace SmartHealthCard.Test
@@ -26,7 +28,7 @@ public async void Decode_Token_Verify_with_JWKS()
2628

2729
//The base of the URL where a validator will retrieve the public keys from (e.g : [Issuer]/.well-known/jwks.json)
2830
Uri Issuer = new Uri("https://sonichealthcare.com/something");
29-
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidExampleOneAsync(Certificate, Issuer);
31+
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidDetectedExampleOneAsync(Certificate, Issuer);
3032

3133
//This testing JwksSupport class provides us with a mocked IJwksProvider that will inject the JWKS file
3234
//rather than make the HTTP call to go get it from a public endpoint.
@@ -53,7 +55,7 @@ public async void Decode_Token_Verify_with_Certificate()
5355

5456
//The base of the URL where a validator will retrieve the public keys from (e.g : [Issuer]/.well-known/jwks.json)
5557
Uri Issuer = new Uri("https://sonichealthcare.com/something");
56-
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidExampleOneAsync(Certificate, Issuer);
58+
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidDetectedExampleOneAsync(Certificate, Issuer);
5759

5860
//This testing JwksSupport class provides us with a mocked IJwksProvider that will inject the JWKS file
5961
//rather than make the HTTP call to go get it from a public endpoint.
@@ -82,7 +84,15 @@ public async void Decode_Token_Verify_InvalidTokenSignature_Certificate()
8284

8385
//The base of the URL where a validator will retrieve the public keys from (e.g : [Issuer]/.well-known/jwks.json)
8486
Uri Issuer = new Uri("https://sonichealthcare.com/something");
85-
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidExampleOneAsync(Certificate, Issuer);
87+
88+
string SmartHealthCardJwsTokenCovidDetected = await SmartHealthCardJwsSupport.GetJWSCovidDetectedExampleOneAsync(Certificate, Issuer);
89+
string SmartHealthCardJwsTokenCovidNotDetected = await SmartHealthCardJwsSupport.GetJWSCovidNotDetectedExampleOneAsync(Certificate, Issuer);
90+
91+
//Here we have taken the Payload of a NotDetected Covid test result and substituted it into
92+
//a token build with a Detected Covid Test result, so the signature is now be invalid for it's payload.
93+
string[] JWSSplitCovidNotDetected = SmartHealthCardJwsTokenCovidNotDetected.Split('.');
94+
string[] JWSSplitCovidDetected = SmartHealthCardJwsTokenCovidDetected.Split('.');
95+
string FraudulentSmartHealthCardJwsToken = string.Join('.', JWSSplitCovidDetected[0], JWSSplitCovidNotDetected[1], JWSSplitCovidDetected[2]);
8696

8797
//This testing JwksSupport class provides us with a mocked IJwksProvider that will inject the JWKS file
8898
//rather than make the HTTP call to go get it from a public endpoint.
@@ -94,12 +104,47 @@ public async void Decode_Token_Verify_InvalidTokenSignature_Certificate()
94104
//### Act #######################################################
95105

96106
//Verify and Decode
97-
SmartHealthCardModel SmartHealthCardModel = await Decoder.DecodeAsync(SmartHealthCardJwsToken, Verify: true);
107+
SmartHealthCardSignatureInvalidException Exec = await Assert.ThrowsAsync<SmartHealthCardSignatureInvalidException>(() => Decoder.DecodeAsync(FraudulentSmartHealthCardJwsToken, Verify: true));
98108

99109
//### Assert #######################################################
110+
Assert.Equal("The JWS signing signature is invalid.", Exec.Message);
111+
112+
}
113+
114+
[Fact]
115+
public async void Decode_Token_Verify_JWKS_Is_Inaccessible()
116+
{
117+
//### Prepare ######################################################
118+
//Get the ECC certificate from the Cert and Private key PEM files
119+
X509Certificate2 Certificate = CertificateSupport.GetCertificateFromPemFiles();
120+
121+
//The base of the URL where a validator will retrieve the public keys from (e.g : [Issuer]/.well-known/jwks.json)
122+
Uri Issuer = new Uri("https://sonichealthcare.com/something");
123+
124+
string SmartHealthCardJwsTokenCovidDetected = await SmartHealthCardJwsSupport.GetJWSCovidDetectedExampleOneAsync(Certificate, Issuer);
125+
string SmartHealthCardJwsTokenCovidNotDetected = await SmartHealthCardJwsSupport.GetJWSCovidNotDetectedExampleOneAsync(Certificate, Issuer);
126+
127+
//Here we have taken the Payload of a NotDetected Covid test result and substituted it into
128+
//a token build with a Detected Covid Test result, so the signature is now be invalid for it's payload.
129+
string[] JWSSplitCovidNotDetected = SmartHealthCardJwsTokenCovidNotDetected.Split('.');
130+
string[] JWSSplitCovidDetected = SmartHealthCardJwsTokenCovidDetected.Split('.');
131+
string FraudulentSmartHealthCardJwsToken = string.Join('.', JWSSplitCovidDetected[0], JWSSplitCovidNotDetected[1], JWSSplitCovidDetected[2]);
132+
133+
//This testing JwksSupport class provides us with a mocked IJwksProvider that will inject the JWKS file
134+
//rather than make the HTTP call to go get it from a public endpoint.
135+
IJwksProvider MockedIJwksProvider = JwksSupport.GetMockedIJwksProvider(Certificate, Issuer);
136+
137+
//Instantiate the SmartHealthCard Decoder
138+
SmartHealthCardDecoder Decoder = new SmartHealthCardDecoder(MockedIJwksProvider);
139+
140+
//### Act #######################################################
141+
142+
//Verify and Decode
143+
SmartHealthCardSignatureInvalidException Exec = await Assert.ThrowsAsync<SmartHealthCardSignatureInvalidException>(() => Decoder.DecodeAsync(FraudulentSmartHealthCardJwsToken, Verify: true));
144+
145+
//### Assert #######################################################
146+
Assert.Equal("The JWS signing signature is invalid.", Exec.Message);
100147

101-
Assert.True(!string.IsNullOrWhiteSpace(SmartHealthCardJwsToken));
102-
Assert.NotNull(SmartHealthCardModel);
103148
}
104149

105150

SmartHealthCard.Test/Support/SmartHealthCardJwsSupport.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,40 @@ namespace SmartHealthCard.Test.Support
1414
{
1515
public static class SmartHealthCardJwsSupport
1616
{
17-
public static async Task<string> GetJWSCovidExampleOneAsync(X509Certificate2 Certificate, Uri Issuer)
17+
public static async Task<string> GetJWSCovidNotDetectedExampleOneAsync(X509Certificate2 Certificate, Uri Issuer)
18+
{
19+
//The Version of FHIR in use
20+
string FhirVersion = "4.0.1";
21+
22+
//Get FHIR bundle
23+
Bundle FhirBundleResource = FhirDataSupport.GetCovid19NotDetectedFhirBundleExample();
24+
string FhirBundleJson = FhirSerializer.SerializeToJson(FhirBundleResource);
25+
26+
//When the Smart Health Card became valid, the from date.
27+
DateTimeOffset IssuanceDateTimeOffset = DateTimeOffset.Now.AddMinutes(-1);
28+
29+
//The Uri for the type of VerifiableCredentials
30+
// Uri VerifiableCredentialType = new Uri("https://smarthealth.cards#covid19");
31+
List<VerifiableCredentialType> VerifiableCredentialTypeList = new List<VerifiableCredentialType>()
32+
{
33+
VerifiableCredentialType.HealthCard,
34+
VerifiableCredentialType.Covid19
35+
};
36+
37+
//Create the SmartHealthCardModel
38+
SmartHealthCardModel SmartHealthCardToEncode = new SmartHealthCardModel(Issuer, IssuanceDateTimeOffset,
39+
new VerifiableCredential(VerifiableCredentialTypeList,
40+
new CredentialSubject(FhirVersion, FhirBundleJson)));
41+
42+
//Instantiate the SmartHealthCard Encoder
43+
SmartHealthCardEncoder SmartHealthCardEncoder = new SmartHealthCardEncoder();
44+
45+
//Get the Smart Health Card JWS Token
46+
return await SmartHealthCardEncoder.GetTokenAsync(Certificate, SmartHealthCardToEncode);
47+
48+
}
49+
50+
public static async Task<string> GetJWSCovidDetectedExampleOneAsync(X509Certificate2 Certificate, Uri Issuer)
1851
{
1952
//The Version of FHIR in use
2053
string FhirVersion = "4.0.1";

SmartHealthCard.Test/TestSmartHealthCardJwsDecoder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public async void Test_JwksProviderReturningRetries()
2626

2727
//The base of the URL where a validator will retrieve the public keys from (e.g : [Issuer]/.well-known/jwks.json)
2828
Uri Issuer = new Uri("https://sonichealthcare.com/something");
29-
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidExampleOneAsync(Certificate, Issuer);
29+
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidDetectedExampleOneAsync(Certificate, Issuer);
3030

3131
//This MockedRetryIJwksProvider only retunes a retry, it does not retuns a JWKS
3232
//IJwksProvider MockedRetryIJwksProvider = JwksSupport.GetMockedRetryIJwksProvider(Certificate,Issuer);
@@ -42,9 +42,9 @@ public async void Test_JwksProviderReturningRetries()
4242

4343
//### Assert #######################################################
4444

45-
var exception = await Assert.ThrowsAsync<SmartHealthCardDecoderException>(Act);
45+
var exception = await Assert.ThrowsAsync<SmartHealthCardJwksRequestException>(Act);
4646
Assert.StartsWith("Unable to obtain the JsonWebKeySet (JWKS) from :", exception.Message);
47-
Assert.Contains("Atempt 1 after", exception.Message);
47+
Assert.Contains("Attempt 1 after", exception.Message);
4848
}
4949
}
5050
public class TestSmartHealthCardJwsDecoderTwo
@@ -58,7 +58,7 @@ public async void Test_JwksProviderReturningRetriesFollowedBySuccess()
5858

5959
//The base of the URL where a validator will retrieve the public keys from (e.g : [Issuer]/.well-known/jwks.json)
6060
Uri Issuer = new Uri("https://sonichealthcare.com/something");
61-
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidExampleOneAsync(Certificate, Issuer);
61+
string SmartHealthCardJwsToken = await SmartHealthCardJwsSupport.GetJWSCovidDetectedExampleOneAsync(Certificate, Issuer);
6262

6363
//This MockedRetryIJwksProvider only retunes a retry, it does not retuns a JWKS
6464
//IJwksProvider MockedRetryIJwksProvider = JwksSupport.GetMockedRetryIJwksProvider(Certificate,Issuer);

0 commit comments

Comments
 (0)