Skip to content

Commit b4e0f8b

Browse files
committed
A lot of refactoring around error handing using the Result class
1 parent 1a50deb commit b4e0f8b

36 files changed

Lines changed: 434 additions & 335 deletions

SmartHealthCard.Test/SmartHealthCardEncoderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public async void Create_Token_Decode_Token()
7171
Assert.True(!string.IsNullOrWhiteSpace(SmartHealthCardJwsToken));
7272

7373

74-
SmartHealthCardModel DecodedSmartHealthCardModle = await Decoder .DecodeAsync(SmartHealthCardJwsToken, Verify: true);
74+
SmartHealthCardModel DecodedSmartHealthCardModle = await Decoder.DecodeAsync(SmartHealthCardJwsToken, Verify: true);
7575

7676
//Check the IssuanceDate as the same to seconds precision
7777
DateTimeOffset ActualIssuanceDate = DecodedSmartHealthCardModle.GetIssuanceDate();

SmartHealthCard.Test/SmartHealthCardJwksTest.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using SmartHealthCard.Token.Encoders;
1313
using System.IO;
1414
using System.Security.Cryptography;
15+
using SmartHealthCard.Token.Support;
1516

1617
namespace SmartHealthCard.Test
1718
{
@@ -38,8 +39,8 @@ public void Jwks_Json_get()
3839
string JwksJson = SmartHealthCardJwks.Get(CertificateList, Minified: false);
3940

4041
//Parse the JSON back to the model
41-
JsonWebKeySet JsonWebKeySet = JsonSerializer.FromJson<JsonWebKeySet>(JwksJson);
42-
42+
Result<JsonWebKeySet> JsonWebKeySetResult = JsonSerializer.FromJson<JsonWebKeySet>(JwksJson);
43+
JsonWebKeySet JsonWebKeySet = JsonWebKeySetResult.Value;
4344

4445
//### Assert #######################################################
4546
Assert.NotNull(JwksJson);

SmartHealthCard.Test/SmartHealthCardModelJsonSerializerTest.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using SmartHealthCard.Token.Serializers.Shc;
99
using SmartHealthCard.Token.Model.Shc;
1010
using SmartHealthCard.Token.Encoders;
11+
using SmartHealthCard.Token.Support;
1112

1213
namespace SmartHealthCard.Test
1314
{
@@ -22,8 +23,9 @@ public void Valid_SHC_Json()
2223

2324
//### Act ##########################################################
2425
JsonSerializer JsonSerializer = new JsonSerializer();
25-
SmartHealthCardModel SmartHealthCardModel = JsonSerializer.FromJson<SmartHealthCardModel>(SmartHealthCardCovidJson);
26-
26+
Result<SmartHealthCardModel> SmartHealthCardModelResult = JsonSerializer.FromJson<SmartHealthCardModel>(SmartHealthCardCovidJson);
27+
SmartHealthCardModel SmartHealthCardModel = SmartHealthCardModelResult.Value;
28+
2729
//### Assert #######################################################
2830

2931
Assert.Equal("1621444043.769", SmartHealthCardModel.IssuanceDate);

SmartHealthCard.Token/Algorithms/ES256Algorithm.cs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using SmartHealthCard.Token.Exceptions;
33
using SmartHealthCard.Token.Model.Jwks;
44
using SmartHealthCard.Token.Serializers.Json;
5+
using SmartHealthCard.Token.Support;
56
using System;
67
using System.Linq;
78
using System.Security.Cryptography;
@@ -54,42 +55,43 @@ public ES256Algorithm(ECDsa? PublicKey, ECDsa? PrivateKey, IJsonSerializer JsonS
5455

5556
private HashAlgorithmName HashAlgorithmName => HashAlgorithmName.SHA256;
5657

57-
public byte[] Sign(byte[] bytesToSign)
58+
public Result<byte[]> Sign(byte[] bytesToSign)
5859
{
5960
if (this.PrivateKey is null)
60-
throw new SignatureSigningException("Unable to sign as no private key has been provided.");
61+
return Result<byte[]>.Fail("Unable to sign as no private key has been provided.");
6162

62-
return this.PrivateKey.SignData(bytesToSign, this.HashAlgorithmName);
63+
return Result<byte[]>.Ok(this.PrivateKey.SignData(bytesToSign, this.HashAlgorithmName));
6364
}
64-
public bool Verify(byte[] bytesToSign, byte[] signature)
65+
66+
public Result<bool> Verify(byte[] bytesToSign, byte[] signature)
6567
{
6668
if (this.PublicKey is null)
67-
throw new SignatureSigningException("Unable to verify signature as no public key has been provided.");
69+
return Result<bool>.Fail("Unable to verify signature as no public key has been provided.");
6870

69-
return this.PublicKey.VerifyData(bytesToSign, signature, this.HashAlgorithmName);
71+
return Result<bool>.Ok(this.PublicKey.VerifyData(bytesToSign, signature, this.HashAlgorithmName));
7072
}
7173

72-
public string GetPointCoordinateX()
74+
public Result<string> GetPointCoordinateX()
7375
{
7476
if (this.PublicKey is null)
75-
throw new SignatureSigningException("Unable to obtain Point Coordinate X from public key as no public key has been provided.");
77+
return Result<string>.Fail("Unable to obtain Point Coordinate X from public key as no public key has been provided.");
7678

7779
ECParameters ECParameters = this.PublicKey.ExportExplicitParameters(false);
7880
if (ECParameters.Q.X is null)
7981
throw new NullReferenceException(nameof(ECParameters.Q.X));
8082

81-
return Base64UrlEncoder.Encode(ECParameters.Q.X);
83+
return Result<string>.Ok(Base64UrlEncoder.Encode(ECParameters.Q.X));
8284
}
83-
public string GetPointCoordinateY()
85+
public Result<string> GetPointCoordinateY()
8486
{
8587
if (this.PublicKey is null)
86-
throw new SignatureSigningException("Unable to obtain Point Coordinate Y from public key as no public key has been provided.");
88+
return Result<string>.Fail("Unable to obtain Point Coordinate Y from public key as no public key has been provided.");
8789

8890
ECParameters ECParameters = this.PublicKey.ExportExplicitParameters(false);
8991
if (ECParameters.Q.Y is null)
9092
throw new NullReferenceException(nameof(ECParameters.Q.Y));
9193

92-
return Base64UrlEncoder.Encode(ECParameters.Q.Y);
94+
return Result<string>.Ok(Base64UrlEncoder.Encode(ECParameters.Q.Y));
9395
}
9496

9597
private static ECDsa? GetPrivateKey(X509Certificate2 cert)
@@ -108,12 +110,12 @@ public string GetPointCoordinateY()
108110
return cert.GetECDsaPublicKey();
109111
}
110112

111-
public static ES256Algorithm FromJWKS(string Kid, JsonWebKeySet JsonWebKeySet, IJsonSerializer JsonSerializer)
113+
public static Result<IAlgorithm> FromJWKS(string Kid, JsonWebKeySet JsonWebKeySet, IJsonSerializer JsonSerializer)
112114
{
113115
JsonWebKey? Key = JsonWebKeySet.Keys.Find(x => x.Kid.Equals(Kid, StringComparison.CurrentCulture));
114116
if (Key is null)
115-
throw new JsonWebKeySetException($"No key matching the token's header kid value of {Kid} found in the sourced JWKS file.");
116-
117+
return Result<IAlgorithm>.Fail($"No key matching the token's header kid value of: {Kid} could be found in the sourced Jason Web Key Set (JWKS) file.");
118+
117119
ECDsa PublicKey = ECDsa.Create(new ECParameters
118120
{
119121
Curve = ECCurve.NamedCurves.nistP256,
@@ -124,23 +126,32 @@ public static ES256Algorithm FromJWKS(string Kid, JsonWebKeySet JsonWebKeySet, I
124126
}
125127
});
126128

127-
return new ES256Algorithm(PublicKey: PublicKey, PrivateKey: null, JsonSerializer: JsonSerializer);
129+
return Result<IAlgorithm>.Ok(new ES256Algorithm(PublicKey: PublicKey, PrivateKey: null, JsonSerializer: JsonSerializer));
128130
}
129131

130-
public string GetKid()
132+
public Result<string> GetKid()
131133
{
132134
if (this.Certificate is null)
133-
throw new NullReferenceException("Unable to get certificate thumb-print as no certificate provided.");
135+
return Result<string>.Fail("Unable to get certificate thumb-print as no certificate provided.");
136+
137+
Result<string> PointCoordinateXResult = this.GetPointCoordinateX();
138+
Result<string> PointCoordinateYResult = this.GetPointCoordinateY();
139+
var CombinedResult = Result.Combine(PointCoordinateXResult, PointCoordinateYResult);
140+
if (CombinedResult.Failure)
141+
return Result<string>.Fail(CombinedResult.ErrorMessage);
134142

135143
var Intermediate = new JWKThumbprintComputationIntermediate(
136144
this.CurveName,
137145
this.KeyTypeName,
138-
this.GetPointCoordinateX(),
139-
this.GetPointCoordinateY());
146+
PointCoordinateXResult.Value,
147+
PointCoordinateYResult.Value);
140148

141-
string Json = JsonSerializer.ToJson(Intermediate, Minified: true);
142-
byte[] Bytes = Hashers.SHA256Hasher.GetSHA256Hash(Json);
143-
return Encoders.Base64UrlEncoder.Encode(Bytes);
149+
Result<string> ToJsonResult = JsonSerializer.ToJson(Intermediate, Minified: true);
150+
if (ToJsonResult.Failure)
151+
return ToJsonResult;
152+
153+
byte[] Bytes = Hashers.SHA256Hasher.GetSHA256Hash(ToJsonResult.Value);
154+
return Result<string>.Ok(Base64UrlEncoder.Encode(Bytes));
144155
}
145156
}
146157
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
namespace SmartHealthCard.Token.Algorithms
1+
using SmartHealthCard.Token.Support;
2+
3+
namespace SmartHealthCard.Token.Algorithms
24
{
35
public interface IAlgorithm
46
{
57
string Name { get; }
68
string KeyTypeName { get; }
79
string CurveName { get; }
8-
string GetKid();
9-
byte[] Sign(byte[] bytesToSign);
10-
bool Verify(byte[] bytesToSign, byte[] signature);
10+
Result<string> GetKid();
11+
Result<byte[]> Sign(byte[] bytesToSign);
12+
Result<bool> Verify(byte[] bytesToSign, byte[] signature);
1113
}
1214
}

SmartHealthCard.Token/Exceptions/InvalidTokenException.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace SmartHealthCard.Token.Exceptions
2+
{
3+
public class InvalidTokenPartsException : SmartHealthCardException
4+
{
5+
public InvalidTokenPartsException(string Message)
6+
: base(Message){ }
7+
}
8+
}

SmartHealthCard.Token/Exceptions/JsonWebKeySetException.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

SmartHealthCard.Token/Exceptions/SignatureSigningException.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

SmartHealthCard.Token/Exceptions/SignatureVerificationException.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)