Skip to content

Commit c9ccccf

Browse files
Use big endian buffers instead of BigInteger for RSA ASN types (#117851)
1 parent 8fac1c5 commit c9ccccf

File tree

12 files changed

+265
-281
lines changed

12 files changed

+265
-281
lines changed

src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<asn:Sequence
33
xmlns:asn="http://schemas.dot.net/asnxml/201808/"
44
name="RSAPrivateKeyAsn"
5-
namespace="System.Security.Cryptography.Asn1"
6-
rebind="false">
5+
namespace="System.Security.Cryptography.Asn1">
76

87
<!--
98
https://tools.ietf.org/html/rfc3447#appendix-C
@@ -29,12 +28,12 @@
2928
Since we don't support otherPrimeInfos (Version=1) just don't map it in.
3029
-->
3130
<asn:Integer name="Version" backingType="int" />
32-
<asn:Integer name="Modulus" />
33-
<asn:Integer name="PublicExponent" />
34-
<asn:Integer name="PrivateExponent" />
35-
<asn:Integer name="Prime1" />
36-
<asn:Integer name="Prime2" />
37-
<asn:Integer name="Exponent1" />
38-
<asn:Integer name="Exponent2" />
39-
<asn:Integer name="Coefficient" />
31+
<asn:Integer name="Modulus" backingType="ReadOnlyMemory" />
32+
<asn:Integer name="PublicExponent" backingType="ReadOnlyMemory" />
33+
<asn:Integer name="PrivateExponent" backingType="ReadOnlyMemory" />
34+
<asn:Integer name="Prime1" backingType="ReadOnlyMemory" />
35+
<asn:Integer name="Prime2" backingType="ReadOnlyMemory" />
36+
<asn:Integer name="Exponent1" backingType="ReadOnlyMemory" />
37+
<asn:Integer name="Exponent2" backingType="ReadOnlyMemory" />
38+
<asn:Integer name="Coefficient" backingType="ReadOnlyMemory" />
4039
</asn:Sequence>

src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPrivateKeyAsn.xml.cs

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ namespace System.Security.Cryptography.Asn1
1212
internal partial struct RSAPrivateKeyAsn
1313
{
1414
internal int Version;
15-
internal System.Numerics.BigInteger Modulus;
16-
internal System.Numerics.BigInteger PublicExponent;
17-
internal System.Numerics.BigInteger PrivateExponent;
18-
internal System.Numerics.BigInteger Prime1;
19-
internal System.Numerics.BigInteger Prime2;
20-
internal System.Numerics.BigInteger Exponent1;
21-
internal System.Numerics.BigInteger Exponent2;
22-
internal System.Numerics.BigInteger Coefficient;
15+
internal ReadOnlyMemory<byte> Modulus;
16+
internal ReadOnlyMemory<byte> PublicExponent;
17+
internal ReadOnlyMemory<byte> PrivateExponent;
18+
internal ReadOnlyMemory<byte> Prime1;
19+
internal ReadOnlyMemory<byte> Prime2;
20+
internal ReadOnlyMemory<byte> Exponent1;
21+
internal ReadOnlyMemory<byte> Exponent2;
22+
internal ReadOnlyMemory<byte> Coefficient;
2323

2424
internal readonly void Encode(AsnWriter writer)
2525
{
@@ -31,14 +31,14 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag)
3131
writer.PushSequence(tag);
3232

3333
writer.WriteInteger(Version);
34-
writer.WriteInteger(Modulus);
35-
writer.WriteInteger(PublicExponent);
36-
writer.WriteInteger(PrivateExponent);
37-
writer.WriteInteger(Prime1);
38-
writer.WriteInteger(Prime2);
39-
writer.WriteInteger(Exponent1);
40-
writer.WriteInteger(Exponent2);
41-
writer.WriteInteger(Coefficient);
34+
writer.WriteInteger(Modulus.Span);
35+
writer.WriteInteger(PublicExponent.Span);
36+
writer.WriteInteger(PrivateExponent.Span);
37+
writer.WriteInteger(Prime1.Span);
38+
writer.WriteInteger(Prime2.Span);
39+
writer.WriteInteger(Exponent1.Span);
40+
writer.WriteInteger(Exponent2.Span);
41+
writer.WriteInteger(Coefficient.Span);
4242
writer.PopSequence(tag);
4343
}
4444

@@ -53,7 +53,7 @@ internal static RSAPrivateKeyAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte
5353
{
5454
AsnValueReader reader = new AsnValueReader(encoded.Span, ruleSet);
5555

56-
DecodeCore(ref reader, expectedTag, out RSAPrivateKeyAsn decoded);
56+
DecodeCore(ref reader, expectedTag, encoded, out RSAPrivateKeyAsn decoded);
5757
reader.ThrowIfNotEmpty();
5858
return decoded;
5959
}
@@ -63,42 +63,53 @@ internal static RSAPrivateKeyAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte
6363
}
6464
}
6565

