Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Fixing OID EKU validation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lakshmi Priya Sekar authored and weshaggard committed Apr 20, 2017
1 parent 0cb3921 commit 5da214b
Show file tree
Hide file tree
Showing 26 changed files with 1,153 additions and 265 deletions.
2 changes: 1 addition & 1 deletion src/Common/src/System/Net/Http/WinHttpException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static int ConvertErrorCodeToHR(int error)
// of HttpClient under the same error conditions. Clients would access
// HttpRequestException.InnerException.HRESULT to discover what caused
// the exception.
switch ((uint)error)
switch (unchecked((uint)error))
{
case Interop.WinHttp.ERROR_WINHTTP_CONNECTION_ERROR:
return unchecked((int)Interop.WinHttp.WININET_E_CONNECTION_RESET);
Expand Down
5 changes: 5 additions & 0 deletions src/Common/tests/System/Net/Capability.Security.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public static bool IsTrustedRootCertificateInstalled()
return s_trustedCertificateSupport.Value;
}

public static bool AreHostsFileNamesInstalled()
{
return !(Configuration.Security.HostsFileNamesInstalled == null);
}

private static bool InitializeTrustedRootCertificateCapability()
{
using (var store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
Expand Down
70 changes: 70 additions & 0 deletions src/Common/tests/System/Net/Configuration.Certificates.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;

using Xunit;

namespace System.Net.Test.Common
{
public static partial class Configuration
{
public static partial class Certificates
{
private const string CertificatePassword = "testcertificate";
private const string TestDataFolder = "TestData";

public static X509Certificate2 GetServerCertificate() => GetCertWithPrivateKey(GetServerCertificateCollection());

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

public static X509Certificate2 GetNoEKUCertificate() => GetCertWithPrivateKey(GetNoEKUCertificateCollection());

public static X509Certificate2 GetSelfSignedServerCertificate() => GetCertWithPrivateKey(GetSelfSignedServerCertificateCollection());

public static X509Certificate2 GetSelfSignedClientCertificate() => GetCertWithPrivateKey(GetSelfSignedClientCertificateCollection());

public static X509Certificate2Collection GetServerCertificateCollection() => GetCertificateCollection("testservereku.contoso.com.pfx");

public static X509Certificate2Collection GetClientCertificateCollection() => GetCertificateCollection("testclienteku.contoso.com.pfx");

public static X509Certificate2Collection GetNoEKUCertificateCollection() => GetCertificateCollection("testnoeku.contoso.com.pfx");

public static X509Certificate2Collection GetSelfSignedServerCertificateCollection() => GetCertificateCollection("testselfsignedservereku.contoso.com.pfx");

public static X509Certificate2Collection GetSelfSignedClientCertificateCollection() => GetCertificateCollection("testselfsignedclienteku.contoso.com.pfx");

private static X509Certificate2Collection GetCertificateCollection(string certificateFileName)
{
var certCollection = new X509Certificate2Collection();
certCollection.Import(Path.Combine(TestDataFolder, certificateFileName), CertificatePassword, X509KeyStorageFlags.DefaultKeySet);
return certCollection;
}

private static X509Certificate2 GetCertWithPrivateKey(X509Certificate2Collection certCollection)
{
X509Certificate2 certificate = null;

foreach (X509Certificate2 c in certCollection)
{
if (certificate == null && c.HasPrivateKey)
{
certificate = c;
}
else
{
c.Dispose();
}
}

Assert.NotNull(certificate);
return certificate;
}
}
}
}
32 changes: 32 additions & 0 deletions src/Common/tests/System/Net/Configuration.Security.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace System.Net.Test.Common
{
public static partial class Configuration
{
public static partial class Security
{
private readonly static string DefaultAzureServer = "corefx-net.cloudapp.net";

public static string ActiveDirectoryName => GetValue("COREFX_NET_AD_DOMAINNAME");

public static string ActiveDirectoryUserName => GetValue("COREFX_NET_AD_USERNAME");

public static string ActiveDirectoryUserPassword => GetValue("COREFX_NET_AD_PASSWORD");

public static Uri TlsServer => GetUriValue("COREFX_NET_SECURITY_TLSSERVERURI", new Uri("https://" + DefaultAzureServer));

public static Uri NegotiateServer => GetUriValue("COREFX_NET_SECURITY_NEGOSERVERURI");

// This should be set if hostnames for all certificates within corefx-testdata have been set to point to 127.0.0.1.
// Example:
// 127.0.0.1 testservereku.contoso.com
// 127.0.0.1 testnoeku.contoso.com
// 127.0.0.1 testclienteku.contoso.com

public static string HostsFileNamesInstalled => GetValue("COREFX_NET_SECURITY_HOSTS_FILE_INSTALLED");
}
}
}
37 changes: 37 additions & 0 deletions src/Common/tests/System/Net/Configuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace System.Net.Test.Common
{
public static partial class Configuration
{
#pragma warning disable 414
private readonly static string DefaultAzureServer = "corefx-net.cloudapp.net";
#pragma warning restore 414

private static string GetValue(string envName, string defaultValue=null)
{
string envValue = Environment.GetEnvironmentVariable(envName);

if (string.IsNullOrWhiteSpace(envValue))
{
return defaultValue;
}

return Environment.ExpandEnvironmentVariables(envValue);
}

private static Uri GetUriValue(string envName, Uri defaultValue=null)
{
string envValue = GetValue(envName, null);

if (envValue == null)
{
return defaultValue;
}

return new Uri(envValue);
}
}
}
176 changes: 176 additions & 0 deletions src/Common/tests/System/Net/HttpsTestClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace System.Net.Test.Common
{
public class HttpsTestClient
{
public class Options
{
public Options(EndPoint remoteEndPoint)
{
RemoteEndpoint = remoteEndPoint;
}

public const string DefaultRequestStringTemplate =
@"GET / HTTP/1.0
Host: {0}
User-Agent: Testing application
";

public string ServerName { get; set; }

public EndPoint RemoteEndpoint { get; }

public X509Certificate2 ClientCertificate { get; set; } =
Configuration.Certificates.GetClientCertificate();

public SslProtocols AllowedProtocols { get; set; } = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;

public SslPolicyErrors IgnoreSslPolicyErrors { get; set; } = SslPolicyErrors.None;
}

private Options _options;
private int _requestCount = 0;
private VerboseTestLogging _log = VerboseTestLogging.GetInstance();

public SslStream Stream { get; private set; }

public HttpsTestClient(Options options)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}

_options = options;
}

public async Task HttpsRequestAsync(Func<string, Task<string>> httpConversation = null)
{
_log.WriteLine("[Client] Disabling SslPolicyErrors: {0}", _options.IgnoreSslPolicyErrors.ToString());

if (httpConversation == null)
{
httpConversation = DefaultHttpConversation;
}

using (var certValidationPolicy = new SslStreamCertificatePolicy(_options.IgnoreSslPolicyErrors))
using (var tcp = new TcpClient())
{
await ConnectToHostAsync(tcp);

using (Stream = new SslStream(tcp.GetStream(), false, certValidationPolicy.SslStreamCallback))
{
X509CertificateCollection clientCerts = null;

if (_options.ClientCertificate != null)
{
clientCerts = new X509CertificateCollection();
clientCerts.Add(_options.ClientCertificate);
}

_log.WriteLine(
"[Client] Connected. Authenticating: server={0}; clientCert={1}",
_options.ServerName,
_options.ClientCertificate != null ? _options.ClientCertificate.Subject : "<null>");

try
{
await Stream.AuthenticateAsClientAsync(
_options.ServerName,
clientCerts,
_options.AllowedProtocols,
checkCertificateRevocation: false).ConfigureAwait(false);
}
catch (Exception ex)
{
_log.WriteLine("[Client] Exception : {0}", ex);
throw ex;
}

_log.WriteLine("[Client] Authenticated protocol {0}", Stream.SslProtocol);

int bytesRead = 0;
string responseString = null;

while (true)
{
string requestString = await httpConversation(responseString).ConfigureAwait(false);
if (requestString == null)
{
return;
}

if (requestString.Length > 0)
{
byte[] requestBuffer = Encoding.UTF8.GetBytes(requestString);

_log.WriteLine("[Client] Sending request ({0} Bytes)", requestBuffer.Length);
await Stream.WriteAsync(requestBuffer, 0, requestBuffer.Length).ConfigureAwait(false);
}

_log.WriteLine("[Client] Waiting for reply...");

byte[] responseBuffer = new byte[2048];
bytesRead = await Stream.ReadAsync(responseBuffer, 0, responseBuffer.Length).ConfigureAwait(false);
responseString = Encoding.UTF8.GetString(responseBuffer, 0, bytesRead);
_log.WriteLine("[Client] {0} Bytes, Response: <{1}>", bytesRead, responseString);
}
}
}
}

private async Task ConnectToHostAsync(TcpClient tcp)
{
string hostName = null;

if (_options.RemoteEndpoint is DnsEndPoint)
{
var dns = (DnsEndPoint)_options.RemoteEndpoint;
hostName = dns.Host;

_log.WriteLine("[Client] Connecting to {0}:{1}", hostName, dns.Port);
await tcp.ConnectAsync(hostName, dns.Port).ConfigureAwait(false);
}
else
{
var ip = (IPEndPoint)_options.RemoteEndpoint;
hostName = ip.Address.ToString();
_log.WriteLine("[Client] Connecting to {0}:{1}", hostName, ip.Port);
await tcp.ConnectAsync(hostName, ip.Port).ConfigureAwait(false);
}

if (_options.ServerName == null)
{
_options.ServerName = hostName;
}
}

private Task<string> DefaultHttpConversation(string read)
{
if (_requestCount == 1 && read.Length == 0)
{
throw new InvalidOperationException("Https empty response.");
}

string requestString = null;
if (read == null)
{
requestString = string.Format(Options.DefaultRequestStringTemplate, _options.ServerName);
}

_requestCount++;
return Task.FromResult(requestString);
}
}
}
Loading

0 comments on commit 5da214b

Please sign in to comment.