Skip to content

Commit 26d94db

Browse files
iNinjaCopilot
andcommitted
Thread safety for ML-DSA key init, null guards in X509 adapter path
- Make _mlDsaPrivateKeyInitialized and _mlDsaPublicKeyInitialized volatile to ensure correct publication across threads in double-checked locking - Add IDX10725 for X509 certs where key extraction fails (unsupported platform or unrecognised key type) - Guard null PrivateKey before passing to InitializeUsingRsa to prevent deferred NRE when X509 cert has no private key - Register IDX10725 in InternalAPI.Unshipped.txt Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 99492ef commit 26d94db

4 files changed

Lines changed: 24 additions & 2 deletions

File tree

src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,28 @@ private void InitializeUsingX509SecurityKey(
302302

303303
InitializeUsingMlDsa(mlDsa);
304304
}
305+
else if (x509SecurityKey.PublicKey == null)
306+
{
307+
// Certificate contains neither a supported classical key (RSA/ECDSA) nor
308+
// an extractable ML-DSA key. This occurs when the certificate uses a key
309+
// type that the platform cannot extract (e.g., ML-DSA on older OS versions).
310+
throw LogHelper.LogExceptionMessage(
311+
new NotSupportedException(
312+
LogHelper.FormatInvariant(
313+
LogMessages.IDX10725,
314+
LogHelper.MarkAsNonPII(algorithm),
315+
LogHelper.MarkAsNonPII(x509SecurityKey.KeyId))));
316+
}
305317
else if (requirePrivateKey)
306318
{
319+
if (x509SecurityKey.PrivateKey == null)
320+
throw LogHelper.LogExceptionMessage(
321+
new InvalidOperationException(
322+
LogHelper.FormatInvariant(
323+
LogMessages.IDX10723,
324+
LogHelper.MarkAsNonPII(algorithm),
325+
LogHelper.MarkAsNonPII(x509SecurityKey.KeyId))));
326+
307327
InitializeUsingRsa(x509SecurityKey.PrivateKey as RSA, algorithm);
308328
}
309329
else

src/Microsoft.IdentityModel.Tokens/InternalAPI.Unshipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,4 @@ const Microsoft.IdentityModel.Tokens.LogMessages.IDX10721 = "IDX10721: Unable to
122122
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10722 = "IDX10722: The AKP JsonWebKey (alg: '{0}') has inconsistent key material. The 'pub' parameter does not match the public key derived from 'priv'." -> string
123123
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10723 = "IDX10723: Unable to extract the private key from the X.509 certificate for algorithm '{0}' (Key: '{1}'). Private key extraction may not be supported on this platform." -> string
124124
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10724 = "IDX10724: Unable to compute a JWK thumbprint, public key extraction from the X.509 certificate is not supported on this platform (Key: '{0}')." -> string
125+
const Microsoft.IdentityModel.Tokens.LogMessages.IDX10725 = "IDX10725: Unable to create a SignatureProvider for algorithm '{0}' (Key: '{1}'). The X.509 certificate key could not be extracted. This may indicate the platform does not support the certificate's key type." -> string

src/Microsoft.IdentityModel.Tokens/LogMessages.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ internal static class LogMessages
281281
public const string IDX10722 = "IDX10722: The AKP JsonWebKey (alg: '{0}') has inconsistent key material. The 'pub' parameter does not match the public key derived from 'priv'.";
282282
public const string IDX10723 = "IDX10723: Unable to extract the private key from the X.509 certificate for algorithm '{0}' (Key: '{1}'). Private key extraction may not be supported on this platform.";
283283
public const string IDX10724 = "IDX10724: Unable to compute a JWK thumbprint, public key extraction from the X.509 certificate is not supported on this platform (Key: '{0}').";
284+
public const string IDX10725 = "IDX10725: Unable to create a SignatureProvider for algorithm '{0}' (Key: '{1}'). The X.509 certificate key could not be extracted. This may indicate the platform does not support the certificate's key type.";
284285

285286
// Json specific errors
286287
//public const string IDX10801 = "IDX10801:"

src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public class X509SecurityKey : AsymmetricSecurityKey
3535
MLDsa _mlDsaPrivateKey;
3636
MLDsa _mlDsaPublicKey;
3737
bool _isMlDsa;
38-
bool _mlDsaPrivateKeyInitialized;
39-
bool _mlDsaPublicKeyInitialized;
38+
volatile bool _mlDsaPrivateKeyInitialized;
39+
volatile bool _mlDsaPublicKeyInitialized;
4040
bool _mlDsaPrivateKeyUnsupported;
4141
#if NET9_0_OR_GREATER
4242
Lock _thisLock = new();

0 commit comments

Comments
 (0)