66-
internal static void Decode(ref AsnValueReader reader, out RSAPrivateKeyAsn decoded)
66+
internal static void Decode(ref AsnValueReader reader, ReadOnlyMemory<byte> rebind, out RSAPrivateKeyAsn decoded)
6767
{
68-
Decode(ref reader, Asn1Tag.Sequence, out decoded);
68+
Decode(ref reader, Asn1Tag.Sequence, rebind, out decoded);
6969
}
7070

71-
internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPrivateKeyAsn decoded)
71+
internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out RSAPrivateKeyAsn decoded)
7272
{
7373
try
7474
{
75-
DecodeCore(ref reader, expectedTag, out decoded);
75+
DecodeCore(ref reader, expectedTag, rebind, out decoded);
7676
}
7777
catch (AsnContentException e)
7878
{
7979
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
8080
}
8181
}
8282

83-
private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPrivateKeyAsn decoded)
83+
private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out RSAPrivateKeyAsn decoded)
8484
{
8585
decoded = default;
8686
AsnValueReader sequenceReader = reader.ReadSequence(expectedTag);
87+
ReadOnlySpan<byte> rebindSpan = rebind.Span;
88+
int offset;
89+
ReadOnlySpan<byte> tmpSpan;
8790

8891

8992
if (!sequenceReader.TryReadInt32(out decoded.Version))
9093
{
9194
sequenceReader.ThrowIfNotEmpty();
9295
}
9396

94-
decoded.Modulus = sequenceReader.ReadInteger();
95-
decoded.PublicExponent = sequenceReader.ReadInteger();
96-
decoded.PrivateExponent = sequenceReader.ReadInteger();
97-
decoded.Prime1 = sequenceReader.ReadInteger();
98-
decoded.Prime2 = sequenceReader.ReadInteger();
99-
decoded.Exponent1 = sequenceReader.ReadInteger();
100-
decoded.Exponent2 = sequenceReader.ReadInteger();
101-
decoded.Coefficient = sequenceReader.ReadInteger();
97+
tmpSpan = sequenceReader.ReadIntegerBytes();
98+
decoded.Modulus = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
99+
tmpSpan = sequenceReader.ReadIntegerBytes();
100+
decoded.PublicExponent = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
101+
tmpSpan = sequenceReader.ReadIntegerBytes();
102+
decoded.PrivateExponent = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
103+
tmpSpan = sequenceReader.ReadIntegerBytes();
104+
decoded.Prime1 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
105+
tmpSpan = sequenceReader.ReadIntegerBytes();
106+
decoded.Prime2 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
107+
tmpSpan = sequenceReader.ReadIntegerBytes();
108+
decoded.Exponent1 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
109+
tmpSpan = sequenceReader.ReadIntegerBytes();
110+
decoded.Exponent2 = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
111+
tmpSpan = sequenceReader.ReadIntegerBytes();
112+
decoded.Coefficient = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
102113

103114
sequenceReader.ThrowIfNotEmpty();
104115
}

src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
<asn:Sequence
33
xmlns:asn="http://schemas.dot.net/asnxml/201808/"
44
name="RSAPublicKeyAsn"
5-
namespace="System.Security.Cryptography.Asn1"
6-
rebind="false">
5+
namespace="System.Security.Cryptography.Asn1">
76

