-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
basic certificate handling for quic #50613
Conversation
Tagging subscribers to this area: @dotnet/ncl Issue DetailsWith microsoft/msquic#1411 support for STUB Tls was removed and we only have real option left. This change adds server support for normal X509Certificate and plus usual verification callback so the fate of the handshake can be decided from .NET. Right now, this is supported only ion Windows, Linux & macOS coming (hopefully) soon. This is also missing support for custom certificate chains, SslStreamCertificateContext, and client certificates. cc: @nibanks
|
Basic certificates should now work on Linux & macOS well.
I will investigate in separate effort. |
...es/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
Outdated
Show resolved
Hide resolved
} | ||
else | ||
{ | ||
flags |= QUIC_CREDENTIAL_FLAGS.INDICATE_CERTIFICATE_RECEIVED | QUIC_CREDENTIAL_FLAGS.NO_CERTIFICATE_VALIDATION; |
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.
You never want to let the TLS stack do the certificate validation?
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.
That how SslStream works now. Long term, we may check if custom callback is present or now. But that is still problematic (at least on Linux) as X509Chain would consider user stores while OS does not have any clue about them. So we would end up in situation when SslStream works and Quick does not or vice versa.
|
||
try | ||
{ | ||
if (certificate == null) |
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.
I don't expect this to ever happen. We shouldn't be calling you with "Peer Certificate Received" if we didn't have a certificate. Personally, I'd say you could just assert here or something.
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.
The null makes perfect sense for server side where client's certificate is optional. I just need to complete that part but the validation callback will be shared.
This is supposed to match our maybe header, which uses uint32_t.
@danmoseley commented on this pull request.
________________________________
In src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fruntime%2Fpull%2F50613%23discussion_r606071720&data=04%7C01%7Cnibanks%40microsoft.com%7Cd5cbe3864a3543a2cd6108d8f593ce93%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637529362500387665%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=SDie88n2VuWx%2FT8DBVDVmRCmxJ46jcvTdMv6FUomGR4%3D&reserved=0>:
@@ -272,6 +275,17 @@ internal struct CredentialConfigCertificateCertificateFileProtected
internal string PrivateKeyPassword;
}
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct CredentialConfigCertificatePkcs12
+ {
+ internal IntPtr Asn1Blob;
+
+ internal int Asn1BlobLength;
We mainly use uint when necessary to match native headers.
|
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicEnums.cs
Outdated
Show resolved
Hide resolved
...es/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
Outdated
Show resolved
Hide resolved
...es/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
Outdated
Show resolved
Hide resolved
...es/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
Outdated
Show resolved
Hide resolved
...es/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
Outdated
Show resolved
Hide resolved
...Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs
Outdated
Show resolved
Hide resolved
byte[] asn1 = certificate.Export(X509ContentType.Pkcs12); | ||
unsafe | ||
{ | ||
fixed (void* ptr = asn1) |
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.
I think this is the only occurrence of fixed
in here. I'm not an interop expert, but should we rather use GCHandle
as we do in other places? Is there any difference in those two? If not should we rather stick to the same approach throughout?
cc: @scalablecory
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.
You need to allocate GCHandle to preserve object for longer time. This basically says "don't move asn1 while I'm in this block" and it is much simpler. (and does not work for the other cases.
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
Show resolved
Hide resolved
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
Outdated
Show resolved
Hide resolved
|
||
if (!OperatingSystem.IsWindows()) | ||
{ | ||
// TODO fix validation with OpenSSL |
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.
What is remaining to do here? Is there an issue?
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.
The issue is that we don't have good way how to get certificate chain right now with OpenSSL.
There is not specific issue AFAIK. I mentally do this as contributions to #49574.
I will follow-up if/when microsoft/msquic#1450 (+implementation) is ready.
src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
Outdated
Show resolved
Hide resolved
all the concerns should be addressed. Following outstanding issues will be follow-up changes:
|
With this, self-signed (and other certificates) will work on Windows @JamesNK. Linux/macOS is getting closer. |
With microsoft/msquic#1411 support for STUB Tls was removed and we only have real option left.
This change adds server support for normal X509Certificate and plus usual verification callback so the fate of the handshake can be decided from .NET.
Right now, this is supported only ion Windows, Linux & macOS coming (hopefully) soon.
This is also missing support for custom certificate chains, SslStreamCertificateContext, and client certificates.
cc: @nibanks