зеркало из https://github.com/mono/mono-tls.git
Add the native provider.
This commit is contained in:
Родитель
7cb2fbabaa
Коммит
982a8e40df
|
@ -49,11 +49,6 @@ namespace Mono.Security.NewTls.Console
|
|||
|
||||
public class Program : TestApp, ICryptoProvider, IRandomNumberGenerator
|
||||
{
|
||||
bool ICryptoProvider.IsEncryptionSupported (CryptoTestHostType type)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
public string SettingsFile {
|
||||
get;
|
||||
private set;
|
||||
|
@ -328,10 +323,14 @@ namespace Mono.Security.NewTls.Console
|
|||
return data;
|
||||
}
|
||||
|
||||
public bool IsSupported (CryptoTestHostType type)
|
||||
public bool IsSupported (CryptoTestHostType type, bool needsEncryption)
|
||||
{
|
||||
if (type == CryptoTestHostType.Mono)
|
||||
return true;
|
||||
if (needsEncryption)
|
||||
return false;
|
||||
if (type == CryptoTestHostType.OpenSsl)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -340,6 +339,8 @@ namespace Mono.Security.NewTls.Console
|
|||
switch (type) {
|
||||
case CryptoTestHostType.Mono:
|
||||
return new MonoCryptoProvider ();
|
||||
case CryptoTestHostType.OpenSsl:
|
||||
return new NativeCryptoProvider ();
|
||||
|
||||
default:
|
||||
throw new NotSupportedException ();
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
<Compile Include="IConnectionFactoryProvider.cs" />
|
||||
<Compile Include="ITestParameterProvider.cs" />
|
||||
<Compile Include="ConnectionFactoryParametersAttribute.cs" />
|
||||
<Compile Include="ICryptoTestContext.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
|
|
|
@ -31,9 +31,7 @@ namespace Mono.Security.NewTls.TestFramework
|
|||
{
|
||||
IRandomNumberGenerator GetRandomNumberGenerator ();
|
||||
|
||||
bool IsSupported (CryptoTestHostType type);
|
||||
|
||||
bool IsEncryptionSupported (CryptoTestHostType type);
|
||||
bool IsSupported (CryptoTestHostType type, bool needsEncryption);
|
||||
|
||||
IHashTestHost GetHashTestHost (CryptoTestHostType type);
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ICryptoTestContext.cs" />
|
||||
<Compile Include="ILineBasedStream.cs" />
|
||||
<Compile Include="StreamWrapper.cs" />
|
||||
<Compile Include="ICertificate.cs" />
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/lib/
|
|
@ -41,6 +41,10 @@
|
|||
<Compile Include="ClientCertificate.cs" />
|
||||
<Compile Include="MonoCryptoProvider.cs" />
|
||||
<Compile Include="SymmetricAlgorithmProxy.cs" />
|
||||
<Compile Include="NativeOpenSsl.cs" />
|
||||
<Compile Include="NativeOpenSslError.cs" />
|
||||
<Compile Include="NativeOpenSslException.cs" />
|
||||
<Compile Include="NativeCryptoProvider.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
|
@ -70,4 +74,18 @@
|
|||
<Name>Xamarin.AsyncTests</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\MartinsPlayground\lib\libNativeOpenSsl.dylib">
|
||||
<Link>libNativeOpenSsl.dylib</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="..\MartinsPlayground\lib\libcrypto.1.0.0.dylib">
|
||||
<Link>libcrypto.1.0.0.dylib</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="..\MartinsPlayground\lib\libssl.1.0.0.dylib">
|
||||
<Link>libssl.1.0.0.dylib</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,126 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Mono.Security.NewTls;
|
||||
using Mono.Security.NewTls.Cipher;
|
||||
using Mono.Security.NewTls.TestFramework;
|
||||
using Xamarin.AsyncTests;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Mono.Security.NewTls.TestProvider
|
||||
{
|
||||
public class NativeCryptoProvider : IHashTestHost
|
||||
{
|
||||
RandomNumberGenerator rng = RandomNumberGenerator.Create ();
|
||||
|
||||
public byte[] GetRandomBytes (int count)
|
||||
{
|
||||
var data = new byte [count];
|
||||
rng.GetBytes (data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public Task Initialize (TestContext ctx, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult<object> (null);
|
||||
}
|
||||
|
||||
public Task PreRun (TestContext ctx, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult<object> (null);
|
||||
}
|
||||
|
||||
public Task PostRun (TestContext ctx, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult<object> (null);
|
||||
}
|
||||
|
||||
public Task Destroy (TestContext ctx, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult<object> (null);
|
||||
}
|
||||
|
||||
static NativeCryptoProvider ()
|
||||
{
|
||||
native_crypto_test_init ();
|
||||
}
|
||||
|
||||
[DllImport (NativeOpenSsl.DLL)]
|
||||
extern static void native_crypto_test_init ();
|
||||
|
||||
[DllImport (NativeOpenSsl.DLL)]
|
||||
extern static int native_crypto_test_PRF (
|
||||
int digest_mask,
|
||||
byte[] seed1, int seed1_len,
|
||||
byte[] seed2, int seed2_len,
|
||||
byte[] seed3, int seed3_len,
|
||||
byte[] seed4, int seed4_len,
|
||||
byte[] seed5, int seed5_len,
|
||||
byte[] sec, int slen,
|
||||
byte[] out1, byte[] out2, int olen);
|
||||
|
||||
[DllImport (NativeOpenSsl.DLL)]
|
||||
extern static int native_crypto_test_digest (
|
||||
int digest_mask, byte[] data, int data_len, byte[] output, int length);
|
||||
|
||||
[DllImport (NativeOpenSsl.DLL)]
|
||||
extern static int native_crypto_test_get_prf_algorithm_sha256 ();
|
||||
|
||||
[DllImport (NativeOpenSsl.DLL)]
|
||||
extern static int native_crypto_test_get_prf_algorithm_sha384 ();
|
||||
|
||||
int GetAlgorithm (HandshakeHashType algorithm)
|
||||
{
|
||||
switch (algorithm) {
|
||||
case HandshakeHashType.SHA256:
|
||||
return native_crypto_test_get_prf_algorithm_sha256 ();
|
||||
case HandshakeHashType.SHA384:
|
||||
return native_crypto_test_get_prf_algorithm_sha384 ();
|
||||
default:
|
||||
throw new NotSupportedException ();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] TestPRF (HandshakeHashType algorithm, byte[] secret, string seed, byte[] data, int length)
|
||||
{
|
||||
var digest_mask = GetAlgorithm (algorithm);
|
||||
|
||||
var output = new byte [length];
|
||||
var temp = new byte [length];
|
||||
|
||||
var seedBytes = Encoding.ASCII.GetBytes (seed);
|
||||
int ret = native_crypto_test_PRF (digest_mask, seedBytes, seedBytes.Length, data, data.Length,
|
||||
null, 0, null, 0, null, 0, secret, secret.Length, output, temp, length);
|
||||
if (ret != 1)
|
||||
throw new InvalidOperationException ();
|
||||
return output;
|
||||
}
|
||||
|
||||
public byte[] TestDigest (HandshakeHashType algorithm, byte[] data)
|
||||
{
|
||||
var digest_mask = GetAlgorithm (algorithm);
|
||||
|
||||
var output = new byte [200];
|
||||
var ret = native_crypto_test_digest (digest_mask, data, data.Length, output, output.Length);
|
||||
if (ret <= 0)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
var buffer = new byte [ret];
|
||||
Buffer.BlockCopy (output, 0, buffer, 0, ret);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public bool SupportsEncryption {
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,490 @@
|
|||
//
|
||||
// NativeOpenSsl.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <martin.baulig@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2014 Xamarin Inc. (http://www.xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Mono.Security.NewTls;
|
||||
using Mono.Security.NewTls.Cipher;
|
||||
using Mono.Security.NewTls.TestFramework;
|
||||
|
||||
namespace Mono.Security.NewTls.TestProvider
|
||||
{
|
||||
public class NativeOpenSsl : Stream
|
||||
{
|
||||
bool isClient;
|
||||
bool enableDebugging;
|
||||
OpenSslHandle handle;
|
||||
CertificateHandle certificate;
|
||||
PrivateKeyHandle privateKey;
|
||||
DebugCallback debug_callback;
|
||||
MessageCallback message_callback;
|
||||
VerifyCallback verify_callback;
|
||||
RemoteValidationCallback managed_cert_callback;
|
||||
ShutdownState shutdownState;
|
||||
TlsException lastAlert;
|
||||
|
||||
public delegate bool RemoteValidationCallback (bool ok, X509Certificate certificate);
|
||||
|
||||
class OpenSslHandle : SafeHandle
|
||||
{
|
||||
OpenSslHandle ()
|
||||
: base (IntPtr.Zero, true)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsInvalid {
|
||||
get { return handle == IntPtr.Zero; }
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle ()
|
||||
{
|
||||
native_openssl_destroy (handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static void native_openssl_destroy (IntPtr handle);
|
||||
}
|
||||
|
||||
class CertificateHandle : SafeHandle
|
||||
{
|
||||
CertificateHandle ()
|
||||
: base (IntPtr.Zero, true)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsInvalid {
|
||||
get { return handle == IntPtr.Zero; }
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle ()
|
||||
{
|
||||
native_openssl_free_certificate (handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static void native_openssl_free_certificate (IntPtr handle);
|
||||
}
|
||||
|
||||
class PrivateKeyHandle : SafeHandle
|
||||
{
|
||||
PrivateKeyHandle ()
|
||||
: base (IntPtr.Zero, true)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsInvalid {
|
||||
get { return handle == IntPtr.Zero; }
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle ()
|
||||
{
|
||||
native_openssl_free_private_key (handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static void native_openssl_free_private_key (IntPtr handle);
|
||||
}
|
||||
|
||||
void OnDebugCallback (bool write, byte[] buffer)
|
||||
{
|
||||
DebugHelper.WriteLine (write ? "WRITE" : "READ", buffer);
|
||||
}
|
||||
|
||||
void OnDebugCallback (int cmd, IntPtr ptr, int size, int ret)
|
||||
{
|
||||
try {
|
||||
DebugHelper.WriteLine ("DEBUG CALLBACK: {0:x} {1:x} {2:x} {3:x}", cmd, ptr.ToInt32 (), size, ret);
|
||||
var buffer = new byte [size];
|
||||
Marshal.Copy (ptr, buffer, 0, size);
|
||||
OnDebugCallback (cmd == 0x82, buffer);
|
||||
} catch (Exception ex) {
|
||||
DebugHelper.WriteLine ("EXCEPTION IN DEBUG CALLBACK: {0}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
void OnMessageCallback (int write_p, int version, int content_type, IntPtr buf, int size)
|
||||
{
|
||||
try {
|
||||
if (enableDebugging)
|
||||
DebugHelper.WriteLine ("MESSAGE CALLBACK: {0} {1:x} {2:x} {3:x} {4:x}",
|
||||
write_p, version, content_type, size, buf.ToInt32 ());
|
||||
|
||||
var buffer = new byte [size];
|
||||
Marshal.Copy (buf, buffer, 0, size);
|
||||
if (enableDebugging)
|
||||
DebugHelper.WriteLine ("MESSAGE", buffer);
|
||||
|
||||
if ((ContentType)content_type == ContentType.Alert) {
|
||||
var alert = new Alert ((AlertLevel)buffer [0], (AlertDescription)buffer [1]);
|
||||
if (enableDebugging)
|
||||
DebugHelper.WriteLine ("ALERT: {0}", alert);
|
||||
lastAlert = new TlsException (alert);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
DebugHelper.WriteLine ("EXCEPTION IN MESSAGE CALLBACK: {0}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
delegate void DebugCallback (int cmd, IntPtr ptr, int size, int ret);
|
||||
|
||||
delegate void MessageCallback (int write_p, int version, int content_type, IntPtr buf, int size);
|
||||
|
||||
void CheckError (int ret)
|
||||
{
|
||||
if (ret != 0) {
|
||||
if (lastAlert != null)
|
||||
throw lastAlert;
|
||||
throw new NativeOpenSslException ((NativeOpenSslError)ret);
|
||||
}
|
||||
}
|
||||
|
||||
internal const string DLL = "NativeOpenSsl";
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static OpenSslHandle native_openssl_initialize (int debug, DebugCallback debug_callback, MessageCallback message_callback);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_create_context (OpenSslHandle handle, bool client);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_create_connection (OpenSslHandle handle);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_connect (OpenSslHandle handle, byte[] ip, int port);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_bind (OpenSslHandle handle, byte[] ip, int port);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_accept (OpenSslHandle handle);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_write (OpenSslHandle handle, byte[] buffer, int offset, int size);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_read (OpenSslHandle handle, byte[] buffer, int offset, int size);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static CertificateHandle native_openssl_load_certificate_from_pem (OpenSslHandle handle, byte[] buffer, int len);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static PrivateKeyHandle native_openssl_load_private_key_from_pem (OpenSslHandle handle, byte[] buffer, int len);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_load_certificate_from_pkcs12 (
|
||||
OpenSslHandle handle, byte[] buffer, int len,
|
||||
[MarshalAs (UnmanagedType.LPStr)] string password, int passlen,
|
||||
out CertificateHandle certificate, out PrivateKeyHandle privateKey);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_set_certificate (
|
||||
OpenSslHandle handle, CertificateHandle certificate, PrivateKeyHandle privateKey);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static void native_openssl_set_certificate_verify (OpenSslHandle handle, int mode, VerifyCallback verify_cb, CertificateVerifyCallback cert_cb, int depth);
|
||||
|
||||
delegate int VerifyCallback (int ok, IntPtr store_ctx);
|
||||
|
||||
delegate int CertificateVerifyCallback (IntPtr store_ctx, IntPtr cert);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int X509_STORE_CTX_get_error (IntPtr store);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static IntPtr X509_STORE_CTX_get_current_cert (IntPtr store);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static IntPtr BIO_s_mem ();
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static IntPtr BIO_new (IntPtr method);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static IntPtr BIO_free (IntPtr bio);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_BIO_get_mem_data (IntPtr bio, out IntPtr data);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int PEM_write_bio_X509 (IntPtr bio, IntPtr cert);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_shutdown (OpenSslHandle handle);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static short native_openssl_get_current_cipher (OpenSslHandle handle);
|
||||
|
||||
[DllImport (DLL)]
|
||||
extern static int native_openssl_set_cipher_list (OpenSslHandle handle, byte[] ciphers, int count);
|
||||
|
||||
public override bool CanRead {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanSeek {
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override void Write (byte[] buffer, int offset, int size)
|
||||
{
|
||||
var ret = native_openssl_write (handle, buffer, offset, size);
|
||||
if (ret != size)
|
||||
throw new ConnectionException ("Write failed.");
|
||||
}
|
||||
|
||||
public override int Read (byte[] buffer, int offset, int size)
|
||||
{
|
||||
return native_openssl_read (handle, buffer, offset, size);
|
||||
}
|
||||
|
||||
public override void Flush ()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public override long Length {
|
||||
get { throw new InvalidOperationException (); }
|
||||
}
|
||||
|
||||
public override long Position {
|
||||
get { throw new InvalidOperationException (); }
|
||||
set { throw new InvalidOperationException (); }
|
||||
}
|
||||
|
||||
public override long Seek (long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new InvalidOperationException ();
|
||||
}
|
||||
|
||||
public override void SetLength (long value)
|
||||
{
|
||||
throw new InvalidOperationException ();
|
||||
}
|
||||
|
||||
public NativeOpenSsl (bool isClient, bool debug)
|
||||
{
|
||||
this.isClient = isClient;
|
||||
this.enableDebugging = debug;
|
||||
|
||||
if (debug)
|
||||
debug_callback = new DebugCallback (OnDebugCallback);
|
||||
|
||||
message_callback = new MessageCallback (OnMessageCallback);
|
||||
|
||||
handle = native_openssl_initialize (debug ? 1 : 0, debug_callback, message_callback);
|
||||
if (handle.IsInvalid)
|
||||
throw new ConnectionException ("Handle invalid.");
|
||||
|
||||
var ret = native_openssl_create_context (handle, isClient);
|
||||
CheckError (ret);
|
||||
}
|
||||
|
||||
public void Connect (IPEndPoint endpoint)
|
||||
{
|
||||
if (!isClient)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
var ret = native_openssl_create_connection (handle);
|
||||
CheckError (ret);
|
||||
|
||||
ret = native_openssl_connect (handle, endpoint.Address.GetAddressBytes (), endpoint.Port);
|
||||
CheckError (ret);
|
||||
}
|
||||
|
||||
public void Bind (IPEndPoint endpoint)
|
||||
{
|
||||
if (isClient)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
var ret = native_openssl_create_connection (handle);
|
||||
CheckError (ret);
|
||||
|
||||
ret = native_openssl_bind (handle, endpoint.Address.GetAddressBytes (), endpoint.Port);
|
||||
CheckError (ret);
|
||||
}
|
||||
|
||||
public void Accept ()
|
||||
{
|
||||
var ret = native_openssl_accept (handle);
|
||||
CheckError (ret);
|
||||
}
|
||||
|
||||
public void SetCertificate (byte[] data)
|
||||
{
|
||||
native_openssl_load_certificate_from_pem (handle, data, data.Length);
|
||||
}
|
||||
|
||||
public void SetPrivateKey (byte[] data)
|
||||
{
|
||||
native_openssl_load_private_key_from_pem (handle, data, data.Length);
|
||||
}
|
||||
|
||||
public void SetCertificate (byte[] data, string password)
|
||||
{
|
||||
var ret = native_openssl_load_certificate_from_pkcs12 (
|
||||
handle, data, data.Length, password, password != null ? password.Length : 0,
|
||||
out certificate, out privateKey);
|
||||
CheckError (ret);
|
||||
|
||||
ret = native_openssl_set_certificate (handle, certificate, privateKey);
|
||||
CheckError (ret);
|
||||
}
|
||||
|
||||
static X509Certificate ReadNativeCertificate (IntPtr ptr)
|
||||
{
|
||||
var bio = BIO_new (BIO_s_mem ());
|
||||
try {
|
||||
var ret = PEM_write_bio_X509 (bio, ptr);
|
||||
if (ret <= 0)
|
||||
throw new NativeOpenSslException (NativeOpenSslError.INVALID_CERT);
|
||||
IntPtr data;
|
||||
var size = native_openssl_BIO_get_mem_data (bio, out data);
|
||||
var buffer = new byte [size];
|
||||
Marshal.Copy (data, buffer, 0, size);
|
||||
return new X509Certificate (buffer);
|
||||
} finally {
|
||||
BIO_free (bio);
|
||||
}
|
||||
}
|
||||
|
||||
int OnVerifyCallback (int ok, IntPtr store_ctx)
|
||||
{
|
||||
try {
|
||||
var cert = X509_STORE_CTX_get_current_cert (store_ctx);
|
||||
var managedCert = ReadNativeCertificate (cert);
|
||||
var ret = managed_cert_callback (ok != 0, managedCert);
|
||||
return ret ? 1 : 0;
|
||||
} catch (Exception ex) {
|
||||
DebugHelper.WriteLine ("EXCEPTION IN VERIFY CALLBACK: {0}", ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int OnCertificateVerifyCallback (IntPtr store_ctx, IntPtr cert)
|
||||
{
|
||||
try {
|
||||
DebugHelper.WriteLine ("CERT VERIFY CALLBACK: {0:x} {1:x}",
|
||||
store_ctx.ToInt32 (), cert.ToInt32 ());
|
||||
var managedCert = ReadNativeCertificate (cert);
|
||||
DebugHelper.WriteLine ("GOT CERTIFICATE: {0} {1}", managedCert, managedCert.Subject);
|
||||
} catch (Exception ex) {
|
||||
DebugHelper.WriteLine ("EXCEPTION IN CERT VERIFY CALLBACK: {0}", ex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum VerifyMode {
|
||||
SSL_VERIFY_NONE= 0x00,
|
||||
SSL_VERIFY_PEER = 0x01,
|
||||
SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 0x02,
|
||||
SSL_VERIFY_CLIENT_ONCE = 0x04
|
||||
}
|
||||
|
||||
public void SetCertificateVerify (VerifyMode mode, RemoteValidationCallback callback)
|
||||
{
|
||||
this.managed_cert_callback = callback;
|
||||
if (callback != null)
|
||||
verify_callback = new VerifyCallback (OnVerifyCallback);
|
||||
native_openssl_set_certificate_verify (handle, (int)mode, verify_callback, null, 10);
|
||||
}
|
||||
|
||||
enum ShutdownState {
|
||||
None,
|
||||
Error,
|
||||
Closed,
|
||||
SentShutdown
|
||||
}
|
||||
|
||||
public bool Shutdown (bool waitForReply)
|
||||
{
|
||||
if (shutdownState == ShutdownState.Error)
|
||||
return false;
|
||||
else if (shutdownState == ShutdownState.Closed)
|
||||
return true;
|
||||
var ret = native_openssl_shutdown (handle);
|
||||
if (ret == 1) {
|
||||
shutdownState = ShutdownState.Closed;
|
||||
return true;
|
||||
}
|
||||
if (!waitForReply) {
|
||||
shutdownState = ShutdownState.SentShutdown;
|
||||
return false;
|
||||
}
|
||||
ret = native_openssl_shutdown (handle);
|
||||
if (ret != 1)
|
||||
throw new IOException ("Shutdown failed.");
|
||||
shutdownState = ShutdownState.Closed;
|
||||
return true;
|
||||
}
|
||||
|
||||
public CipherSuiteCode CurrentCipher {
|
||||
get { return (CipherSuiteCode)native_openssl_get_current_cipher (handle); }
|
||||
}
|
||||
|
||||
public void SetCipherList (ICollection<CipherSuiteCode> ciphers)
|
||||
{
|
||||
var codes = new TlsBuffer (ciphers.Count * 2);
|
||||
foreach (var cipher in ciphers)
|
||||
codes.Write ((short)cipher);
|
||||
|
||||
var ret = native_openssl_set_cipher_list (handle, codes.Buffer, ciphers.Count);
|
||||
CheckError (ret);
|
||||
}
|
||||
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (disposing) {
|
||||
if (certificate != null) {
|
||||
certificate.Dispose ();
|
||||
certificate = null;
|
||||
}
|
||||
if (privateKey != null) {
|
||||
privateKey.Dispose ();
|
||||
privateKey = null;
|
||||
}
|
||||
if (handle != null) {
|
||||
handle.Dispose ();
|
||||
handle = null;
|
||||
}
|
||||
}
|
||||
base.Dispose (disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// NativeOpenSslError.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <martin.baulig@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2014 Xamarin Inc. (http://www.xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
|
||||
namespace Mono.Security.NewTls.TestProvider
|
||||
{
|
||||
// Keep in sync with the native code
|
||||
public enum NativeOpenSslError
|
||||
{
|
||||
Ok,
|
||||
SOCKET,
|
||||
SSL_CONNECT,
|
||||
SSL_ACCEPT,
|
||||
PKCS12_LOAD,
|
||||
PKCS12_VERIFY,
|
||||
PKCS12_PARSE,
|
||||
INVALID_CERT,
|
||||
INVALID_PKEY,
|
||||
PKEY_DOES_NOT_MATCH,
|
||||
CREATE_CONTEXT,
|
||||
CREATE_CONNECTION,
|
||||
INVALID_CIPHER
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// NativeOpenSslException.cs
|
||||
//
|
||||
// Author:
|
||||
// Martin Baulig <martin.baulig@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2014 Xamarin Inc. (http://www.xamarin.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
|
||||
namespace Mono.Security.NewTls.TestProvider
|
||||
{
|
||||
public class NativeOpenSslException : Exception
|
||||
{
|
||||
public NativeOpenSslException (NativeOpenSslError error)
|
||||
: base (error.ToString ())
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ namespace Mono.Security.NewTls.Tests
|
|||
using TestFramework;
|
||||
|
||||
[AsyncTestFixture]
|
||||
public class CryptoTest : ITestHost<IHashTestHost>
|
||||
public class HashTest : ITestHost<IHashTestHost>
|
||||
{
|
||||
public IHashTestHost CreateInstance (TestContext context)
|
||||
{
|
||||
|
@ -297,7 +297,7 @@ namespace Mono.Security.NewTls.Tests
|
|||
[AsyncTest]
|
||||
public void SimpleTest (TestContext ctx, [TestHost] IHashTestHost provider)
|
||||
{
|
||||
ctx.LogMessage ("SIMPLE TEST: {0}", provider);
|
||||
ctx.LogMessage ("HASH TEST: {0}", provider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,12 +32,12 @@
|
|||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="NewTlsTestFeatures.cs" />
|
||||
<Compile Include="CryptoTest.cs" />
|
||||
<Compile Include="TestGaloisCounterCipher.cs" />
|
||||
<Compile Include="CipherTest.cs" />
|
||||
<Compile Include="TestGaloisCounterGipher-Generated.cs" />
|
||||
<Compile Include="TestCbcBlockCipher-Generated.cs" />
|
||||
<Compile Include="TestCbcBlockCipher.cs" />
|
||||
<Compile Include="HashTest.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Mono.Security.NewTls.Tests
|
|||
static bool IsOpenSslSupported ()
|
||||
{
|
||||
var provider = DependencyInjector.Get<ICryptoProvider> ();
|
||||
return provider.IsSupported (CryptoTestHostType.OpenSsl);
|
||||
return provider.IsSupported (CryptoTestHostType.OpenSsl, true);
|
||||
}
|
||||
|
||||
static NewTlsTestFeatures ()
|
||||
|
|
Загрузка…
Ссылка в новой задаче