From 2562415fd983f1111c3c381ba48c1b2ba54a4506 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 11:34:12 -0400 Subject: [PATCH 01/34] First set of key loaders to use value-type reading --- .../Cryptography/Asn1/ECDomainParameters.xml | 10 +- .../Asn1/ECDomainParameters.xml.cs | 58 ++++++++ .../Cryptography/Asn1/ECPrivateKey.xml | 9 +- .../Cryptography/Asn1/ECPrivateKey.xml.cs | 105 ++++++++++++++ .../Cryptography/Asn1/MLDsaPrivateKeyAsn.xml | 8 +- .../Asn1/MLDsaPrivateKeyAsn.xml.cs | 86 ++++++++++++ .../Asn1/MLDsaPrivateKeyBothAsn.xml | 3 +- .../Asn1/MLDsaPrivateKeyBothAsn.xml.cs | 74 ++++++++++ .../Cryptography/Asn1/MLKemPrivateKeyAsn.xml | 8 +- .../Asn1/MLKemPrivateKeyAsn.xml.cs | 86 ++++++++++++ .../Asn1/MLKemPrivateKeyBothAsn.xml | 3 +- .../Asn1/MLKemPrivateKeyBothAsn.xml.cs | 74 ++++++++++ .../Cryptography/Asn1/PrivateKeyInfoAsn.xml | 14 +- .../Asn1/PrivateKeyInfoAsn.xml.cs | 132 ++++++++++++++++++ .../Cryptography/Asn1/SpecifiedECDomain.xml | 5 +- .../Asn1/SpecifiedECDomain.xml.cs | 92 ++++++++++++ .../Security/Cryptography/CompositeMLDsa.cs | 18 ++- .../CompositeMLDsaManaged.ECDsa.cs | 95 ++++++------- .../System/Security/Cryptography/Helpers.cs | 10 +- .../Security/Cryptography/KeyFormatHelper.cs | 59 ++++++++ .../src/System/Security/Cryptography/MLDsa.cs | 64 ++++----- .../src/System/Security/Cryptography/MLKem.cs | 40 +++--- .../System/Security/Cryptography/SlhDsa.cs | 19 ++- 23 files changed, 925 insertions(+), 147 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml index 2ca6f12c0466f6..2048a92a4392dd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - + - \ No newline at end of file + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs index c5c1a5cd340afc..56133fc212f3a2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs @@ -118,4 +118,62 @@ private static void DecodeCore(ref ValueAsnReader reader, ReadOnlyMemory r } } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueECDomainParameters + { + internal System.Security.Cryptography.Asn1.ValueSpecifiedECDomain Specified; + internal bool HasSpecified; + internal string? Named; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueECDomainParameters decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueECDomainParameters decoded) + { + try + { + DecodeCore(ref reader, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, out ValueECDomainParameters decoded) + { + decoded = default; + Asn1Tag tag = reader.PeekTag(); + + if (tag.HasSameClassAndValue(Asn1Tag.Sequence)) + { + System.Security.Cryptography.Asn1.ValueSpecifiedECDomain tmpSpecified; + System.Security.Cryptography.Asn1.ValueSpecifiedECDomain.Decode(ref reader, out tmpSpecified); + decoded.Specified = tmpSpecified; + + decoded.HasSpecified = true; + } + else if (tag.HasSameClassAndValue(Asn1Tag.ObjectIdentifier)) + { + decoded.Named = reader.ReadObjectIdentifier(); + } + else + { + throw new CryptographicException(); + } + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml index c5fcf187449e23..7972746362c76f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs index 5b1bd3e8efd494..98ec3238211d43 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs @@ -138,6 +138,111 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R } + sequenceReader.ThrowIfNotEmpty(); + } + } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueECPrivateKey + { + internal int Version; + internal ReadOnlySpan PrivateKey; + internal System.Security.Cryptography.Asn1.ValueECDomainParameters Parameters; + internal bool HasParameters; + internal ReadOnlySpan PublicKey; + internal bool HasPublicKey; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueECPrivateKey decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueECPrivateKey decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueECPrivateKey decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueECPrivateKey decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueECPrivateKey decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + ValueAsnReader explicitReader; + ReadOnlySpan tmpSpan; + + + if (!sequenceReader.TryReadInt32(out decoded.Version)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + + if (sequenceReader.TryReadPrimitiveOctetString(out tmpSpan)) + { + decoded.PrivateKey = tmpSpan; + } + else + { + decoded.PrivateKey = sequenceReader.ReadOctetString(); + } + + + if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) + { + explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + System.Security.Cryptography.Asn1.ValueECDomainParameters tmpParameters; + System.Security.Cryptography.Asn1.ValueECDomainParameters.Decode(ref explicitReader, out tmpParameters); + decoded.Parameters = tmpParameters; + + decoded.HasParameters = true; + explicitReader.ThrowIfNotEmpty(); + } + + + if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) + { + explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); + + if (explicitReader.TryReadPrimitiveBitString(out _, out tmpSpan)) + { + decoded.PublicKey = tmpSpan; + } + else + { + decoded.PublicKey = explicitReader.ReadBitString(out _); + } + + decoded.HasPublicKey = true; + explicitReader.ThrowIfNotEmpty(); + } + + sequenceReader.ThrowIfNotEmpty(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml index 439609c36fc65f..faf0d6872436a2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs index af874c8186eb70..dbbbce610526e7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs @@ -147,4 +147,90 @@ private static void DecodeCore(ref ValueAsnReader reader, ReadOnlyMemory r } } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueMLDsaPrivateKeyAsn + { + internal ReadOnlySpan Seed; + internal bool HasSeed; + internal ReadOnlySpan ExpandedKey; + internal bool HasExpandedKey; + internal System.Security.Cryptography.Asn1.ValueMLDsaPrivateKeyBothAsn Both; + internal bool HasBoth; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueMLDsaPrivateKeyAsn decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueMLDsaPrivateKeyAsn decoded) + { + try + { + DecodeCore(ref reader, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, out ValueMLDsaPrivateKeyAsn decoded) + { + decoded = default; + Asn1Tag tag = reader.PeekTag(); + ReadOnlySpan tmpSpan; + + if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) + { + + if (reader.TryReadPrimitiveOctetString(out tmpSpan, new Asn1Tag(TagClass.ContextSpecific, 0))) + { + decoded.Seed = tmpSpan; + } + else + { + decoded.Seed = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 0)); + } + + decoded.HasSeed = true; + } + else if (tag.HasSameClassAndValue(Asn1Tag.PrimitiveOctetString)) + { + + if (reader.TryReadPrimitiveOctetString(out tmpSpan)) + { + decoded.ExpandedKey = tmpSpan; + } + else + { + decoded.ExpandedKey = reader.ReadOctetString(); + } + + decoded.HasExpandedKey = true; + } + else if (tag.HasSameClassAndValue(Asn1Tag.Sequence)) + { + System.Security.Cryptography.Asn1.ValueMLDsaPrivateKeyBothAsn tmpBoth; + System.Security.Cryptography.Asn1.ValueMLDsaPrivateKeyBothAsn.Decode(ref reader, out tmpBoth); + decoded.Both = tmpBoth; + + decoded.HasBoth = true; + } + else + { + throw new CryptographicException(); + } + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml index 8f19fe890289f7..0ae83d5f1d847c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs index 7b15373d0afa72..b34df12487145d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs @@ -147,4 +147,90 @@ private static void DecodeCore(ref ValueAsnReader reader, ReadOnlyMemory r } } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueMLKemPrivateKeyAsn + { + internal ReadOnlySpan Seed; + internal bool HasSeed; + internal ReadOnlySpan ExpandedKey; + internal bool HasExpandedKey; + internal System.Security.Cryptography.Asn1.ValueMLKemPrivateKeyBothAsn Both; + internal bool HasBoth; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueMLKemPrivateKeyAsn decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueMLKemPrivateKeyAsn decoded) + { + try + { + DecodeCore(ref reader, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, out ValueMLKemPrivateKeyAsn decoded) + { + decoded = default; + Asn1Tag tag = reader.PeekTag(); + ReadOnlySpan tmpSpan; + + if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) + { + + if (reader.TryReadPrimitiveOctetString(out tmpSpan, new Asn1Tag(TagClass.ContextSpecific, 0))) + { + decoded.Seed = tmpSpan; + } + else + { + decoded.Seed = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 0)); + } + + decoded.HasSeed = true; + } + else if (tag.HasSameClassAndValue(Asn1Tag.PrimitiveOctetString)) + { + + if (reader.TryReadPrimitiveOctetString(out tmpSpan)) + { + decoded.ExpandedKey = tmpSpan; + } + else + { + decoded.ExpandedKey = reader.ReadOctetString(); + } + + decoded.HasExpandedKey = true; + } + else if (tag.HasSameClassAndValue(Asn1Tag.Sequence)) + { + System.Security.Cryptography.Asn1.ValueMLKemPrivateKeyBothAsn tmpBoth; + System.Security.Cryptography.Asn1.ValueMLKemPrivateKeyBothAsn.Decode(ref reader, out tmpBoth); + decoded.Both = tmpBoth; + + decoded.HasBoth = true; + } + else + { + throw new CryptographicException(); + } + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml index 9360d3255dc22f..a2657d0ff7b901 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - + - - + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs index 44b49b66f5d4d3..981f0c33dd8dd8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs @@ -134,4 +134,136 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R sequenceReader.ThrowIfNotEmpty(); } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValuePrivateKeyInfoAsn + { + internal int Version; + internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn PrivateKeyAlgorithm; + internal ReadOnlySpan PrivateKey; + internal ReadOnlySpan Attributes; + internal bool HasAttributes; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePrivateKeyInfoAsn decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePrivateKeyInfoAsn decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValuePrivateKeyInfoAsn decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePrivateKeyInfoAsn decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePrivateKeyInfoAsn decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + ReadOnlySpan tmpSpan; + + + if (!sequenceReader.TryReadInt32(out decoded.Version)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref sequenceReader, out decoded.PrivateKeyAlgorithm); + + if (sequenceReader.TryReadPrimitiveOctetString(out tmpSpan)) + { + decoded.PrivateKey = tmpSpan; + } + else + { + decoded.PrivateKey = sequenceReader.ReadOctetString(); + } + + + if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) + { + decoded.Attributes = sequenceReader.ReadEncodedValue(); + decoded.HasAttributes = true; + } + + + sequenceReader.ThrowIfNotEmpty(); + } + + + internal AttributesEnumerable GetAttributes(AsnEncodingRules ruleSet) + { + return new AttributesEnumerable(Attributes, ruleSet); + } + + internal readonly ref struct AttributesEnumerable + { + private readonly ReadOnlySpan _encoded; + private readonly AsnEncodingRules _ruleSet; + + internal AttributesEnumerable(ReadOnlySpan encoded, AsnEncodingRules ruleSet) + { + _encoded = encoded; + _ruleSet = ruleSet; + } + + public Enumerator GetEnumerator() => new Enumerator(_encoded, _ruleSet); + + internal ref struct Enumerator + { + private ValueAsnReader _reader; + private System.Security.Cryptography.Asn1.ValueAttributeAsn _current; + + internal Enumerator(ReadOnlySpan encoded, AsnEncodingRules ruleSet) + { + if (!encoded.IsEmpty) + { + ValueAsnReader outerReader = new ValueAsnReader(encoded, ruleSet); + _reader = outerReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); + outerReader.ThrowIfNotEmpty(); + } + + _current = default; + } + + public System.Security.Cryptography.Asn1.ValueAttributeAsn Current => _current; + + public bool MoveNext() + { + if (!_reader.HasData) + { + return false; + } + + System.Security.Cryptography.Asn1.ValueAttributeAsn.Decode(ref _reader, out _current); + return true; + } + } + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml index 75056194341b6a..6f50aa39a0f213 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - \ No newline at end of file + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs index 95a799d7cb3e3a..ab7b58a2990425 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs @@ -82,4 +82,59 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R sequenceReader.ThrowIfNotEmpty(); } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueRSAPublicKeyAsn + { + internal ReadOnlySpan Modulus; + internal ReadOnlySpan PublicExponent; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRSAPublicKeyAsn decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRSAPublicKeyAsn decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueRSAPublicKeyAsn decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueRSAPublicKeyAsn decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueRSAPublicKeyAsn decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + + decoded.Modulus = sequenceReader.ReadIntegerBytes(); + decoded.PublicExponent = sequenceReader.ReadIntegerBytes(); + + sequenceReader.ThrowIfNotEmpty(); + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs index d2570a9173dc19..2a6f49a388077a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs @@ -8,14 +8,19 @@ namespace System.Security.Cryptography { internal static partial class KeyBlobHelpers { - internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory) + internal static byte[] ToUnsignedIntegerBytes(this ReadOnlySpan span) { - if (memory.Length > 1 && memory.Span[0] == 0) + if (span.Length > 1 && span[0] == 0) { - return memory.Slice(1).ToArray(); + return span.Slice(1).ToArray(); } - return memory.ToArray(); + return span.ToArray(); + } + + internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory) + { + return ToUnsignedIntegerBytes(memory.Span); } internal static void ToUnsignedIntegerBytes(this ReadOnlyMemory memory, Span destination) diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs index beba3ef856f373..9b2d275dae6841 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs @@ -104,7 +104,7 @@ public override RSAParameters ExportParameters(bool includePrivateParameters) if (sequenceReader.PeekTag().Equals(Asn1Tag.Integer)) { - AlgorithmIdentifierAsn ignored = default; + ValueAlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.ReadRsaPublicKey(keyBlob, ignored, out key); } else diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.macOS.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.macOS.cs index 2fbebb5a7d4495..6c3810da4d2def 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.macOS.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.macOS.cs @@ -44,7 +44,7 @@ private static RSAParameters ExportParametersFromLegacyKey(SecKeyPair keys, bool if (sequenceReader.PeekTag().Equals(Asn1Tag.Integer)) { - AlgorithmIdentifierAsn ignored = default; + ValueAlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.ReadRsaPublicKey(keyBlob, ignored, out key); } else diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs index 016082439bc35c..26c4422c0bcafb 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs @@ -91,22 +91,11 @@ static TRet ExtractParametersWithCallback(RSAParametersCallback parameters } } - internal static unsafe TRet FromPkcs1PublicKey( + internal static TRet FromPkcs1PublicKey( ReadOnlySpan keyData, RSAParametersCallback parametersReader) { - fixed (byte* ptr = &MemoryMarshal.GetReference(keyData)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, keyData.Length)) - { - return FromPkcs1PublicKey(manager.Memory, parametersReader); - } - } - } - - internal static TRet FromPkcs1PublicKey(ReadOnlyMemory keyData, RSAParametersCallback parametersReader) - { - RSAPublicKeyAsn key = RSAPublicKeyAsn.Decode(keyData, AsnEncodingRules.BER); + ValueRSAPublicKeyAsn.Decode(keyData, AsnEncodingRules.BER, out ValueRSAPublicKeyAsn key); RSAParameters parameters = new RSAParameters { @@ -117,6 +106,12 @@ internal static TRet FromPkcs1PublicKey(ReadOnlyMemory keyData, RSAP return parametersReader(parameters); } + // TODO: remove? + internal static TRet FromPkcs1PublicKey(ReadOnlyMemory keyData, RSAParametersCallback parametersReader) + { + return FromPkcs1PublicKey(keyData.Span, parametersReader); + } + internal static AsnWriter WritePkcs1PublicKey(in RSAParameters rsaParameters) { if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs index 0342133f8dcab3..e1da78fc92406d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs @@ -29,8 +29,8 @@ internal static void FromPkcs1PrivateKey( } internal static void ReadRsaPublicKey( - ReadOnlyMemory keyData, - in AlgorithmIdentifierAsn algId, + ReadOnlySpan keyData, + in ValueAlgorithmIdentifierAsn algId, out RSAParameters ret) { ret = FromPkcs1PublicKey(keyData, rsaParameters => rsaParameters); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs index e9454c4f76a7f6..fb84fa8ca402e0 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs @@ -888,7 +888,7 @@ public override unsafe void ImportSubjectPublicKeyInfo(ReadOnlySpan source } } - public virtual unsafe void ImportRSAPublicKey(ReadOnlySpan source, out int bytesRead) + public virtual void ImportRSAPublicKey(ReadOnlySpan source, out int bytesRead) { try { @@ -899,18 +899,12 @@ public virtual unsafe void ImportRSAPublicKey(ReadOnlySpan source, out int out _, out int localRead); - fixed (byte* ptr = &MemoryMarshal.GetReference(source)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, localRead)) - { - AlgorithmIdentifierAsn ignored = default; - RSAKeyFormatHelper.ReadRsaPublicKey(manager.Memory, ignored, out RSAParameters rsaParameters); + ValueAlgorithmIdentifierAsn ignored = default; + RSAKeyFormatHelper.ReadRsaPublicKey(source, ignored, out RSAParameters rsaParameters); - ImportParameters(rsaParameters); + ImportParameters(rsaParameters); - bytesRead = localRead; - } - } + bytesRead = localRead; } catch (AsnContentException e) { From f83e2e73154fe617a210e8956360f13a65508c07 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 12:14:32 -0400 Subject: [PATCH 04/34] Fix encoding of unknown algorithms --- .../Common/src/System/Security/Cryptography/Helpers.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs index 490fa392deadc3..ddfcf8458a34a6 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs @@ -217,11 +217,15 @@ internal static IncrementalHash CreateIncrementalHash(HashAlgorithmName hashAlgo internal static CryptographicException CreateAlgorithmUnknownException(ref readonly ValueAlgorithmIdentifierAsn identifier) { AsnWriter encodedId = new(AsnEncodingRules.DER); - encodedId.WriteObjectIdentifier(identifier.Algorithm); - if (identifier.HasParameters) + using (encodedId.PushSequence()) { - encodedId.WriteEncodedValue(identifier.Parameters); + encodedId.WriteObjectIdentifier(identifier.Algorithm); + + if (identifier.HasParameters) + { + encodedId.WriteEncodedValue(identifier.Parameters); + } } #if NET return encodedId.Encode(static encoded => CreateAlgorithmUnknownException(Convert.ToHexString(encoded))); From aafa60bb9879798f32ade0fabfbc927a13fb2665 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 12:15:35 -0400 Subject: [PATCH 05/34] Move more RSA public key reading to value readers --- .../Security/Cryptography/KeyFormatHelper.cs | 29 +++++++++++++++++ .../Cryptography/RSAKeyFormatHelper.cs | 31 ++++++------------- .../Security/Cryptography/RSAOpenSsl.cs | 16 +++++----- .../src/System/Security/Cryptography/RSA.cs | 16 +++------- 4 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs index 0cea11095b63b0..6bef240063f1b9 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs @@ -89,6 +89,35 @@ internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( return spki.SubjectPublicKey; } + internal static ReadOnlySpan ReadSubjectPublicKeyInfo( + string[] validOids, + ReadOnlySpan source, + out int bytesRead) + { + ValueSubjectPublicKeyInfoAsn spki; + int read; + + try + { + // X.509 SubjectPublicKeyInfo is described as DER. + ValueAsnReader reader = new ValueAsnReader(source, AsnEncodingRules.DER); + read = reader.PeekEncodedValue().Length; + ValueSubjectPublicKeyInfoAsn.Decode(ref reader, out spki); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + if (Array.IndexOf(validOids, spki.Algorithm.Algorithm) < 0) + { + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + } + + bytesRead = read; + return spki.SubjectPublicKey; + } + private static void ReadSubjectPublicKeyInfo( string[] validOids, ReadOnlyMemory source, diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs index e1da78fc92406d..a05e8599bf8621 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs @@ -69,9 +69,15 @@ internal static void ReadSubjectPublicKeyInfo( out key); } - internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( - ReadOnlyMemory source, - out int bytesRead) + // internal static ReadOnlyMemory ReadSubjectPublicKeyInfo(ReadOnlyMemory source, out int bytesRead) + // { + // return KeyFormatHelper.ReadSubjectPublicKeyInfo( + // s_validOids, + // source, + // out bytesRead); + // } + + internal static ReadOnlySpan ReadSubjectPublicKeyInfo(ReadOnlySpan source, out int bytesRead) { return KeyFormatHelper.ReadSubjectPublicKeyInfo( s_validOids, @@ -79,25 +85,6 @@ internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( out bytesRead); } - /// - /// Checks that a SubjectPublicKeyInfo represents an RSA key. - /// - /// The number of bytes read from . - internal static unsafe int CheckSubjectPublicKeyInfo(ReadOnlySpan source) - { - int bytesRead; - - fixed (byte* ptr = source) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, source.Length)) - { - _ = ReadSubjectPublicKeyInfo(manager.Memory, out bytesRead); - } - } - - return bytesRead; - } - internal static ReadOnlyMemory ReadPkcs8( ReadOnlyMemory source, out int bytesRead) diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs index 4c69763709e631..52e157a3e2d469 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs @@ -316,7 +316,7 @@ private bool TryExportPrivateKey(TryExportPrivateKeySelector selector, Span(Func, T> exporter) + private T ExportPublicKey(Func, T> exporter) { // It's entirely possible that this line will cause the key to be generated in the first place. SafeEvpPKeyHandle key = GetKey(); @@ -334,7 +334,7 @@ private T ExportPublicKey(Func, T> exporter) } private bool TryExportPublicKey( - Func, ReadOnlyMemory>? transform, + Func, ReadOnlySpan>? transform, Span destination, out int bytesWritten) { @@ -345,14 +345,14 @@ private bool TryExportPublicKey( try { - ReadOnlyMemory data = spki; + ReadOnlySpan data = spki; if (transform != null) { data = transform(data); } - return data.Span.TryCopyToDestination(destination, out bytesWritten); + return data.TryCopyToDestination(destination, out bytesWritten); } finally { @@ -385,7 +385,7 @@ public override byte[] ExportRSAPublicKey() return ExportPublicKey( static spki => { - ReadOnlyMemory pkcs1 = RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(spki, out int read); + ReadOnlySpan pkcs1 = RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(spki, out int read); Debug.Assert(read == spki.Length); return pkcs1.ToArray(); }); @@ -396,7 +396,7 @@ public override bool TryExportRSAPublicKey(Span destination, out int bytes return TryExportPublicKey( spki => { - ReadOnlyMemory pkcs1 = RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(spki, out int read); + ReadOnlySpan pkcs1 = RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(spki, out int read); Debug.Assert(read == spki.Length); return pkcs1; }, @@ -436,7 +436,7 @@ public override RSAParameters ExportParameters(bool includePrivateParameters) { RSAParameters ret; RSAKeyFormatHelper.ReadSubjectPublicKeyInfo( - spki.Span, + spki, out int read, out ret); @@ -515,7 +515,7 @@ private void ImportSubjectPublicKeyInfo( if (checkAlgorithm) { - read = RSAKeyFormatHelper.CheckSubjectPublicKeyInfo(source); + RSAKeyFormatHelper.ReadSubjectPublicKeyInfo(source, out read); } else { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs index fb84fa8ca402e0..c0757af491acb9 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs @@ -874,18 +874,12 @@ private unsafe AsnWriter WritePkcs1PrivateKey() public override unsafe void ImportSubjectPublicKeyInfo(ReadOnlySpan source, out int bytesRead) { - fixed (byte* ptr = &MemoryMarshal.GetReference(source)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, source.Length)) - { - ReadOnlyMemory pkcs1 = RSAKeyFormatHelper.ReadSubjectPublicKeyInfo( - manager.Memory, - out int localRead); + ReadOnlySpan pkcs1 = RSAKeyFormatHelper.ReadSubjectPublicKeyInfo( + source, + out int localRead); - ImportRSAPublicKey(pkcs1.Span, out _); - bytesRead = localRead; - } - } + ImportRSAPublicKey(pkcs1, out _); + bytesRead = localRead; } public virtual void ImportRSAPublicKey(ReadOnlySpan source, out int bytesRead) From f932e376adedcf3486c18c8fa7e1918c5d235e03 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 12:18:41 -0400 Subject: [PATCH 06/34] Remove dead reader code --- .../System/Security/Cryptography/DSAKeyFormatHelper.cs | 10 ---------- .../System/Security/Cryptography/RSAKeyFormatHelper.cs | 8 -------- 2 files changed, 18 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs index 211086b4f2bf49..bb057eeb892e2d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs @@ -172,16 +172,6 @@ internal static void ReadSubjectPublicKeyInfo( out key); } - internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( - ReadOnlyMemory source, - out int bytesRead) - { - return KeyFormatHelper.ReadSubjectPublicKeyInfo( - s_validOids, - source, - out bytesRead); - } - internal static void ReadPkcs8( ReadOnlySpan source, out int bytesRead, diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs index a05e8599bf8621..6231aba31300ca 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs @@ -69,14 +69,6 @@ internal static void ReadSubjectPublicKeyInfo( out key); } - // internal static ReadOnlyMemory ReadSubjectPublicKeyInfo(ReadOnlyMemory source, out int bytesRead) - // { - // return KeyFormatHelper.ReadSubjectPublicKeyInfo( - // s_validOids, - // source, - // out bytesRead); - // } - internal static ReadOnlySpan ReadSubjectPublicKeyInfo(ReadOnlySpan source, out int bytesRead) { return KeyFormatHelper.ReadSubjectPublicKeyInfo( From 203b6087a35b6097d1817ef3fbc191e0f9631767 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 12:21:05 -0400 Subject: [PATCH 07/34] Remove unused memory reader --- .../Security/Cryptography/KeyFormatHelper.cs | 29 ------------------- .../Cryptography/EccKeyFormatHelper.cs | 10 ------- 2 files changed, 39 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs index 6bef240063f1b9..9ed5427023fd05 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs @@ -60,35 +60,6 @@ internal static void ReadSubjectPublicKeyInfo( bytesRead = read; } - internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( - string[] validOids, - ReadOnlyMemory source, - out int bytesRead) - { - SubjectPublicKeyInfoAsn spki; - int read; - - try - { - // X.509 SubjectPublicKeyInfo is described as DER. - ValueAsnReader reader = new ValueAsnReader(source.Span, AsnEncodingRules.DER); - read = reader.PeekEncodedValue().Length; - SubjectPublicKeyInfoAsn.Decode(ref reader, source, out spki); - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - - if (Array.IndexOf(validOids, spki.Algorithm.Algorithm) < 0) - { - throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); - } - - bytesRead = read; - return spki.SubjectPublicKey; - } - internal static ReadOnlySpan ReadSubjectPublicKeyInfo( string[] validOids, ReadOnlySpan source, diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/EccKeyFormatHelper.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/EccKeyFormatHelper.cs index 25826217d325c2..69546b5663c3fb 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/EccKeyFormatHelper.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/EccKeyFormatHelper.cs @@ -35,16 +35,6 @@ internal static void ReadSubjectPublicKeyInfo( out key); } - internal static ReadOnlyMemory ReadSubjectPublicKeyInfo( - ReadOnlyMemory source, - out int bytesRead) - { - return KeyFormatHelper.ReadSubjectPublicKeyInfo( - s_validOids, - source, - out bytesRead); - } - internal static void ReadEncryptedPkcs8( ReadOnlySpan source, ReadOnlySpan password, From b965e1ed50f5a3c0479bf46a69a609f402bf11c7 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 12:57:24 -0400 Subject: [PATCH 08/34] Remove now unused code --- .../Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs index 26c4422c0bcafb..a855f24e2b1544 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs @@ -106,12 +106,6 @@ internal static TRet FromPkcs1PublicKey( return parametersReader(parameters); } - // TODO: remove? - internal static TRet FromPkcs1PublicKey(ReadOnlyMemory keyData, RSAParametersCallback parametersReader) - { - return FromPkcs1PublicKey(keyData.Span, parametersReader); - } - internal static AsnWriter WritePkcs1PublicKey(in RSAParameters rsaParameters) { if (rsaParameters.Modulus == null || rsaParameters.Exponent == null) From 7d84a90c23c631c38d273b11bcc903e6ddaeeacb Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 14:16:50 -0400 Subject: [PATCH 09/34] Value struct support for PasswordBasedEncryption --- .../Asn1/AlgorithmIdentifierAsn.manual.cs | 14 +++ .../Cryptography/Asn1/PBEParameter.xml | 7 +- .../Cryptography/Asn1/PBEParameter.xml.cs | 70 +++++++++++ .../Cryptography/Asn1/PBES2Params.xml | 15 ++- .../Cryptography/Asn1/PBES2Params.xml.cs | 55 +++++++++ .../Cryptography/Asn1/Pbkdf2Params.xml | 16 ++- .../Cryptography/Asn1/Pbkdf2Params.xml.cs | 89 ++++++++++++++ .../Cryptography/Asn1/Pbkdf2SaltChoice.xml | 10 +- .../Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs | 70 +++++++++++ .../Asn1/Rc2CbcParameters.manual.cs | 19 ++- .../Cryptography/Asn1/Rc2CbcParameters.xml | 7 +- .../Cryptography/Asn1/Rc2CbcParameters.xml.cs | 70 +++++++++++ .../Cryptography/PasswordBasedEncryption.cs | 113 ++++++++++++------ 13 files changed, 498 insertions(+), 57 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs index b8a5da88b67b47..b0389c14f5431f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs @@ -58,6 +58,20 @@ internal static bool RepresentsNull(ReadOnlyMemory? parameters) return span[1] == 0; } + + internal ValueAlgorithmIdentifierAsn AsValueAlgorithmIdentifierAsn() + { + ValueAlgorithmIdentifierAsn val = default; + val.Algorithm = Algorithm; + + if (Parameters is ReadOnlyMemory parameters) + { + val.HasParameters = true; + val.Parameters = parameters.Span; + } + + return val; + } } internal ref partial struct ValueAlgorithmIdentifierAsn diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml index 906213922a9f9d..51cf8ee0821f54 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> @@ -21,4 +22,4 @@ that specific platforms may have their own limits. This defines ours to int.MaxValue. --> - \ No newline at end of file + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs index efe53f8cf4e780..e7e18fb682800a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs @@ -91,6 +91,76 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R } + sequenceReader.ThrowIfNotEmpty(); + } + } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValuePBEParameter + { + internal ReadOnlySpan Salt; + internal int IterationCount; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePBEParameter decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePBEParameter decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValuePBEParameter decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePBEParameter decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePBEParameter decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + ReadOnlySpan tmpSpan; + + + if (sequenceReader.TryReadPrimitiveOctetString(out tmpSpan)) + { + decoded.Salt = tmpSpan; + } + else + { + decoded.Salt = sequenceReader.ReadOctetString(); + } + + + if (!sequenceReader.TryReadInt32(out decoded.IterationCount)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + sequenceReader.ThrowIfNotEmpty(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml index a313795eefe02b..48c9f0f4172b0e 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - - - \ No newline at end of file + + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs index 46a5de36e3104b..f9eab16a17c358 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs @@ -77,4 +77,59 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R sequenceReader.ThrowIfNotEmpty(); } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValuePBES2Params + { + internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn KeyDerivationFunc; + internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn EncryptionScheme; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePBES2Params decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePBES2Params decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValuePBES2Params decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePBES2Params decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePBES2Params decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref sequenceReader, out decoded.KeyDerivationFunc); + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref sequenceReader, out decoded.EncryptionScheme); + + sequenceReader.ThrowIfNotEmpty(); + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml index 3f9723b3d862dc..15479d6ce6b366 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - + - - + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs index 0012541c13dbf3..509ebf8a034ff8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs @@ -144,6 +144,95 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R } + sequenceReader.ThrowIfNotEmpty(); + } + } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValuePbkdf2Params + { + internal System.Security.Cryptography.Asn1.ValuePbkdf2SaltChoice Salt; + internal int IterationCount; + internal int? KeyLength; + internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn Prf; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePbkdf2Params decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePbkdf2Params decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValuePbkdf2Params decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePbkdf2Params decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValuePbkdf2Params decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + ValueAsnReader defaultReader; + + System.Security.Cryptography.Asn1.ValuePbkdf2SaltChoice.Decode(ref sequenceReader, out decoded.Salt); + + if (!sequenceReader.TryReadInt32(out decoded.IterationCount)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + + if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer)) + { + + if (sequenceReader.TryReadInt32(out int tmpKeyLength)) + { + decoded.KeyLength = tmpKeyLength; + } + else + { + sequenceReader.ThrowIfNotEmpty(); + } + + } + + + if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence)) + { + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref sequenceReader, out decoded.Prf); + } + else + { + defaultReader = new ValueAsnReader(SharedPbkdf2Params.DefaultPrf, AsnEncodingRules.DER); + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref defaultReader, out decoded.Prf); + } + + sequenceReader.ThrowIfNotEmpty(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml index 4d1e0d6a1128be..c004c0de671b6c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - - \ No newline at end of file + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs index e816489548d4ac..e97f70b72ef48d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs @@ -123,4 +123,74 @@ private static void DecodeCore(ref ValueAsnReader reader, ReadOnlyMemory r } } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValuePbkdf2SaltChoice + { + internal ReadOnlySpan Specified; + internal bool HasSpecified; + internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn OtherSource; + internal bool HasOtherSource; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePbkdf2SaltChoice decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValuePbkdf2SaltChoice decoded) + { + try + { + DecodeCore(ref reader, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, out ValuePbkdf2SaltChoice decoded) + { + decoded = default; + Asn1Tag tag = reader.PeekTag(); + ReadOnlySpan tmpSpan; + + if (tag.HasSameClassAndValue(Asn1Tag.PrimitiveOctetString)) + { + + if (reader.TryReadPrimitiveOctetString(out tmpSpan)) + { + decoded.Specified = tmpSpan; + } + else + { + decoded.Specified = reader.ReadOctetString(); + } + + decoded.HasSpecified = true; + } + else if (tag.HasSameClassAndValue(Asn1Tag.Sequence)) + { + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn tmpOtherSource; + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref reader, out tmpOtherSource); + decoded.OtherSource = tmpOtherSource; + + decoded.HasOtherSource = true; + } + else + { + throw new CryptographicException(); + } + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.manual.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.manual.cs index 46f0cec08c6bd9..64fbcd055e4a8a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.manual.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.manual.cs @@ -10,9 +10,9 @@ namespace System.Security.Cryptography.Asn1 // Since 3370 says to just use that alternative there's no fallback in this code for handling // just an IV which means that an effective key size of 32-bits has been chosen. Since 40-bit is the // smallest supported by .NET that's not really a problem. - internal partial struct Rc2CbcParameters + file static class Rc2CbcEncoding { - private static ReadOnlySpan Rc2EkbEncoding => + internal static ReadOnlySpan Rc2EkbEncoding => [ 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, @@ -31,12 +31,15 @@ internal partial struct Rc2CbcParameters 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, ]; + } + internal partial struct Rc2CbcParameters + { internal Rc2CbcParameters(ReadOnlyMemory iv, int keySize) { Rc2Version = keySize > byte.MaxValue ? keySize : - Rc2EkbEncoding[keySize]; + Rc2CbcEncoding.Rc2EkbEncoding[keySize]; Iv = iv; } @@ -44,6 +47,14 @@ internal Rc2CbcParameters(ReadOnlyMemory iv, int keySize) internal int GetEffectiveKeyBits() => Rc2Version > byte.MaxValue ? Rc2Version : - Rc2EkbEncoding.IndexOf((byte)Rc2Version); + Rc2CbcEncoding.Rc2EkbEncoding.IndexOf((byte)Rc2Version); + } + + internal ref partial struct ValueRc2CbcParameters + { + internal int GetEffectiveKeyBits() => + Rc2Version > byte.MaxValue ? + Rc2Version : + Rc2CbcEncoding.Rc2EkbEncoding.IndexOf((byte)Rc2Version); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml index b7dbcdc5841b9e..a1c059150652a4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml @@ -2,14 +2,15 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - + - \ No newline at end of file + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs index 6c934f9d2f9520..e3f1de734199ad 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs @@ -86,6 +86,71 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R } + sequenceReader.ThrowIfNotEmpty(); + } + } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueEncryptedPrivateKeyInfoAsn + { + internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn EncryptionAlgorithm; + internal ReadOnlySpan EncryptedData; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueEncryptedPrivateKeyInfoAsn decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueEncryptedPrivateKeyInfoAsn decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueEncryptedPrivateKeyInfoAsn decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueEncryptedPrivateKeyInfoAsn decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueEncryptedPrivateKeyInfoAsn decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + ReadOnlySpan tmpSpan; + + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref sequenceReader, out decoded.EncryptionAlgorithm); + + if (sequenceReader.TryReadPrimitiveOctetString(out tmpSpan)) + { + decoded.EncryptedData = tmpSpan; + } + else + { + decoded.EncryptedData = sequenceReader.ReadOctetString(); + } + + sequenceReader.ThrowIfNotEmpty(); } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs index bb057eeb892e2d..c4f7baa328dffd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/DSAKeyFormatHelper.cs @@ -16,11 +16,11 @@ internal static class DSAKeyFormatHelper }; internal static void ReadDsaPrivateKey( - ReadOnlyMemory xBytes, - in AlgorithmIdentifierAsn algId, + ReadOnlySpan xBytes, + in ValueAlgorithmIdentifierAsn algId, out DSAParameters ret) { - if (!algId.Parameters.HasValue) + if (!algId.HasParameters) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } @@ -30,7 +30,7 @@ internal static void ReadDsaPrivateKey( try { ReadOnlySpan xSpan = AsnDecoder.ReadIntegerBytes( - xBytes.Span, + xBytes, AsnEncodingRules.DER, out int consumed); @@ -47,7 +47,7 @@ internal static void ReadDsaPrivateKey( throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } - DssParms parms = DssParms.Decode(algId.Parameters.Value, AsnEncodingRules.BER); + ValueDssParms.Decode(algId.Parameters, AsnEncodingRules.BER, out ValueDssParms parms); // Sanity checks from FIPS 186-4 4.1/4.2. Since FIPS 186-5 withdrew DSA/DSS // these will never change again. diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs index d4dcad048d2384..f9b7ee14fa77d3 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs @@ -31,6 +31,7 @@ internal static unsafe void ReadEncryptedPkcs8( } } + // TODO vcsjones nuke internal static unsafe void ReadEncryptedPkcs8( string[] validOids, ReadOnlySpan source, @@ -54,6 +55,7 @@ internal static unsafe void ReadEncryptedPkcs8( } } + // TODO vcsjones nuke private static void ReadEncryptedPkcs8( string[] validOids, ReadOnlyMemory source, @@ -72,6 +74,25 @@ private static void ReadEncryptedPkcs8( out ret); } + internal static void ReadEncryptedPkcs8( + string[] validOids, + ReadOnlySpan source, + ReadOnlySpan password, + ValueKeyReader keyReader, + out int bytesRead, + out TRet ret) + { + ReadEncryptedPkcs8( + validOids, + source, + password, + ReadOnlySpan.Empty, + keyReader, + out bytesRead, + out ret); + } + + // TODO vcsjones nuke private static void ReadEncryptedPkcs8( string[] validOids, ReadOnlyMemory source, @@ -90,6 +111,25 @@ private static void ReadEncryptedPkcs8( out ret); } + internal static void ReadEncryptedPkcs8( + string[] validOids, + ReadOnlySpan source, + ReadOnlySpan passwordBytes, + ValueKeyReader keyReader, + out int bytesRead, + out TRet ret) + { + ReadEncryptedPkcs8( + validOids, + source, + ReadOnlySpan.Empty, + passwordBytes, + keyReader, + out bytesRead, + out ret); + } + + // TODO vcsjones - nuke? private static void ReadEncryptedPkcs8( string[] validOids, ReadOnlyMemory source, @@ -155,6 +195,71 @@ private static void ReadEncryptedPkcs8( } } + private static void ReadEncryptedPkcs8( + string[] validOids, + ReadOnlySpan source, + ReadOnlySpan password, + ReadOnlySpan passwordBytes, + ValueKeyReader keyReader, + out int bytesRead, + out TRet ret) + { + int read; + ValueEncryptedPrivateKeyInfoAsn epki; + + try + { + ValueAsnReader reader = new ValueAsnReader(source, AsnEncodingRules.BER); + read = reader.PeekEncodedValue().Length; + ValueEncryptedPrivateKeyInfoAsn.Decode(ref reader, out epki); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + // No supported encryption algorithms produce more bytes of decryption output than there + // were of decryption input. + byte[] decrypted = CryptoPool.Rent(epki.EncryptedData.Length); + Memory decryptedMemory = decrypted; + + try + { + int decryptedBytes = PasswordBasedEncryption.Decrypt( + epki.EncryptionAlgorithm, + password, + passwordBytes, + epki.EncryptedData, + decrypted); + + decryptedMemory = decryptedMemory.Slice(0, decryptedBytes); + + ReadPkcs8( + validOids, + decryptedMemory.Span, + keyReader, + out int innerRead, + out ret); + + if (innerRead != decryptedMemory.Length) + { + ret = default!; + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); + } + + bytesRead = read; + } + catch (CryptographicException e) + { + throw new CryptographicException(SR.Cryptography_Pkcs8_EncryptedReadFailed, e); + } + finally + { + CryptographicOperations.ZeroMemory(decryptedMemory.Span); + CryptoPool.Return(decrypted, clearSize: 0); + } + } + internal static AsnWriter WriteEncryptedPkcs8( ReadOnlySpan password, AsnWriter pkcs8Writer, From c8acec47e04c1b2872a67ac48f70d87378b0b70d Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 16:39:39 -0400 Subject: [PATCH 11/34] Spanify RSA key loaded --- .../Cryptography/Asn1/RSAPrivateKeyAsn.xml | 5 +- .../Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs | 74 +++++++++++++++++++ .../Security/Cryptography/KeyBlobHelpers.cs | 21 ++++-- .../Security/Cryptography/KeyFormatHelper.cs | 26 +++++++ .../Security/Cryptography/RSAAppleCrypto.cs | 32 ++++---- .../Cryptography/RSAKeyFormatHelper.Pkcs1.cs | 24 ++---- .../Cryptography/RSAKeyFormatHelper.cs | 34 +++------ .../Security/Cryptography/RSAOpenSsl.cs | 24 +++--- .../src/System/Security/Cryptography/RSA.cs | 14 +--- 9 files changed, 158 insertions(+), 96 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml index e6101a539349f9..4fb469e788d4b7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs index 6b8ec4138ff738..580a1f3f26e1bc 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs @@ -114,4 +114,78 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R sequenceReader.ThrowIfNotEmpty(); } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueRSAPrivateKeyAsn + { + internal int Version; + internal ReadOnlySpan Modulus; + internal ReadOnlySpan PublicExponent; + internal ReadOnlySpan PrivateExponent; + internal ReadOnlySpan Prime1; + internal ReadOnlySpan Prime2; + internal ReadOnlySpan Exponent1; + internal ReadOnlySpan Exponent2; + internal ReadOnlySpan Coefficient; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRSAPrivateKeyAsn decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRSAPrivateKeyAsn decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueRSAPrivateKeyAsn decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueRSAPrivateKeyAsn decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueRSAPrivateKeyAsn decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + + + if (!sequenceReader.TryReadInt32(out decoded.Version)) + { + sequenceReader.ThrowIfNotEmpty(); + } + + decoded.Modulus = sequenceReader.ReadIntegerBytes(); + decoded.PublicExponent = sequenceReader.ReadIntegerBytes(); + decoded.PrivateExponent = sequenceReader.ReadIntegerBytes(); + decoded.Prime1 = sequenceReader.ReadIntegerBytes(); + decoded.Prime2 = sequenceReader.ReadIntegerBytes(); + decoded.Exponent1 = sequenceReader.ReadIntegerBytes(); + decoded.Exponent2 = sequenceReader.ReadIntegerBytes(); + decoded.Coefficient = sequenceReader.ReadIntegerBytes(); + + sequenceReader.ThrowIfNotEmpty(); + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs index 2a6f49a388077a..80dd2e736b0937 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyBlobHelpers.cs @@ -24,31 +24,36 @@ internal static byte[] ToUnsignedIntegerBytes(this ReadOnlyMemory memory) } internal static void ToUnsignedIntegerBytes(this ReadOnlyMemory memory, Span destination) + { + ToUnsignedIntegerBytes(memory.Span, destination); + } + + internal static void ToUnsignedIntegerBytes(this ReadOnlySpan span, Span destination) { int length = destination.Length; - if (memory.Length == length) + if (span.Length == length) { - memory.Span.CopyTo(destination); + span.CopyTo(destination); return; } - if (memory.Length == length + 1) + if (span.Length == length + 1) { - if (memory.Span[0] == 0) + if (span[0] == 0) { - memory.Span.Slice(1).CopyTo(destination); + span.Slice(1).CopyTo(destination); return; } } - if (memory.Length > length) + if (span.Length > length) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } - destination.Slice(0, destination.Length - memory.Length).Clear(); - memory.Span.CopyTo(destination.Slice(length - memory.Length)); + destination.Slice(0, destination.Length - span.Length).Clear(); + span.CopyTo(destination.Slice(length - span.Length)); } internal static void WriteKeyParameterInteger(this AsnWriter writer, ReadOnlySpan integer) diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs index 9ed5427023fd05..21ac83abb2c7c2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs @@ -164,6 +164,7 @@ internal static void ReadPkcs8( } } + // TODO vcsjones nuke internal static ReadOnlyMemory ReadPkcs8( string[] validOids, ReadOnlyMemory source, @@ -189,6 +190,31 @@ internal static ReadOnlyMemory ReadPkcs8( } } + internal static ReadOnlySpan ReadPkcs8( + string[] validOids, + ReadOnlySpan source, + out int bytesRead) + { + try + { + ValueAsnReader reader = new ValueAsnReader(source, AsnEncodingRules.BER); + int read = reader.PeekEncodedValue().Length; + ValuePrivateKeyInfoAsn.Decode(ref reader, out ValuePrivateKeyInfoAsn privateKeyInfo); + + if (Array.IndexOf(validOids, privateKeyInfo.PrivateKeyAlgorithm.Algorithm) < 0) + { + throw new CryptographicException(SR.Cryptography_NotValidPublicOrPrivateKey); + } + + bytesRead = read; + return privateKeyInfo.PrivateKey; + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + private static void ReadPkcs8( string[] validOids, ReadOnlyMemory source, diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs index 9b2d275dae6841..426c9f73dcf5d5 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAAppleCrypto.cs @@ -119,7 +119,7 @@ public override RSAParameters ExportParameters(bool includePrivateParameters) } else { - AlgorithmIdentifierAsn ignored = default; + ValueAlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.FromPkcs1PrivateKey( keyBlob, ignored, @@ -161,24 +161,18 @@ public override unsafe void ImportRSAPublicKey(ReadOnlySpan source, out in { ThrowIfDisposed(); - fixed (byte* ptr = &MemoryMarshal.GetReference(source)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, source.Length)) - { - // Validate the DER value and get the number of bytes. - RSAKeyFormatHelper.ReadRsaPublicKey( - manager.Memory, - out int localRead); - - SafeSecKeyRefHandle publicKey = Interop.AppleCrypto.CreateDataKey( - source.Slice(0, localRead), - Interop.AppleCrypto.PAL_KeyAlgorithm.RSA, - isPublic: true); - SetKey(SecKeyPair.PublicOnly(publicKey)); - - bytesRead = localRead; - } - } + // Validate the DER value and get the number of bytes. + RSAKeyFormatHelper.ReadRsaPublicKey( + source, + out int localRead); + + SafeSecKeyRefHandle publicKey = Interop.AppleCrypto.CreateDataKey( + source.Slice(0, localRead), + Interop.AppleCrypto.PAL_KeyAlgorithm.RSA, + isPublic: true); + SetKey(SecKeyPair.PublicOnly(publicKey)); + + bytesRead = localRead; } public override void ImportEncryptedPkcs8PrivateKey( diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs index a855f24e2b1544..693911e3fe390f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.Pkcs1.cs @@ -12,26 +12,12 @@ internal static partial class RSAKeyFormatHelper { internal delegate TRet RSAParametersCallback(RSAParameters parameters); - internal static unsafe TRet FromPkcs1PrivateKey( - ReadOnlySpan keyData, - RSAParametersCallback parametersReader, - bool pinAndClearParameters = true) - { - fixed (byte* ptr = &MemoryMarshal.GetReference(keyData)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, keyData.Length)) - { - return FromPkcs1PrivateKey(manager.Memory, parametersReader, pinAndClearParameters); - } - } - } - internal static TRet FromPkcs1PrivateKey( - ReadOnlyMemory keyData, + ReadOnlySpan keyData, RSAParametersCallback parametersReader, bool pinAndClearParameters = true) { - RSAPrivateKeyAsn key = RSAPrivateKeyAsn.Decode(keyData, AsnEncodingRules.BER); + ValueRSAPrivateKeyAsn.Decode(keyData, AsnEncodingRules.BER, out ValueRSAPrivateKeyAsn key); const int MaxSupportedVersion = 0; @@ -70,15 +56,15 @@ internal static TRet FromPkcs1PrivateKey( using (PinAndClear.Track(parameters.DQ)) using (PinAndClear.Track(parameters.InverseQ)) { - return ExtractParametersWithCallback(parametersReader, ref key, ref parameters); + return ExtractParametersWithCallback(parametersReader, key, ref parameters); } } else { - return ExtractParametersWithCallback(parametersReader, ref key, ref parameters); + return ExtractParametersWithCallback(parametersReader, key, ref parameters); } - static TRet ExtractParametersWithCallback(RSAParametersCallback parametersReader, ref RSAPrivateKeyAsn key, ref RSAParameters parameters) + static TRet ExtractParametersWithCallback(RSAParametersCallback parametersReader, in ValueRSAPrivateKeyAsn key, ref RSAParameters parameters) { key.PrivateExponent.ToUnsignedIntegerBytes(parameters.D); key.Prime1.ToUnsignedIntegerBytes(parameters.P); diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs index 6231aba31300ca..b50e5a2a4b1420 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAKeyFormatHelper.cs @@ -16,8 +16,8 @@ internal static partial class RSAKeyFormatHelper }; internal static void FromPkcs1PrivateKey( - ReadOnlyMemory keyData, - in AlgorithmIdentifierAsn algId, + ReadOnlySpan keyData, + in ValueAlgorithmIdentifierAsn algId, out RSAParameters ret) { if (!algId.HasNullEquivalentParameters()) @@ -36,17 +36,15 @@ internal static void ReadRsaPublicKey( ret = FromPkcs1PublicKey(keyData, rsaParameters => rsaParameters); } - internal static void ReadRsaPublicKey( - ReadOnlyMemory keyData, - out int bytesRead) + internal static void ReadRsaPublicKey(ReadOnlySpan keyData, out int bytesRead) { int read; try { - ValueAsnReader reader = new ValueAsnReader(keyData.Span, AsnEncodingRules.DER); + ValueAsnReader reader = new ValueAsnReader(keyData, AsnEncodingRules.DER); read = reader.PeekEncodedValue().Length; - RSAPublicKeyAsn.Decode(keyData, AsnEncodingRules.BER); + ValueRSAPublicKeyAsn.Decode(keyData, AsnEncodingRules.BER, out _); } catch (AsnContentException e) { @@ -77,32 +75,18 @@ internal static ReadOnlySpan ReadSubjectPublicKeyInfo(ReadOnlySpan s out bytesRead); } - internal static ReadOnlyMemory ReadPkcs8( - ReadOnlyMemory source, - out int bytesRead) + internal static ReadOnlySpan ReadPkcs8(ReadOnlySpan source, out int bytesRead) { - return KeyFormatHelper.ReadPkcs8( - s_validOids, - source, - out bytesRead); + return KeyFormatHelper.ReadPkcs8(s_validOids, source, out bytesRead); } /// /// Checks that a Pkcs8PrivateKeyInfo represents an RSA key. /// /// The number of bytes read from . - internal static unsafe int CheckPkcs8(ReadOnlySpan source) + internal static int CheckPkcs8(ReadOnlySpan source) { - int bytesRead; - - fixed (byte* ptr = source) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, source.Length)) - { - _ = ReadPkcs8(manager.Memory, out bytesRead); - } - } - + ReadPkcs8(source, out int bytesRead); return bytesRead; } diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs index 52e157a3e2d469..060f002ebb527f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAOpenSsl.cs @@ -273,11 +273,11 @@ private static bool TryEncrypt( return true; } - private delegate T ExportPrivateKeyFunc(ReadOnlyMemory pkcs8, ReadOnlyMemory pkcs1); + private delegate T ExportPrivateKeyFunc(ReadOnlySpan pkcs8, ReadOnlySpan pkcs1); - private delegate ReadOnlyMemory TryExportPrivateKeySelector( - ReadOnlyMemory pkcs8, - ReadOnlyMemory pkcs1); + private delegate ReadOnlySpan TryExportPrivateKeySelector( + ReadOnlySpan pkcs8, + ReadOnlySpan pkcs1); private T ExportPrivateKey(ExportPrivateKeyFunc exporter) { @@ -288,7 +288,7 @@ private T ExportPrivateKey(ExportPrivateKeyFunc exporter) try { - ReadOnlyMemory pkcs1 = VerifyPkcs8(p8); + ReadOnlySpan pkcs1 = VerifyPkcs8(p8); return exporter(p8, pkcs1); } finally @@ -306,9 +306,9 @@ private bool TryExportPrivateKey(TryExportPrivateKeySelector selector, Span pkcs1 = VerifyPkcs8(p8); - ReadOnlyMemory selected = selector(p8, pkcs1); - return selected.Span.TryCopyToDestination(destination, out bytesWritten); + ReadOnlySpan pkcs1 = VerifyPkcs8(p8); + ReadOnlySpan selected = selector(p8, pkcs1); + return selected.TryCopyToDestination(destination, out bytesWritten); } finally { @@ -424,7 +424,7 @@ public override RSAParameters ExportParameters(bool includePrivateParameters) return ExportPrivateKey( static (pkcs8, pkcs1) => { - AlgorithmIdentifierAsn algId = default; + ValueAlgorithmIdentifierAsn algId = default; RSAParameters ret; RSAKeyFormatHelper.FromPkcs1PrivateKey(pkcs1, in algId, out ret); return ret; @@ -776,7 +776,7 @@ public override bool VerifyHash(ReadOnlySpan hash, ReadOnlySpan sign signature); } - private static ReadOnlyMemory VerifyPkcs8(ReadOnlyMemory pkcs8) + private static ReadOnlySpan VerifyPkcs8(ReadOnlySpan pkcs8) { // OpenSSL 1.1.1 will export RSA public keys as a PKCS#8, but this makes a broken structure. // @@ -785,9 +785,9 @@ private static ReadOnlyMemory VerifyPkcs8(ReadOnlyMemory pkcs8) try { - ReadOnlyMemory pkcs1Priv = RSAKeyFormatHelper.ReadPkcs8(pkcs8, out int read); + ReadOnlySpan pkcs1Priv = RSAKeyFormatHelper.ReadPkcs8(pkcs8, out int read); Debug.Assert(read == pkcs8.Length); - _ = RSAPrivateKeyAsn.Decode(pkcs1Priv, AsnEncodingRules.BER); + ValueRSAPrivateKeyAsn.Decode(pkcs1Priv, AsnEncodingRules.BER, out _); return pkcs1Priv; } catch (CryptographicException) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs index c0757af491acb9..0a20a111358dac 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs @@ -935,18 +935,10 @@ public virtual unsafe void ImportRSAPrivateKey(ReadOnlySpan source, out in public override unsafe void ImportPkcs8PrivateKey(ReadOnlySpan source, out int bytesRead) { - fixed (byte* ptr = &MemoryMarshal.GetReference(source)) - { - using (MemoryManager manager = new PointerMemoryManager(ptr, source.Length)) - { - ReadOnlyMemory pkcs1 = RSAKeyFormatHelper.ReadPkcs8( - manager.Memory, - out int localRead); + ReadOnlySpan pkcs1 = RSAKeyFormatHelper.ReadPkcs8(source, out int localRead); - ImportRSAPrivateKey(pkcs1.Span, out _); - bytesRead = localRead; - } - } + ImportRSAPrivateKey(pkcs1, out _); + bytesRead = localRead; } public override unsafe void ImportEncryptedPkcs8PrivateKey( From f4775805069ba8f50c7dc05514a7a1f2199e1583 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 12 Mar 2026 17:10:17 -0400 Subject: [PATCH 12/34] Tweak some types for future reading --- .../Security/Cryptography/Asn1/CurveAsn.xml | 5 +- .../Cryptography/Asn1/CurveAsn.xml.cs | 92 +++++++++++++++++++ .../Security/Cryptography/Asn1/FieldID.xml | 5 +- .../Security/Cryptography/Asn1/FieldID.xml.cs | 55 +++++++++++ .../Cryptography/Asn1/SpecifiedECDomain.xml | 10 +- .../Asn1/SpecifiedECDomain.xml.cs | 8 +- 6 files changed, 165 insertions(+), 10 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml index 9c02e2713b5e3e..51b5ee45a03356 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml @@ -2,7 +2,8 @@ + namespace="System.Security.Cryptography.Asn1" + emitType="both"> - \ No newline at end of file + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs index d60d6723b68891..853272cd0ad093 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs @@ -95,4 +95,59 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R sequenceReader.ThrowIfNotEmpty(); } } + + [StructLayout(LayoutKind.Sequential)] + internal ref partial struct ValueFieldID + { + internal string FieldType; + internal ReadOnlySpan Parameters; + + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueFieldID decoded) + { + Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); + } + + internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueFieldID decoded) + { + try + { + ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); + + DecodeCore(ref reader, expectedTag, out decoded); + reader.ThrowIfNotEmpty(); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + internal static void Decode(scoped ref ValueAsnReader reader, out ValueFieldID decoded) + { + Decode(ref reader, Asn1Tag.Sequence, out decoded); + } + + internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueFieldID decoded) + { + try + { + DecodeCore(ref reader, expectedTag, out decoded); + } + catch (AsnContentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueFieldID decoded) + { + decoded = default; + ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); + + decoded.FieldType = sequenceReader.ReadObjectIdentifier(); + decoded.Parameters = sequenceReader.ReadEncodedValue(); + + sequenceReader.ThrowIfNotEmpty(); + } + } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml index 6f50aa39a0f213..4e81120c82ee69 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml @@ -23,8 +23,14 @@ ECPoint ::= OCTET STRING --> - - + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs index 2ca3710ff8c55c..27a48e967c6431 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs @@ -143,8 +143,8 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R internal ref partial struct ValueSpecifiedECDomain { internal int Version; - internal ReadOnlySpan FieldID; - internal ReadOnlySpan Curve; + internal System.Security.Cryptography.Asn1.ValueFieldID FieldID; + internal System.Security.Cryptography.Asn1.ValueCurveAsn Curve; internal ReadOnlySpan Base; internal ReadOnlySpan Order; internal ReadOnlySpan Cofactor; @@ -200,8 +200,8 @@ private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expecte sequenceReader.ThrowIfNotEmpty(); } - decoded.FieldID = sequenceReader.ReadEncodedValue(); - decoded.Curve = sequenceReader.ReadEncodedValue(); + System.Security.Cryptography.Asn1.ValueFieldID.Decode(ref sequenceReader, out decoded.FieldID); + System.Security.Cryptography.Asn1.ValueCurveAsn.Decode(ref sequenceReader, out decoded.Curve); if (sequenceReader.TryReadPrimitiveOctetString(out tmpSpan)) { From 2abb5cf3347b31424fd2e51fa1995f98ab9afc38 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 10:05:11 -0400 Subject: [PATCH 13/34] Value-ify ML-KEM PKCS#8 export --- .../Asn1/AlgorithmIdentifierAsn.xml.cs | 35 +- .../Cryptography/Asn1/AttributeAsn.xml.cs | 30 +- .../Cryptography/Asn1/CurveAsn.xml.cs | 22 +- .../Cryptography/Asn1/DssParms.xml.cs | 17 +- .../Asn1/ECDomainParameters.xml.cs | 37 +- .../Cryptography/Asn1/ECPrivateKey.xml.cs | 32 +- .../Asn1/EncryptedPrivateKeyInfoAsn.xml.cs | 16 +- .../Security/Cryptography/Asn1/FieldID.xml.cs | 30 +- .../Asn1/MLDsaPrivateKeyAsn.xml.cs | 39 +- .../Asn1/MLDsaPrivateKeyBothAsn.xml.cs | 16 +- .../Asn1/MLKemPrivateKeyAsn.xml.cs | 39 +- .../Asn1/MLKemPrivateKeyBothAsn.xml.cs | 16 +- .../Cryptography/Asn1/PBEParameter.xml.cs | 16 +- .../Cryptography/Asn1/PBES2Params.xml.cs | 16 +- .../Cryptography/Asn1/Pbkdf2Params.xml.cs | 34 +- .../Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs | 30 +- .../Cryptography/Asn1/PrivateKeyInfoAsn.xml | 2 +- .../Asn1/PrivateKeyInfoAsn.xml.cs | 50 +++ .../Cryptography/Asn1/PssParamsAsn.xml.cs | 72 +++- .../Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs | 23 +- .../Cryptography/Asn1/RSAPublicKeyAsn.xml.cs | 16 +- .../Cryptography/Asn1/Rc2CbcParameters.xml.cs | 16 +- .../Asn1/SpecifiedECDomain.xml.cs | 38 +- .../Asn1/SubjectPublicKeyInfoAsn.xml.cs | 16 +- .../Cryptography/Asn1/X509ExtensionAsn.xml.cs | 36 +- .../System/Security/Cryptography/Asn1/asn.xsd | 1 + .../Security/Cryptography/Asn1/asn.xslt | 358 +++++++++++++++++- .../System/Security/Cryptography/Helpers.cs | 11 +- .../Security/Cryptography/MLKemPkcs8.cs | 16 +- .../Pkcs/Asn1/MessageImprint.xml.cs | 23 +- .../Pkcs/Asn1/Rfc3161TstInfo.xml.cs | 79 +++- .../Asn1/CertificationRequestInfoAsn.xml.cs | 41 +- 32 files changed, 1177 insertions(+), 46 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs index f9b8eae0bdf29d..3840eb9a988580 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -113,6 +113,39 @@ internal ref partial struct ValueAlgorithmIdentifierAsn internal ReadOnlySpan Parameters; internal bool HasParameters; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + try + { + writer.WriteObjectIdentifier(Algorithm); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + if (HasParameters) + { + try + { + writer.WriteEncodedValue(Parameters); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueAlgorithmIdentifierAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs index a25b39a22327c6..dba4124cf15dec 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -126,6 +126,34 @@ internal ref partial struct ValueAttributeAsn internal string AttrType; internal ReadOnlySpan AttrValues; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + try + { + writer.WriteObjectIdentifier(AttrType); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + try + { + writer.WriteEncodedValue(AttrValues); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueAttributeAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs index 45fe7abf3bb5de..99b0e0b57229cd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -129,6 +129,26 @@ internal ref partial struct ValueCurveAsn internal ReadOnlySpan Seed; internal bool HasSeed; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteOctetString(A); + writer.WriteOctetString(B); + + if (HasSeed) + { + writer.WriteBitString(Seed, 0); + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueCurveAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs index c1b716820a5618..e18f13ad879226 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -88,6 +88,21 @@ internal ref partial struct ValueDssParms internal System.Numerics.BigInteger Q; internal System.Numerics.BigInteger G; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(P); + writer.WriteInteger(Q); + writer.WriteInteger(G); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueDssParms decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs index 56133fc212f3a2..592fa0a52c73cc 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -126,6 +126,41 @@ internal ref partial struct ValueECDomainParameters internal bool HasSpecified; internal string? Named; + internal readonly void Encode(AsnWriter writer) + { + bool wroteValue = false; + + if (HasSpecified) + { + if (wroteValue) + throw new CryptographicException(); + + Specified.Encode(writer); + wroteValue = true; + } + + if (Named != null) + { + if (wroteValue) + throw new CryptographicException(); + + try + { + writer.WriteObjectIdentifier(Named); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + wroteValue = true; + } + + if (!wroteValue) + { + throw new CryptographicException(); + } + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueECDomainParameters decoded) { try diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs index 98ec3238211d43..6e4b311e525eeb 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -152,6 +152,36 @@ internal ref partial struct ValueECPrivateKey internal ReadOnlySpan PublicKey; internal bool HasPublicKey; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Version); + writer.WriteOctetString(PrivateKey); + + if (HasParameters) + { + writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + Parameters.Encode(writer); + writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + } + + + if (HasPublicKey) + { + writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); + writer.WriteBitString(PublicKey, 0); + writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueECPrivateKey decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs index e3f1de734199ad..a929a96da4dffa 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -96,6 +96,20 @@ internal ref partial struct ValueEncryptedPrivateKeyInfoAsn internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn EncryptionAlgorithm; internal ReadOnlySpan EncryptedData; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + EncryptionAlgorithm.Encode(writer); + writer.WriteOctetString(EncryptedData); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueEncryptedPrivateKeyInfoAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs index 853272cd0ad093..c093cfd7abb1f6 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -102,6 +102,34 @@ internal ref partial struct ValueFieldID internal string FieldType; internal ReadOnlySpan Parameters; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + try + { + writer.WriteObjectIdentifier(FieldType); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + try + { + writer.WriteEncodedValue(Parameters); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueFieldID decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs index dbbbce610526e7..43551117b732ac 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -158,6 +158,43 @@ internal ref partial struct ValueMLDsaPrivateKeyAsn internal System.Security.Cryptography.Asn1.ValueMLDsaPrivateKeyBothAsn Both; internal bool HasBoth; + internal readonly void Encode(AsnWriter writer) + { + bool wroteValue = false; + + if (HasSeed) + { + if (wroteValue) + throw new CryptographicException(); + + writer.WriteOctetString(Seed, new Asn1Tag(TagClass.ContextSpecific, 0)); + wroteValue = true; + } + + if (HasExpandedKey) + { + if (wroteValue) + throw new CryptographicException(); + + writer.WriteOctetString(ExpandedKey); + wroteValue = true; + } + + if (HasBoth) + { + if (wroteValue) + throw new CryptographicException(); + + Both.Encode(writer); + wroteValue = true; + } + + if (!wroteValue) + { + throw new CryptographicException(); + } + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueMLDsaPrivateKeyAsn decoded) { try diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs index 17c743ed15dc58..85e7b21c92f258 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -105,6 +105,20 @@ internal ref partial struct ValueMLDsaPrivateKeyBothAsn internal ReadOnlySpan Seed; internal ReadOnlySpan ExpandedKey; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteOctetString(Seed); + writer.WriteOctetString(ExpandedKey); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueMLDsaPrivateKeyBothAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs index b34df12487145d..560580effcac61 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -158,6 +158,43 @@ internal ref partial struct ValueMLKemPrivateKeyAsn internal System.Security.Cryptography.Asn1.ValueMLKemPrivateKeyBothAsn Both; internal bool HasBoth; + internal readonly void Encode(AsnWriter writer) + { + bool wroteValue = false; + + if (HasSeed) + { + if (wroteValue) + throw new CryptographicException(); + + writer.WriteOctetString(Seed, new Asn1Tag(TagClass.ContextSpecific, 0)); + wroteValue = true; + } + + if (HasExpandedKey) + { + if (wroteValue) + throw new CryptographicException(); + + writer.WriteOctetString(ExpandedKey); + wroteValue = true; + } + + if (HasBoth) + { + if (wroteValue) + throw new CryptographicException(); + + Both.Encode(writer); + wroteValue = true; + } + + if (!wroteValue) + { + throw new CryptographicException(); + } + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueMLKemPrivateKeyAsn decoded) { try diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs index ad994da2e986e3..f57af1d46c46be 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -105,6 +105,20 @@ internal ref partial struct ValueMLKemPrivateKeyBothAsn internal ReadOnlySpan Seed; internal ReadOnlySpan ExpandedKey; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteOctetString(Seed); + writer.WriteOctetString(ExpandedKey); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueMLKemPrivateKeyBothAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs index e7e18fb682800a..124323bc446264 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -101,6 +101,20 @@ internal ref partial struct ValuePBEParameter internal ReadOnlySpan Salt; internal int IterationCount; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteOctetString(Salt); + writer.WriteInteger(IterationCount); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePBEParameter decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs index f9eab16a17c358..417d773e9536b7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -84,6 +84,20 @@ internal ref partial struct ValuePBES2Params internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn KeyDerivationFunc; internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn EncryptionScheme; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + KeyDerivationFunc.Encode(writer); + EncryptionScheme.Encode(writer); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePBES2Params decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs index 509ebf8a034ff8..64f3de08c15bde 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -156,6 +156,38 @@ internal ref partial struct ValuePbkdf2Params internal int? KeyLength; internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn Prf; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + Salt.Encode(writer); + writer.WriteInteger(IterationCount); + + if (KeyLength.HasValue) + { + writer.WriteInteger(KeyLength.Value); + } + + + // DEFAULT value handler for Prf. + { + AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER); + Prf.Encode(tmp); + + if (!tmp.EncodedValueEquals(SharedPbkdf2Params.DefaultPrf)) + { + tmp.CopyTo(writer); + } + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePbkdf2Params decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs index e97f70b72ef48d..c8a15d3b683ab7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -132,6 +132,34 @@ internal ref partial struct ValuePbkdf2SaltChoice internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn OtherSource; internal bool HasOtherSource; + internal readonly void Encode(AsnWriter writer) + { + bool wroteValue = false; + + if (HasSpecified) + { + if (wroteValue) + throw new CryptographicException(); + + writer.WriteOctetString(Specified); + wroteValue = true; + } + + if (HasOtherSource) + { + if (wroteValue) + throw new CryptographicException(); + + OtherSource.Encode(writer); + wroteValue = true; + } + + if (!wroteValue) + { + throw new CryptographicException(); + } + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePbkdf2SaltChoice decoded) { try diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml index d76f120e4306ce..d201129f618c9c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml @@ -26,7 +26,7 @@ typeName="System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn" valueTypeName="System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn" /> - + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs index 981f0c33dd8dd8..4155af72f41080 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs @@ -144,6 +144,34 @@ internal ref partial struct ValuePrivateKeyInfoAsn internal ReadOnlySpan Attributes; internal bool HasAttributes; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Version); + PrivateKeyAlgorithm.Encode(writer); + writer.WriteOctetString(PrivateKey); + + if (HasAttributes) + { + try + { + writer.WriteEncodedValue(Attributes); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePrivateKeyInfoAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); @@ -265,5 +293,27 @@ public bool MoveNext() } } } + + + internal ref struct AttributesBuilder + { + private readonly AsnWriter _writer; + + internal AttributesBuilder(AsnWriter writer) + { + _writer = writer; + _writer.PushSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); + } + + public void Add(scoped in System.Security.Cryptography.Asn1.ValueAttributeAsn value) + { + value.Encode(_writer); + } + + public void Finish() + { + _writer.PopSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); + } + } } } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs index 43e8ff1f4c64ad..b06991433ee56b 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -262,6 +262,76 @@ internal ref partial struct ValuePssParamsAsn internal int SaltLength; internal int TrailerField; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + + // DEFAULT value handler for HashAlgorithm. + { + AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER); + HashAlgorithm.Encode(tmp); + + if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultHashAlgorithm)) + { + writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + tmp.CopyTo(writer); + writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + } + } + + + // DEFAULT value handler for MaskGenAlgorithm. + { + AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER); + MaskGenAlgorithm.Encode(tmp); + + if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultMaskGenAlgorithm)) + { + writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); + tmp.CopyTo(writer); + writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); + } + } + + + // DEFAULT value handler for SaltLength. + { + const int AsnManagedIntegerDerMaxEncodeSize = 6; + AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER, initialCapacity: AsnManagedIntegerDerMaxEncodeSize); + tmp.WriteInteger(SaltLength); + + if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultSaltLength)) + { + writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); + tmp.CopyTo(writer); + writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); + } + } + + + // DEFAULT value handler for TrailerField. + { + const int AsnManagedIntegerDerMaxEncodeSize = 6; + AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER, initialCapacity: AsnManagedIntegerDerMaxEncodeSize); + tmp.WriteInteger(TrailerField); + + if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultTrailerField)) + { + writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); + tmp.CopyTo(writer); + writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); + } + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValuePssParamsAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs index 580a1f3f26e1bc..d1737bc7470e32 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -128,6 +128,27 @@ internal ref partial struct ValueRSAPrivateKeyAsn internal ReadOnlySpan Exponent2; internal ReadOnlySpan Coefficient; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Version); + writer.WriteInteger(Modulus); + writer.WriteInteger(PublicExponent); + writer.WriteInteger(PrivateExponent); + writer.WriteInteger(Prime1); + writer.WriteInteger(Prime2); + writer.WriteInteger(Exponent1); + writer.WriteInteger(Exponent2); + writer.WriteInteger(Coefficient); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRSAPrivateKeyAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs index ab7b58a2990425..f59c209a3de2d7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -89,6 +89,20 @@ internal ref partial struct ValueRSAPublicKeyAsn internal ReadOnlySpan Modulus; internal ReadOnlySpan PublicExponent; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Modulus); + writer.WriteInteger(PublicExponent); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRSAPublicKeyAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs index 49656be9fe2749..b68c37f6c00275 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -101,6 +101,20 @@ internal ref partial struct ValueRc2CbcParameters internal int Rc2Version; internal ReadOnlySpan Iv; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Rc2Version); + writer.WriteOctetString(Iv); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRc2CbcParameters decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs index 27a48e967c6431..a26f3758ddd88e 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -151,6 +151,42 @@ internal ref partial struct ValueSpecifiedECDomain internal bool HasCofactor; internal string? Hash; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Version); + FieldID.Encode(writer); + Curve.Encode(writer); + writer.WriteOctetString(Base); + writer.WriteInteger(Order); + + if (HasCofactor) + { + writer.WriteInteger(Cofactor); + } + + + if (Hash != null) + { + try + { + writer.WriteObjectIdentifier(Hash); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueSpecifiedECDomain decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs index 80ce6bb17b408e..0cd5faffe3cec4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -96,6 +96,20 @@ internal ref partial struct ValueSubjectPublicKeyInfoAsn internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn Algorithm; internal ReadOnlySpan SubjectPublicKey; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + Algorithm.Encode(writer); + writer.WriteBitString(SubjectPublicKey, 0); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueSubjectPublicKeyInfoAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs index 04efe34e8044cf..14eb4e6d8a0712 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -147,6 +147,40 @@ internal ref partial struct ValueX509ExtensionAsn internal bool Critical; internal ReadOnlySpan ExtnValue; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + try + { + writer.WriteObjectIdentifier(ExtnId); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + // DEFAULT value handler for Critical. + { + const int AsnBoolDerEncodeSize = 3; + AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER, initialCapacity: AsnBoolDerEncodeSize); + tmp.WriteBoolean(Critical); + + if (!tmp.EncodedValueEquals(SharedX509ExtensionAsn.DefaultCritical)) + { + tmp.CopyTo(writer); + } + } + + writer.WriteOctetString(ExtnValue); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueX509ExtensionAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xsd b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xsd index 871198187108f9..723c1ed8dbec7a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xsd +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xsd @@ -154,6 +154,7 @@ + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt index 0768fd3cf3e9c6..e8ada68a5e0c8d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt @@ -152,6 +152,18 @@ namespace internal ref partial struct Value { + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan<byte> encoded, AsnEncodingRules ruleSet, out Value decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); @@ -200,7 +212,7 @@ namespace sequenceReader.ThrowIfNotEmpty(); } - } + } } @@ -295,6 +307,16 @@ namespace internal ref partial struct Value { + internal readonly void Encode(AsnWriter writer) + { + bool wroteValue = false; + + if (!wroteValue) + { + throw new CryptographicException(); + } + } + internal static void Decode(ReadOnlySpan<byte> encoded, AsnEncodingRules ruleSet, out Value decoded) { try @@ -334,7 +356,7 @@ namespace throw new CryptographicException(); } } - } + } } @@ -350,6 +372,10 @@ namespace Error: implicitTag and universalTagNumber both specified in [] + + Error: emitValueBuilder requires valueName in [] + + Error: neither optional or defaultDerInit may be specified for fields in a Choice type () @@ -1401,4 +1427,332 @@ namespace + + + + + + + + // DEFAULT value handler for . + { + + + + + + + + if (!tmp.EncodedValueEquals()) + { + tmp.CopyTo(writer); + } + } + + + + + + + + + + + + + + + + + if (Has) + { + } + + + + if ( != null) + { + } + + + + if (.HasValue) + { + } + + + + + + + + + + + + // DEFAULT value handler for . + { + + + + + + + + if (!tmp.EncodedValueEquals()) + { + writer.PushSequence(); + tmp.CopyTo(writer); + writer.PopSequence(); + } + } + + + writer.PushSequence(); + writer.PopSequence(); + + + + + + + + + + + + + + + + + + + + + + + + + + + // Validator for tag constraint for + { + if (!Asn1Tag.TryDecode(, out Asn1Tag validateTag, out _) || + !validateTag.HasSameClassAndValue()) + { + throw new CryptographicException(); + } + } + + + try + { + .WriteEncodedValue(); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + + + + + + + + .WriteOctetString(); + + + + + + + + + .WriteBitString(, 0); + + + + + + + + + .WriteInteger(); + + + + + + + + + .Encode(); + + + + + + + + + try + { + .WriteEncodedValue(); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + + + + + + + + try + { + .WriteEncodedValue(); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + + + + + + + if (Has) + { + if (wroteValue) + throw new CryptographicException(); + + wroteValue = true; + } + + + + if (Has) + { + if (wroteValue) + throw new CryptographicException(); + + wroteValue = true; + } + + + + if (Has) + { + if (wroteValue) + throw new CryptographicException(); + + wroteValue = true; + } + + + + if (Has) + { + if (wroteValue) + throw new CryptographicException(); + + wroteValue = true; + } + + + + + if (.HasValue) + { + if (wroteValue) + throw new CryptographicException(); + + wroteValue = true; + } + + + + + if ( != null) + { + if (wroteValue) + throw new CryptographicException(); + + wroteValue = true; + } + + + + + + + + SetOf + Sequence + + + + + + ReadOnlySpan<byte> + + + + + internal ref struct Builder + { + private readonly AsnWriter _writer; + + internal Builder(AsnWriter writer) + { + _writer = writer; + _writer.Push(); + } + + public void Add(scoped in value) + { + value.Encode(_writer); + } + + public void Add(ReadOnlySpan<byte> encodedValue) + { + try + { + _writer.WriteEncodedValue(encodedValue); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + public void Finish() + { + _writer.Pop(); + } + } + + + + + + + + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs index ddfcf8458a34a6..d43568bf5427f1 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Helpers.cs @@ -217,16 +217,7 @@ internal static IncrementalHash CreateIncrementalHash(HashAlgorithmName hashAlgo internal static CryptographicException CreateAlgorithmUnknownException(ref readonly ValueAlgorithmIdentifierAsn identifier) { AsnWriter encodedId = new(AsnEncodingRules.DER); - - using (encodedId.PushSequence()) - { - encodedId.WriteObjectIdentifier(identifier.Algorithm); - - if (identifier.HasParameters) - { - encodedId.WriteEncodedValue(identifier.Parameters); - } - } + identifier.Encode(encodedId); #if NET return encodedId.Encode(static encoded => CreateAlgorithmUnknownException(Convert.ToHexString(encoded))); #else diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs b/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs index 6a3fef4b221b90..a80664b6d25e4f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs @@ -15,13 +15,13 @@ internal static bool TryExportPkcs8PrivateKey( Span destination, out int bytesWritten) { - AlgorithmIdentifierAsn algorithmIdentifier = new() + ValueAlgorithmIdentifierAsn algorithmIdentifier = new() { Algorithm = kem.Algorithm.Oid, - Parameters = default(ReadOnlyMemory?), + HasParameters = false, }; - MLKemPrivateKeyAsn privateKeyAsn = default; + ValueMLKemPrivateKeyAsn privateKeyAsn = default; byte[]? rented = null; int written = 0; @@ -31,19 +31,21 @@ internal static bool TryExportPkcs8PrivateKey( { int seedSize = kem.Algorithm.PrivateSeedSizeInBytes; rented = CryptoPool.Rent(seedSize); - Memory buffer = rented.AsMemory(0, seedSize); - kem.ExportPrivateSeed(buffer.Span); + Span buffer = rented.AsSpan(0, seedSize); + kem.ExportPrivateSeed(buffer); written = buffer.Length; privateKeyAsn.Seed = buffer; + privateKeyAsn.HasSeed = true; } else if (hasDecapsulationKey) { int decapsulationKeySize = kem.Algorithm.DecapsulationKeySizeInBytes; rented = CryptoPool.Rent(decapsulationKeySize); - Memory buffer = rented.AsMemory(0, decapsulationKeySize); - kem.ExportDecapsulationKey(buffer.Span); + Span buffer = rented.AsSpan(0, decapsulationKeySize); + kem.ExportDecapsulationKey(buffer); written = buffer.Length; privateKeyAsn.ExpandedKey = buffer; + privateKeyAsn.HasExpandedKey = true; } else { diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs index afa4625be943a9..a70cbf92b9dd0c 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -96,6 +96,27 @@ internal ref partial struct ValueMessageImprint internal ReadOnlySpan HashAlgorithm; internal ReadOnlySpan HashedMessage; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + try + { + writer.WriteEncodedValue(HashAlgorithm); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + writer.WriteOctetString(HashedMessage); + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueMessageImprint decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs index 1a71b5f83937ff..6039f5094e2a27 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -251,6 +251,83 @@ internal ref partial struct ValueRfc3161TstInfo internal ReadOnlySpan Extensions; internal bool HasExtensions; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Version); + try + { + writer.WriteObjectIdentifier(Policy); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + MessageImprint.Encode(writer); + writer.WriteInteger(SerialNumber); + writer.WriteGeneralizedTime(GenTime, false); + + if (Accuracy.HasValue) + { + Accuracy.Value.Encode(writer); + } + + + // DEFAULT value handler for Ordering. + { + const int AsnBoolDerEncodeSize = 3; + AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER, initialCapacity: AsnBoolDerEncodeSize); + tmp.WriteBoolean(Ordering); + + if (!tmp.EncodedValueEquals(SharedRfc3161TstInfo.DefaultOrdering)) + { + tmp.CopyTo(writer); + } + } + + + if (HasNonce) + { + writer.WriteInteger(Nonce); + } + + + if (HasTsa) + { + writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + try + { + writer.WriteEncodedValue(Tsa); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + } + + + if (HasExtensions) + { + try + { + writer.WriteEncodedValue(Extensions); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + } + + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueRfc3161TstInfo decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs index 12ac6712256a99..16d0df96e39629 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -141,6 +141,45 @@ internal ref partial struct ValueCertificationRequestInfoAsn internal System.Security.Cryptography.Asn1.ValueSubjectPublicKeyInfoAsn SubjectPublicKeyInfo; internal ReadOnlySpan Attributes; + internal readonly void Encode(AsnWriter writer) + { + Encode(writer, Asn1Tag.Sequence); + } + + internal readonly void Encode(AsnWriter writer, Asn1Tag tag) + { + writer.PushSequence(tag); + + writer.WriteInteger(Version); + // Validator for tag constraint for Subject + { + if (!Asn1Tag.TryDecode(Subject, out Asn1Tag validateTag, out _) || + !validateTag.HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) + { + throw new CryptographicException(); + } + } + + try + { + writer.WriteEncodedValue(Subject); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + SubjectPublicKeyInfo.Encode(writer); + try + { + writer.WriteEncodedValue(Attributes); + } + catch (ArgumentException e) + { + throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); + } + writer.PopSequence(tag); + } + internal static void Decode(ReadOnlySpan encoded, AsnEncodingRules ruleSet, out ValueCertificationRequestInfoAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); From 37bdfdf073a142a289ae7d53f016cfa31657f872 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 10:23:50 -0400 Subject: [PATCH 14/34] Move Choice tag validation to file-scoped Validate class Move the #if DEBUG ensureUniqueTag validation from the Choice struct's static constructor into a separate file static class (Validate) that is emitted regardless of emitType. This ensures tag uniqueness validation runs even for ref-only Choice types like MLKemPrivateKeyAsn. The entire Validate class is wrapped in #if DEBUG so it is completely absent in release builds. The class uses the Validate prefix (not Shared) to avoid any potential collision with the Shared class used for defaultDerInit in Sequence types. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Asn1/DirectoryStringAsn.xml.cs | 25 ++-- .../Asn1/ECDomainParameters.xml.cs | 17 ++- .../Cryptography/Asn1/GeneralNameAsn.xml.cs | 33 ++--- .../Asn1/MLDsaPrivateKeyAsn.xml.cs | 19 +-- .../Cryptography/Asn1/MLKemPrivateKeyAsn.xml | 2 +- .../Asn1/MLKemPrivateKeyAsn.xml.cs | 125 +----------------- .../Asn1/MLKemPrivateKeyBothAsn.xml | 2 +- .../Asn1/MLKemPrivateKeyBothAsn.xml.cs | 93 +------------ .../Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs | 17 ++- .../Asn1/Pkcs7/CertificateChoiceAsn.xml.cs | 25 ++-- .../Asn1/Pkcs7/SignerIdentifierAsn.xml.cs | 19 +-- .../Security/Cryptography/Asn1/asn.xslt | 15 ++- .../KeyAgreeRecipientIdentifierAsn.xml.cs | 19 +-- .../Asn1/OriginatorIdentifierOrKeyAsn.xml.cs | 21 +-- .../Pkcs/Asn1/RecipientIdentifierAsn.xml.cs | 19 +-- .../Pkcs/Asn1/RecipientInfoAsn.xml.cs | 19 +-- .../Pkcs/Asn1/SignedAttributesSet.xml.cs | 17 ++- .../Asn1/DistributionPointNameAsn.xml.cs | 19 +-- .../X509Certificates/Asn1/TimeAsn.xml.cs | 19 +-- 19 files changed, 181 insertions(+), 344 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs index 06fda83e8b0d4b..b4acfd6d07c907 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -8,17 +8,10 @@ namespace System.Security.Cryptography.Asn1 { - [StructLayout(LayoutKind.Sequential)] - internal partial struct DirectoryStringAsn - { - internal string? TeletexString; - internal string? PrintableString; - internal ReadOnlyMemory? UniversalString; - internal string? Utf8String; - internal string? BmpString; - #if DEBUG - static DirectoryStringAsn() + file static class ValidateDirectoryStringAsn + { + static ValidateDirectoryStringAsn() { var usedTags = new System.Collections.Generic.Dictionary(); Action ensureUniqueTag = (tag, fieldName) => @@ -37,8 +30,18 @@ static DirectoryStringAsn() ensureUniqueTag(new Asn1Tag(UniversalTagNumber.UTF8String), "Utf8String"); ensureUniqueTag(new Asn1Tag(UniversalTagNumber.BMPString), "BmpString"); } + } #endif + [StructLayout(LayoutKind.Sequential)] + internal partial struct DirectoryStringAsn + { + internal string? TeletexString; + internal string? PrintableString; + internal ReadOnlyMemory? UniversalString; + internal string? Utf8String; + internal string? BmpString; + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs index 592fa0a52c73cc..c31efe3df231c8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs @@ -8,14 +8,10 @@ namespace System.Security.Cryptography.Asn1 { - [StructLayout(LayoutKind.Sequential)] - internal partial struct ECDomainParameters - { - internal System.Security.Cryptography.Asn1.SpecifiedECDomain? Specified; - internal string? Named; - #if DEBUG - static ECDomainParameters() + file static class ValidateECDomainParameters + { + static ValidateECDomainParameters() { var usedTags = new System.Collections.Generic.Dictionary(); Action ensureUniqueTag = (tag, fieldName) => @@ -31,8 +27,15 @@ static ECDomainParameters() ensureUniqueTag(Asn1Tag.Sequence, "Specified"); ensureUniqueTag(Asn1Tag.ObjectIdentifier, "Named"); } + } #endif + [StructLayout(LayoutKind.Sequential)] + internal partial struct ECDomainParameters + { + internal System.Security.Cryptography.Asn1.SpecifiedECDomain? Specified; + internal string? Named; + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs index 022813b3f73c04..6c7aff3513e6c9 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -8,21 +8,10 @@ namespace System.Security.Cryptography.Asn1 { - [StructLayout(LayoutKind.Sequential)] - internal partial struct GeneralNameAsn - { - internal System.Security.Cryptography.Asn1.OtherNameAsn? OtherName; - internal string? Rfc822Name; - internal string? DnsName; - internal ReadOnlyMemory? X400Address; - internal ReadOnlyMemory? DirectoryName; - internal System.Security.Cryptography.Asn1.EdiPartyNameAsn? EdiPartyName; - internal string? Uri; - internal ReadOnlyMemory? IPAddress; - internal string? RegisteredId; - #if DEBUG - static GeneralNameAsn() + file static class ValidateGeneralNameAsn + { + static ValidateGeneralNameAsn() { var usedTags = new System.Collections.Generic.Dictionary(); Action ensureUniqueTag = (tag, fieldName) => @@ -45,8 +34,22 @@ static GeneralNameAsn() ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 7), "IPAddress"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 8), "RegisteredId"); } + } #endif + [StructLayout(LayoutKind.Sequential)] + internal partial struct GeneralNameAsn + { + internal System.Security.Cryptography.Asn1.OtherNameAsn? OtherName; + internal string? Rfc822Name; + internal string? DnsName; + internal ReadOnlyMemory? X400Address; + internal ReadOnlyMemory? DirectoryName; + internal System.Security.Cryptography.Asn1.EdiPartyNameAsn? EdiPartyName; + internal string? Uri; + internal ReadOnlyMemory? IPAddress; + internal string? RegisteredId; + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs index 43551117b732ac..1e910a890a01ef 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs @@ -8,15 +8,10 @@ namespace System.Security.Cryptography.Asn1 { - [StructLayout(LayoutKind.Sequential)] - internal partial struct MLDsaPrivateKeyAsn - { - internal ReadOnlyMemory? Seed; - internal ReadOnlyMemory? ExpandedKey; - internal System.Security.Cryptography.Asn1.MLDsaPrivateKeyBothAsn? Both; - #if DEBUG - static MLDsaPrivateKeyAsn() + file static class ValidateMLDsaPrivateKeyAsn + { + static ValidateMLDsaPrivateKeyAsn() { var usedTags = new System.Collections.Generic.Dictionary(); Action ensureUniqueTag = (tag, fieldName) => @@ -33,8 +28,16 @@ static MLDsaPrivateKeyAsn() ensureUniqueTag(Asn1Tag.PrimitiveOctetString, "ExpandedKey"); ensureUniqueTag(Asn1Tag.Sequence, "Both"); } + } #endif + [StructLayout(LayoutKind.Sequential)] + internal partial struct MLDsaPrivateKeyAsn + { + internal ReadOnlyMemory? Seed; + internal ReadOnlyMemory? ExpandedKey; + internal System.Security.Cryptography.Asn1.MLDsaPrivateKeyBothAsn? Both; + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml index 292351381b54d2..6762958dbb8b4d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml @@ -3,7 +3,7 @@ xmlns:asn="http://schemas.dot.net/asnxml/201808/" name="MLKemPrivateKeyAsn" namespace="System.Security.Cryptography.Asn1" - emitType="both"> + emitType="ref"> - - - - - SetOf - Sequence - - - - - - ReadOnlySpan<byte> - - - - - internal ref struct Builder - { - private readonly AsnWriter _writer; - - internal Builder(AsnWriter writer) - { - _writer = writer; - _writer.Push(); - } - - public void Add(scoped in value) - { - value.Encode(_writer); - } - - public void Add(ReadOnlySpan<byte> encodedValue) - { - try - { - _writer.WriteEncodedValue(encodedValue); - } - catch (ArgumentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - - public void Finish() - { - _writer.Pop(); - } - } - - - - - - - - - From 959d34f6b2fbc46fb66495f4ae439e306395592e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 12:27:13 -0400 Subject: [PATCH 23/34] Convert several loaders to be ref only --- .../Security/Cryptography/Asn1/DssParms.xml | 3 +- .../Cryptography/Asn1/DssParms.xml.cs | 73 ---------- .../Cryptography/Asn1/PBEParameter.xml | 2 +- .../Cryptography/Asn1/PBEParameter.xml.cs | 87 ------------ .../Cryptography/Asn1/PBES2Params.xml | 2 +- .../Cryptography/Asn1/PBES2Params.xml.cs | 70 --------- .../Cryptography/Asn1/Pbkdf2Params.xml | 2 +- .../Cryptography/Asn1/Pbkdf2Params.xml.cs | 134 ------------------ .../Cryptography/Asn1/Pbkdf2SaltChoice.xml | 2 +- .../Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs | 97 ------------- .../Cryptography/Asn1/RSAPrivateKeyAsn.xml | 2 +- .../Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs | 107 -------------- .../Cryptography/Asn1/RSAPublicKeyAsn.xml | 2 +- .../Cryptography/Asn1/RSAPublicKeyAsn.xml.cs | 75 ---------- .../X509CertificateLoader.Pkcs12.cs | 23 +-- 15 files changed, 20 insertions(+), 661 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml index ea0adb05d0521f..d56602fbf85ff8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml @@ -3,8 +3,7 @@ xmlns:asn="http://schemas.dot.net/asnxml/201808/" name="DssParms" namespace="System.Security.Cryptography.Asn1" - rebind="false" - emitType="both"> + emitType="ref"> diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml index 8dd1ad06dc3ea9..d7d087cc50254f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml @@ -18,7 +18,6 @@ diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml index bdaffd0bbc1354..d612dfa842722e 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml @@ -39,6 +39,5 @@ ML-DSA-87-PrivateKey ::= CHOICE { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml index 6762958dbb8b4d..3e741d9e3fcfe3 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml @@ -39,6 +39,5 @@ diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml index 774ab85001ff3c..0cf5926c2368db 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml @@ -15,10 +15,8 @@ --> diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml index d88bb8129d2d8f..0e4af860fada9d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml @@ -20,7 +20,6 @@ --> diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs index 76e2d5619f5378..eedcfe08818ec7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs @@ -21,16 +21,15 @@ file static class SharedPssParamsAsn #if DEBUG static SharedPssParamsAsn() { - PssParamsAsn decoded = default; - ReadOnlyMemory rebind = default; + ValuePssParamsAsn decoded = default; ValueAsnReader reader; reader = new ValueAsnReader(SharedPssParamsAsn.DefaultHashAlgorithm, AsnEncodingRules.DER); - System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(ref reader, rebind, out decoded.HashAlgorithm); + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref reader, out decoded.HashAlgorithm); reader.ThrowIfNotEmpty(); reader = new ValueAsnReader(SharedPssParamsAsn.DefaultMaskGenAlgorithm, AsnEncodingRules.DER); - System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(ref reader, rebind, out decoded.MaskGenAlgorithm); + System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn.Decode(ref reader, out decoded.MaskGenAlgorithm); reader.ThrowIfNotEmpty(); reader = new ValueAsnReader(SharedPssParamsAsn.DefaultSaltLength, AsnEncodingRules.DER); @@ -54,206 +53,6 @@ static SharedPssParamsAsn() #endif } - [StructLayout(LayoutKind.Sequential)] - internal partial struct PssParamsAsn - { - internal System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn HashAlgorithm; - internal System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn MaskGenAlgorithm; - internal int SaltLength; - internal int TrailerField; - - internal readonly void Encode(AsnWriter writer) - { - Encode(writer, Asn1Tag.Sequence); - } - - internal readonly void Encode(AsnWriter writer, Asn1Tag tag) - { - writer.PushSequence(tag); - - - // DEFAULT value handler for HashAlgorithm. - { - AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER); - HashAlgorithm.Encode(tmp); - - if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultHashAlgorithm)) - { - writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); - tmp.CopyTo(writer); - writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); - } - } - - - // DEFAULT value handler for MaskGenAlgorithm. - { - AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER); - MaskGenAlgorithm.Encode(tmp); - - if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultMaskGenAlgorithm)) - { - writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); - tmp.CopyTo(writer); - writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); - } - } - - - // DEFAULT value handler for SaltLength. - { - const int AsnManagedIntegerDerMaxEncodeSize = 6; - AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER, initialCapacity: AsnManagedIntegerDerMaxEncodeSize); - tmp.WriteInteger(SaltLength); - - if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultSaltLength)) - { - writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); - tmp.CopyTo(writer); - writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); - } - } - - - // DEFAULT value handler for TrailerField. - { - const int AsnManagedIntegerDerMaxEncodeSize = 6; - AsnWriter tmp = new AsnWriter(AsnEncodingRules.DER, initialCapacity: AsnManagedIntegerDerMaxEncodeSize); - tmp.WriteInteger(TrailerField); - - if (!tmp.EncodedValueEquals(SharedPssParamsAsn.DefaultTrailerField)) - { - writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); - tmp.CopyTo(writer); - writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); - } - } - - writer.PopSequence(tag); - } - - internal static PssParamsAsn Decode(ReadOnlyMemory encoded, AsnEncodingRules ruleSet) - { - return Decode(Asn1Tag.Sequence, encoded, ruleSet); - } - - internal static PssParamsAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory encoded, AsnEncodingRules ruleSet) - { - try - { - ValueAsnReader reader = new ValueAsnReader(encoded.Span, ruleSet); - - DecodeCore(ref reader, expectedTag, encoded, out PssParamsAsn decoded); - reader.ThrowIfNotEmpty(); - return decoded; - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - - internal static void Decode(ref ValueAsnReader reader, ReadOnlyMemory rebind, out PssParamsAsn decoded) - { - Decode(ref reader, Asn1Tag.Sequence, rebind, out decoded); - } - - internal static void Decode(ref ValueAsnReader reader, Asn1Tag expectedTag, ReadOnlyMemory rebind, out PssParamsAsn decoded) - { - try - { - DecodeCore(ref reader, expectedTag, rebind, out decoded); - } - catch (AsnContentException e) - { - throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); - } - } - - private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, ReadOnlyMemory rebind, out PssParamsAsn decoded) - { - decoded = default; - ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); - ValueAsnReader explicitReader; - ValueAsnReader defaultReader; - - - if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) - { - explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); - System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(ref explicitReader, rebind, out decoded.HashAlgorithm); - explicitReader.ThrowIfNotEmpty(); - } - else - { - defaultReader = new ValueAsnReader(SharedPssParamsAsn.DefaultHashAlgorithm, AsnEncodingRules.DER); - System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(ref defaultReader, rebind, out decoded.HashAlgorithm); - } - - - if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) - { - explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); - System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(ref explicitReader, rebind, out decoded.MaskGenAlgorithm); - explicitReader.ThrowIfNotEmpty(); - } - else - { - defaultReader = new ValueAsnReader(SharedPssParamsAsn.DefaultMaskGenAlgorithm, AsnEncodingRules.DER); - System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(ref defaultReader, rebind, out decoded.MaskGenAlgorithm); - } - - - if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) - { - explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); - - if (!explicitReader.TryReadInt32(out decoded.SaltLength)) - { - explicitReader.ThrowIfNotEmpty(); - } - - explicitReader.ThrowIfNotEmpty(); - } - else - { - defaultReader = new ValueAsnReader(SharedPssParamsAsn.DefaultSaltLength, AsnEncodingRules.DER); - - if (!defaultReader.TryReadInt32(out decoded.SaltLength)) - { - defaultReader.ThrowIfNotEmpty(); - } - - } - - - if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) - { - explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); - - if (!explicitReader.TryReadInt32(out decoded.TrailerField)) - { - explicitReader.ThrowIfNotEmpty(); - } - - explicitReader.ThrowIfNotEmpty(); - } - else - { - defaultReader = new ValueAsnReader(SharedPssParamsAsn.DefaultTrailerField, AsnEncodingRules.DER); - - if (!defaultReader.TryReadInt32(out decoded.TrailerField)) - { - defaultReader.ThrowIfNotEmpty(); - } - - } - - - sequenceReader.ThrowIfNotEmpty(); - } - } - [StructLayout(LayoutKind.Sequential)] internal ref partial struct ValuePssParamsAsn { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt index a5e2e46206d4e5..eed8f083561516 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt @@ -67,16 +67,17 @@ namespace { file static class Shared { -#if DEBUG +#if DEBUG static Shared() { - decoded = default; + decoded = default; ReadOnlyMemory<byte> rebind = default; ValueAsnReader reader; - ValueAsnReader collectionReader; + ValueAsnReader collectionReader; Value decoded = default; + ValueAsnReader reader; } #endif - } + } [StructLayout(LayoutKind.Sequential)] internal partial struct @@ -388,6 +389,13 @@ namespace reader = new ValueAsnReader(, AsnEncodingRules.DER); reader.ThrowIfNotEmpty(); + + + reader = new ValueAsnReader(, AsnEncodingRules.DER); + reader.ThrowIfNotEmpty(); + + + diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs index aa22394632913d..ff8b13e2cb0b56 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs index a70cbf92b9dd0c..0037446a132199 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs index c08ebfb44d1a29..ce5be3bd708460 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs index 6ed1bcad262b0a..1b0d1d6a6413a0 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs index 0cc49cbca8e432..3749edb63c9697 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs index 6039f5094e2a27..71b94a67d28a51 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs index 0c2ccef7045c97..dd954ba2d20469 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs index 557f7c94e4e4f8..e6788d5e22cd5c 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/CmsSignature.RSA.cs @@ -311,7 +311,10 @@ protected override RSASignaturePadding GetSignaturePadding( throw new CryptographicException(SR.Cryptography_Pkcs_PssParametersMissing); } - PssParamsAsn pssParams = PssParamsAsn.Decode(signatureParameters.Value, AsnEncodingRules.DER); + ValuePssParamsAsn.Decode( + signatureParameters.Value.Span, + AsnEncodingRules.DER, + out ValuePssParamsAsn pssParams); if (pssParams.HashAlgorithm.Algorithm != digestAlgorithmOid) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs index c1daad2b756e25..d34d4d248915e1 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs @@ -70,10 +70,10 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg // * don't allow custom trailer // we don't have to worry about any of the DEFAULTs. (specify, specify, specify, omit). - PssParamsAsn parameters = new PssParamsAsn + ValuePssParamsAsn parameters = new ValuePssParamsAsn { - HashAlgorithm = new AlgorithmIdentifierAsn { Algorithm = digestOid }, - MaskGenAlgorithm = new AlgorithmIdentifierAsn { Algorithm = Oids.Mgf1 }, + HashAlgorithm = new ValueAlgorithmIdentifierAsn { Algorithm = digestOid }, + MaskGenAlgorithm = new ValueAlgorithmIdentifierAsn { Algorithm = Oids.Mgf1 }, SaltLength = cbSalt, TrailerField = 1, }; @@ -90,7 +90,7 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg parameters.Encode(writer); - AlgorithmIdentifierAsn identifier = new AlgorithmIdentifierAsn + ValueAlgorithmIdentifierAsn identifier = new ValueAlgorithmIdentifierAsn { Algorithm = Oids.RsaPss, Parameters = writer.Encode(), From 020110ac7b5acd24a758864665bc6d63538db22a Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 13:24:45 -0400 Subject: [PATCH 27/34] Actually do validation --- .../Asn1/DirectoryStringAsn.xml.cs | 14 +++++++++++++- .../Asn1/ECDomainParameters.xml.cs | 14 +++++++++++++- .../Cryptography/Asn1/GeneralNameAsn.xml.cs | 14 +++++++++++++- .../Asn1/MLDsaPrivateKeyAsn.xml.cs | 14 +++++++++++++- .../Asn1/MLKemPrivateKeyAsn.xml.cs | 14 +++++++++++++- .../Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs | 14 +++++++++++++- .../Asn1/Pkcs7/CertificateChoiceAsn.xml.cs | 14 +++++++++++++- .../Asn1/Pkcs7/SignerIdentifierAsn.xml.cs | 14 +++++++++++++- .../Security/Cryptography/Asn1/asn.xslt | 19 +++++++++++++++++++ .../KeyAgreeRecipientIdentifierAsn.xml.cs | 14 +++++++++++++- .../Asn1/OriginatorIdentifierOrKeyAsn.xml.cs | 14 +++++++++++++- .../Pkcs/Asn1/RecipientIdentifierAsn.xml.cs | 14 +++++++++++++- .../Pkcs/Asn1/RecipientInfoAsn.xml.cs | 14 +++++++++++++- .../Pkcs/Asn1/SignedAttributesSet.xml.cs | 14 +++++++++++++- .../Asn1/DistributionPointNameAsn.xml.cs | 14 +++++++++++++- .../X509Certificates/Asn1/TimeAsn.xml.cs | 14 +++++++++++++- 16 files changed, 214 insertions(+), 15 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs index e9c23155876a8b..7739ef790957dd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -30,6 +30,11 @@ static ValidateDirectoryStringAsn() ensureUniqueTag(new Asn1Tag(UniversalTagNumber.UTF8String), "Utf8String"); ensureUniqueTag(new Asn1Tag(UniversalTagNumber.BMPString), "BmpString"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -42,6 +47,13 @@ internal partial struct DirectoryStringAsn internal string? Utf8String; internal string? BmpString; +#if DEBUG + static DirectoryStringAsn() + { + ValidateDirectoryStringAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs index c72377756601dd..8555925314bc1c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidateECDomainParameters() ensureUniqueTag(Asn1Tag.Sequence, "Specified"); ensureUniqueTag(Asn1Tag.ObjectIdentifier, "Named"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -37,6 +42,13 @@ internal ref partial struct ValueECDomainParameters internal bool HasSpecified; internal string? Named; +#if DEBUG + static ValueECDomainParameters() + { + ValidateECDomainParameters.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs index d206ddb3119a28..9c422ab82af910 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -34,6 +34,11 @@ static ValidateGeneralNameAsn() ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 7), "IPAddress"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 8), "RegisteredId"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -50,6 +55,13 @@ internal partial struct GeneralNameAsn internal ReadOnlyMemory? IPAddress; internal string? RegisteredId; +#if DEBUG + static GeneralNameAsn() + { + ValidateGeneralNameAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs index 641bf6a39b4cbe..306c5d1ca277e2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -28,6 +28,11 @@ static ValidateMLDsaPrivateKeyAsn() ensureUniqueTag(Asn1Tag.PrimitiveOctetString, "ExpandedKey"); ensureUniqueTag(Asn1Tag.Sequence, "Both"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -41,6 +46,13 @@ internal ref partial struct ValueMLDsaPrivateKeyAsn internal System.Security.Cryptography.Asn1.ValueMLDsaPrivateKeyBothAsn Both; internal bool HasBoth; +#if DEBUG + static ValueMLDsaPrivateKeyAsn() + { + ValidateMLDsaPrivateKeyAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs index 098c362b3fdf68..65309aefa8fb78 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -28,6 +28,11 @@ static ValidateMLKemPrivateKeyAsn() ensureUniqueTag(Asn1Tag.PrimitiveOctetString, "ExpandedKey"); ensureUniqueTag(Asn1Tag.Sequence, "Both"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -41,6 +46,13 @@ internal ref partial struct ValueMLKemPrivateKeyAsn internal System.Security.Cryptography.Asn1.ValueMLKemPrivateKeyBothAsn Both; internal bool HasBoth; +#if DEBUG + static ValueMLKemPrivateKeyAsn() + { + ValidateMLKemPrivateKeyAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs index 4894b61687d7a7..ca1cac7b15a45f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidatePbkdf2SaltChoice() ensureUniqueTag(Asn1Tag.PrimitiveOctetString, "Specified"); ensureUniqueTag(Asn1Tag.Sequence, "OtherSource"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -38,6 +43,13 @@ internal ref partial struct ValuePbkdf2SaltChoice internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn OtherSource; internal bool HasOtherSource; +#if DEBUG + static ValuePbkdf2SaltChoice() + { + ValidatePbkdf2SaltChoice.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs index e298d6d92dbe57..c67beb887d3d52 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -30,6 +30,11 @@ static ValidateCertificateChoiceAsn() ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 2), "AttributeCertificateV2"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 3), "OtherCertificateFormat"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -42,6 +47,13 @@ internal partial struct CertificateChoiceAsn internal ReadOnlyMemory? AttributeCertificateV2; internal System.Security.Cryptography.Asn1.Pkcs7.OtherCertificateFormat? OtherCertificateFormat; +#if DEBUG + static CertificateChoiceAsn() + { + ValidateCertificateChoiceAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs index 7d3d6a31b9b2b6..c82b3c8d58a765 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidateSignerIdentifierAsn() ensureUniqueTag(Asn1Tag.Sequence, "IssuerAndSerialNumber"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "SubjectKeyIdentifier"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -36,6 +41,13 @@ internal partial struct SignerIdentifierAsn internal System.Security.Cryptography.Asn1.Pkcs7.IssuerAndSerialNumberAsn? IssuerAndSerialNumber; internal ReadOnlyMemory? SubjectKeyIdentifier; +#if DEBUG + static SignerIdentifierAsn() + { + ValidateSignerIdentifierAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt index eed8f083561516..3dadb2c867eca2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt @@ -245,6 +245,11 @@ namespace }; } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -252,6 +257,13 @@ namespace internal partial struct { +#if DEBUG + static () + { + Validate.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; @@ -311,6 +323,13 @@ namespace internal ref partial struct Value { +#if DEBUG + static Value() + { + Validate.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs index ff8b13e2cb0b56..059f8d11f98000 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidateKeyAgreeRecipientIdentifierAsn() ensureUniqueTag(Asn1Tag.Sequence, "IssuerAndSerialNumber"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "RKeyId"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -36,6 +41,13 @@ internal partial struct KeyAgreeRecipientIdentifierAsn internal System.Security.Cryptography.Asn1.Pkcs7.IssuerAndSerialNumberAsn? IssuerAndSerialNumber; internal System.Security.Cryptography.Pkcs.Asn1.RecipientKeyIdentifier? RKeyId; +#if DEBUG + static KeyAgreeRecipientIdentifierAsn() + { + ValidateKeyAgreeRecipientIdentifierAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs index ce5be3bd708460..304313d49c6ed5 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -28,6 +28,11 @@ static ValidateOriginatorIdentifierOrKeyAsn() ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "SubjectKeyIdentifier"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 1), "OriginatorKey"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -38,6 +43,13 @@ internal partial struct OriginatorIdentifierOrKeyAsn internal ReadOnlyMemory? SubjectKeyIdentifier; internal System.Security.Cryptography.Pkcs.Asn1.OriginatorPublicKeyAsn? OriginatorKey; +#if DEBUG + static OriginatorIdentifierOrKeyAsn() + { + ValidateOriginatorIdentifierOrKeyAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs index 1b0d1d6a6413a0..247743d4c673fc 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidateRecipientIdentifierAsn() ensureUniqueTag(Asn1Tag.Sequence, "IssuerAndSerialNumber"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "SubjectKeyIdentifier"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -36,6 +41,13 @@ internal partial struct RecipientIdentifierAsn internal System.Security.Cryptography.Asn1.Pkcs7.IssuerAndSerialNumberAsn? IssuerAndSerialNumber; internal ReadOnlyMemory? SubjectKeyIdentifier; +#if DEBUG + static RecipientIdentifierAsn() + { + ValidateRecipientIdentifierAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs index 3749edb63c9697..633b7ee6ee59bf 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidateRecipientInfoAsn() ensureUniqueTag(Asn1Tag.Sequence, "Ktri"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 1), "Kari"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -36,6 +41,13 @@ internal partial struct RecipientInfoAsn internal System.Security.Cryptography.Pkcs.Asn1.KeyTransRecipientInfoAsn? Ktri; internal System.Security.Cryptography.Pkcs.Asn1.KeyAgreeRecipientInfoAsn? Kari; +#if DEBUG + static RecipientInfoAsn() + { + ValidateRecipientInfoAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs index dd954ba2d20469..7dc31616d45d8d 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidateSignedAttributesSet() ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "SignedAttributes"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -35,6 +40,13 @@ internal partial struct SignedAttributesSet { internal System.Security.Cryptography.Asn1.AttributeAsn[]? SignedAttributes; +#if DEBUG + static SignedAttributesSet() + { + ValidateSignedAttributesSet.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs index 01e653c69995e0..288b41bd44bbd0 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -28,6 +28,11 @@ static ValidateDistributionPointNameAsn() ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "FullName"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 1), "NameRelativeToCRLIssuer"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -37,6 +42,13 @@ internal partial struct DistributionPointNameAsn internal System.Security.Cryptography.Asn1.GeneralNameAsn[]? FullName; internal ReadOnlyMemory? NameRelativeToCRLIssuer; +#if DEBUG + static DistributionPointNameAsn() + { + ValidateDistributionPointNameAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs index f4d0b9c1c052e1..9d1ca94b67a86f 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -27,6 +27,11 @@ static ValidateTimeAsn() ensureUniqueTag(Asn1Tag.UtcTime, "UtcTime"); ensureUniqueTag(Asn1Tag.GeneralizedTime, "GeneralTime"); } + + [System.Runtime.CompilerServices.MethodImpl( + System.Runtime.CompilerServices.MethodImplOptions.NoInlining | + System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] + internal static void Validate() { } } #endif @@ -36,6 +41,13 @@ internal partial struct TimeAsn internal DateTimeOffset? UtcTime; internal DateTimeOffset? GeneralTime; +#if DEBUG + static TimeAsn() + { + ValidateTimeAsn.Validate(); + } +#endif + internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; From 60ba8d8c2e912466422ac9b2a31bae009bb7ba7e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 14:59:24 -0400 Subject: [PATCH 28/34] Fix tests --- .../MLDsa/MLDsaImplementationTests.cs | 49 +++++++++------- .../MLDsa/MLDsaTestHelpers.cs | 58 ++++++++++++++++--- .../System/Security/Cryptography/AsnUtils.cs | 19 ++++-- .../Security/Cryptography/MLKemBaseTests.cs | 19 ++++-- .../tests/X509Certificates/ExportTests.cs | 19 ++++-- 5 files changed, 116 insertions(+), 48 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs index 996558d86fc0f0..ffe68209c770c0 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs @@ -270,9 +270,10 @@ public static void ImportPkcs8PrivateKey_AlgorithmErrorsInAsn() // Create an invalid ML-DSA PKCS8 with parameters AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - MLDsaPrivateKeyAsn seed = new MLDsaPrivateKeyAsn + ValueMLDsaPrivateKeyAsn seed = new ValueMLDsaPrivateKeyAsn { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], + HasSeed = true, }; seed.Encode(writer); @@ -302,56 +303,62 @@ public static void ImportPkcs8PrivateKey_AlgorithmErrorsInAsn() [Fact] public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() { - AssertInvalidAsn(new MLDsaPrivateKeyAsn + AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn { - Both = new MLDsaPrivateKeyBothAsn() + Both = new ValueMLDsaPrivateKeyBothAsn(), + HasBoth = true, }); - AssertInvalidAsn(new MLDsaPrivateKeyAsn + AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn { - Both = new MLDsaPrivateKeyBothAsn + Both = new ValueMLDsaPrivateKeyBothAsn { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], - } + }, + HasBoth = true, }); - AssertInvalidAsn(new MLDsaPrivateKeyAsn + AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn { - Both = new MLDsaPrivateKeyBothAsn + Both = new ValueMLDsaPrivateKeyBothAsn { ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], - } + }, + HasBoth = true, }); - AssertInvalidAsn(new MLDsaPrivateKeyAsn + AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn { - Both = new MLDsaPrivateKeyBothAsn + Both = new ValueMLDsaPrivateKeyBothAsn { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes - 1], ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], - } + }, + HasBoth = true, }); - AssertInvalidAsn(new MLDsaPrivateKeyAsn + AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn { - Both = new MLDsaPrivateKeyBothAsn + Both = new ValueMLDsaPrivateKeyBothAsn { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes - 1], - } + }, + HasBoth = true, }); - AssertInvalidAsn(new MLDsaPrivateKeyAsn + AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn { - Both = new MLDsaPrivateKeyBothAsn + Both = new ValueMLDsaPrivateKeyBothAsn { // This will also fail because the seed and expanded key mismatch Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], - } + }, + HasBoth = true, }); - static void AssertInvalidAsn(MLDsaPrivateKeyAsn privateKeyAsn) + static void AssertInvalidAsn(ValueMLDsaPrivateKeyAsn privateKeyAsn) { PrivateKeyInfoAsn pkcs8 = new PrivateKeyInfoAsn { @@ -433,12 +440,12 @@ public static void AlgorithmMatches_GenerateKey(MLDsaAlgorithm algorithm) MLDsaTestHelpers.AssertImportPublicKey(import => AssertThrowIfNotSupported(() => - WithDispose(import(), mldsa => + WithDispose(import(), mldsa => Assert.Equal(algorithm, mldsa.Algorithm))), algorithm, publicKey); MLDsaTestHelpers.AssertImportPrivateKey(import => AssertThrowIfNotSupported(() => - WithDispose(import(), mldsa => + WithDispose(import(), mldsa => Assert.Equal(algorithm, mldsa.Algorithm))), algorithm, privateKey); MLDsaTestHelpers.AssertImportPrivateSeed(import => diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs index 581e7ae8140660..2204a7795bfb38 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs @@ -138,9 +138,10 @@ internal static void AssertImportPrivateKey(Action> testDirectCall, } AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - MLDsaPrivateKeyAsn privateKeyAsn = new MLDsaPrivateKeyAsn + ValueMLDsaPrivateKeyAsn privateKeyAsn = new ValueMLDsaPrivateKeyAsn { - ExpandedKey = privateKey + ExpandedKey = privateKey, + HasExpandedKey = true, }; privateKeyAsn.Encode(writer); @@ -178,9 +179,10 @@ internal static void AssertImportPrivateSeed(Action> testDirectCall, } AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); - MLDsaPrivateKeyAsn privateKey = new MLDsaPrivateKeyAsn + ValueMLDsaPrivateKeyAsn privateKey = new ValueMLDsaPrivateKeyAsn { Seed = privateSeed, + HasSeed = true, }; privateKey.Encode(writer); @@ -301,10 +303,29 @@ internal static void AssertExportMLDsaPrivateKey(Action> dir }); AssertExportPkcs8PrivateKey(exportPkcs8 => + { indirectCallback(mldsa => - MLDsaPrivateKeyAsn.Decode( - PrivateKeyInfoAsn.Decode( - exportPkcs8(mldsa), AsnEncodingRules.DER).PrivateKey, AsnEncodingRules.DER).ExpandedKey?.ToArray())); + { + ValuePrivateKeyInfoAsn.Decode( + exportPkcs8(mldsa), + AsnEncodingRules.DER, + out ValuePrivateKeyInfoAsn privateKeyInfo); + + ValueMLDsaPrivateKeyAsn.Decode( + privateKeyInfo.PrivateKey, + AsnEncodingRules.DER, + out ValueMLDsaPrivateKeyAsn mldsaPrivateKeyInfo); + + if (mldsaPrivateKeyInfo.HasExpandedKey) + { + return mldsaPrivateKeyInfo.ExpandedKey.ToArray(); + } + else + { + return null; + } + }); + }); } internal static void AssertExportMLDsaPrivateSeed(Action> callback) => @@ -320,10 +341,29 @@ internal static void AssertExportMLDsaPrivateSeed(Action> di }); AssertExportPkcs8PrivateKey(exportPkcs8 => + { indirectCallback(mldsa => - MLDsaPrivateKeyAsn.Decode( - PrivateKeyInfoAsn.Decode( - exportPkcs8(mldsa), AsnEncodingRules.DER).PrivateKey, AsnEncodingRules.DER).Seed?.ToArray())); + { + ValuePrivateKeyInfoAsn.Decode( + exportPkcs8(mldsa), + AsnEncodingRules.DER, + out ValuePrivateKeyInfoAsn privateKeyInfo); + + ValueMLDsaPrivateKeyAsn.Decode( + privateKeyInfo.PrivateKey, + AsnEncodingRules.DER, + out ValueMLDsaPrivateKeyAsn mldsaPrivateKeyInfo); + + if (mldsaPrivateKeyInfo.HasSeed) + { + return mldsaPrivateKeyInfo.Seed.ToArray(); + } + else + { + return null; + } + }); + }); } internal static void AssertExportPkcs8PrivateKey(MLDsa mldsa, Action callback) => diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AsnUtils.cs b/src/libraries/Common/tests/System/Security/Cryptography/AsnUtils.cs index 680d27d7782b87..84198a7b89bc68 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AsnUtils.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AsnUtils.cs @@ -37,18 +37,25 @@ internal static void AssertEncryptedPkcs8PrivateKeyContents(EncryptedPrivateKeyI { // pbeWithSHA1And3-KeyTripleDES-CBC Assert.Equal("1.2.840.113549.1.12.1.3", algorithmIdentifier.Algorithm); - PBEParameter pbeParameterAsn = PBEParameter.Decode(algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER); + ValuePBEParameter.Decode( + algorithmIdentifier.Parameters.Value.Span, + AsnEncodingRules.BER, + out ValuePBEParameter pbeParameterAsn); Assert.Equal(pbeParameters.IterationCount, pbeParameterAsn.IterationCount); } else { Assert.Equal("1.2.840.113549.1.5.13", algorithmIdentifier.Algorithm); // PBES2 - PBES2Params pbes2Params = PBES2Params.Decode(algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER); + ValuePBES2Params.Decode( + algorithmIdentifier.Parameters.Value.Span, + AsnEncodingRules.BER, + out ValuePBES2Params pbes2Params); Assert.Equal("1.2.840.113549.1.5.12", pbes2Params.KeyDerivationFunc.Algorithm); // PBKDF2 - Pbkdf2Params pbkdf2Params = Pbkdf2Params.Decode( - pbes2Params.KeyDerivationFunc.Parameters.Value, - AsnEncodingRules.BER); + ValuePbkdf2Params.Decode( + pbes2Params.KeyDerivationFunc.Parameters, + AsnEncodingRules.BER, + out ValuePbkdf2Params pbkdf2Params); string expectedEncryptionOid = pbeParameters.EncryptionAlgorithm switch { PbeEncryptionAlgorithm.Aes128Cbc => "2.16.840.1.101.3.4.1.2", @@ -62,7 +69,7 @@ internal static void AssertEncryptedPkcs8PrivateKeyContents(EncryptedPrivateKeyI Assert.Equal(expectedEncryptionOid, pbes2Params.EncryptionScheme.Algorithm); } - static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(Pbkdf2Params pbkdf2Params) + static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(in ValuePbkdf2Params pbkdf2Params) { return pbkdf2Params.Prf.Algorithm switch { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs index 5f97ca8d3d576a..fbc4c3b87870d6 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs @@ -566,18 +566,25 @@ private static void AssertEncryptedPkcs8PrivateKeyContents(PbeParameters pbePara { // pbeWithSHA1And3-KeyTripleDES-CBC Assert.Equal("1.2.840.113549.1.12.1.3", algorithmIdentifier.Algorithm); - PBEParameter pbeParameterAsn = PBEParameter.Decode(algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER); + ValuePBEParameter.Decode( + algorithmIdentifier.Parameters.Value.Span, + AsnEncodingRules.BER, + out ValuePBEParameter pbeParameterAsn); Assert.Equal(pbeParameters.IterationCount, pbeParameterAsn.IterationCount); } else { Assert.Equal("1.2.840.113549.1.5.13", algorithmIdentifier.Algorithm); // PBES2 - PBES2Params pbes2Params = PBES2Params.Decode(algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER); + ValuePBES2Params.Decode( + algorithmIdentifier.Parameters.Value.Span, + AsnEncodingRules.BER, + out ValuePBES2Params pbes2Params); Assert.Equal("1.2.840.113549.1.5.12", pbes2Params.KeyDerivationFunc.Algorithm); // PBKDF2 - Pbkdf2Params pbkdf2Params = Pbkdf2Params.Decode( - pbes2Params.KeyDerivationFunc.Parameters.Value, - AsnEncodingRules.BER); + ValuePbkdf2Params.Decode( + pbes2Params.KeyDerivationFunc.Parameters, + AsnEncodingRules.BER, + out ValuePbkdf2Params pbkdf2Params); string expectedEncryptionOid = pbeParameters.EncryptionAlgorithm switch { PbeEncryptionAlgorithm.Aes128Cbc => "2.16.840.1.101.3.4.1.2", @@ -592,7 +599,7 @@ private static void AssertEncryptedPkcs8PrivateKeyContents(PbeParameters pbePara } } - private static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(Pbkdf2Params pbkdf2Params) + private static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(in ValuePbkdf2Params pbkdf2Params) { return pbkdf2Params.Prf.Algorithm switch { diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs index 7f13477421e654..649ab7697747d7 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs @@ -1001,18 +1001,25 @@ void AssertEncryptionAlgorithm(AlgorithmIdentifierAsn algorithmIdentifier) { // pbeWithSHA1And3-KeyTripleDES-CBC Assert.Equal("1.2.840.113549.1.12.1.3", algorithmIdentifier.Algorithm); - PBEParameter pbeParameter = PBEParameter.Decode(algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER); + ValuePBEParameter.Decode( + algorithmIdentifier.Parameters.Value.Span, + AsnEncodingRules.BER, + out ValuePBEParameter pbeParameter); Assert.Equal(expectedIterations, pbeParameter.IterationCount); } else { Assert.Equal("1.2.840.113549.1.5.13", algorithmIdentifier.Algorithm); // PBES2 - PBES2Params pbes2Params = PBES2Params.Decode(algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER); + ValuePBES2Params.Decode( + algorithmIdentifier.Parameters.Value.Span, + AsnEncodingRules.BER, + out ValuePBES2Params pbes2Params); Assert.Equal("1.2.840.113549.1.5.12", pbes2Params.KeyDerivationFunc.Algorithm); // PBKDF2 - Pbkdf2Params pbkdf2Params = Pbkdf2Params.Decode( - pbes2Params.KeyDerivationFunc.Parameters.Value, - AsnEncodingRules.BER); + ValuePbkdf2Params.Decode( + pbes2Params.KeyDerivationFunc.Parameters, + AsnEncodingRules.BER, + out ValuePbkdf2Params pbkdf2Params); string expectedEncryptionOid = expectedEncryptionAlgorithm switch { PbeEncryptionAlgorithm.Aes128Cbc => "2.16.840.1.101.3.4.1.2", @@ -1028,7 +1035,7 @@ void AssertEncryptionAlgorithm(AlgorithmIdentifierAsn algorithmIdentifier) } } - private static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(Pbkdf2Params pbkdf2Params) + private static HashAlgorithmName GetHashAlgorithmFromPbkdf2Params(in ValuePbkdf2Params pbkdf2Params) { return pbkdf2Params.Prf.Algorithm switch { From 5b4425697b82210be61295a490a86e0d5a0fba7c Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 15:00:51 -0400 Subject: [PATCH 29/34] Back to key reader --- .../Security/Cryptography/KeyFormatHelper.Encrypted.cs | 6 +++--- .../src/System/Security/Cryptography/KeyFormatHelper.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs index 09f09834bead1b..e3616e7766faf7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.Encrypted.cs @@ -18,7 +18,7 @@ internal static void ReadEncryptedPkcs8( string[] validOids, ReadOnlySpan source, ReadOnlySpan password, - ValueKeyReader keyReader, + KeyReader keyReader, out int bytesRead, out TRet ret) { @@ -36,7 +36,7 @@ internal static void ReadEncryptedPkcs8( string[] validOids, ReadOnlySpan source, ReadOnlySpan passwordBytes, - ValueKeyReader keyReader, + KeyReader keyReader, out int bytesRead, out TRet ret) { @@ -55,7 +55,7 @@ private static void ReadEncryptedPkcs8( ReadOnlySpan source, ReadOnlySpan password, ReadOnlySpan passwordBytes, - ValueKeyReader keyReader, + KeyReader keyReader, out int bytesRead, out TRet ret) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs index 76eac17d101bcd..7f99cdcc676a2b 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs @@ -11,12 +11,12 @@ namespace System.Security.Cryptography { internal static partial class KeyFormatHelper { - internal delegate void ValueKeyReader(ReadOnlySpan key, in ValueAlgorithmIdentifierAsn algId, out TRet ret); + internal delegate void KeyReader(ReadOnlySpan key, in ValueAlgorithmIdentifierAsn algId, out TRet ret); internal static void ReadSubjectPublicKeyInfo( string[] validOids, ReadOnlySpan source, - ValueKeyReader keyReader, + KeyReader keyReader, out int bytesRead, out TRet ret) { @@ -75,7 +75,7 @@ internal static ReadOnlySpan ReadSubjectPublicKeyInfo( internal static void ReadPkcs8( string[] validOids, ReadOnlySpan source, - ValueKeyReader keyReader, + KeyReader keyReader, out int bytesRead, out TRet ret) { From d57e61ceb362208df0d2d7e50682814b9dad5de0 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 16:05:10 -0400 Subject: [PATCH 30/34] Add whitespace in the generated C# --- .../Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs | 3 ++- .../System/Security/Cryptography/Asn1/AttributeAsn.xml.cs | 3 ++- .../src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/DssParms.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs | 2 +- .../Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/FieldID.xml.cs | 3 ++- .../Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs | 2 +- .../Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/PBEParameter.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs | 2 +- .../Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs | 3 ++- .../System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs | 2 +- .../Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs | 2 +- .../Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs | 2 +- .../Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs | 2 +- .../Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs | 2 +- .../Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs | 2 +- .../Common/src/System/Security/Cryptography/Asn1/asn.xslt | 4 ++++ .../Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs | 3 ++- .../Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs | 4 +++- .../X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs | 5 ++++- 24 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs index 5b413ac631d281..780db04c9ca8c0 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -133,6 +133,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) if (HasParameters) { + try { writer.WriteEncodedValue(Parameters); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs index 268f6a1366ef2f..04dd0473505088 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -143,6 +143,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } + try { writer.WriteEncodedValue(AttrValues); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs index 17c75dc3aeaaab..155fd6d52bc33d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs index 5ba6c1c52f338c..6143131a2de084 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs index 1e8f531326f878..8cfca770c96168 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs index ea916323870e1a..a929a96da4dffa 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs index 0a329718d65419..2fdd4f31a8d75f 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -31,6 +31,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } + try { writer.WriteEncodedValue(Parameters); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs index affdb1a9393c25..8f381e29c1b9cd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs index 81ec916a4d6d75..4f9441cc9bb1c2 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs index 5a3e34508257e1..bf9263134cdf03 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs index ba71dee2ce87e9..358070cbfd096e 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs index f38cb1acb409ee..8a2f3904d6c50d 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs index 409954457dd985..202862de0aac11 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -159,6 +159,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) if (HasAttributes) { + try { writer.WriteEncodedValue(Attributes); diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs index eedcfe08818ec7..eb868e594e1abf 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs index fc47e8335df909..044ef9ae273aa0 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs index f9d829892576c8..f77374253cf556 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs index 16c0a4361e9024..b68c37f6c00275 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs index b5b723200baa13..29df6e516b69ce 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs index f7de7452f92fb7..0cd5faffe3cec4 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs index b3140132e0f5cd..14eb4e6d8a0712 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt index 3dadb2c867eca2..db2900de79c0c0 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt @@ -1570,6 +1570,7 @@ namespace + // Validator for tag constraint for { if (!Asn1Tag.TryDecode(, out Asn1Tag validateTag, out _) || @@ -1580,6 +1581,7 @@ namespace } + try { .WriteEncodedValue(); @@ -1632,6 +1634,7 @@ namespace + try { .WriteEncodedValue(); @@ -1648,6 +1651,7 @@ namespace + try { .WriteEncodedValue(); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs index 0037446a132199..43e66431955eda 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -105,6 +105,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) { writer.PushSequence(tag); + try { writer.WriteEncodedValue(HashAlgorithm); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs index 71b94a67d28a51..a183c4d03dc96c 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -301,6 +301,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) if (HasTsa) { writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); + try { writer.WriteEncodedValue(Tsa); @@ -315,6 +316,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) if (HasExtensions) { + try { writer.WriteEncodedValue(Extensions); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs index ac9a53795601e3..3aa0f43ccf6163 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code @@ -151,6 +151,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) writer.PushSequence(tag); writer.WriteInteger(Version); + // Validator for tag constraint for Subject { if (!Asn1Tag.TryDecode(Subject, out Asn1Tag validateTag, out _) || @@ -160,6 +161,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) } } + try { writer.WriteEncodedValue(Subject); @@ -169,6 +171,7 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag) throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } SubjectPublicKeyInfo.Encode(writer); + try { writer.WriteEncodedValue(Attributes); From 06e2428a6087b2d3cd3b50874a838a4495edcbaf Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 16:10:59 -0400 Subject: [PATCH 31/34] Put the BOM back. --- .../Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/DssParms.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs | 2 +- .../Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs | 2 +- .../Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs | 2 +- .../Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs | 2 +- .../Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs | 2 +- .../Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs | 2 +- .../Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs | 2 +- .../src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs | 2 +- .../Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs | 2 +- .../System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs | 2 +- .../Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs | 2 +- .../Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs | 2 +- .../Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs | 2 +- .../Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs | 2 +- .../Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs | 2 +- .../Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs | 2 +- .../Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs | 2 +- .../X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs | 2 +- .../X509Certificates/Asn1/DistributionPointNameAsn.xml.cs | 2 +- .../Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs | 2 +- 38 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs index 780db04c9ca8c0..77644ad61ee9a5 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs index 04dd0473505088..947f33222f3d73 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AttributeAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs index 155fd6d52bc33d..17c75dc3aeaaab 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs index 7739ef790957dd..9aa9503531fc79 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DirectoryStringAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs index 6143131a2de084..5ba6c1c52f338c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/DssParms.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs index 8555925314bc1c..3ab4302f315791 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs index 8cfca770c96168..1e8f531326f878 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs index a929a96da4dffa..ea916323870e1a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/EncryptedPrivateKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs index 2fdd4f31a8d75f..e8b44b15ec5b1b 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/FieldID.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs index 9c422ab82af910..a39128815529ac 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/GeneralNameAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs index 306c5d1ca277e2..f8066e604acdbf 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs index 8f381e29c1b9cd..affdb1a9393c25 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyBothAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs index 65309aefa8fb78..3b34656ed6a6ed 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs index 4f9441cc9bb1c2..81ec916a4d6d75 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyBothAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs index bf9263134cdf03..5a3e34508257e1 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBEParameter.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs index 358070cbfd096e..ba71dee2ce87e9 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PBES2Params.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs index 8a2f3904d6c50d..f38cb1acb409ee 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2Params.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs index ca1cac7b15a45f..32d47ce870c877 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs index c67beb887d3d52..d0d6eb900828ca 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/CertificateChoiceAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs index c82b3c8d58a765..c50ef554058221 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pkcs7/SignerIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs index 202862de0aac11..d71c82dfc23486 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs index eb868e594e1abf..eedcfe08818ec7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PssParamsAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs index 044ef9ae273aa0..fc47e8335df909 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs index f77374253cf556..f9d829892576c8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs index b68c37f6c00275..16c0a4361e9024 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Rc2CbcParameters.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs index 29df6e516b69ce..b5b723200baa13 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs index 0cd5faffe3cec4..f7de7452f92fb7 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SubjectPublicKeyInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs index 14eb4e6d8a0712..b3140132e0f5cd 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/X509ExtensionAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs index 059f8d11f98000..b6f5dff5dcb9c4 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/KeyAgreeRecipientIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs index 43e66431955eda..3c0a07d01952f7 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/MessageImprint.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs index 304313d49c6ed5..40226a40064abd 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/OriginatorIdentifierOrKeyAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs index 247743d4c673fc..3e5392d5879287 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientIdentifierAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs index 633b7ee6ee59bf..61d978cc1186ed 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/RecipientInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs index a183c4d03dc96c..296b9064937ec7 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs index 7dc31616d45d8d..225c073f1b8b39 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/SignedAttributesSet.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs index 3aa0f43ccf6163..039aa29f2316e0 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/CertificationRequestInfoAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs index 288b41bd44bbd0..c7446dce138cf7 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/DistributionPointNameAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs index 9d1ca94b67a86f..1c303d6bb661b3 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/Asn1/TimeAsn.xml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code From b2727b6d5badf466ca50ff1dda44b2a459717b6e Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 17:10:37 -0400 Subject: [PATCH 32/34] Fix missing HasParameter assignments, fix missing slice --- .../Common/src/System/Security/Cryptography/RSAAndroid.cs | 1 + .../src/System/Security/Cryptography/RSA.cs | 2 +- .../X509Certificates/RSAPssX509SignatureGenerator.cs | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs index 6c0a8da998dc42..643737228ed0b3 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs @@ -424,6 +424,7 @@ public override void ImportRSAPublicKey(ReadOnlySpan source, out int bytes { Algorithm = Oids.Rsa, Parameters = AlgorithmIdentifierAsn.ExplicitDerNull.Span, + HasParameters = true, }, SubjectPublicKey = subjectPublicKey, }; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs index 0a20a111358dac..36723978608a75 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/RSA.cs @@ -894,7 +894,7 @@ public virtual void ImportRSAPublicKey(ReadOnlySpan source, out int bytesR out int localRead); ValueAlgorithmIdentifierAsn ignored = default; - RSAKeyFormatHelper.ReadRsaPublicKey(source, ignored, out RSAParameters rsaParameters); + RSAKeyFormatHelper.ReadRsaPublicKey(source.Slice(0, localRead), ignored, out RSAParameters rsaParameters); ImportParameters(rsaParameters); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs index d34d4d248915e1..ecb0248c11ce54 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs @@ -86,6 +86,7 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg } parameters.MaskGenAlgorithm.Parameters = writer.Encode(); + parameters.MaskGenAlgorithm.HasParameters = true; writer.Reset(); parameters.Encode(writer); @@ -94,6 +95,7 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg { Algorithm = Oids.RsaPss, Parameters = writer.Encode(), + HasParameters = true, }; writer.Reset(); From 48238990fd6a23e7f3ff5013596e470959f86157 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 18:38:01 -0400 Subject: [PATCH 33/34] Change optional fields to avoid torn values --- .../Asn1/AlgorithmIdentifierAsn.manual.cs | 1 - .../Asn1/AlgorithmIdentifierAsn.xml.cs | 14 +++- .../Cryptography/Asn1/CurveAsn.xml.cs | 14 +++- .../Asn1/ECDomainParameters.xml.cs | 14 +++- .../Cryptography/Asn1/ECPrivateKey.xml.cs | 28 ++++++-- .../Asn1/MLDsaPrivateKeyAsn.xml.cs | 42 ++++++++++-- .../Asn1/MLKemPrivateKeyAsn.xml.cs | 42 ++++++++++-- .../Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs | 28 ++++++-- .../Asn1/PrivateKeyInfoAsn.xml.cs | 14 +++- .../Asn1/SpecifiedECDomain.xml.cs | 14 +++- .../Security/Cryptography/Asn1/asn.xslt | 64 +++++++++++++------ .../Security/Cryptography/MLDsaPkcs8.cs | 1 - .../Security/Cryptography/MLKemPkcs8.cs | 3 - .../Security/Cryptography/RSAAndroid.cs | 1 - .../MLDsa/MLDsaImplementationTests.cs | 7 -- .../MLDsa/MLDsaTestHelpers.cs | 2 - .../Pkcs/Asn1/Rfc3161TstInfo.xml.cs | 42 ++++++++++-- .../RSAPssX509SignatureGenerator.cs | 2 - 18 files changed, 259 insertions(+), 74 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs index b0389c14f5431f..6fbcc3fdeaba1a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.manual.cs @@ -66,7 +66,6 @@ internal ValueAlgorithmIdentifierAsn AsValueAlgorithmIdentifierAsn() if (Parameters is ReadOnlyMemory parameters) { - val.HasParameters = true; val.Parameters = parameters.Span; } diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs index 77644ad61ee9a5..b016191ccadf5b 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/AlgorithmIdentifierAsn.xml.cs @@ -110,8 +110,18 @@ private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, R internal ref partial struct ValueAlgorithmIdentifierAsn { internal string Algorithm; - internal ReadOnlySpan Parameters; - internal bool HasParameters; + + internal ReadOnlySpan Parameters + { + get; + set + { + HasParameters = true; + field = value; + } + } + + internal bool HasParameters { get; private set; } internal readonly void Encode(AsnWriter writer) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs index 17c75dc3aeaaab..c82d2f52fadb30 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/CurveAsn.xml.cs @@ -13,8 +13,18 @@ internal ref partial struct ValueCurveAsn { internal ReadOnlySpan A; internal ReadOnlySpan B; - internal ReadOnlySpan Seed; - internal bool HasSeed; + + internal ReadOnlySpan Seed + { + get; + set + { + HasSeed = true; + field = value; + } + } + + internal bool HasSeed { get; private set; } internal readonly void Encode(AsnWriter writer) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs index 3ab4302f315791..a767b35b44bcfc 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECDomainParameters.xml.cs @@ -38,8 +38,18 @@ internal static void Validate() { } [StructLayout(LayoutKind.Sequential)] internal ref partial struct ValueECDomainParameters { - internal System.Security.Cryptography.Asn1.ValueSpecifiedECDomain Specified; - internal bool HasSpecified; + + internal System.Security.Cryptography.Asn1.ValueSpecifiedECDomain Specified + { + get; + set + { + HasSpecified = true; + field = value; + } + } + + internal bool HasSpecified { get; private set; } internal string? Named; #if DEBUG diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs index 1e8f531326f878..dc8385227eb5d1 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/ECPrivateKey.xml.cs @@ -13,10 +13,30 @@ internal ref partial struct ValueECPrivateKey { internal int Version; internal ReadOnlySpan PrivateKey; - internal System.Security.Cryptography.Asn1.ValueECDomainParameters Parameters; - internal bool HasParameters; - internal ReadOnlySpan PublicKey; - internal bool HasPublicKey; + + internal System.Security.Cryptography.Asn1.ValueECDomainParameters Parameters + { + get; + set + { + HasParameters = true; + field = value; + } + } + + internal bool HasParameters { get; private set; } + + internal ReadOnlySpan PublicKey + { + get; + set + { + HasPublicKey = true; + field = value; + } + } + + internal bool HasPublicKey { get; private set; } internal readonly void Encode(AsnWriter writer) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs index f8066e604acdbf..1c1d204457d223 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLDsaPrivateKeyAsn.xml.cs @@ -39,12 +39,42 @@ internal static void Validate() { } [StructLayout(LayoutKind.Sequential)] internal ref partial struct ValueMLDsaPrivateKeyAsn { - internal ReadOnlySpan Seed; - internal bool HasSeed; - internal ReadOnlySpan ExpandedKey; - internal bool HasExpandedKey; - internal System.Security.Cryptography.Asn1.ValueMLDsaPrivateKeyBothAsn Both; - internal bool HasBoth; + + internal ReadOnlySpan Seed + { + get; + set + { + HasSeed = true; + field = value; + } + } + + internal bool HasSeed { get; private set; } + + internal ReadOnlySpan ExpandedKey + { + get; + set + { + HasExpandedKey = true; + field = value; + } + } + + internal bool HasExpandedKey { get; private set; } + + internal System.Security.Cryptography.Asn1.ValueMLDsaPrivateKeyBothAsn Both + { + get; + set + { + HasBoth = true; + field = value; + } + } + + internal bool HasBoth { get; private set; } #if DEBUG static ValueMLDsaPrivateKeyAsn() diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs index 3b34656ed6a6ed..cd2ab689a2d953 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/MLKemPrivateKeyAsn.xml.cs @@ -39,12 +39,42 @@ internal static void Validate() { } [StructLayout(LayoutKind.Sequential)] internal ref partial struct ValueMLKemPrivateKeyAsn { - internal ReadOnlySpan Seed; - internal bool HasSeed; - internal ReadOnlySpan ExpandedKey; - internal bool HasExpandedKey; - internal System.Security.Cryptography.Asn1.ValueMLKemPrivateKeyBothAsn Both; - internal bool HasBoth; + + internal ReadOnlySpan Seed + { + get; + set + { + HasSeed = true; + field = value; + } + } + + internal bool HasSeed { get; private set; } + + internal ReadOnlySpan ExpandedKey + { + get; + set + { + HasExpandedKey = true; + field = value; + } + } + + internal bool HasExpandedKey { get; private set; } + + internal System.Security.Cryptography.Asn1.ValueMLKemPrivateKeyBothAsn Both + { + get; + set + { + HasBoth = true; + field = value; + } + } + + internal bool HasBoth { get; private set; } #if DEBUG static ValueMLKemPrivateKeyAsn() diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs index 32d47ce870c877..5e99e95bd6bf4c 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/Pbkdf2SaltChoice.xml.cs @@ -38,10 +38,30 @@ internal static void Validate() { } [StructLayout(LayoutKind.Sequential)] internal ref partial struct ValuePbkdf2SaltChoice { - internal ReadOnlySpan Specified; - internal bool HasSpecified; - internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn OtherSource; - internal bool HasOtherSource; + + internal ReadOnlySpan Specified + { + get; + set + { + HasSpecified = true; + field = value; + } + } + + internal bool HasSpecified { get; private set; } + + internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn OtherSource + { + get; + set + { + HasOtherSource = true; + field = value; + } + } + + internal bool HasOtherSource { get; private set; } #if DEBUG static ValuePbkdf2SaltChoice() diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs index d71c82dfc23486..f990660d39d50a 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/PrivateKeyInfoAsn.xml.cs @@ -141,8 +141,18 @@ internal ref partial struct ValuePrivateKeyInfoAsn internal int Version; internal System.Security.Cryptography.Asn1.ValueAlgorithmIdentifierAsn PrivateKeyAlgorithm; internal ReadOnlySpan PrivateKey; - internal ReadOnlySpan Attributes; - internal bool HasAttributes; + + internal ReadOnlySpan Attributes + { + get; + set + { + HasAttributes = true; + field = value; + } + } + + internal bool HasAttributes { get; private set; } internal readonly void Encode(AsnWriter writer) { diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs index b5b723200baa13..29ae27b3fdc236 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/SpecifiedECDomain.xml.cs @@ -16,8 +16,18 @@ internal ref partial struct ValueSpecifiedECDomain internal System.Security.Cryptography.Asn1.ValueCurveAsn Curve; internal ReadOnlySpan Base; internal ReadOnlySpan Order; - internal ReadOnlySpan Cofactor; - internal bool HasCofactor; + + internal ReadOnlySpan Cofactor + { + get; + set + { + HasCofactor = true; + field = value; + } + } + + internal bool HasCofactor { get; private set; } internal string? Hash; internal readonly void Encode(AsnWriter writer) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt index db2900de79c0c0..72d14b2981bd56 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt +++ b/src/libraries/Common/src/System/Security/Cryptography/Asn1/asn.xslt @@ -1123,37 +1123,59 @@ namespace - - internal ReadOnlySpan<byte> ; - internal bool Has; + + ReadOnlySpan<byte> + - - internal ReadOnlySpan<byte> ; - internal bool Has; + + ReadOnlySpan<byte> + - - internal ReadOnlySpan<byte> ; - internal bool Has; + + ReadOnlySpan<byte> + - - internal ReadOnlySpan<byte> ; - internal bool Has; + + ReadOnlySpan<byte> + - - internal ReadOnlySpan<byte> ; - internal bool Has; + + ReadOnlySpan<byte> + - - internal ; - internal bool Has; + + + internal ? ; - - internal ReadOnlySpan<byte> ; - internal bool Has; + + ReadOnlySpan<byte> + + + + + + + + + internal + { + get; + set + { + Has = true; + field = value; + } + } + + internal bool Has { get; private set; } + + internal ; + + diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs b/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs index 67836d5eb27170..3513139f6474cf 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLDsaPkcs8.cs @@ -18,7 +18,6 @@ internal static bool TryExportPkcs8PrivateKey( ValueAlgorithmIdentifierAsn algorithmIdentifier = new() { Algorithm = dsa.Algorithm.Oid, - HasParameters = false, }; ValueMLDsaPrivateKeyAsn privateKeyAsn = default; diff --git a/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs b/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs index a80664b6d25e4f..4e61221c89afb8 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/MLKemPkcs8.cs @@ -18,7 +18,6 @@ internal static bool TryExportPkcs8PrivateKey( ValueAlgorithmIdentifierAsn algorithmIdentifier = new() { Algorithm = kem.Algorithm.Oid, - HasParameters = false, }; ValueMLKemPrivateKeyAsn privateKeyAsn = default; @@ -35,7 +34,6 @@ internal static bool TryExportPkcs8PrivateKey( kem.ExportPrivateSeed(buffer); written = buffer.Length; privateKeyAsn.Seed = buffer; - privateKeyAsn.HasSeed = true; } else if (hasDecapsulationKey) { @@ -45,7 +43,6 @@ internal static bool TryExportPkcs8PrivateKey( kem.ExportDecapsulationKey(buffer); written = buffer.Length; privateKeyAsn.ExpandedKey = buffer; - privateKeyAsn.HasExpandedKey = true; } else { diff --git a/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs b/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs index 643737228ed0b3..6c0a8da998dc42 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/RSAAndroid.cs @@ -424,7 +424,6 @@ public override void ImportRSAPublicKey(ReadOnlySpan source, out int bytes { Algorithm = Oids.Rsa, Parameters = AlgorithmIdentifierAsn.ExplicitDerNull.Span, - HasParameters = true, }, SubjectPublicKey = subjectPublicKey, }; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs index ffe68209c770c0..425834743c014c 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs @@ -273,7 +273,6 @@ public static void ImportPkcs8PrivateKey_AlgorithmErrorsInAsn() ValueMLDsaPrivateKeyAsn seed = new ValueMLDsaPrivateKeyAsn { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], - HasSeed = true, }; seed.Encode(writer); @@ -306,7 +305,6 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn { Both = new ValueMLDsaPrivateKeyBothAsn(), - HasBoth = true, }); AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn @@ -315,7 +313,6 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() { Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], }, - HasBoth = true, }); AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn @@ -324,7 +321,6 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() { ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], }, - HasBoth = true, }); AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn @@ -334,7 +330,6 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes - 1], ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], }, - HasBoth = true, }); AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn @@ -344,7 +339,6 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes - 1], }, - HasBoth = true, }); AssertInvalidAsn(new ValueMLDsaPrivateKeyAsn @@ -355,7 +349,6 @@ public static void ImportPkcs8PrivateKey_KeyErrorsInAsn() Seed = new byte[MLDsaAlgorithm.MLDsa44.PrivateSeedSizeInBytes], ExpandedKey = new byte[MLDsaAlgorithm.MLDsa44.PrivateKeySizeInBytes], }, - HasBoth = true, }); static void AssertInvalidAsn(ValueMLDsaPrivateKeyAsn privateKeyAsn) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs index 2204a7795bfb38..07e274abc4e00e 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs @@ -141,7 +141,6 @@ internal static void AssertImportPrivateKey(Action> testDirectCall, ValueMLDsaPrivateKeyAsn privateKeyAsn = new ValueMLDsaPrivateKeyAsn { ExpandedKey = privateKey, - HasExpandedKey = true, }; privateKeyAsn.Encode(writer); @@ -182,7 +181,6 @@ internal static void AssertImportPrivateSeed(Action> testDirectCall, ValueMLDsaPrivateKeyAsn privateKey = new ValueMLDsaPrivateKeyAsn { Seed = privateSeed, - HasSeed = true, }; privateKey.Encode(writer); diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs index 296b9064937ec7..b8479444370505 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/Asn1/Rfc3161TstInfo.xml.cs @@ -244,12 +244,42 @@ internal ref partial struct ValueRfc3161TstInfo internal DateTimeOffset GenTime; internal System.Security.Cryptography.Pkcs.Asn1.Rfc3161Accuracy? Accuracy; internal bool Ordering; - internal ReadOnlySpan Nonce; - internal bool HasNonce; - internal ReadOnlySpan Tsa; - internal bool HasTsa; - internal ReadOnlySpan Extensions; - internal bool HasExtensions; + + internal ReadOnlySpan Nonce + { + get; + set + { + HasNonce = true; + field = value; + } + } + + internal bool HasNonce { get; private set; } + + internal ReadOnlySpan Tsa + { + get; + set + { + HasTsa = true; + field = value; + } + } + + internal bool HasTsa { get; private set; } + + internal ReadOnlySpan Extensions + { + get; + set + { + HasExtensions = true; + field = value; + } + } + + internal bool HasExtensions { get; private set; } internal readonly void Encode(AsnWriter writer) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs index ecb0248c11ce54..d34d4d248915e1 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPssX509SignatureGenerator.cs @@ -86,7 +86,6 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg } parameters.MaskGenAlgorithm.Parameters = writer.Encode(); - parameters.MaskGenAlgorithm.HasParameters = true; writer.Reset(); parameters.Encode(writer); @@ -95,7 +94,6 @@ public override byte[] GetSignatureAlgorithmIdentifier(HashAlgorithmName hashAlg { Algorithm = Oids.RsaPss, Parameters = writer.Encode(), - HasParameters = true, }; writer.Reset(); From 9c259184bd1635ab2d00b0e20413f22fc0d1a986 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 13 Mar 2026 19:09:54 -0400 Subject: [PATCH 34/34] Apply suggestion from @vcsjones --- .../Common/src/System/Security/Cryptography/KeyFormatHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs index 7f99cdcc676a2b..66dc46b83c9ef1 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/KeyFormatHelper.cs @@ -30,7 +30,7 @@ internal static void ReadSubjectPublicKeyInfo( ValueSubjectPublicKeyInfoAsn.Decode(ref reader, out spki); } catch (AsnContentException e) - { + { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); }