Skip to content

Commit a4051a5

Browse files
authored
use new API on new windows to get TLS13 (#37888)
* use new API on new windows to get TLS13 * use unmanaged ref to avoid copy * feedback from review * feedback from review * feedback from review * kick the build
1 parent 059782e commit a4051a5

File tree

14 files changed

+292
-11
lines changed

14 files changed

+292
-11
lines changed

src/libraries/Common/src/Interop/Windows/SspiCli/ISSPIInterface.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ internal interface ISSPIInterface
1414
int EnumerateSecurityPackages(out int pkgnum, out SafeFreeContextBuffer pkgArray);
1515
int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref SafeSspiAuthDataHandle authdata, out SafeFreeCredentials outCredential);
1616
int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential);
17+
unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCH_CREDENTIALS* authdata, out SafeFreeCredentials outCredential);
1718
int AcquireDefaultCredential(string moduleName, Interop.SspiCli.CredentialUse usage, out SafeFreeCredentials outCredential);
1819
int AcceptSecurityContext(SafeFreeCredentials? credential, ref SafeDeleteSslContext? context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags);
1920
int InitializeSecurityContext(ref SafeFreeCredentials? credential, ref SafeDeleteSslContext? context, string? targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags);

src/libraries/Common/src/Interop/Windows/SspiCli/Interop.SSPI.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,92 @@ public enum Flags
214214
}
215215
}
216216

