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
Use libcurl+openssl to support TLS client certs
Browse files Browse the repository at this point in the history
Make curlHandler support Client Certificates when the linked libcurl's
ssl backend is compatible with openssl. CurlHandler is also updated to
support ChannelBindingToken
  • Loading branch information
kapilash committed Nov 19, 2015
1 parent e63c2de commit d3be6bb
Show file tree
Hide file tree
Showing 26 changed files with 872 additions and 358 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ internal enum CURLcode
CURLE_UNSUPPORTED_PROTOCOL = 1,
CURLE_NOT_BUILT_IN = 4,
CURLE_COULDNT_RESOLVE_HOST = 6,
CURLE_ABORTED_BY_CALLBACK = 42,
CURLE_UNKNOWN_OPTION = 48,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal static partial class Http

public delegate ulong ReadWriteCallback(IntPtr buffer, ulong bufferSize, ulong nitems, IntPtr userPointer);

public delegate CURLcode SslCtxCallback(IntPtr curl, IntPtr sslCtx);
public delegate CURLcode SslCtxCallback(IntPtr curl, IntPtr sslCtx, IntPtr userPointer);

[DllImport(Libraries.HttpNative)]
public static extern void RegisterSeekCallback(
Expand All @@ -66,6 +66,7 @@ public static extern void RegisterReadWriteCallback(
public static extern CURLcode RegisterSslCtxCallback(
SafeCurlHandle curl,
SslCtxCallback callback,
IntPtr userPointer,
ref SafeCallbackHandle callbackHandle);

[DllImport(Libraries.HttpNative)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ internal static partial class Ssl
[DllImport(Libraries.CryptoNative)]
internal static extern IntPtr TlsV1_2Method();

[DllImport(Libraries.CryptoNative)]
internal static extern void SetProtocolOptions(SafeSslContextHandle ctx, SslProtocols protocols);

[DllImport(Libraries.CryptoNative)]
internal static extern SafeSslHandle SslCreate(SafeSslContextHandle ctx);

Expand Down Expand Up @@ -104,16 +101,19 @@ internal static extern bool GetSslConnectionInfo(
internal static extern SafeSharedX509StackHandle SslGetPeerCertChain(SafeSslHandle ssl);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslCtxUseCertificate(SafeSslContextHandle ctx, SafeX509Handle certPtr);
internal static extern void GetStreamSizes(out int header, out int trailer, out int maximumMessage);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslGetPeerFinished(SafeSslHandle ssl, IntPtr buf, int count);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslCtxUsePrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);
internal static extern int SslGetFinished(SafeSslHandle ssl, IntPtr buf, int count);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslCtxCheckPrivateKey(SafeSslContextHandle ctx);
internal static extern bool SslSessionReused(SafeSslHandle ssl);

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetQuietShutdown(SafeSslContextHandle ctx);
internal static extern bool SslAddExtraChainCert(SafeSslHandle ssl, SafeX509Handle x509);

[DllImport(Libraries.CryptoNative, EntryPoint = "SslGetClientCAList")]
private static extern SafeSharedX509NameStackHandle SslGetClientCAList_private(SafeSslHandle ssl);
Expand All @@ -132,27 +132,6 @@ internal static SafeSharedX509NameStackHandle SslGetClientCAList(SafeSslHandle s
return handle;
}

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetVerify(SafeSslContextHandle ctx, SslCtxSetVerifyCallback callback);

[DllImport(Libraries.CryptoNative)]
internal static extern void SetEncryptionPolicy(SafeSslContextHandle ctx, EncryptionPolicy policy);

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetClientCAList(SafeSslContextHandle ctx, SafeX509NameStackHandle x509NameStackPtr);

[DllImport(Libraries.CryptoNative)]
internal static extern void GetStreamSizes(out int header, out int trailer, out int maximumMessage);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslGetPeerFinished(SafeSslHandle ssl, IntPtr buf, int count);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslGetFinished(SafeSslHandle ssl, IntPtr buf, int count);

[DllImport(Libraries.CryptoNative)]
internal static extern bool SslSessionReused(SafeSslHandle ssl);

internal static class SslMethods
{
internal static readonly IntPtr TLSv1_method = TlsV1Method();
Expand Down Expand Up @@ -289,6 +268,11 @@ protected override bool ReleaseHandle()
private SafeSslHandle() : base(IntPtr.Zero, true)
{
}

internal SafeSslHandle(IntPtr validSslPointer, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
{
handle = validSslPointer;
}
}

internal sealed class SafeChannelBindingHandle : SafeHandle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ internal static partial class Interop
internal static partial class Ssl
{
internal delegate int AppVerifyCallback(IntPtr storeCtx, IntPtr arg);
internal delegate int ClientCertCallback(IntPtr ssl, out IntPtr x509, out IntPtr pkey);

[DllImport(Libraries.CryptoNative)]
internal static extern SafeSslContextHandle SslCtxCreate(IntPtr method);
Expand All @@ -19,6 +20,9 @@ internal static partial class Ssl

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetCertVerifyCallback(SafeSslContextHandle ctx, AppVerifyCallback cb, IntPtr arg);

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetClientCertCallback(SafeSslContextHandle ctx, ClientCertCallback callback);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Diagnostics;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Security.Authentication.ExtendedProtection;
using System.Security.Cryptography;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal static partial class Ssl
{
[DllImport(Libraries.CryptoNative)]
internal static extern void SetProtocolOptions(SafeSslContextHandle ctx, SslProtocols protocols);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslCtxUseCertificate(SafeSslContextHandle ctx, SafeX509Handle certPtr);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslCtxUsePrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);

[DllImport(Libraries.CryptoNative)]
internal static extern int SslCtxCheckPrivateKey(SafeSslContextHandle ctx);

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetQuietShutdown(SafeSslContextHandle ctx);

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetVerify(SafeSslContextHandle ctx, SslCtxSetVerifyCallback callback);

[DllImport(Libraries.CryptoNative)]
internal static extern void SetEncryptionPolicy(SafeSslContextHandle ctx, EncryptionPolicy policy);

[DllImport(Libraries.CryptoNative)]
internal static extern void SslCtxSetClientCAList(SafeSslContextHandle ctx, SafeX509NameStackHandle x509NameStackPtr);
}
}
34 changes: 1 addition & 33 deletions src/Common/src/Interop/Unix/libssl/Interop.OpenSsl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

internal static partial class Interop
{
internal static class OpenSsl
internal static partial class OpenSsl
{
private static Ssl.SslCtxSetVerifyCallback s_verifyClientCertificate = VerifyClientCertificate;

Expand Down Expand Up @@ -291,38 +291,6 @@ private static void QueryUniqueChannelBinding(SafeSslHandle context, SafeChannel
bindingHandle.SetCertHashLength(certHashLength);
}

private static HashAlgorithm GetHashForChannelBinding(X509Certificate2 cert)
{
Oid signatureAlgorithm = cert.SignatureAlgorithm;
switch (signatureAlgorithm.Value)
{
// RFC 5929 4.1 says that MD5 and SHA1 both upgrade to EvpSha256 for cbt calculation
case "1.2.840.113549.2.5": // MD5
case "1.2.840.113549.1.1.4": // MD5RSA
case "1.3.14.3.2.26": // SHA1
case "1.2.840.10040.4.3": // SHA1DSA
case "1.2.840.10045.4.1": // SHA1ECDSA
case "1.2.840.113549.1.1.5": // SHA1RSA
case "2.16.840.1.101.3.4.2.1": // SHA256
case "1.2.840.10045.4.3.2": // SHA256ECDSA
case "1.2.840.113549.1.1.11": // SHA256RSA
return SHA256.Create();

case "2.16.840.1.101.3.4.2.2": // SHA384
case "1.2.840.10045.4.3.3": // SHA384ECDSA
case "1.2.840.113549.1.1.12": // SHA384RSA
return SHA384.Create();

case "2.16.840.1.101.3.4.2.3": // SHA512
case "1.2.840.10045.4.3.4": // SHA512ECDSA
case "1.2.840.113549.1.1.13": // SHA512RSA
return SHA512.Create();

default:
throw new ArgumentException(signatureAlgorithm.Value);
}
}

private static IntPtr GetSslMethod(SslProtocols protocols)
{
Debug.Assert(protocols != SslProtocols.None, "All protocols are disabled");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;


internal static partial class Interop
{
internal static partial class OpenSsl
{
internal static HashAlgorithm GetHashForChannelBinding(X509Certificate2 cert)
{
Oid signatureAlgorithm = cert.SignatureAlgorithm;
switch (signatureAlgorithm.Value)
{
// RFC 5929 4.1 says that MD5 and SHA1 both upgrade to EvpSha256 for cbt calculation
case "1.2.840.113549.2.5": // MD5
case "1.2.840.113549.1.1.4": // MD5RSA
case "1.3.14.3.2.26": // SHA1
case "1.2.840.10040.4.3": // SHA1DSA
case "1.2.840.10045.4.1": // SHA1ECDSA
case "1.2.840.113549.1.1.5": // SHA1RSA
case "2.16.840.1.101.3.4.2.1": // SHA256
case "1.2.840.10045.4.3.2": // SHA256ECDSA
case "1.2.840.113549.1.1.11": // SHA256RSA
return SHA256.Create();

case "2.16.840.1.101.3.4.2.2": // SHA384
case "1.2.840.10045.4.3.3": // SHA384ECDSA
case "1.2.840.113549.1.1.12": // SHA384RSA
return SHA384.Create();

case "2.16.840.1.101.3.4.2.3": // SHA512
case "1.2.840.10045.4.3.4": // SHA512ECDSA
case "1.2.840.113549.1.1.13": // SHA512RSA
return SHA512.Create();

default:
throw new ArgumentException(signatureAlgorithm.Value);
}
}
}
}
1 change: 1 addition & 0 deletions src/Common/src/System/Net/Http/HttpHandlerDefaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ internal static class HttpHandlerDefaults
public const bool DefaultAutomaticRedirection = true;
public const bool DefaultUseCookies = true;
public const bool DefaultPreAuthenticate = false;
public const ClientCertificateOption DefaultClientCertificateOption = ClientCertificateOption.Manual;
}
}
Loading

0 comments on commit d3be6bb

Please sign in to comment.