Skip to content

Commit 8016504

Browse files
authored
Implement OID4VP for mdocs (#157)
* adjust OID4VP signatures Signed-off-by: Kevin <kevin.dinh@lissi.id> * adjust ICredential Signed-off-by: Kevin <kevin.dinh@lissi.id> * implement base64url type Signed-off-by: Kevin <kevin.dinh@lissi.id> * refactorings Signed-off-by: Kevin <kevin.dinh@lissi.id> * adjust mdoc lib folder structure Signed-off-by: Kevin <kevin.dinh@lissi.id> * rename namespaces to issuer namespaces Signed-off-by: Kevin <kevin.dinh@lissi.id> * security stuff in core project Signed-off-by: Kevin <kevin.dinh@lissi.id> * add keyId to MdocRecord Signed-off-by: Kevin <kevin.dinh@lissi.id> * add comments to ClientMetadata.cs Signed-off-by: Kevin <kevin.dinh@lissi.id> * implement mdoc presentation Signed-off-by: Kevin <kevin.dinh@lissi.id> * implement mdoc oid4vp Signed-off-by: Kevin <kevin.dinh@lissi.id> * adjust tests Signed-off-by: Kevin <kevin.dinh@lissi.id> * some cleanup Signed-off-by: Kevin <kevin.dinh@lissi.id> * bump dotnet version in pipeline Signed-off-by: Kevin <kevin.dinh@lissi.id> * bump nuget version in pipeline Signed-off-by: Kevin <kevin.dinh@lissi.id> * bump nuget version in pipeline Signed-off-by: Kevin <kevin.dinh@lissi.id> * bump nuget version in pipeline Signed-off-by: Kevin <kevin.dinh@lissi.id> * minor refactor Signed-off-by: Kevin <kevin.dinh@lissi.id> * fix merge Signed-off-by: Kevin <kevin.dinh@lissi.id> * rename SdJwtSignerService to SdJwtSigner Signed-off-by: Kevin <kevin.dinh@lissi.id> * introduce raw signature Signed-off-by: Kevin <kevin.dinh@lissi.id> * fix merge Signed-off-by: Kevin <kevin.dinh@lissi.id> * adjust cose signature Signed-off-by: Kevin <kevin.dinh@lissi.id> * add string funcs Signed-off-by: Kevin <kevin.dinh@lissi.id> --------- Signed-off-by: Kevin <kevin.dinh@lissi.id>
1 parent 84031a1 commit 8016504

File tree

122 files changed

+2511
-1418
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+2511
-1418
lines changed

.github/workflows/publish-nuget.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,17 @@ jobs:
3838
echo "APP_VERSION=$VERSION$SUFFIX" >> $GITHUB_ENV
3939
4040
- name: Setup NuGet
41-
uses: NuGet/setup-nuget@v1.0.5
41+
uses: NuGet/setup-nuget@v2
42+
with:
43+
nuget-version: 6.10.2
4244

4345
- name: Restore dependencies
4446
run: nuget restore $SOLUTION
4547

4648
- name: Setup .NET
4749
uses: actions/setup-dotnet@v3
4850
with:
49-
dotnet-version: 3.1.*
51+
dotnet-version: 8.0.*
5052

5153
# - name: Install libindy library
5254
# run: |

src/Hyperledger.Aries/Storage/Models/Interfaces/ICredential.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Microsoft.IdentityModel.Tokens;
2+
3+
namespace WalletFramework.Core.Base64Url;
4+
5+
public readonly struct Base64UrlString
6+
{
7+
private string Value { get; }
8+
9+
private Base64UrlString(string value)
10+
{
11+
Value = value;
12+
}
13+
14+
public override string ToString() => Value;
15+
16+
public static implicit operator string(Base64UrlString base64UrlString) => base64UrlString.ToString();
17+
18+
public static Base64UrlString CreateBase64UrlString(IEnumerable<byte> base64UrlBytes)
19+
{
20+
var result = Base64UrlEncoder.Encode(base64UrlBytes.ToArray());
21+
return new Base64UrlString(result);
22+
}
23+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace WalletFramework.Core.Credentials.Abstractions;
2+
3+
/// <summary>
4+
/// This interface is used to represent a credential.
5+
/// </summary>
6+
public interface ICredential
7+
{
8+
CredentialId GetId();
9+
}

src/WalletFramework.Core/Cryptography/Abstractions/IKeyStore.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,21 @@ public interface IKeyStore
1818
Task<KeyId> GenerateKey(string alg = "ES256", bool isPermanent = true);
1919

2020
/// <summary>
21-
/// Asynchronously loads a key by its identifier and returns it as a JSON Web Key (JWK) containing the public key
22-
/// information.
21+
/// Gets the public key of the pair
2322
/// </summary>
24-
/// <param name="keyId">The identifier of the key to load.</param>
25-
/// <returns>A <see cref="Task{TResult}" /> representing the loaded key as a JWK string.</returns>
26-
Task<string> LoadKey(KeyId keyId);
23+
/// <param name="keyId">The identifier of the key pair.</param>
24+
/// <returns>
25+
/// The public key
26+
/// </returns>
27+
Task<PublicKey> GetPublicKey(KeyId keyId);
2728

2829
/// <summary>
2930
/// Asynchronously signs the given payload using the key identified by the provided key ID.
3031
/// </summary>
3132
/// <param name="keyId">The identifier of the key to use for signing.</param>
3233
/// <param name="payload">The payload to sign.</param>
3334
/// <returns>A <see cref="Task{TResult}" /> representing the signed payload as a byte array.</returns>
34-
Task<byte[]> Sign(KeyId keyId, byte[] payload);
35+
Task<RawSignature> Sign(KeyId keyId, byte[] payload);
3536

3637
/// <summary>
3738
/// Asynchronously deletes the key associated with the provided key ID.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
using WalletFramework.Core.Functional;
2+
3+
namespace WalletFramework.Core.Cryptography.Errors;
4+
5+
public record InvalidSignatureError(string Message, Exception E) : Error(Message, E);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using WalletFramework.Core.Base64Url;
2+
3+
namespace WalletFramework.Core.Cryptography.Models;
4+
5+
public record PublicKey(Base64UrlString X, Base64UrlString Y)
6+
{
7+
public string KeyType => "EC";
8+
9+
public string Curve => "P-256";
10+
}
11+
12+
public static class PublicKeyFun
13+
{
14+
public static object ToJwkObj(this PublicKey publicKey) => new
15+
{
16+
kty = publicKey.KeyType,
17+
crv = publicKey.Curve,
18+
x = publicKey.X.ToString(),
19+
y = publicKey.Y.ToString()
20+
};
21+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using Org.BouncyCastle.Asn1;
2+
using WalletFramework.Core.Cryptography.Errors;
3+
using WalletFramework.Core.Functional;
4+
5+
namespace WalletFramework.Core.Cryptography.Models;
6+
7+
public readonly struct RawSignature
8+
{
9+
private byte[] Value { get; }
10+
11+
public byte[] AsByteArray => Value;
12+
13+
public RawSignature(byte[] value)
14+
{
15+
Value = value;
16+
}
17+
18+
public static implicit operator byte[](RawSignature signature) => signature.AsByteArray;
19+
20+
public static Validation<RawSignature> FromDerSignature(byte[] derSignature)
21+
{
22+
try
23+
{
24+
var seq = (Asn1Sequence)Asn1Object.FromByteArray(derSignature);
25+
var r = ((DerInteger)seq[0]).Value;
26+
var s = ((DerInteger)seq[1]).Value;
27+
var rBytes = r.ToByteArrayUnsigned();
28+
var sBytes = s.ToByteArrayUnsigned();
29+
rBytes = PadTo32Bytes(rBytes);
30+
sBytes = PadTo32Bytes(sBytes);
31+
32+
var signatureBytes = rBytes.Concat(sBytes).ToArray();
33+
return new RawSignature(signatureBytes);
34+
}
35+
catch (Exception e)
36+
{
37+
return new InvalidSignatureError("The signature could not be transformed to RAW format", e);
38+
}
39+
}
40+
41+
private static byte[] PadTo32Bytes(byte[] value)
42+
{
43+
if (value.Length == 32)
44+
return value;
45+
46+
if (value.Length > 32)
47+
throw new ArgumentException("Value is too large to fit in 32 bytes");
48+
49+
var padded = new byte[32];
50+
Array.Copy(value, 0, padded, 32 - value.Length, value.Length);
51+
return padded;
52+
}
53+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Security.Cryptography;
2+
3+
namespace WalletFramework.Core.Encoding;
4+
5+
public readonly struct Sha256Hash
6+
{
7+
private byte[] Value { get; }
8+
9+
private Sha256Hash(byte[] value)
10+
{
11+
Value = value;
12+
}
13+
14+
public byte[] AsBytes => Value;
15+
16+
public override string ToString() => Value.ToString();
17+
18+
public static implicit operator byte[](Sha256Hash sha256Hash) => sha256Hash.Value;
19+
20+
public static Sha256Hash ComputeHash(byte[] value)
21+
{
22+
var sha256 = SHA256.Create();
23+
var hash = sha256.ComputeHash(value);
24+
return new Sha256Hash(hash);
25+
}
26+
}
27+

src/WalletFramework.Core/Functional/OptionFun.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,14 @@ public static Option<IEnumerable<TR>> TraverseAny<T, TR>(
8888
return list.Any() ? list : Option<IEnumerable<TR>>.None;
8989
});
9090
}
91-
91+
92+
public static Option<IEnumerable<T>> AsOption<T>(this IEnumerable<T> enumerable) =>
93+
// ReSharper disable once PossibleMultipleEnumeration
94+
enumerable.IsEmpty()
95+
? Option<IEnumerable<T>>.None
96+
// ReSharper disable once PossibleMultipleEnumeration
97+
: Some(enumerable);
98+
9299
public static T UnwrapOrThrow<T>(this Option<T> option, Exception e) =>
93100
option.Match(
94101
t => t,

0 commit comments

Comments
 (0)