Skip to content

Commit 0262a63

Browse files
authored
Improve use of PAL's RawData for X509Certificate
1 parent 649626b commit 0262a63

File tree

3 files changed

+22
-24
lines changed

3 files changed

+22
-24
lines changed

src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public void CloneTo(X509Certificate2Collection collection)
118118

119119
private static string GetCertificateHashString(ICertificatePal certPal)
120120
{
121-
return X509Certificate.GetCertHashString(HashAlgorithmName.SHA256, certPal);
121+
return X509Certificate.GetCertHashString(HashAlgorithmName.SHA256, certPal.RawData);
122122
}
123123

124124
private struct EnumCertificatesContext

src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class X509Certificate : IDisposable, IDeserializationCallback, ISerializa
2525
private volatile string? _lazyKeyAlgorithm;
2626
private volatile byte[]? _lazyKeyAlgorithmParameters;
2727
private volatile byte[]? _lazyPublicKey;
28+
private volatile byte[]? _lazyRawData;
2829
private DateTime _lazyNotBefore = DateTime.MinValue;
2930
private DateTime _lazyNotAfter = DateTime.MinValue;
3031

@@ -37,6 +38,7 @@ public virtual void Reset()
3738
_lazyKeyAlgorithm = null;
3839
_lazyKeyAlgorithmParameters = null;
3940
_lazyPublicKey = null;
41+
_lazyRawData = null;
4042
_lazyNotBefore = DateTime.MinValue;
4143
_lazyNotAfter = DateTime.MinValue;
4244

@@ -242,6 +244,15 @@ void IDeserializationCallback.OnDeserialization(object? sender)
242244
throw new PlatformNotSupportedException();
243245
}
244246

247+
private protected ReadOnlyMemory<byte> PalRawDataMemory
248+
{
249+
get
250+
{
251+
ThrowIfInvalid();
252+
return _lazyRawData ??= Pal.RawData;
253+
}
254+
}
255+
245256
public IntPtr Handle => Pal is null ? IntPtr.Zero : Pal.Handle;
246257

247258
public string Issuer
@@ -343,12 +354,7 @@ public virtual byte[] GetCertHash()
343354
public virtual byte[] GetCertHash(HashAlgorithmName hashAlgorithm)
344355
{
345356
ThrowIfInvalid();
346-
return GetCertHash(hashAlgorithm, Pal);
347-
}
348-
349-
private static byte[] GetCertHash(HashAlgorithmName hashAlgorithm, ICertificatePalCore certPal)
350-
{
351-
return CryptographicOperations.HashData(hashAlgorithm, certPal.RawData);
357+
return CryptographicOperations.HashData(hashAlgorithm, PalRawDataMemory.Span);
352358
}
353359

354360
public virtual bool TryGetCertHash(
@@ -358,7 +364,7 @@ public virtual bool TryGetCertHash(
358364
{
359365
ThrowIfInvalid();
360366

361-
return CryptographicOperations.TryHashData(hashAlgorithm, Pal.RawData, destination, out bytesWritten);
367+
return CryptographicOperations.TryHashData(hashAlgorithm, PalRawDataMemory.Span, destination, out bytesWritten);
362368
}
363369

364370
public virtual string GetCertHashString()
@@ -370,13 +376,15 @@ public virtual string GetCertHashString()
370376
public virtual string GetCertHashString(HashAlgorithmName hashAlgorithm)
371377
{
372378
ThrowIfInvalid();
373-
374-
return GetCertHashString(hashAlgorithm, Pal);
379+
return GetCertHashString(hashAlgorithm, PalRawDataMemory.Span);
375380
}
376381

377-
internal static string GetCertHashString(HashAlgorithmName hashAlgorithm, ICertificatePalCore certPal)
382+
internal static string GetCertHashString(HashAlgorithmName hashAlgorithm, ReadOnlySpan<byte> rawData)
378383
{
379-
return GetCertHash(hashAlgorithm, certPal).ToHexStringUpper();
384+
Span<byte> buffer = stackalloc byte[64]; // Largest supported hash size is 512 bits
385+
386+
int written = CryptographicOperations.HashData(hashAlgorithm, rawData, buffer);
387+
return Convert.ToHexString(buffer.Slice(0, written));
380388
}
381389

382390
// Only use for internal purposes when the returned byte[] will not be mutated
@@ -409,7 +417,7 @@ public virtual byte[] GetRawCertData()
409417
{
410418
ThrowIfInvalid();
411419

412-
return Pal.RawData.CloneByteArray();
420+
return PalRawDataMemory.ToArray();
413421
}
414422

415423
public override int GetHashCode()

src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ namespace System.Security.Cryptography.X509Certificates
1616
{
1717
public class X509Certificate2 : X509Certificate
1818
{
19-
private volatile byte[]? _lazyRawData;
2019
private volatile Oid? _lazySignatureAlgorithm;
2120
private volatile int _lazyVersion;
2221
private volatile X500DistinguishedName? _lazySubjectName;
@@ -30,7 +29,6 @@ public class X509Certificate2 : X509Certificate
3029

3130
public override void Reset()
3231
{
33-
_lazyRawData = null;
3432
_lazySignatureAlgorithm = null;
3533
_lazyVersion = 0;
3634
_lazySubjectName = null;
@@ -327,15 +325,7 @@ public PublicKey PublicKey
327325
/// Unlike <see cref="RawData" />, this does not create a fresh copy of the data
328326
/// every time.
329327
/// </remarks>
330-
public ReadOnlyMemory<byte> RawDataMemory
331-
{
332-
get
333-
{
334-
ThrowIfInvalid();
335-
336-
return _lazyRawData ??= Pal.RawData;
337-
}
338-
}
328+
public ReadOnlyMemory<byte> RawDataMemory => PalRawDataMemory;
339329

340330
public string SerialNumber => GetSerialNumberString();
341331

0 commit comments

Comments
 (0)