Skip to content

Commit

Permalink
Reduce allocations parsing X.509 certificates on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
vcsjones authored Jun 22, 2022
1 parent 7e46936 commit b1839d3
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<byte> encodedSubjectName = _certContext.CertContext->pCertInfo->Subject.DangerousAsSpan();
X500DistinguishedName subjectName = new X500DistinguishedName(encodedSubjectName);
GC.KeepAlive(this);
return subjectName;
Expand All @@ -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<byte> encodedIssuerName = _certContext.CertContext->pCertInfo->Issuer.DangerousAsSpan();
X500DistinguishedName issuerName = new X500DistinguishedName(encodedIssuerName);
GC.KeepAlive(this);
return issuerName;
Expand All @@ -365,16 +367,20 @@ public IEnumerable<X509Extension> 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<byte> rawData = pCertExtension->Value.DangerousAsSpan();
extensions[i] = new X509Extension(oid, rawData, critical);
}

GC.KeepAlive(this);
return extensions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -317,8 +317,8 @@ private static ISet<string> 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
Expand Down

0 comments on commit b1839d3

Please sign in to comment.