From 89fa29bf1cff62a79108679e96f323863153d868 Mon Sep 17 00:00:00 2001 From: Yann Crumeyrolle Date: Sun, 21 Jul 2024 22:11:26 +0200 Subject: [PATCH] Add some tests for #581, already fixed in #569 (#584) --- .../Cryptography/EllipticalCurves.cs | 13 +++++++++++++ src/JsonWebToken/Jwk.cs | 19 +++---------------- src/JsonWebToken/PasswordBasedJwk.cs | 2 +- test/JsonWebToken.Tests/ECJwkTests.cs | 16 +++++++++++----- test/JsonWebToken.Tests/JwkTestsBase.cs | 2 +- .../PasswordBasedJwkTests.cs | 12 ++++++++---- test/JsonWebToken.Tests/RsaJwkTests.cs | 13 ++++++++++--- test/JsonWebToken.Tests/SymmetricJwkTests.cs | 7 +++++-- 8 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/JsonWebToken/Cryptography/EllipticalCurves.cs b/src/JsonWebToken/Cryptography/EllipticalCurves.cs index 792ca287..f613174f 100644 --- a/src/JsonWebToken/Cryptography/EllipticalCurves.cs +++ b/src/JsonWebToken/Cryptography/EllipticalCurves.cs @@ -110,6 +110,19 @@ public static EllipticalCurve FromString(string crv) return curve; } + + /// Cast the into its representation. + public static explicit operator EllipticalCurve?(string? value) + { + if (value is null) + { + return null; + } + + return FromString(value); ; + } + + /// Tries to parse a into a . public static bool TryParse(string crv, [NotNullWhen(true)] out EllipticalCurve? curve) { diff --git a/src/JsonWebToken/Jwk.cs b/src/JsonWebToken/Jwk.cs index 173b44d2..c8689ec9 100644 --- a/src/JsonWebToken/Jwk.cs +++ b/src/JsonWebToken/Jwk.cs @@ -641,22 +641,9 @@ public bool TryGetKeyUnwrapper(EncryptionAlgorithm? encryptionAlgorithm, KeyMana public byte[] Canonicalize() { int size = GetCanonicalizeSize(); - byte[]? arrayToReturn = null; - try - { - Span buffer = size > Constants.MaxStackallocBytes - ? (arrayToReturn = ArrayPool.Shared.Rent(size)) - : stackalloc byte[size]; - Canonicalize(buffer); - return buffer.Slice(0, size).ToArray(); - } - finally - { - if (arrayToReturn != null) - { - ArrayPool.Shared.Return(arrayToReturn); - } - } + var buffer = new byte[size]; + Canonicalize(buffer); + return buffer; } /// Compute the normal form, as defined by https://tools.ietf.org/html/rfc7638#section-3.2, and writes it to the . diff --git a/src/JsonWebToken/PasswordBasedJwk.cs b/src/JsonWebToken/PasswordBasedJwk.cs index 93ec5080..f8f5cb5a 100644 --- a/src/JsonWebToken/PasswordBasedJwk.cs +++ b/src/JsonWebToken/PasswordBasedJwk.cs @@ -84,7 +84,7 @@ public static PasswordBasedJwk FromPassphrase(string passphrase, KeyManagementAl ThrowHelper.ThrowArgumentNullException(ExceptionArgument.bytes); } - var innerKey = SymmetricJwk.FromByteArray(Utf8.GetBytes(passphrase), algorithm, computeThumbprint); + var innerKey = SymmetricJwk.FromByteArray(Utf8.GetBytes(passphrase), computeThumbprint); return new PasswordBasedJwk(innerKey, iterationCount, saltSizeInBytes, algorithm); } diff --git a/test/JsonWebToken.Tests/ECJwkTests.cs b/test/JsonWebToken.Tests/ECJwkTests.cs index 32b50512..b8adbbf2 100644 --- a/test/JsonWebToken.Tests/ECJwkTests.cs +++ b/test/JsonWebToken.Tests/ECJwkTests.cs @@ -142,7 +142,7 @@ public void Equal(EllipticalCurve crv) key.Kid = JsonEncodedText.Encode("X"); copiedKey.Kid = JsonEncodedText.Encode("Y"); Assert.NotEqual(key, copiedKey); - + Assert.NotEqual(key, Jwk.None); } @@ -180,15 +180,21 @@ public override Signer CreateSigner_Failed(Jwk key, SignatureAlgorithm alg) return base.CreateSigner_Failed(key, alg); } - [Fact] - public override void Canonicalize() + [Theory] + [InlineData("ES256")] + [InlineData("ES384")] + [InlineData("ES512")] + [InlineData("ES256K")] + public override void Canonicalize(string alg) { - var jwk = ECJwk.GeneratePrivateKey(SignatureAlgorithm.ES256); + var jwk = ECJwk.GeneratePrivateKey((SignatureAlgorithm)alg); var canonicalizedKey = (ECJwk)CanonicalizeKey(jwk); Assert.True(canonicalizedKey.D.IsEmpty); + bool supported = EllipticalCurve.TryGetSupportedCurve((SignatureAlgorithm)alg, out var crv); - Assert.Equal(EllipticalCurve.P256.Id, canonicalizedKey.Crv.Id); + Assert.True(supported); + Assert.Equal(crv.Id, canonicalizedKey.Crv.Id); Assert.False(canonicalizedKey.X.IsEmpty); Assert.False(canonicalizedKey.Y.IsEmpty); } diff --git a/test/JsonWebToken.Tests/JwkTestsBase.cs b/test/JsonWebToken.Tests/JwkTestsBase.cs index 02f1c18b..8f665e97 100644 --- a/test/JsonWebToken.Tests/JwkTestsBase.cs +++ b/test/JsonWebToken.Tests/JwkTestsBase.cs @@ -47,7 +47,7 @@ public virtual Signer CreateSigner_Failed(Jwk key, SignatureAlgorithm alg) return signer; } - public abstract void Canonicalize(); + public abstract void Canonicalize(string alg); public Jwk CanonicalizeKey(Jwk key) { diff --git a/test/JsonWebToken.Tests/PasswordBasedJwkTests.cs b/test/JsonWebToken.Tests/PasswordBasedJwkTests.cs index 80e2336b..7fe0e79d 100644 --- a/test/JsonWebToken.Tests/PasswordBasedJwkTests.cs +++ b/test/JsonWebToken.Tests/PasswordBasedJwkTests.cs @@ -28,7 +28,7 @@ public void Equal() key.Kid = JsonEncodedText.Encode("X"); copiedKey.Kid = JsonEncodedText.Encode("Y"); Assert.NotEqual(key, copiedKey); - + Assert.NotEqual(key, Jwk.None); } @@ -39,10 +39,14 @@ public override KeyWrapper CreateKeyWrapper_Succeed(Jwk key, EncryptionAlgorithm return base.CreateKeyWrapper_Succeed(key, enc, alg); } - [Fact] - public override void Canonicalize() + [Theory] + [InlineData("PBES2-HS256+A128KW")] + [InlineData("PBES2-HS384+A192KW")] + [InlineData("PBES2-HS512+A256KW")] + public override void Canonicalize(string alg) { - var jwk = PasswordBasedJwk.FromPassphrase("Thus from my lips, by yours, my sin is purged."); + var jwk = PasswordBasedJwk.FromPassphrase("Thus from my lips, by yours, my sin is purged.", (KeyManagementAlgorithm)alg); // something is wrong here... how to provide the PBES alg ? + //var jwk = PasswordBasedJwk.FromPassphrase("Thus from my lips, by yours, my sin is purged."); // something is wrong here... how to provide the PBES alg ? var canonicalizedKey = (SymmetricJwk)CanonicalizeKey(jwk); Assert.NotEmpty(canonicalizedKey.ToArray()); } diff --git a/test/JsonWebToken.Tests/RsaJwkTests.cs b/test/JsonWebToken.Tests/RsaJwkTests.cs index 0b6726cc..4ea3fa10 100644 --- a/test/JsonWebToken.Tests/RsaJwkTests.cs +++ b/test/JsonWebToken.Tests/RsaJwkTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.Contracts; using System.Numerics; using System.Security.Cryptography; using System.Text; @@ -286,10 +287,16 @@ public override Signer CreateSigner_Succeed(Jwk key, SignatureAlgorithm alg) return base.CreateSigner_Succeed(key, alg); } - [Fact] - public override void Canonicalize() + [Theory] + [InlineData("RS256")] + [InlineData("RS384")] + [InlineData("RS512")] + [InlineData("PS256")] + [InlineData("PS384")] + [InlineData("PS512")] + public override void Canonicalize(string alg) { - var jwk = RsaJwk.GeneratePrivateKey(2048, SignatureAlgorithm.RS256); + var jwk = RsaJwk.GeneratePrivateKey(2048, (SignatureAlgorithm)alg); var canonicalizedKey = (RsaJwk)CanonicalizeKey(jwk); Assert.False(canonicalizedKey.E.IsEmpty); Assert.False(canonicalizedKey.N.IsEmpty); diff --git a/test/JsonWebToken.Tests/SymmetricJwkTests.cs b/test/JsonWebToken.Tests/SymmetricJwkTests.cs index 5a03ece2..99c61925 100644 --- a/test/JsonWebToken.Tests/SymmetricJwkTests.cs +++ b/test/JsonWebToken.Tests/SymmetricJwkTests.cs @@ -46,8 +46,11 @@ public override Signer CreateSigner_Succeed(Jwk key, SignatureAlgorithm alg) return base.CreateSigner_Succeed(key, alg); } - [Fact] - public override void Canonicalize() + [Theory] + [InlineData("HS256")] + [InlineData("HS384")] + [InlineData("HS512")] + public override void Canonicalize(string alg) { var jwk = SymmetricJwk.GenerateKey(SignatureAlgorithm.HS256); var canonicalizedKey = (SymmetricJwk)CanonicalizeKey(jwk);