Skip to content

Commit

Permalink
Ensure that JWS can be verified using public key information only
Browse files Browse the repository at this point in the history
  • Loading branch information
alexzautke committed Aug 15, 2024
1 parent 53b114d commit 0878eeb
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 15 deletions.
8 changes: 5 additions & 3 deletions CreativeCode.JWS.Tests/JwsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public void CompactJwsWithRsaSignatureCanBeSerialized()
var signature = parts.Last();
signature.Length.Should().BePositive("A JWS signature should be present");

VerifySignature(jwk, SigningInput(joseHeader, Encoding.UTF8.GetBytes("payload")), Base64urlDecode(signature)).Should().BeTrue();
var publicKey = new JWK.JWK(jwk.Export());
VerifySignature(publicKey, SigningInput(joseHeader, Encoding.UTF8.GetBytes("payload")), Base64urlDecode(signature)).Should().BeTrue();
}

[Fact]
Expand Down Expand Up @@ -110,8 +111,9 @@ public void CompactJwsWithEcSignatureCanBeSerialized()

var signature = parts.Last();
signature.Length.Should().BePositive("A JWS signature should be present");

VerifySignature(jwk, SigningInput(joseHeader, Encoding.UTF8.GetBytes("payload")), Base64urlDecode(signature)).Should().BeTrue();

var publicKey = new JWK.JWK(jwk.Export());
VerifySignature(publicKey, SigningInput(joseHeader, Encoding.UTF8.GetBytes("payload")), Base64urlDecode(signature)).Should().BeTrue();
}

[Fact]
Expand Down
63 changes: 51 additions & 12 deletions JWS/JWS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,47 @@ private static HashAlgorithmName TranslateRsaHashAlgorithm(Algorithm algorithm)

private static RSACryptoServiceProvider CreateRsaKeyFromJWK(JWK.JWK jwk)
{
var rsaParameters = new RSAParameters
var rsaParameters = new RSAParameters();
if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterD, out var dValue))
{
D = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterD]),
Exponent = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterE]),
Modulus = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterN]),
P = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterP]),
Q = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterQ]),
DP = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterDP]),
DQ = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterDQ]),
InverseQ = Base64urlDecode(jwk.KeyParameters[KeyParameter.RSAKeyParameterQI]),
};
rsaParameters.D = Base64urlDecode(dValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterE, out var eValue))
{
rsaParameters.Exponent = Base64urlDecode(eValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterN, out var nValue))
{
rsaParameters.Modulus = Base64urlDecode(nValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterP, out var pValue))
{
rsaParameters.P = Base64urlDecode(pValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterQ, out var qValue))
{
rsaParameters.Q = Base64urlDecode(qValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterDP, out var dpValue))
{
rsaParameters.DP = Base64urlDecode(dpValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterDQ, out var dqValue))
{
rsaParameters.DQ = Base64urlDecode(dqValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.RSAKeyParameterQI, out var qiValue))
{
rsaParameters.InverseQ = Base64urlDecode(qiValue);
}

var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);

Expand Down Expand Up @@ -194,9 +224,18 @@ private static ECDsa CreateEcKeyFromJWK(JWK.JWK jwk)
var ecParameters = new ECParameters()
{
Curve = TranslateCurve(jwk.Algorithm),
D = Base64urlDecode(jwk.KeyParameters[KeyParameter.ECKeyParameterD]),
Q = new ECPoint { X = Base64urlDecode(jwk.KeyParameters[KeyParameter.ECKeyParameterX]), Y = Base64urlDecode(jwk.KeyParameters[KeyParameter.ECKeyParameterY]) }
};

if (jwk.KeyParameters.TryGetValue(KeyParameter.ECKeyParameterD, out var dValue))
{
ecParameters.D = Base64urlDecode(dValue);
}

if (jwk.KeyParameters.TryGetValue(KeyParameter.ECKeyParameterX, out var xValue) && jwk.KeyParameters.TryGetValue(KeyParameter.ECKeyParameterY, out var yValue))
{
ecParameters.Q = new ECPoint { X = Base64urlDecode(xValue), Y = Base64urlDecode(yValue) };
}

ecParameters.Validate();
return ECDsa.Create(ecParameters);
}
Expand Down

0 comments on commit 0878eeb

Please sign in to comment.