87
<!--
98
https://tools.ietf.org/html/rfc3447#appendix-C
@@ -13,6 +12,6 @@
1312
publicExponent INTEGER - e
1413
}
1514
-->
16-
<asn:Integer name="Modulus" />
17-
<asn:Integer name="PublicExponent" />
15+
<asn:Integer name="Modulus" backingType="ReadOnlyMemory" />
16+
<asn:Integer name="PublicExponent" backingType="ReadOnlyMemory" />
1817
</asn:Sequence>

src/libraries/Common/src/System/Security/Cryptography/Asn1/RSAPublicKeyAsn.xml.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ namespace System.Security.Cryptography.Asn1
1111
[StructLayout(LayoutKind.Sequential)]
1212
internal partial struct RSAPublicKeyAsn
1313
{
14-
internal System.Numerics.BigInteger Modulus;
15-
internal System.Numerics.BigInteger PublicExponent;
14+
internal ReadOnlyMemory<byte> Modulus;
15+
internal ReadOnlyMemory<byte> PublicExponent;
1616

1717
internal readonly void Encode(AsnWriter writer)
1818
{
@@ -23,8 +23,8 @@ internal readonly void Encode(AsnWriter writer, Asn1Tag tag)
2323
{
2424
writer.PushSequence(tag);
2525

26-
writer.WriteInteger(Modulus);
27-
writer.WriteInteger(PublicExponent);
26+
writer.WriteInteger(Modulus.Span);
27+
writer.WriteInteger(PublicExponent.Span);
2828
writer.PopSequence(tag);
2929
}
3030

@@ -39,7 +39,7 @@ internal static RSAPublicKeyAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte>
3939
{
4040
AsnValueReader reader = new AsnValueReader(encoded.Span, ruleSet);
4141

42-
DecodeCore(ref reader, expectedTag, out RSAPublicKeyAsn decoded);
42+
DecodeCore(ref reader, expectedTag, encoded, out RSAPublicKeyAsn decoded);
4343
reader.ThrowIfNotEmpty();
4444
return decoded;
4545
}
@@ -49,30 +49,35 @@ internal static RSAPublicKeyAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte>
4949
}
5050
}
5151

52-
internal static void Decode(ref AsnValueReader reader, out RSAPublicKeyAsn decoded)
52+
internal static void Decode(ref AsnValueReader reader, ReadOnlyMemory<byte> rebind, out RSAPublicKeyAsn decoded)
5353
{
54-
Decode(ref reader, Asn1Tag.Sequence, out decoded);
54+
Decode(ref reader, Asn1Tag.Sequence, rebind, out decoded);
5555
}
5656

57-
internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPublicKeyAsn decoded)
57+
internal static void Decode(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out RSAPublicKeyAsn decoded)
5858
{
5959
try
6060
{
61-
DecodeCore(ref reader, expectedTag, out decoded);
61+
DecodeCore(ref reader, expectedTag, rebind, out decoded);
6262
}
6363
catch (AsnContentException e)
6464
{
6565
throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e);
6666
}
6767
}
6868

69-
private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, out RSAPublicKeyAsn decoded)
69+
private static void DecodeCore(ref AsnValueReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out RSAPublicKeyAsn decoded)
7070
{
7171
decoded = default;
7272
AsnValueReader sequenceReader = reader.ReadSequence(expectedTag);
73+
ReadOnlySpan<byte> rebindSpan = rebind.Span;
74+
int offset;
75+
ReadOnlySpan<byte> tmpSpan;
7376

74-
decoded.Modulus = sequenceReader.ReadInteger();
75-
decoded.PublicExponent = sequenceReader.ReadInteger();
77+
tmpSpan = sequenceReader.ReadIntegerBytes();
78+
decoded.Modulus = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
79+
tmpSpan = sequenceReader.ReadIntegerBytes();
80+
decoded.PublicExponent = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray();
7681

7782
sequenceReader.ThrowIfNotEmpty();
7883
}

0 commit comments

Comments
 (0)