Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 023ecc9

Browse files
author
Lakshmi Priya Sekar
committed
Fixing OID EKU validation.
1 parent 46a7dcc commit 023ecc9

23 files changed

+915
-186
lines changed

src/Common/src/System/Net/Http/WinHttpException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public static int ConvertErrorCodeToHR(int error)
2323
// of HttpClient under the same error conditions. Clients would access
2424
// HttpRequestException.InnerException.HRESULT to discover what caused
2525
// the exception.
26-
switch ((uint)error)
26+
switch (unchecked((uint)error))
2727
{
2828
case Interop.WinHttp.ERROR_WINHTTP_CONNECTION_ERROR:
2929
return unchecked((int)Interop.WinHttp.WININET_E_CONNECTION_RESET);

src/Common/tests/System/Net/Capability.Security.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public static bool IsNegotiateServerAvailable()
3232
return !(Configuration.Security.NegotiateServer == null);
3333
}
3434

35+
public static bool AreHostsFileNamesInstalled()
36+
{
37+
return !(Configuration.Security.HostsFileNamesInstalled == null);
38+
}
39+
3540
private static bool InitializeTrustedRootCertificateCapability()
3641
{
3742
using (var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))

src/Common/tests/System/Net/Configuration.Certificates.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,21 @@ public static partial class Certificates
2525

2626
public static X509Certificate2 GetClientCertificate() => GetCertWithPrivateKey(GetClientCertificateCollection());
2727

28-
public static X509Certificate2Collection GetServerCertificateCollection() => GetCertificateCollection("contoso.com.pfx");
28+
public static X509Certificate2 GetNoEKUCertificate() => GetCertWithPrivateKey(GetNoEKUCertificateCollection());
2929

30-
public static X509Certificate2Collection GetClientCertificateCollection() => GetCertificateCollection("testclient1_at_contoso.com.pfx");
30+
public static X509Certificate2 GetSelfSignedServerCertificate() => GetCertWithPrivateKey(GetSelfSignedServerCertificateCollection());
31+
32+
public static X509Certificate2 GetSelfSignedClientCertificate() => GetCertWithPrivateKey(GetSelfSignedClientCertificateCollection());
33+
34+
public static X509Certificate2Collection GetServerCertificateCollection() => GetCertificateCollection("testservereku.contoso.com.pfx");
35+
36+
public static X509Certificate2Collection GetClientCertificateCollection() => GetCertificateCollection("testclienteku.contoso.com.pfx");
37+
38+
public static X509Certificate2Collection GetNoEKUCertificateCollection() => GetCertificateCollection("testnoeku.contoso.com.pfx");
39+
40+
public static X509Certificate2Collection GetSelfSignedServerCertificateCollection() => GetCertificateCollection("testselfsignedservereku.contoso.com.pfx");
41+
42+
public static X509Certificate2Collection GetSelfSignedClientCertificateCollection() => GetCertificateCollection("testselfsignedclienteku.contoso.com.pfx");
3143

