-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Spanify some Windows X.509 PAL and improve formatting. #69448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Tagging subscribers to this area: @dotnet/area-system-security, @vcsjones Issue DetailsThis PR does:
|
...m.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Windows.cs
Outdated
Show resolved
Hide resolved
...m.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/FindPal.Windows.cs
Outdated
Show resolved
Hide resolved
| if ((uint)cb > MaxStackAllocSize) | ||
| { | ||
| throw Marshal.GetLastWin32Error().ToCryptographicException(); | ||
| decoded = new byte[cb]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible cb is negative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's extremely unlikely as the data we are dealing with here is typically a dozen to a few hundred bytes. If it overflows to negative then the array-new will give a runtime exception, but I don't anticipate it would ever happen unless someone was doing something extremely nonsensical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And in case it's ambiguous, Win32 calls it DWORD, so there's not "negative", just "really, really big"
| return false; | ||
| } | ||
|
|
||
| byte[] actual = new byte[cbData]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could probably do some improvement here.
- If cbData != keyIdentifier.Length return false without the second dip.
- If cbData <= some cap, stackalloc.
cbData'll be 20 99% of the time, so even a stackalloc-128 probably eliminates all allocations from this routine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And we could do even better if we did the stackalloc first.
const int MaxStackAlloc = 64;
if (keyIdentifier.Length <= MaxStackAlloc)
{
Span<byte> actualKeyId = stackalloc byte[keyIdentifier.Length];
if (!Interop.Crypt32.CertGetCertificateContextProperty(pCertContext, Interop.Crypt32.CertContextPropId.CERT_KEY_IDENTIFIER_PROP_ID, actualKeyId, ref cbData))
{
return false;
}
return actualKeyId.Slice(0, cbData).SequenceEquals(keyIdentifier);
}
else
{
// the current code, more or less.
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If cbData != keyIdentifier.Length return false without the second dip.
I'm a little nervous of that since some CAPI APIs I've seen, on the "give null and I'll give you a length" give you a size that is at least big enough to hold the result, while the second call with the real buffer gives the "real" length.
Agree we can put some things on the stack though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stackalloc byte[keyIdentifier.Length];
ಠ_ಠ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK,
Span<byte> actualKeyId = stackalloc byte[64];
if (keyIdentifier.Length <= actualKeyId.Length)
{
...
}😄
This PR does:
DecodeObjectNoThrowto operate off ofReadOnlySpan<byte>instead ofbyte[]. This lets us save a few allocations since the input is usually from aDATA_BLOB.DecodeObjectNoThrowto accept and returnTStateandTResult. This means the callback functions can be fully static and not capture state, thus making them easier to extract in to static-local functions.