diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs index bc6869bdd0a72..8c49a91f7aa85 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs @@ -329,7 +329,8 @@ public X500DistinguishedName SubjectName { unsafe { - byte[] encodedSubjectName = _certContext.CertContext->pCertInfo->Subject.ToByteArray(); + // X500DN creates a copy of the data for itself; data is kept alive with GC.KeepAlive. + ReadOnlySpan encodedSubjectName = _certContext.CertContext->pCertInfo->Subject.DangerousAsSpan(); X500DistinguishedName subjectName = new X500DistinguishedName(encodedSubjectName); GC.KeepAlive(this); return subjectName; @@ -343,7 +344,8 @@ public X500DistinguishedName IssuerName { unsafe { - byte[] encodedIssuerName = _certContext.CertContext->pCertInfo->Issuer.ToByteArray(); + // X500DN creates a copy of the data for itself; data is kept alive with GC.KeepAlive. + ReadOnlySpan encodedIssuerName = _certContext.CertContext->pCertInfo->Issuer.DangerousAsSpan(); X500DistinguishedName issuerName = new X500DistinguishedName(encodedIssuerName); GC.KeepAlive(this); return issuerName; @@ -365,16 +367,20 @@ public IEnumerable Extensions Interop.Crypt32.CERT_INFO* pCertInfo = _certContext.CertContext->pCertInfo; int numExtensions = pCertInfo->cExtension; X509Extension[] extensions = new X509Extension[numExtensions]; + for (int i = 0; i < numExtensions; i++) { Interop.Crypt32.CERT_EXTENSION* pCertExtension = (Interop.Crypt32.CERT_EXTENSION*)pCertInfo->rgExtension.ToPointer() + i; string oidValue = Marshal.PtrToStringAnsi(pCertExtension->pszObjId)!; Oid oid = new Oid(oidValue, friendlyName: null); bool critical = pCertExtension->fCritical != 0; - byte[] rawData = pCertExtension->Value.ToByteArray(); + // X509Extension creates a copy of the data for itself. The underlying data + // is kept alive with the KeepAlive below. + ReadOnlySpan rawData = pCertExtension->Value.DangerousAsSpan(); extensions[i] = new X509Extension(oid, rawData, critical); } + GC.KeepAlive(this); return extensions; } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePolicy.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePolicy.cs index 22430e72cb5ea..321348e91968f 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePolicy.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePolicy.cs @@ -289,7 +289,7 @@ private static int ReadInhibitAnyPolicyExtension(byte[] rawData) { try { - AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER); + AsnValueReader reader = new AsnValueReader(rawData, AsnEncodingRules.DER); int inhibitAnyPolicy; reader.TryReadInt32(out inhibitAnyPolicy); reader.ThrowIfNotEmpty(); @@ -317,8 +317,8 @@ private static ISet ReadExtendedKeyUsageExtension(byte[] rawData) try { - AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER); - AsnReader sequenceReader = reader.ReadSequence(); + AsnValueReader reader = new AsnValueReader(rawData, AsnEncodingRules.DER); + AsnValueReader sequenceReader = reader.ReadSequence(); reader.ThrowIfNotEmpty(); //OidCollection usages