3244
private static X509Certificate2Collection GetCertificateCollection(string certificateFileName)
3345
{

src/Common/tests/System/Net/Configuration.Security.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ public static partial class Security
1919
public static Uri TlsServer => GetUriValue("COREFX_NET_SECURITY_TLSSERVERURI", new Uri("https://" + DefaultAzureServer));
2020

2121
public static Uri NegotiateServer => GetUriValue("COREFX_NET_SECURITY_NEGOSERVERURI");
22+
23+
// This should be set if hostnames for all certificates within corefx-testdata have been set to point to 127.0.0.1.
24+
// Example:
25+
// 127.0.0.1 testservereku.contoso.com
26+
// 127.0.0.1 testnoeku.contoso.com
27+
// 127.0.0.1 testclienteku.contoso.com
28+
29+
public static string HostsFileNamesInstalled => GetValue("COREFX_NET_SECURITY_HOSTS_FILE_INSTALLED");
2230
}
2331
}
2432
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Net.Security;
6+
using System.Net.Security.Tests;
7+
using System.Net.Sockets;
8+
using System.Security.Authentication;
9+
using System.Security.Cryptography.X509Certificates;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
13+
namespace System.Net.Test.Common
14+
{
15+
public class HttpsTestClient
16+
{
17+
public class Options
18+
{
19+
public Options(EndPoint remoteEndPoint)
20+
{
21+
RemoteEndpoint = remoteEndPoint;
22+
}
23+
24+
public const string DefaultRequestStringTemplate =
25+
@"GET / HTTP/1.0
26+
Host: {0}
27+
User-Agent: Testing application
28+
29+
";
30+
31+
public string ServerName { get; set; }
32+
33+
public EndPoint RemoteEndpoint { get; }
34+
35+
public X509Certificate2 ClientCertificate { get; set; } =
36+
Configuration.Certificates.GetClientCertificate();
37+
38+
public SslProtocols AllowedProtocols { get; set; } = SslProtocols.None;
39+
40+
public SslPolicyErrors IgnoreSslPolicyErrors { get; set; } = SslPolicyErrors.None;
41+
}
42+
43+
private Options _options;
44+
private int _requestCount = 0;
45+
private VerboseTestLogging _log = VerboseTestLogging.GetInstance();
46+
47+
public SslStream Stream { get; private set; }
48+
49+
public HttpsTestClient(Options options)
50+
{
51+
_options = options ?? throw new ArgumentNullException(nameof(options));
52+
}
53+
54+
public async Task HttpsRequestAsync(Func<string, Task<string>> httpConversation = null)
55+
{
56+
_log.WriteLine("[Client] Disabling SslPolicyErrors: {0}", _options.IgnoreSslPolicyErrors.ToString());
57+
58+
if (httpConversation == null)
59+
{
60+
httpConversation = DefaultHttpConversation;
61+
}
62+
63+
using (var certValidationPolicy = new SslStreamCertificatePolicy(_options.IgnoreSslPolicyErrors))
64+
using (var tcp = new TcpClient())
65+
{
66+
await ConnectToHostAsync(tcp);
67+
68+
using (Stream = new SslStream(tcp.GetStream(), false, certValidationPolicy.SslStreamCallback))
69+
{
70+
X509CertificateCollection clientCerts = null;
71+
72+
if (_options.ClientCertificate != null)
73+
{
74+
clientCerts = new X509CertificateCollection();
75+
clientCerts.Add(_options.ClientCertificate);
76+
}
77+
78+
_log.WriteLine(
79+
"[Client] Connected. Authenticating: server={0}; clientCert={1}",
80+
_options.ServerName,
81+
_options.ClientCertificate != null ? _options.ClientCertificate.Subject : "<null>");
82+
83+
try
84+
{
85+
await Stream.AuthenticateAsClientAsync(
86+
_options.ServerName,
87+
clientCerts,
88+
_options.AllowedProtocols,
89+
checkCertificateRevocation: false).ConfigureAwait(false);
90+
}
91+
catch (Exception ex)
92+
{
93+
_log.WriteLine("[Client] Exception : {0}", ex);
94+
throw ex;
95+
}
96+
97+
_log.WriteLine("[Client] Authenticated protocol {0}", Stream.SslProtocol);
98+
99+
int bytesRead = 0;
100+
string responseString = null;
101+
102+
while (true)
103+
{
104+
string requestString = await httpConversation(responseString).ConfigureAwait(false);
105+
if (requestString == null)
106+
{
107+
return;
108+
}
109+
110+
if (requestString.Length > 0)
111+
{
112+
byte[] requestBuffer = Encoding.UTF8.GetBytes(requestString);
113+
114+
_log.WriteLine("[Client] Sending request ({0} Bytes)", requestBuffer.Length);
115+
await Stream.WriteAsync(requestBuffer, 0, requestBuffer.Length).ConfigureAwait(false);
116+
}
117+
118+
_log.WriteLine("[Client] Waiting for reply...");
119+
120+
byte[] responseBuffer = new byte[2048];
121+
bytesRead = await Stream.ReadAsync(responseBuffer, 0, responseBuffer.Length).ConfigureAwait(false);
122+
responseString = Encoding.UTF8.GetString(responseBuffer, 0, bytesRead);
123+
_log.WriteLine("[Client] {0} Bytes, Response: <{1}>", bytesRead, responseString);
124+
}
125+
}
126+
}
127+
}
128+
129+
private async Task ConnectToHostAsync(TcpClient tcp)
130+
{
131+
string hostName = null;
132+
133+
if (_options.RemoteEndpoint is DnsEndPoint)
134+
{
135+
var dns = (DnsEndPoint)_options.RemoteEndpoint;
136+
hostName = dns.Host;
137+
138+
_log.WriteLine("[Client] Connecting to {0}:{1}", hostName, dns.Port);
139+
await tcp.ConnectAsync(hostName, dns.Port).ConfigureAwait(false);
140+
}
141+
else
142+
{
143+
var ip = (IPEndPoint)_options.RemoteEndpoint;
144+
hostName = ip.Address.ToString();
145+
_log.WriteLine("[Client] Connecting to {0}:{1}", hostName, ip.Port);
146+
await tcp.ConnectAsync(hostName, ip.Port).ConfigureAwait(false);
147+
}
148+
149+
if (_options.ServerName == null)
150+
{
151+
_options.ServerName = hostName;
152+
}
153+
}
154+
155+
private Task<string> DefaultHttpConversation(string read)
156+
{
157+
if (_requestCount == 1 && read.Length == 0)
158+
{
159+
throw new InvalidOperationException("Https empty response.");
160+
}
161+
162+
string requestString = null;
163+
if (read == null)
164+
{
165+
requestString = string.Format(Options.DefaultRequestStringTemplate, _options.ServerName);
166+
}
167+
168+
_requestCount++;
169+
return Task.FromResult(requestString);
170+
}
171+
}
172+
}

0 commit comments

Comments
 (0)