From 9539d0c9c7ffe957b7788fb7cfd35a315a9ea5b2 Mon Sep 17 00:00:00 2001
From: joegoldman674 <147369450+joegoldman2@users.noreply.github.com>
Date: Sat, 21 Oct 2023 09:54:07 -0700
Subject: [PATCH 1/8] Add ECDsa support in X509SecurityKey
---
src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs b/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
index 5b7687ec10..2b020b9b90 100644
--- a/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
+++ b/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
@@ -79,7 +79,8 @@ public AsymmetricAlgorithm PrivateKey
if (!_privateKeyAvailabilityDetermined)
{
#if NET461 || NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
- _privateKey = RSACertificateExtensions.GetRSAPrivateKey(Certificate);
+ var rsaPrivateKey = Certificate.GetRSAPrivateKey();
+ _privateKey = rsaPrivateKey != null ? rsaPrivateKey : Certificate.GetECDsaPrivateKey();
#else
_privateKey = Certificate.PrivateKey;
#endif
@@ -106,7 +107,8 @@ public AsymmetricAlgorithm PublicKey
if (_publicKey == null)
{
#if NET461 || NET462 || NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
- _publicKey = RSACertificateExtensions.GetRSAPublicKey(Certificate);
+ var rsaPublicKey = Certificate.GetRSAPublicKey();
+ _publicKey = rsaPublicKey != null ? rsaPublicKey : Certificate.GetECDsaPublicKey();
#else
_publicKey = Certificate.PublicKey.Key;
#endif
@@ -163,7 +165,7 @@ public X509Certificate2 Certificate
/// https://datatracker.ietf.org/doc/html/rfc7638
public override bool CanComputeJwkThumbprint()
{
- return (PublicKey as RSA) != null ? true : false;
+ return PublicKey is RSA || PublicKey is ECDsa;
}
///
@@ -173,7 +175,7 @@ public override bool CanComputeJwkThumbprint()
/// https://datatracker.ietf.org/doc/html/rfc7638
public override byte[] ComputeJwkThumbprint()
{
- return new RsaSecurityKey(PublicKey as RSA).ComputeJwkThumbprint();
+ return PublicKey is RSA ? new RsaSecurityKey(PublicKey as RSA).ComputeJwkThumbprint() : new ECDsaSecurityKey(PublicKey as ECDsa).ComputeJwkThumbprint();
}
///
From 47d85e45bd922abfb073b858b97badc925f69045 Mon Sep 17 00:00:00 2001
From: joegoldman2 <147369450+joegoldman@users.noreply.github.com>
Date: Tue, 2 Jul 2024 06:02:26 +0000
Subject: [PATCH 2/8] Add unit test
---
.../KeyingMaterial.cs | 4 ++++
.../X509SecurityKeyTests.cs | 17 +++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
index 9251fc487a..7c380b0980 100644
--- a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
+++ b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
@@ -98,6 +98,10 @@ static public class KeyingMaterial
public static SigningCredentials DefaultX509SigningCreds_2048_RsaSha2_Sha2 = new SigningCredentials(DefaultX509Key_2048, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
public static X509Certificate2 DefaultAsymmetricCert_2048 = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_2048), CertPassword, X509KeyStorageFlags.MachineKeySet);
+ // 256 bit ECDSA
+ public const string DefaultX509Data_256ECDSA = @"MIIEnwIBAzCCBFsGCSqGSIb3DQEHAaCCBEwEggRIMIIERDCCAc0GCSqGSIb3DQEHAaCCAb4EggG6MIIBtjCCAbIGCyqGSIb3DQEMCgECoIHMMIHJMBwGCiqGSIb3DQEMAQMwDgQIX9xRjIVa2ZcCAgfQBIGo+O4xXEkTBqcaF9nf6qRwrMfy7hvE7katRb6braieeTFrDZO4QwnmheBT3RMk/9sBEXjFGhdJHpf4FQHkKtTpimlyTVHlSR+B2NWrzQK4id18ZwsVihusyPwbM73Uu9o+3vZMCdM15tNQBwsUpmYIRzD3wcnVAD/VJBr3JoRSSjBmz6nKpMvjc1ZtBADjqUWdjO+aDLxS+AM0sfH8i0ivmSIZqUekf6wuMYHTMBMGCSqGSIb3DQEJFTEGBAQBAAAAMF0GCSqGSIb3DQEJFDFQHk4AdABlAC0ANQBiAGIANwA5ADIAYgA5AC0AOAA5AGIANAAtADQAYgBmADAALQA4ADcAZAA0AC0ANgBjADkAZQBhADQANwA3ADAAYgA5ADkwXQYJKwYBBAGCNxEBMVAeTgBNAGkAYwByAG8AcwBvAGYAdAAgAFMAbwBmAHQAdwBhAHIAZQAgAEsAZQB5ACAAUwB0AG8AcgBhAGcAZQAgAFAAcgBvAHYAaQBkAGUAcjCCAm8GCSqGSIb3DQEHBqCCAmAwggJcAgEAMIICVQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMwDgQIOd7DHkPXTdwCAgfQgIICKAGcaQokoScTUhpYGZvp5i78HCicnc5l9YpWqhDBMMFhQDhziIdu2Kd0Rc9eprukunrcsbWiH2N8Ag6RgyPZwSgdKJF/oHMQ5L40KzOl1i7c+Uz+PfOfPTRGSqNpTVVm7d2/C8XfZFpDFUugNkY+NknFEvODEPtVTsXc6LB/Tjdr4o8ypt+ZKtKLfFD8n0mo1gX6A694cjLE89vHKUMsF1zito8My8k9Z6fakaXv92GlpC1Jro/gTp2TPAfp166F7pUQrd4jQuDZhKId4GeXwi9Ggn4KxvGpuOW0dJdtR+lNNLPh2AnsGXyL3gYCsHiLKGz3bAvMql9Lee12BErVf/7iYG3XDtx8i4xLzTJm6l8CwoUuLh8XCcBLmYxnBGHXhBfHNoFri+OiO/IHRZpMkDws5fnzT5VjTZ0umuJKbLmgdh4j465IcZUKSvSPxon13fyC5wxZZHD4W3XCP9lTEtFxsUkYfn6j3HNrfq+4zclr7zjPnyGOxD3V0B3oGn8xzzXoyVbgaxrWRvFQPau1mEdTLlSbKkHQIkI1qYlTGjbX5BTXt3vPo3juThe5O47WpRLp8lmFTrVIv/qvcQ3pBlVJaYhtijGxJOMH8Qii4dB3Ru/4w+u54UzzFAepPLJbn5fwnw3Lw6+gaiUyxRUmykB4tLjpFBQd1BIEdpKpzS0aT4Q68YScOGQdEDvPibimdlhcXabdNAEvX5Hv2yRE8gNMc8l52f8ckTA7MB8wBwYFKw4DAhoEFJRQSVRoIwasJHhxXd4V2H5b9OvaBBQs4phgMd4xS41WD/LsCBhxV2AhRgICB9A=";
+ public static X509Certificate2 DefaultCert_256ECDSA = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_256ECDSA), CertPassword, X509KeyStorageFlags.Exportable);
+
public static string DefaultX509Data_2048_Public = @"MIICyjCCAbKgAwIBAgIQJPMYqnyiTY1GQYAwZxadMjANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDExZBREZTIFNpZ25pbmcgLSBTVFMuY29tMB4XDTEyMTAwOTIyMTA0OVoXDTEzMTAwOTIyMTA0OVowITEfMB0GA1UEAxMWQURGUyBTaWduaW5nIC0gU1RTLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmeVPJz8o7ayB3AS2dJtsIo/eXqeNhZ+ZqEJgHVHc0JAAgNNwR++moMt8+iIlOKZiAL8dvQBKOuPms+FfqrG1HshnMiLcuadtWUqOntxUdyQLcEKvdaFOqOppqmasqGFtRLPwYKIkZOkj8ikndNzI6PZV46mw18nLaN6rTByMnjVA5n9Lf7Cdu7lmxlKGJOI5F0IfeaW68/kY1bdw3KAEb1aOKHj0r7RJ2joRuHJ+96kw1bA2T6bGC/1LYND3DFsnQQtMBl7LlDrSG1gGoiZxCoQmPCxfrTCrYKGK6y9j6IQ4MCmJpnt0l/INL5i88TjctF4IkJwbJGn9iY2fIIBxMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAq/SyHGCLpBm+Gmh5I7BAWJXvtPaIelt30WgKVXRHccxRVIYpKOfAA2iPuD/CVruFz6pnP4K7o2KLAs+XJptigYzLEjKw6rY4836ZJC8m5kfBVanu45OW39nxzxp1udbxQ5gAdmvnY/2agpFhCFR8M1BtWON6G3SzHwo2dXHh+ettOO2LtK38e1+Uy+KGowRw/m4gprSIvgN3AAo7e0PnFblZn6vRgMsK60QB5D8f+Kxdg2I3ZGQcPBQI2fpjEDQCZVc2LV4ywPX4QDPfmYjn+1IaU9w7unbh+oUGQsrdKw3gsdzWEsX/IMXTDf46FEOjV+JqE7VilzcNuDcQ0x9K8gAA";
public static X509Certificate2 DefaultCert_2048_Public
{
diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs
index db9bf67af1..b77220606d 100644
--- a/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs
+++ b/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs
@@ -77,6 +77,23 @@ public void Constructor()
TestUtilities.AssertFailIfErrors(context);
}
+ [Fact]
+ public void Constructor_WithECDsa()
+ {
+ var certificate = KeyingMaterial.DefaultCert_256ECDSA;
+ var x509SecurityKey = new X509SecurityKey(certificate);
+ var context = new CompareContext();
+ IdentityComparer.AreEqual(x509SecurityKey.KeyId, certificate.Thumbprint, context);
+ IdentityComparer.AreEqual(x509SecurityKey.X5t, Base64UrlEncoder.Encode(certificate.GetCertHash()), context);
+ IdentityComparer.AreEqual(certificate, x509SecurityKey.Certificate, context);
+ Assert.NotNull(x509SecurityKey.PublicKey);
+ Assert.NotNull(x509SecurityKey.PrivateKey);
+ Assert.Equal(PrivateKeyStatus.Exists, x509SecurityKey.PrivateKeyStatus);
+ Assert.True(x509SecurityKey.CanComputeJwkThumbprint());
+ Assert.NotEmpty(x509SecurityKey.ComputeJwkThumbprint());
+ TestUtilities.AssertFailIfErrors(context);
+ }
+
[Fact]
public void CanComputeJwkThumbprint()
{
From 4f3008827ce5eae5b2ac4153b97a74728fcf09b0 Mon Sep 17 00:00:00 2001
From: joegoldman2 <147369450+joegoldman@users.noreply.github.com>
Date: Tue, 2 Jul 2024 17:25:53 +0000
Subject: [PATCH 3/8] Add support for ECDsa in
JsonWebKeyConverter.ConvertFromX509SecurityKey
---
.../JsonWebKeyConverter.cs | 37 ++++++++--
.../JsonWebKeyConverterTest.cs | 68 ++++++++++---------
2 files changed, 67 insertions(+), 38 deletions(-)
diff --git a/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs b/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
index 337e94baeb..2388fd9fac 100644
--- a/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
@@ -97,9 +97,16 @@ public static JsonWebKey ConvertFromX509SecurityKey(X509SecurityKey key)
if (key == null)
throw LogHelper.LogArgumentNullException(nameof(key));
+ var kty = key.PublicKey switch
+ {
+ RSA => JsonWebAlgorithmsKeyTypes.RSA,
+ ECDsa => JsonWebAlgorithmsKeyTypes.EllipticCurve,
+ _ => throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10674, LogHelper.MarkAsNonPII(key.GetType().FullName))))
+ };
+
var jsonWebKey = new JsonWebKey
{
- Kty = JsonWebAlgorithmsKeyTypes.RSA,
+ Kty = kty,
Kid = key.KeyId,
X5t = key.X5t,
ConvertedSecurityKey = key
@@ -129,13 +136,31 @@ public static JsonWebKey ConvertFromX509SecurityKey(X509SecurityKey key, bool re
if (key == null)
throw LogHelper.LogArgumentNullException(nameof(key));
- RSA rsaKey;
if (key.PrivateKeyStatus == PrivateKeyStatus.Exists)
- rsaKey = key.PrivateKey as RSA;
- else
- rsaKey = key.PublicKey as RSA;
+ {
+ if (key.PrivateKey is RSA rsaPrivateKey)
+ {
+ return ConvertFromRSASecurityKey(new RsaSecurityKey(rsaPrivateKey) { KeyId = key.KeyId });
+ }
+#if NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
+ else if (key.PrivateKey is ECDsa ecdsaPrivateKey)
+ {
+ return ConvertFromECDsaSecurityKey(new ECDsaSecurityKey(ecdsaPrivateKey) { KeyId = key.KeyId });
+ }
+#endif
+ }
+ else if (key.PublicKey is RSA rsaPublicKey)
+ {
+ return ConvertFromRSASecurityKey(new RsaSecurityKey(rsaPublicKey) { KeyId = key.KeyId });
+ }
+#if NET472 || NETSTANDARD2_0 || NET6_0_OR_GREATER
+ else if (key.PublicKey is ECDsa ecdsaPublicKey)
+ {
+ return ConvertFromECDsaSecurityKey(new ECDsaSecurityKey(ecdsaPublicKey) { KeyId = key.KeyId });
+ }
+#endif
- return ConvertFromRSASecurityKey(new RsaSecurityKey(rsaKey) { KeyId = key.KeyId });
+ throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10674, LogHelper.MarkAsNonPII(key.GetType().FullName))));
}
///
diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs b/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
index c9503ee45b..79d08935e3 100644
--- a/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
+++ b/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
@@ -11,7 +11,7 @@ namespace Microsoft.IdentityModel.Tokens.Tests
{
public class JsonWebKeyConverterTest
{
- [Theory, MemberData(nameof(ConvertSecurityKeyToJsonWebKeyTheoryData))]
+ [Theory, MemberData(nameof(ConversionKeyTheoryData))]
public void ConvertSecurityKeyToJsonWebKey(JsonWebKeyConverterTheoryData theoryData)
{
var context = TestUtilities.WriteHeader($"{this}.ConvertSecurityKeyToJsonWebKey", theoryData);
@@ -24,7 +24,7 @@ public void ConvertSecurityKeyToJsonWebKey(JsonWebKeyConverterTheoryData theoryD
if (convertedKey.ConvertedSecurityKey.GetType() != theoryData.SecurityKey.GetType())
context.AddDiff($"theoryData.JsonWebKey.RelatedSecurityKey.GetType(): '{theoryData.JsonWebKey.ConvertedSecurityKey.GetType()}' != theoryData.SecurityKey.GetType(): '{theoryData.SecurityKey.GetType()}'.");
}
- catch(Exception ex)
+ catch (Exception ex)
{
theoryData.ExpectedException.ProcessException(ex, context);
}
@@ -32,7 +32,7 @@ public void ConvertSecurityKeyToJsonWebKey(JsonWebKeyConverterTheoryData theoryD
TestUtilities.AssertFailIfErrors(context);
}
- [Theory, MemberData(nameof(ConvertToJsonWebKeyToSecurityKeyTheoryData))]
+ [Theory, MemberData(nameof(ConversionKeyTheoryData))]
public void ConvertJsonWebKeyToSecurityKey(JsonWebKeyConverterTheoryData theoryData)
{
var context = TestUtilities.WriteHeader($"{this}.ConvertJsonWebKeyToSecurityKey", theoryData);
@@ -63,9 +63,9 @@ public void ConvertX509SecurityKeyAsRsaSecurityKeyToJsonWebKey(JsonWebKeyConvert
theoryData.ExpectedException.ProcessNoException(context);
IdentityComparer.AreEqual(convertedKey, theoryData.JsonWebKey, context);
- var expectedConvertedKeyType = theoryData.RepresentAsRsaKey == true ? typeof(RsaSecurityKey) : typeof(X509SecurityKey);
- if (convertedKey.ConvertedSecurityKey.GetType() != expectedConvertedKeyType)
- context.AddDiff($"convertedKey.ConvertedSecurityKey.GetType(): '{convertedKey.ConvertedSecurityKey.GetType()}' != expectedConvertedKeyType: '{expectedConvertedKeyType}'.");
+ //var expectedConvertedKeyType = theoryData.RepresentAsRsaKey == true ? typeof(RsaSecurityKey) : typeof(X509SecurityKey);
+ //if (convertedKey.ConvertedSecurityKey.GetType() != expectedConvertedKeyType)
+ //context.AddDiff($"convertedKey.ConvertedSecurityKey.GetType(): '{convertedKey.ConvertedSecurityKey.GetType()}' != expectedConvertedKeyType: '{expectedConvertedKeyType}'.");
}
catch (Exception ex)
{
@@ -75,32 +75,6 @@ public void ConvertX509SecurityKeyAsRsaSecurityKeyToJsonWebKey(JsonWebKeyConvert
TestUtilities.AssertFailIfErrors(context);
}
- public static TheoryData ConvertSecurityKeyToJsonWebKeyTheoryData
- {
- get
- {
- var theoryData = ConversionKeyTheoryData;
-#if !NET472 && !NET_CORE
- theoryData.Add(new JsonWebKeyConverterTheoryData
- {
- SecurityKey = KeyingMaterial.Ecdsa256Key,
- JsonWebKey = KeyingMaterial.JsonWebKeyP256_Public,
- ExpectedException = ExpectedException.NotSupportedException("IDX10674"),
- TestId = "SecurityKeyNotSupported"
- });
-#endif
- return theoryData;
- }
- }
-
- public static TheoryData ConvertToJsonWebKeyToSecurityKeyTheoryData
- {
- get
- {
- return ConversionKeyTheoryData;
- }
- }
-
public static TheoryData ConversionKeyTheoryData
{
get
@@ -235,7 +209,37 @@ public static TheoryData ConvertX509SecurityKeyTo
JsonWebKey = KeyingMaterial.JsonWebKeyX509_2048_Public_As_RSA,
TestId = nameof(KeyingMaterial.DefaultX509Key_2048_Public) + nameof(JsonWebKeyConverterTheoryData.RepresentAsRsaKey)
});
+#if NET472 || NET_CORE
+ theoryData.Add(new JsonWebKeyConverterTheoryData
+ {
+ SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA,
+ JsonWebKey = KeyingMaterial.JsonWebKeyX509_256ECDSA,
+ TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA)
+ });
+
+ theoryData.Add(new JsonWebKeyConverterTheoryData
+ {
+ SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA_With_KeyId,
+ JsonWebKey = KeyingMaterial.JsonWebKeyX509_256ECDSA_With_KeyId,
+ TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA_With_KeyId)
+ });
+
+ theoryData.Add(new JsonWebKeyConverterTheoryData
+ {
+ SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA_Public_With_KeyId,
+ RepresentAsRsaKey = true,
+ JsonWebKey = KeyingMaterial.JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId_Public,
+ TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA_Public) + nameof(JsonWebKeyConverterTheoryData.RepresentAsRsaKey)
+ });
+ theoryData.Add(new JsonWebKeyConverterTheoryData
+ {
+ SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA,
+ RepresentAsRsaKey = true,
+ JsonWebKey = KeyingMaterial.JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId,
+ TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA)
+ });
+#endif
return theoryData;
}
}
From 197831db21fbedbb656871649ae7a6825698657c Mon Sep 17 00:00:00 2001
From: joegoldman2 <147369450+joegoldman@users.noreply.github.com>
Date: Tue, 2 Jul 2024 17:29:38 +0000
Subject: [PATCH 4/8] Update unit test
---
.../KeyingMaterial.cs | 85 ++++++++++++++++++-
1 file changed, 83 insertions(+), 2 deletions(-)
diff --git a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
index 7c380b0980..8f80da259d 100644
--- a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
+++ b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
@@ -99,8 +99,16 @@ static public class KeyingMaterial
public static X509Certificate2 DefaultAsymmetricCert_2048 = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_2048), CertPassword, X509KeyStorageFlags.MachineKeySet);
// 256 bit ECDSA
- public const string DefaultX509Data_256ECDSA = @"MIIEnwIBAzCCBFsGCSqGSIb3DQEHAaCCBEwEggRIMIIERDCCAc0GCSqGSIb3DQEHAaCCAb4EggG6MIIBtjCCAbIGCyqGSIb3DQEMCgECoIHMMIHJMBwGCiqGSIb3DQEMAQMwDgQIX9xRjIVa2ZcCAgfQBIGo+O4xXEkTBqcaF9nf6qRwrMfy7hvE7katRb6braieeTFrDZO4QwnmheBT3RMk/9sBEXjFGhdJHpf4FQHkKtTpimlyTVHlSR+B2NWrzQK4id18ZwsVihusyPwbM73Uu9o+3vZMCdM15tNQBwsUpmYIRzD3wcnVAD/VJBr3JoRSSjBmz6nKpMvjc1ZtBADjqUWdjO+aDLxS+AM0sfH8i0ivmSIZqUekf6wuMYHTMBMGCSqGSIb3DQEJFTEGBAQBAAAAMF0GCSqGSIb3DQEJFDFQHk4AdABlAC0ANQBiAGIANwA5ADIAYgA5AC0AOAA5AGIANAAtADQAYgBmADAALQA4ADcAZAA0AC0ANgBjADkAZQBhADQANwA3ADAAYgA5ADkwXQYJKwYBBAGCNxEBMVAeTgBNAGkAYwByAG8AcwBvAGYAdAAgAFMAbwBmAHQAdwBhAHIAZQAgAEsAZQB5ACAAUwB0AG8AcgBhAGcAZQAgAFAAcgBvAHYAaQBkAGUAcjCCAm8GCSqGSIb3DQEHBqCCAmAwggJcAgEAMIICVQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMwDgQIOd7DHkPXTdwCAgfQgIICKAGcaQokoScTUhpYGZvp5i78HCicnc5l9YpWqhDBMMFhQDhziIdu2Kd0Rc9eprukunrcsbWiH2N8Ag6RgyPZwSgdKJF/oHMQ5L40KzOl1i7c+Uz+PfOfPTRGSqNpTVVm7d2/C8XfZFpDFUugNkY+NknFEvODEPtVTsXc6LB/Tjdr4o8ypt+ZKtKLfFD8n0mo1gX6A694cjLE89vHKUMsF1zito8My8k9Z6fakaXv92GlpC1Jro/gTp2TPAfp166F7pUQrd4jQuDZhKId4GeXwi9Ggn4KxvGpuOW0dJdtR+lNNLPh2AnsGXyL3gYCsHiLKGz3bAvMql9Lee12BErVf/7iYG3XDtx8i4xLzTJm6l8CwoUuLh8XCcBLmYxnBGHXhBfHNoFri+OiO/IHRZpMkDws5fnzT5VjTZ0umuJKbLmgdh4j465IcZUKSvSPxon13fyC5wxZZHD4W3XCP9lTEtFxsUkYfn6j3HNrfq+4zclr7zjPnyGOxD3V0B3oGn8xzzXoyVbgaxrWRvFQPau1mEdTLlSbKkHQIkI1qYlTGjbX5BTXt3vPo3juThe5O47WpRLp8lmFTrVIv/qvcQ3pBlVJaYhtijGxJOMH8Qii4dB3Ru/4w+u54UzzFAepPLJbn5fwnw3Lw6+gaiUyxRUmykB4tLjpFBQd1BIEdpKpzS0aT4Q68YScOGQdEDvPibimdlhcXabdNAEvX5Hv2yRE8gNMc8l52f8ckTA7MB8wBwYFKw4DAhoEFJRQSVRoIwasJHhxXd4V2H5b9OvaBBQs4phgMd4xS41WD/LsCBhxV2AhRgICB9A=";
+ public const string DefaultX509Data_256ECDSA = "MIIEnwIBAzCCBFsGCSqGSIb3DQEHAaCCBEwEggRIMIIERDCCAc0GCSqGSIb3DQEHAaCCAb4EggG6MIIBtjCCAbIGCyqGSIb3DQEMCgECoIHMMIHJMBwGCiqGSIb3DQEMAQMwDgQIX9xRjIVa2ZcCAgfQBIGo+O4xXEkTBqcaF9nf6qRwrMfy7hvE7katRb6braieeTFrDZO4QwnmheBT3RMk/9sBEXjFGhdJHpf4FQHkKtTpimlyTVHlSR+B2NWrzQK4id18ZwsVihusyPwbM73Uu9o+3vZMCdM15tNQBwsUpmYIRzD3wcnVAD/VJBr3JoRSSjBmz6nKpMvjc1ZtBADjqUWdjO+aDLxS+AM0sfH8i0ivmSIZqUekf6wuMYHTMBMGCSqGSIb3DQEJFTEGBAQBAAAAMF0GCSqGSIb3DQEJFDFQHk4AdABlAC0ANQBiAGIANwA5ADIAYgA5AC0AOAA5AGIANAAtADQAYgBmADAALQA4ADcAZAA0AC0ANgBjADkAZQBhADQANwA3ADAAYgA5ADkwXQYJKwYBBAGCNxEBMVAeTgBNAGkAYwByAG8AcwBvAGYAdAAgAFMAbwBmAHQAdwBhAHIAZQAgAEsAZQB5ACAAUwB0AG8AcgBhAGcAZQAgAFAAcgBvAHYAaQBkAGUAcjCCAm8GCSqGSIb3DQEHBqCCAmAwggJcAgEAMIICVQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMwDgQIOd7DHkPXTdwCAgfQgIICKAGcaQokoScTUhpYGZvp5i78HCicnc5l9YpWqhDBMMFhQDhziIdu2Kd0Rc9eprukunrcsbWiH2N8Ag6RgyPZwSgdKJF/oHMQ5L40KzOl1i7c+Uz+PfOfPTRGSqNpTVVm7d2/C8XfZFpDFUugNkY+NknFEvODEPtVTsXc6LB/Tjdr4o8ypt+ZKtKLfFD8n0mo1gX6A694cjLE89vHKUMsF1zito8My8k9Z6fakaXv92GlpC1Jro/gTp2TPAfp166F7pUQrd4jQuDZhKId4GeXwi9Ggn4KxvGpuOW0dJdtR+lNNLPh2AnsGXyL3gYCsHiLKGz3bAvMql9Lee12BErVf/7iYG3XDtx8i4xLzTJm6l8CwoUuLh8XCcBLmYxnBGHXhBfHNoFri+OiO/IHRZpMkDws5fnzT5VjTZ0umuJKbLmgdh4j465IcZUKSvSPxon13fyC5wxZZHD4W3XCP9lTEtFxsUkYfn6j3HNrfq+4zclr7zjPnyGOxD3V0B3oGn8xzzXoyVbgaxrWRvFQPau1mEdTLlSbKkHQIkI1qYlTGjbX5BTXt3vPo3juThe5O47WpRLp8lmFTrVIv/qvcQ3pBlVJaYhtijGxJOMH8Qii4dB3Ru/4w+u54UzzFAepPLJbn5fwnw3Lw6+gaiUyxRUmykB4tLjpFBQd1BIEdpKpzS0aT4Q68YScOGQdEDvPibimdlhcXabdNAEvX5Hv2yRE8gNMc8l52f8ckTA7MB8wBwYFKw4DAhoEFJRQSVRoIwasJHhxXd4V2H5b9OvaBBQs4phgMd4xS41WD/LsCBhxV2AhRgICB9A=";
+ public const string DefaultX509Data_256ECDSA_Public = "MIIBujCCAV+gAwIBAgIQQ6xJuTdhTpFKGAJNoeAXNTAKBggqhkjOPQQDAjAiMSAwHgYDVQQDDBdLZXlTdG9yZVRlc3RDZXJ0aWZpY2F0ZTAeFw0yNDA3MDIwNTIyNDdaFw0yNTA3MDIwNTQyNDdaMCIxIDAeBgNVBAMMF0tleVN0b3JlVGVzdENlcnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9+coKp9Bai6DHq5f9FCSBTizhlZDp4hY1E98AG9YGZIt/8SPRaZzKIe6JKcqT/PaOywh0MAwtNDglttAa+Tr8KN3MHUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAlBgNVHREEHjAcghpDTj1LZXlTdG9yZVRlc3RDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUjmT0SStRinfVGLKXtQXPf2dRiuYwCgYIKoZIzj0EAwIDSQAwRgIhAKhS2I54EALm367IuKHE1P44TNWOqGphLUfwj6e/HwUNAiEAmOzj//RrjFauhxGLn50Fn8M05Y1KmNtP5UGHytaPEsE=";
+ public static string DefaultX509Key_256ECDSA_KeyId = "DefaultX509Key_256ECDSA_KeyId";
+ public static string DefaultX509Key_256ECDSA_Thumbprint = "CEE96753ACDF7BBE12F61FD59BE9521482B566D8";
public static X509Certificate2 DefaultCert_256ECDSA = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_256ECDSA), CertPassword, X509KeyStorageFlags.Exportable);
+ public static X509Certificate2 DefaultCert_256ECDSA_Public = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_256ECDSA_Public), CertPassword, X509KeyStorageFlags.Exportable);
+ public static X509SecurityKey DefaultX509Key_256ECDSA = new X509SecurityKey(DefaultCert_256ECDSA);
+ public static X509SecurityKey DefaultX509Key_256ECDSA_With_KeyId = new X509SecurityKey(DefaultCert_256ECDSA) { KeyId = DefaultX509Key_256ECDSA_KeyId };
+ public static X509SecurityKey DefaultX509Key_256ECDSA_Public = new X509SecurityKey(DefaultCert_256ECDSA_Public);
+ public static X509SecurityKey DefaultX509Key_256ECDSA_Public_With_KeyId = new X509SecurityKey(DefaultCert_256ECDSA_Public) { KeyId = DefaultX509Key_256ECDSA_KeyId };
public static string DefaultX509Data_2048_Public = @"MIICyjCCAbKgAwIBAgIQJPMYqnyiTY1GQYAwZxadMjANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDExZBREZTIFNpZ25pbmcgLSBTVFMuY29tMB4XDTEyMTAwOTIyMTA0OVoXDTEzMTAwOTIyMTA0OVowITEfMB0GA1UEAxMWQURGUyBTaWduaW5nIC0gU1RTLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmeVPJz8o7ayB3AS2dJtsIo/eXqeNhZ+ZqEJgHVHc0JAAgNNwR++moMt8+iIlOKZiAL8dvQBKOuPms+FfqrG1HshnMiLcuadtWUqOntxUdyQLcEKvdaFOqOppqmasqGFtRLPwYKIkZOkj8ikndNzI6PZV46mw18nLaN6rTByMnjVA5n9Lf7Cdu7lmxlKGJOI5F0IfeaW68/kY1bdw3KAEb1aOKHj0r7RJ2joRuHJ+96kw1bA2T6bGC/1LYND3DFsnQQtMBl7LlDrSG1gGoiZxCoQmPCxfrTCrYKGK6y9j6IQ4MCmJpnt0l/INL5i88TjctF4IkJwbJGn9iY2fIIBxMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAq/SyHGCLpBm+Gmh5I7BAWJXvtPaIelt30WgKVXRHccxRVIYpKOfAA2iPuD/CVruFz6pnP4K7o2KLAs+XJptigYzLEjKw6rY4836ZJC8m5kfBVanu45OW39nxzxp1udbxQ5gAdmvnY/2agpFhCFR8M1BtWON6G3SzHwo2dXHh+ettOO2LtK38e1+Uy+KGowRw/m4gprSIvgN3AAo7e0PnFblZn6vRgMsK60QB5D8f+Kxdg2I3ZGQcPBQI2fpjEDQCZVc2LV4ywPX4QDPfmYjn+1IaU9w7unbh+oUGQsrdKw3gsdzWEsX/IMXTDf46FEOjV+JqE7VilzcNuDcQ0x9K8gAA";
public static X509Certificate2 DefaultCert_2048_Public
@@ -217,7 +225,6 @@ public static RsaSecurityKey RsaSecurityKey2
public static readonly ECDsaSecurityKey Ecdsa521Key_Public;
// SymmetricKeys
-
public static string DefaultSymmetricKeyEncoded_56 = "bd0Q+Z6Ydw==";
public static byte[] DefaultSymmetricKeyBytes_56 = Convert.FromBase64String(DefaultSymmetricKeyEncoded_56);
public static SymmetricSecurityKey DefaultSymmetricSecurityKey_56 = new SymmetricSecurityKey(DefaultSymmetricKeyBytes_56) { KeyId = "DefaultSymmetricSecurityKey_56" };
@@ -1060,6 +1067,80 @@ public static JsonWebKey JsonWebKeyX509_2048_As_RSA_With_KeyId
}
}
+#if NET472 || NET_CORE
+ public static JsonWebKey JsonWebKeyX509_256ECDSA
+ {
+ get
+ {
+ var jsonWebKey = new JsonWebKey
+ {
+ Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,
+ Kid = DefaultX509Key_256ECDSA_Thumbprint,
+ X5t = Base64UrlEncoder.Encode(DefaultCert_256ECDSA.GetCertHash())
+ };
+
+ jsonWebKey.X5c.Add(Convert.ToBase64String(DefaultCert_256ECDSA.RawData));
+ return jsonWebKey;
+ }
+ }
+
+ public static JsonWebKey JsonWebKeyX509_256ECDSA_With_KeyId
+ {
+ get
+ {
+ var jsonWebKey = new JsonWebKey
+ {
+ Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,
+ Kid = DefaultX509Key_256ECDSA_KeyId,
+ X5t = Base64UrlEncoder.Encode(DefaultCert_256ECDSA.GetCertHash())
+ };
+
+ jsonWebKey.X5c.Add(Convert.ToBase64String(DefaultCert_256ECDSA.RawData));
+ return jsonWebKey;
+ }
+ }
+
+ public static JsonWebKey JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId_Public
+ {
+ get
+ {
+ var ecdsa = DefaultX509Key_256ECDSA_Public_With_KeyId.PublicKey as ECDsa;
+ var ecParams = ecdsa.ExportParameters(false);
+
+ var jsonWebKey = new JsonWebKey
+ {
+ Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,
+ Kid = DefaultX509Key_256ECDSA_KeyId,
+ Crv = JsonWebKeyECTypes.P256,
+ X = Base64UrlEncoder.Encode(ecParams.Q.X),
+ Y = Base64UrlEncoder.Encode(ecParams.Q.Y),
+ };
+
+ return jsonWebKey;
+ }
+ }
+
+ public static JsonWebKey JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId
+ {
+ get
+ {
+ var ecdsa = DefaultX509Key_256ECDSA_With_KeyId.PrivateKey as ECDsa;
+ var ecParams = ecdsa.ExportParameters(true);
+
+ var jsonWebKey = new JsonWebKey
+ {
+ Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,
+ Kid = DefaultX509Key_256ECDSA_KeyId,
+ Crv = JsonWebKeyECTypes.P256,
+ D = Base64UrlEncoder.Encode(ecParams.D),
+ X = Base64UrlEncoder.Encode(ecParams.Q.X),
+ Y = Base64UrlEncoder.Encode(ecParams.Q.Y),
+ };
+
+ return jsonWebKey;
+ }
+ }
+#endif
private static SecureString ConvertToSecureString(string password)
{
if (password == null)
From 6676f8c7fd84bde9001de7fab2f76d1c86fe10a2 Mon Sep 17 00:00:00 2001
From: joegoldman2 <147369450+joegoldman@users.noreply.github.com>
Date: Wed, 3 Jul 2024 03:34:54 +0000
Subject: [PATCH 5/8] Remove use of self-signed certificate
---
.../KeyingMaterial.cs | 31 ++++++++++---------
.../JsonWebKeyConverterTest.cs | 10 +++---
2 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
index 8f80da259d..4eaaf63e30 100644
--- a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
+++ b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
@@ -99,16 +99,11 @@ static public class KeyingMaterial
public static X509Certificate2 DefaultAsymmetricCert_2048 = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_2048), CertPassword, X509KeyStorageFlags.MachineKeySet);
// 256 bit ECDSA
- public const string DefaultX509Data_256ECDSA = "MIIEnwIBAzCCBFsGCSqGSIb3DQEHAaCCBEwEggRIMIIERDCCAc0GCSqGSIb3DQEHAaCCAb4EggG6MIIBtjCCAbIGCyqGSIb3DQEMCgECoIHMMIHJMBwGCiqGSIb3DQEMAQMwDgQIX9xRjIVa2ZcCAgfQBIGo+O4xXEkTBqcaF9nf6qRwrMfy7hvE7katRb6braieeTFrDZO4QwnmheBT3RMk/9sBEXjFGhdJHpf4FQHkKtTpimlyTVHlSR+B2NWrzQK4id18ZwsVihusyPwbM73Uu9o+3vZMCdM15tNQBwsUpmYIRzD3wcnVAD/VJBr3JoRSSjBmz6nKpMvjc1ZtBADjqUWdjO+aDLxS+AM0sfH8i0ivmSIZqUekf6wuMYHTMBMGCSqGSIb3DQEJFTEGBAQBAAAAMF0GCSqGSIb3DQEJFDFQHk4AdABlAC0ANQBiAGIANwA5ADIAYgA5AC0AOAA5AGIANAAtADQAYgBmADAALQA4ADcAZAA0AC0ANgBjADkAZQBhADQANwA3ADAAYgA5ADkwXQYJKwYBBAGCNxEBMVAeTgBNAGkAYwByAG8AcwBvAGYAdAAgAFMAbwBmAHQAdwBhAHIAZQAgAEsAZQB5ACAAUwB0AG8AcgBhAGcAZQAgAFAAcgBvAHYAaQBkAGUAcjCCAm8GCSqGSIb3DQEHBqCCAmAwggJcAgEAMIICVQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMwDgQIOd7DHkPXTdwCAgfQgIICKAGcaQokoScTUhpYGZvp5i78HCicnc5l9YpWqhDBMMFhQDhziIdu2Kd0Rc9eprukunrcsbWiH2N8Ag6RgyPZwSgdKJF/oHMQ5L40KzOl1i7c+Uz+PfOfPTRGSqNpTVVm7d2/C8XfZFpDFUugNkY+NknFEvODEPtVTsXc6LB/Tjdr4o8ypt+ZKtKLfFD8n0mo1gX6A694cjLE89vHKUMsF1zito8My8k9Z6fakaXv92GlpC1Jro/gTp2TPAfp166F7pUQrd4jQuDZhKId4GeXwi9Ggn4KxvGpuOW0dJdtR+lNNLPh2AnsGXyL3gYCsHiLKGz3bAvMql9Lee12BErVf/7iYG3XDtx8i4xLzTJm6l8CwoUuLh8XCcBLmYxnBGHXhBfHNoFri+OiO/IHRZpMkDws5fnzT5VjTZ0umuJKbLmgdh4j465IcZUKSvSPxon13fyC5wxZZHD4W3XCP9lTEtFxsUkYfn6j3HNrfq+4zclr7zjPnyGOxD3V0B3oGn8xzzXoyVbgaxrWRvFQPau1mEdTLlSbKkHQIkI1qYlTGjbX5BTXt3vPo3juThe5O47WpRLp8lmFTrVIv/qvcQ3pBlVJaYhtijGxJOMH8Qii4dB3Ru/4w+u54UzzFAepPLJbn5fwnw3Lw6+gaiUyxRUmykB4tLjpFBQd1BIEdpKpzS0aT4Q68YScOGQdEDvPibimdlhcXabdNAEvX5Hv2yRE8gNMc8l52f8ckTA7MB8wBwYFKw4DAhoEFJRQSVRoIwasJHhxXd4V2H5b9OvaBBQs4phgMd4xS41WD/LsCBhxV2AhRgICB9A=";
- public const string DefaultX509Data_256ECDSA_Public = "MIIBujCCAV+gAwIBAgIQQ6xJuTdhTpFKGAJNoeAXNTAKBggqhkjOPQQDAjAiMSAwHgYDVQQDDBdLZXlTdG9yZVRlc3RDZXJ0aWZpY2F0ZTAeFw0yNDA3MDIwNTIyNDdaFw0yNTA3MDIwNTQyNDdaMCIxIDAeBgNVBAMMF0tleVN0b3JlVGVzdENlcnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9+coKp9Bai6DHq5f9FCSBTizhlZDp4hY1E98AG9YGZIt/8SPRaZzKIe6JKcqT/PaOywh0MAwtNDglttAa+Tr8KN3MHUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAlBgNVHREEHjAcghpDTj1LZXlTdG9yZVRlc3RDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUjmT0SStRinfVGLKXtQXPf2dRiuYwCgYIKoZIzj0EAwIDSQAwRgIhAKhS2I54EALm367IuKHE1P44TNWOqGphLUfwj6e/HwUNAiEAmOzj//RrjFauhxGLn50Fn8M05Y1KmNtP5UGHytaPEsE=";
+ public static X509Certificate2 DefaultCert_256ECDSA;
+ public static string DefaultX509Key_256ECDSA_Thumbprint;
public static string DefaultX509Key_256ECDSA_KeyId = "DefaultX509Key_256ECDSA_KeyId";
- public static string DefaultX509Key_256ECDSA_Thumbprint = "CEE96753ACDF7BBE12F61FD59BE9521482B566D8";
- public static X509Certificate2 DefaultCert_256ECDSA = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_256ECDSA), CertPassword, X509KeyStorageFlags.Exportable);
- public static X509Certificate2 DefaultCert_256ECDSA_Public = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_256ECDSA_Public), CertPassword, X509KeyStorageFlags.Exportable);
- public static X509SecurityKey DefaultX509Key_256ECDSA = new X509SecurityKey(DefaultCert_256ECDSA);
- public static X509SecurityKey DefaultX509Key_256ECDSA_With_KeyId = new X509SecurityKey(DefaultCert_256ECDSA) { KeyId = DefaultX509Key_256ECDSA_KeyId };
- public static X509SecurityKey DefaultX509Key_256ECDSA_Public = new X509SecurityKey(DefaultCert_256ECDSA_Public);
- public static X509SecurityKey DefaultX509Key_256ECDSA_Public_With_KeyId = new X509SecurityKey(DefaultCert_256ECDSA_Public) { KeyId = DefaultX509Key_256ECDSA_KeyId };
+ public static X509SecurityKey DefaultX509Key_256ECDSA;
+ public static X509SecurityKey DefaultX509Key_256ECDSA_With_KeyId;
public static string DefaultX509Data_2048_Public = @"MIICyjCCAbKgAwIBAgIQJPMYqnyiTY1GQYAwZxadMjANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDExZBREZTIFNpZ25pbmcgLSBTVFMuY29tMB4XDTEyMTAwOTIyMTA0OVoXDTEzMTAwOTIyMTA0OVowITEfMB0GA1UEAxMWQURGUyBTaWduaW5nIC0gU1RTLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmeVPJz8o7ayB3AS2dJtsIo/eXqeNhZ+ZqEJgHVHc0JAAgNNwR++moMt8+iIlOKZiAL8dvQBKOuPms+FfqrG1HshnMiLcuadtWUqOntxUdyQLcEKvdaFOqOppqmasqGFtRLPwYKIkZOkj8ikndNzI6PZV46mw18nLaN6rTByMnjVA5n9Lf7Cdu7lmxlKGJOI5F0IfeaW68/kY1bdw3KAEb1aOKHj0r7RJ2joRuHJ+96kw1bA2T6bGC/1LYND3DFsnQQtMBl7LlDrSG1gGoiZxCoQmPCxfrTCrYKGK6y9j6IQ4MCmJpnt0l/INL5i88TjctF4IkJwbJGn9iY2fIIBxMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAq/SyHGCLpBm+Gmh5I7BAWJXvtPaIelt30WgKVXRHccxRVIYpKOfAA2iPuD/CVruFz6pnP4K7o2KLAs+XJptigYzLEjKw6rY4836ZJC8m5kfBVanu45OW39nxzxp1udbxQ5gAdmvnY/2agpFhCFR8M1BtWON6G3SzHwo2dXHh+ettOO2LtK38e1+Uy+KGowRw/m4gprSIvgN3AAo7e0PnFblZn6vRgMsK60QB5D8f+Kxdg2I3ZGQcPBQI2fpjEDQCZVc2LV4ywPX4QDPfmYjn+1IaU9w7unbh+oUGQsrdKw3gsdzWEsX/IMXTDf46FEOjV+JqE7VilzcNuDcQ0x9K8gAA";
public static X509Certificate2 DefaultCert_2048_Public
@@ -513,6 +508,11 @@ static KeyingMaterial()
Ecdsa256Key_Public = new ECDsaSecurityKey(Ecdsa256_Public) { KeyId = "ECDsa256Key_Public" };
Ecdsa384Key_Public = new ECDsaSecurityKey(Ecdsa384_Public) { KeyId = "ECDsa384Key_Public" };
Ecdsa521Key_Public = new ECDsaSecurityKey(Ecdsa521_Public) { KeyId = "ECDsa521Key_Public" };
+
+ DefaultCert_256ECDSA = new CertificateRequest("CN=KeyStoreTestCertificate", Ecdsa256, HashAlgorithmName.SHA256).CreateSelfSigned(notBefore: DateTimeOffset.UtcNow, notAfter: DateTimeOffset.UtcNow.AddHours(1));
+ DefaultX509Key_256ECDSA_Thumbprint = DefaultCert_256ECDSA.Thumbprint;
+ DefaultX509Key_256ECDSA = new X509SecurityKey(DefaultCert_256ECDSA);
+ DefaultX509Key_256ECDSA_With_KeyId = new X509SecurityKey(DefaultCert_256ECDSA) { KeyId = DefaultX509Key_256ECDSA_KeyId };
#endif
}
@@ -1100,20 +1100,21 @@ public static JsonWebKey JsonWebKeyX509_256ECDSA_With_KeyId
}
}
- public static JsonWebKey JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId_Public
+ public static JsonWebKey JsonWebKeyX509_256ECDSA_As_ECDSA
{
get
{
- var ecdsa = DefaultX509Key_256ECDSA_Public_With_KeyId.PublicKey as ECDsa;
- var ecParams = ecdsa.ExportParameters(false);
+ var ecdsa = DefaultX509Key_256ECDSA.PrivateKey as ECDsa;
+ var ecParams = ecdsa.ExportParameters(true);
var jsonWebKey = new JsonWebKey
{
Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,
- Kid = DefaultX509Key_256ECDSA_KeyId,
+ Kid = DefaultX509Key_256ECDSA_Thumbprint,
Crv = JsonWebKeyECTypes.P256,
+ D = Base64UrlEncoder.Encode(ecParams.D),
X = Base64UrlEncoder.Encode(ecParams.Q.X),
- Y = Base64UrlEncoder.Encode(ecParams.Q.Y),
+ Y = Base64UrlEncoder.Encode(ecParams.Q.Y)
};
return jsonWebKey;
@@ -1134,7 +1135,7 @@ public static JsonWebKey JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId
Crv = JsonWebKeyECTypes.P256,
D = Base64UrlEncoder.Encode(ecParams.D),
X = Base64UrlEncoder.Encode(ecParams.Q.X),
- Y = Base64UrlEncoder.Encode(ecParams.Q.Y),
+ Y = Base64UrlEncoder.Encode(ecParams.Q.Y)
};
return jsonWebKey;
diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs b/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
index 79d08935e3..98e523602d 100644
--- a/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
+++ b/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
@@ -226,18 +226,18 @@ public static TheoryData ConvertX509SecurityKeyTo
theoryData.Add(new JsonWebKeyConverterTheoryData
{
- SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA_Public_With_KeyId,
+ SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA,
RepresentAsRsaKey = true,
- JsonWebKey = KeyingMaterial.JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId_Public,
- TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA_Public) + nameof(JsonWebKeyConverterTheoryData.RepresentAsRsaKey)
+ JsonWebKey = KeyingMaterial.JsonWebKeyX509_256ECDSA_As_ECDSA,
+ TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA_With_KeyId) + nameof(JsonWebKeyConverterTheoryData.RepresentAsRsaKey)
});
theoryData.Add(new JsonWebKeyConverterTheoryData
{
- SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA,
+ SecurityKey = KeyingMaterial.DefaultX509Key_256ECDSA_With_KeyId,
RepresentAsRsaKey = true,
JsonWebKey = KeyingMaterial.JsonWebKeyX509_256ECDSA_As_ECDSA_With_KeyId,
- TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA)
+ TestId = nameof(KeyingMaterial.DefaultX509Key_256ECDSA) + nameof(JsonWebKeyConverterTheoryData.RepresentAsRsaKey)
});
#endif
return theoryData;
From 4fbfb2243b6dcd41cbe35768bfc6fcdae17a970a Mon Sep 17 00:00:00 2001
From: joegoldman2 <147369450+joegoldman@users.noreply.github.com>
Date: Wed, 3 Jul 2024 03:39:25 +0000
Subject: [PATCH 6/8] Change order for validation
---
.../JsonWebKeyConverter.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs b/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
index 2388fd9fac..28673795bb 100644
--- a/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
@@ -130,12 +130,12 @@ public static JsonWebKey ConvertFromX509SecurityKey(X509SecurityKey key)
/// if is null.
public static JsonWebKey ConvertFromX509SecurityKey(X509SecurityKey key, bool representAsRsaKey)
{
- if (!representAsRsaKey)
- return ConvertFromX509SecurityKey(key);
-
if (key == null)
throw LogHelper.LogArgumentNullException(nameof(key));
+ if (!representAsRsaKey)
+ return ConvertFromX509SecurityKey(key);
+
if (key.PrivateKeyStatus == PrivateKeyStatus.Exists)
{
if (key.PrivateKey is RSA rsaPrivateKey)
@@ -192,15 +192,15 @@ public static JsonWebKey ConvertFromSymmetricSecurityKey(SymmetricSecurityKey ke
/// if is null.
public static JsonWebKey ConvertFromECDsaSecurityKey(ECDsaSecurityKey key)
{
- if (!ECDsaAdapter.SupportsECParameters())
- throw LogHelper.LogExceptionMessage(new PlatformNotSupportedException(LogMessages.IDX10695));
-
if (key == null)
throw LogHelper.LogArgumentNullException(nameof(key));
if (key.ECDsa == null)
throw LogHelper.LogArgumentNullException(nameof(key.ECDsa));
+ if (!ECDsaAdapter.SupportsECParameters())
+ throw LogHelper.LogExceptionMessage(new PlatformNotSupportedException(LogMessages.IDX10695));
+
ECParameters parameters;
try
{
From b920682956841e9b576c0151d9194d601ba559fc Mon Sep 17 00:00:00 2001
From: joegoldman2 <147369450+joegoldman@users.noreply.github.com>
Date: Wed, 3 Jul 2024 04:43:11 +0000
Subject: [PATCH 7/8] Add condition for .NET 4.7.2 or NET
---
test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
index 4eaaf63e30..a2b959c966 100644
--- a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
+++ b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
@@ -98,12 +98,14 @@ static public class KeyingMaterial
public static SigningCredentials DefaultX509SigningCreds_2048_RsaSha2_Sha2 = new SigningCredentials(DefaultX509Key_2048, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
public static X509Certificate2 DefaultAsymmetricCert_2048 = new X509Certificate2(Convert.FromBase64String(DefaultX509Data_2048), CertPassword, X509KeyStorageFlags.MachineKeySet);
+#if NET472 || NET_CORE
// 256 bit ECDSA
public static X509Certificate2 DefaultCert_256ECDSA;
public static string DefaultX509Key_256ECDSA_Thumbprint;
public static string DefaultX509Key_256ECDSA_KeyId = "DefaultX509Key_256ECDSA_KeyId";
public static X509SecurityKey DefaultX509Key_256ECDSA;
public static X509SecurityKey DefaultX509Key_256ECDSA_With_KeyId;
+#endif
public static string DefaultX509Data_2048_Public = @"MIICyjCCAbKgAwIBAgIQJPMYqnyiTY1GQYAwZxadMjANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDExZBREZTIFNpZ25pbmcgLSBTVFMuY29tMB4XDTEyMTAwOTIyMTA0OVoXDTEzMTAwOTIyMTA0OVowITEfMB0GA1UEAxMWQURGUyBTaWduaW5nIC0gU1RTLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmeVPJz8o7ayB3AS2dJtsIo/eXqeNhZ+ZqEJgHVHc0JAAgNNwR++moMt8+iIlOKZiAL8dvQBKOuPms+FfqrG1HshnMiLcuadtWUqOntxUdyQLcEKvdaFOqOppqmasqGFtRLPwYKIkZOkj8ikndNzI6PZV46mw18nLaN6rTByMnjVA5n9Lf7Cdu7lmxlKGJOI5F0IfeaW68/kY1bdw3KAEb1aOKHj0r7RJ2joRuHJ+96kw1bA2T6bGC/1LYND3DFsnQQtMBl7LlDrSG1gGoiZxCoQmPCxfrTCrYKGK6y9j6IQ4MCmJpnt0l/INL5i88TjctF4IkJwbJGn9iY2fIIBxMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAq/SyHGCLpBm+Gmh5I7BAWJXvtPaIelt30WgKVXRHccxRVIYpKOfAA2iPuD/CVruFz6pnP4K7o2KLAs+XJptigYzLEjKw6rY4836ZJC8m5kfBVanu45OW39nxzxp1udbxQ5gAdmvnY/2agpFhCFR8M1BtWON6G3SzHwo2dXHh+ettOO2LtK38e1+Uy+KGowRw/m4gprSIvgN3AAo7e0PnFblZn6vRgMsK60QB5D8f+Kxdg2I3ZGQcPBQI2fpjEDQCZVc2LV4ywPX4QDPfmYjn+1IaU9w7unbh+oUGQsrdKw3gsdzWEsX/IMXTDf46FEOjV+JqE7VilzcNuDcQ0x9K8gAA";
public static X509Certificate2 DefaultCert_2048_Public
From 9ea0c2dc50dca400975cd9391e33a6535304e408 Mon Sep 17 00:00:00 2001
From: joegoldman2 <147369450+joegoldman@users.noreply.github.com>
Date: Sat, 17 Aug 2024 11:41:00 +0000
Subject: [PATCH 8/8] Fix unit tests
---
test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs | 1 -
.../JsonWebKeyConverterTest.cs | 5 ++---
.../X509SecurityKeyTests.cs | 2 ++
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
index a2b959c966..17c5a94bc5 100644
--- a/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
+++ b/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs
@@ -516,7 +516,6 @@ static KeyingMaterial()
DefaultX509Key_256ECDSA = new X509SecurityKey(DefaultCert_256ECDSA);
DefaultX509Key_256ECDSA_With_KeyId = new X509SecurityKey(DefaultCert_256ECDSA) { KeyId = DefaultX509Key_256ECDSA_KeyId };
#endif
-
}
#if NET462
diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs b/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
index 2ebdc8d424..bee08cdbec 100644
--- a/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
+++ b/test/Microsoft.IdentityModel.Tokens.Tests/JsonWebKeyConverterTest.cs
@@ -63,9 +63,8 @@ public void ConvertX509SecurityKeyAsRsaSecurityKeyToJsonWebKey(JsonWebKeyConvert
theoryData.ExpectedException.ProcessNoException(context);
IdentityComparer.AreEqual(convertedKey, theoryData.JsonWebKey, context);
- //var expectedConvertedKeyType = theoryData.RepresentAsRsaKey == true ? typeof(RsaSecurityKey) : typeof(X509SecurityKey);
- //if (convertedKey.ConvertedSecurityKey.GetType() != expectedConvertedKeyType)
- //context.AddDiff($"convertedKey.ConvertedSecurityKey.GetType(): '{convertedKey.ConvertedSecurityKey.GetType()}' != expectedConvertedKeyType: '{expectedConvertedKeyType}'.");
+ if (!theoryData.RepresentAsRsaKey && convertedKey.ConvertedSecurityKey.GetType() != typeof(X509SecurityKey))
+ context.AddDiff($"convertedKey.ConvertedSecurityKey.GetType() should be {typeof(X509SecurityKey)}.");
}
catch (Exception ex)
{
diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs
index b77220606d..e1405b378f 100644
--- a/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs
+++ b/test/Microsoft.IdentityModel.Tokens.Tests/X509SecurityKeyTests.cs
@@ -77,6 +77,7 @@ public void Constructor()
TestUtilities.AssertFailIfErrors(context);
}
+#if NET472 || NET_CORE
[Fact]
public void Constructor_WithECDsa()
{
@@ -93,6 +94,7 @@ public void Constructor_WithECDsa()
Assert.NotEmpty(x509SecurityKey.ComputeJwkThumbprint());
TestUtilities.AssertFailIfErrors(context);
}
+#endif
[Fact]
public void CanComputeJwkThumbprint()