217+
[StructLayout(LayoutKind.Sequential)]
218+
internal unsafe struct SCH_CREDENTIALS
219+
{
220+
public const int CurrentVersion = 0x5;
221+
222+
public int dwVersion;
223+
public int dwCredformat;
224+
public int cCreds;
225+
226+
// This is pointer to arry of CERT_CONTEXT*
227+
// We do not use it directly in .NET. Instead, we wrap returned OS pointer in safe handle.
228+
public void* paCred;
229+
230+
public IntPtr hRootStore; // == always null, OTHERWISE NOT RELIABLE
231+
public int cMappers;
232+
public IntPtr aphMappers; // == always null, OTHERWISE NOT RELIABLE
233+
234+
public int dwSessionLifespan;
235+
public SCH_CREDENTIALS.Flags dwFlags;
236+
public int cTlsParameters;
237+
public TLS_PARAMETERS* pTlsParameters;
238+
239+
[Flags]
240+
public enum Flags
241+
{
242+
Zero = 0,
243+
SCH_CRED_NO_SYSTEM_MAPPER = 0x02,
244+
SCH_CRED_NO_SERVERNAME_CHECK = 0x04,
245+
SCH_CRED_MANUAL_CRED_VALIDATION = 0x08,
246+
SCH_CRED_NO_DEFAULT_CREDS = 0x10,
247+
SCH_CRED_AUTO_CRED_VALIDATION = 0x20,
248+
SCH_CRED_USE_DEFAULT_CREDS = 0x40,
249+
SCH_DISABLE_RECONNECTS = 0x80,
250+
SCH_CRED_REVOCATION_CHECK_END_CERT = 0x100,
251+
SCH_CRED_REVOCATION_CHECK_CHAIN = 0x200,
252+
SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x400,
253+
SCH_CRED_IGNORE_NO_REVOCATION_CHECK = 0x800,
254+
SCH_CRED_IGNORE_REVOCATION_OFFLINE = 0x1000,
255+
SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE = 0x2000,
256+
SCH_SEND_ROOT_CERT = 0x40000,
257+
SCH_SEND_AUX_RECORD = 0x00200000,
258+
SCH_USE_STRONG_CRYPTO = 0x00400000,
259+
SCH_USE_PRESHAREDKEY_ONLY = 0x800000,
260+
SCH_ALLOW_NULL_ENCRYPTION = 0x02000000,
261+
}
262+
}
263+
264+
[StructLayout(LayoutKind.Sequential)]
265+
internal unsafe struct TLS_PARAMETERS
266+
{
267+
public int cAlpnIds; // Valid for server applications only. Must be zero otherwise. Number of ALPN IDs in rgstrAlpnIds; set to 0 if applies to all.
268+
public IntPtr rgstrAlpnIds; // Valid for server applications only. Must be NULL otherwise. Array of ALPN IDs that the following settings apply to; set to NULL if applies to all.
269+
public uint grbitDisabledProtocols; // List protocols you DO NOT want negotiated.
270+
public int cDisabledCrypto; // Number of CRYPTO_SETTINGS structures; set to 0 if there are none.
271+
public CRYPTO_SETTINGS* pDisabledCrypto; // Array of CRYPTO_SETTINGS structures; set to NULL if there are none;
272+
public TLS_PARAMETERS.Flags dwFlags; // Optional flags to pass; set to 0 if there are none.
273+
274+
[Flags]
275+
public enum Flags
276+
{
277+
Zero = 0,
278+
TLS_PARAMS_OPTIONAL = 0x01, // Valid for server applications only. Must be zero otherwise.
279+
// TLS_PARAMETERS that will only be honored if they do not cause this server to terminate the handshake.
280+
}
281+
}
282+
283+
[StructLayout(LayoutKind.Sequential)]
284+
internal unsafe struct CRYPTO_SETTINGS
285+
{
286+
public TlsAlgorithmUsage eAlgorithmUsage; // How this algorithm is being used.
287+
public UNICODE_STRING* strCngAlgId; // CNG algorithm identifier.
288+
public int cChainingModes; // Set to 0 if CNG algorithm does not have a chaining mode.
289+
public UNICODE_STRING* rgstrChainingModes; // Set to NULL if CNG algorithm does not have a chaining mode.
290+
public int dwMinBitLength; // Blacklist key sizes less than this. Set to 0 if not defined or CNG algorithm implies bit length.
291+
public int dwMaxBitLength; // Blacklist key sizes greater than this. Set to 0 if not defined or CNG algorithm implies bit length.
292+
293+
public enum TlsAlgorithmUsage
294+
{
295+
TlsParametersCngAlgUsageKeyExchange, // Key exchange algorithm. RSA, ECHDE, DHE, etc.
296+
TlsParametersCngAlgUsageSignature, // Signature algorithm. RSA, DSA, ECDSA, etc.
297+
TlsParametersCngAlgUsageCipher, // Encryption algorithm. AES, DES, RC4, etc.
298+
TlsParametersCngAlgUsageDigest, // Digest of cipher suite. SHA1, SHA256, SHA384, etc.
299+
TlsParametersCngAlgUsageCertSig // Signature and/or hash used to sign certificate. RSA, DSA, ECDSA, SHA1, SHA256, etc.
300+
}
301+
}
302+
217303
[StructLayout(LayoutKind.Sequential)]
218304
internal unsafe struct SecBuffer
219305
{
@@ -344,6 +430,20 @@ internal static extern unsafe int AcquireCredentialsHandleW(
344430
[Out] out long timeStamp
345431
);
346432

433+
[DllImport(Interop.Libraries.SspiCli, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
434+
internal static extern unsafe int AcquireCredentialsHandleW(
435+
[In] string? principal,
436+
[In] string moduleName,
437+
[In] int usage,
438+
[In] void* logonID,
439+
[In] SCH_CREDENTIALS* authData,
440+
[In] void* keyCallback,
441+
[In] void* keyArgument,
442+
ref CredHandle handlePtr,
443+
[Out] out long timeStamp
444+
);
445+
446+
347447
[DllImport(Interop.Libraries.SspiCli, ExactSpelling = true, SetLastError = true)]
348448
internal static extern unsafe int InitializeSecurityContextW(
349449
ref CredHandle credentialHandle,

src/libraries/Common/src/Interop/Windows/SspiCli/SSPIAuthType.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.Credentia
4545
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
4646
}
4747

48+
public unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCH_CREDENTIALS* authdata, out SafeFreeCredentials outCredential)
49+
{
50+
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, authdata, out outCredential);
51+
}
52+
4853
public int AcceptSecurityContext(SafeFreeCredentials? credential, ref SafeDeleteSslContext? context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
4954
{
5055
return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags);

src/libraries/Common/src/Interop/Windows/SspiCli/SSPISecureChannelType.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.Credentia
4545
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
4646
}
4747

48+
public unsafe int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, Interop.SspiCli.SCH_CREDENTIALS* authdata, out SafeFreeCredentials outCredential)
49+
{
50+
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, authdata, out outCredential);
51+
}
52+
4853
public int AcceptSecurityContext(SafeFreeCredentials? credential, ref SafeDeleteSslContext? context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
4954
{
5055
return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags);

src/libraries/Common/src/Interop/Windows/SspiCli/SSPIWrapper.cs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,28 @@ public static SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secMod
110110

111111
public static SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, Interop.SspiCli.SCHANNEL_CRED scc)
112112
{
113-
if (NetEventSource.Log.IsEnabled()) NetEventSource.Log.AcquireCredentialsHandle(package, intent, scc);
114-
115-
SafeFreeCredentials? outCredential = null;
116113
int errorCode = secModule.AcquireCredentialsHandle(
117114
package,
118115
intent,
119116
ref scc,
120-
out outCredential);
117+
out SafeFreeCredentials outCredential);
118+
119+
if (errorCode != 0)
120+
{
121+
if (NetEventSource.IsEnabled) NetEventSource.Error(null, SR.Format(SR.net_log_operation_failed_with_error, nameof(AcquireCredentialsHandle), $"0x{errorCode:X}"));
122+
throw new Win32Exception(errorCode);
123+
}
124+
125+
return outCredential;
126+
}
127+
128+
public static unsafe SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secModule, string package, Interop.SspiCli.CredentialUse intent, Interop.SspiCli.SCH_CREDENTIALS* scc)
129+
{
130+
int errorCode = secModule.AcquireCredentialsHandle(
131+
package,
132+
intent,
133+
scc,
134+
out SafeFreeCredentials outCredential);
121135

122136
if (errorCode != 0)
123137
{

src/libraries/Common/src/Interop/Windows/SspiCli/SecuritySafeHandles.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,38 @@ public static unsafe int AcquireCredentialsHandle(
301301

302302
return errorCode;
303303
}
304+
305+
public static unsafe int AcquireCredentialsHandle(
306+
string package,
307+
Interop.SspiCli.CredentialUse intent,
308+
Interop.SspiCli.SCH_CREDENTIALS* authdata,
309+
out SafeFreeCredentials outCredential)
310+
{
311+
long timeStamp;
312+
313+
outCredential = new SafeFreeCredential_SECURITY();
314+
315+
int errorCode = Interop.SspiCli.AcquireCredentialsHandleW(
316+
null,
317+
package,
318+
(int)intent,
319+
null,
320+
authdata,
321+
null,
322+
null,
323+
ref outCredential._handle,
324+
out timeStamp);
325+
326+
if (NetEventSource.IsEnabled) NetEventSource.Verbose(null, $"{nameof(Interop.SspiCli.AcquireCredentialsHandleW)} returns 0x{errorCode:x}, handle = {outCredential}");
327+
328+
if (errorCode != 0)
329+
{
330+
outCredential.SetHandleAsInvalid();
331+
}
332+
333+
return errorCode;
334+
}
335+
304336
}
305337

306338
//

src/libraries/System.Net.Http/src/System.Net.Http.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@
429429
<Compile Include="System\Net\Http\SocketsHttpHandler\CurrentUserIdentityProvider.Windows.cs" />
430430
<Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs"
431431
Link="Common\Interop\Windows\Interop.Libraries.cs" />
432+
<Compile Include="$(CommonPath)Interop\Windows\Interop.UNICODE_STRING.cs"
433+
Link="Common\Interop\Windows\Interop.UNICODE_STRING.cs" />
432434
<Compile Include="$(CommonPath)\Interop\Windows\Crypt32\Interop.CertEnumCertificatesInStore.cs"
433435
Link="Common\Interop\Windows\Crypt32\Interop.CertEnumCertificatesInStore.cs" />
434436
<Compile Include="$(CommonPath)\Interop\Windows\Crypt32\Interop.certificates_types.cs"

src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@
115115
<Compile Include="System\Net\Windows\WebSockets\WebSocketProtocolComponent.cs" />
116116
<Compile Include="$(CommonPath)Interop\Windows\Interop.Libraries.cs"
117117
Link="Common\Interop\Windows\Interop.Libraries.cs" />
118+
<Compile Include="$(CommonPath)Interop\Windows\Interop.UNICODE_STRING.cs"
119+
Link="Common\Interop\Windows\Interop.UNICODE_STRING.cs" />
118120
<Compile Include="$(CommonPath)Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs"
119121
Link="Common\Interop\Windows\SChannel\Interop.SecPkgContext_ApplicationProtocol.cs" />
120122
<Compile Include="$(CommonPath)Interop\Windows\Interop.BOOL.cs"

src/libraries/System.Net.Mail/src/System.Net.Mail.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@
125125
Link="Common\System\Net\Security\NetEventSource.Security.cs" />
126126
<Compile Include="$(CommonPath)System\HexConverter.cs"
127127
Link="Common\System\HexConverter.cs" />
128+
<Compile Include="$(CommonPath)Interop\Windows\Interop.UNICODE_STRING.cs"
129+
Link="Common\Interop\Windows\Interop.UNICODE_STRING.cs" />
128130
</ItemGroup>
129131
<!-- Unix specific files -->
130132
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">

src/libraries/System.Net.Mail/tests/Unit/System.Net.Mail.Unit.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,5 +261,7 @@
261261
Link="Common\Interop\Windows\SspiCli\SecuritySafeHandles.cs" />
262262
<Compile Include="$(CommonPath)Interop\Windows\SspiCli\SSPIWrapper.cs"
263263
Link="Common\Interop\Windows\SspiCli\SSPIWrapper.cs" />
264+
<Compile Include="$(CommonPath)Interop\Windows\Interop.UNICODE_STRING.cs"
265+
Link="Common\Interop\Windows\Interop.UNICODE_STRING.cs" />
264266
</ItemGroup>
265267
</Project>

0 commit comments

Comments
 (0)