public static void VerifyDuplicateKey_NeverValidHandle() { using (SafeEvpPKeyHandle pkey = new SafeEvpPKeyHandle(IntPtr.Zero, false)) { Assert.Throws<ArgumentException>(() => new DSAOpenSsl(pkey)); } }
internal static extern int UpRefEvpPkey(SafeEvpPKeyHandle handle);
internal static extern int SslCtxUsePrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);
internal static partial SafeEvpPKeyCtxHandle EvpPKeyCtxCreate(SafeEvpPKeyHandle pkey, SafeEvpPKeyHandle peerkey, out uint secretLength);
private static void SetSslCertificate(libssl.SafeSslContextHandle contextPtr, SafeX509Handle certPtr, SafeEvpPKeyHandle keyPtr) { Debug.Assert(certPtr != null && !certPtr.IsInvalid, "certPtr != null && !certPtr.IsInvalid"); Debug.Assert(keyPtr != null && !keyPtr.IsInvalid, "keyPtr != null && !keyPtr.IsInvalid"); int retVal = libssl.SSL_CTX_use_certificate(contextPtr, certPtr); if (1 != retVal) { throw CreateSslException("Failed to use SSL certificate"); } retVal = libssl.SSL_CTX_use_PrivateKey(contextPtr, keyPtr); if (1 != retVal) { throw CreateSslException("Failed to use SSL certificate private key"); } //check private key retVal = libssl.SSL_CTX_check_private_key(contextPtr); if (1 != retVal) { throw CreateSslException("Certificate pivate key check failed"); } }
internal void SetPrivateKey(SafeEvpPKeyHandle privateKey) { _privateKey = privateKey; }
internal static partial bool EvpPkeySetEcKey(SafeEvpPKeyHandle pkey, SafeEcKeyHandle key);
private int TlsClientCertCallback(IntPtr ssl, out IntPtr certHandle, out IntPtr privateKeyHandle) { const int CertificateSet = 1, NoCertificateSet = 0, SuspendHandshake = -1; certHandle = IntPtr.Zero; privateKeyHandle = IntPtr.Zero; if (ssl == IntPtr.Zero) { Debug.Fail("Expected valid SSL pointer"); EventSourceTrace("Invalid SSL pointer in callback"); return(NoCertificateSet); } SafeSslHandle sslHandle = null; X509Chain chain = null; X509Certificate2 certificate = null; try { sslHandle = new SafeSslHandle(ssl, ownsHandle: false); ISet <string> issuerNames = GetRequestCertificateAuthorities(sslHandle); if (_clientCertificates != null) // manual mode { // If there's one certificate, just use it. Otherwise, try to find the best one. if (_clientCertificates.Count == 1) { certificate = _clientCertificates[0]; chain = TLSCertificateExtensions.BuildNewChain(certificate, includeClientApplicationPolicy: false); } else if (!_clientCertificates.TryFindClientCertificate(issuerNames, out certificate, out chain)) { EventSourceTrace("No manual certificate or chain."); return(NoCertificateSet); } } else if (!GetAutomaticClientCertificate(issuerNames, out certificate, out chain)) // automatic mode { EventSourceTrace("No automatic certificate or chain."); return(NoCertificateSet); } SafeEvpPKeyHandle privateKeySafeHandle = null; Interop.Crypto.CheckValidOpenSslHandle(certificate.Handle); using (RSAOpenSsl rsa = certificate.GetRSAPrivateKey() as RSAOpenSsl) { if (rsa != null) { privateKeySafeHandle = rsa.DuplicateKeyHandle(); EventSourceTrace("RSA key"); } else { using (ECDsaOpenSsl ecdsa = certificate.GetECDsaPrivateKey() as ECDsaOpenSsl) { if (ecdsa != null) { privateKeySafeHandle = ecdsa.DuplicateKeyHandle(); EventSourceTrace("ECDsa key"); } } } } if (privateKeySafeHandle == null || privateKeySafeHandle.IsInvalid) { EventSourceTrace("Invalid private key"); return(NoCertificateSet); } SafeX509Handle certSafeHandle = Interop.Crypto.X509Duplicate(certificate.Handle); Interop.Crypto.CheckValidOpenSslHandle(certSafeHandle); if (chain != null) { for (int i = chain.ChainElements.Count - 2; i > 0; i--) { SafeX509Handle dupCertHandle = Interop.Crypto.X509Duplicate(chain.ChainElements[i].Certificate.Handle); Interop.Crypto.CheckValidOpenSslHandle(dupCertHandle); if (!Interop.Ssl.SslAddExtraChainCert(sslHandle, dupCertHandle)) { EventSourceTrace("Failed to add extra chain certificate"); dupCertHandle.Dispose(); // we still own the safe handle; clean it up return(SuspendHandshake); } dupCertHandle.SetHandleAsInvalid(); // ownership has been transferred to sslHandle; do not free via this safe handle } } certHandle = certSafeHandle.DangerousGetHandle(); privateKeyHandle = privateKeySafeHandle.DangerousGetHandle(); EventSourceTrace("Client certificate set: {0}", certificate); // Ownership has been transferred to OpenSSL; do not free these handles certSafeHandle.SetHandleAsInvalid(); privateKeySafeHandle.SetHandleAsInvalid(); return(CertificateSet); } finally { if (_clientCertificates == null) { certificate?.Dispose(); // only dispose cert if it's automatic / newly created } chain?.Dispose(); sslHandle?.Dispose(); } }
internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX509Handle certHandle, SafeEvpPKeyHandle certKeyHandle, EncryptionPolicy policy, SslAuthenticationOptions sslAuthenticationOptions) { SafeSslHandle context = null; // Always use SSLv23_method, regardless of protocols. It supports negotiating to the highest // mutually supported version and can thus handle any of the set protocols, and we then use // SetProtocolOptions to ensure we only allow the ones requested. using (SafeSslContextHandle innerContext = Ssl.SslCtxCreate(Ssl.SslMethods.SSLv23_method)) { if (innerContext.IsInvalid) { throw CreateSslException(SR.net_allocate_ssl_context_failed); } if (!Interop.Ssl.Tls13Supported) { if (protocols != SslProtocols.None && CipherSuitesPolicyPal.WantsTls13(protocols)) { protocols = protocols & (~SslProtocols.Tls13); } } else if (CipherSuitesPolicyPal.WantsTls13(protocols) && CipherSuitesPolicyPal.ShouldOptOutOfTls13(sslAuthenticationOptions.CipherSuitesPolicy, policy)) { if (protocols == SslProtocols.None) { // we are using default settings but cipher suites policy says that TLS 1.3 // is not compatible with our settings (i.e. we requested no encryption or disabled // all TLS 1.3 cipher suites) protocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12; } else { // user explicitly asks for TLS 1.3 but their policy is not compatible with TLS 1.3 throw new SslException( SR.Format(SR.net_ssl_encryptionpolicy_notsupported, policy)); } } if (CipherSuitesPolicyPal.ShouldOptOutOfLowerThanTls13(sslAuthenticationOptions.CipherSuitesPolicy, policy)) { if (!CipherSuitesPolicyPal.WantsTls13(protocols)) { // We cannot provide neither TLS 1.3 or non TLS 1.3, user disabled all cipher suites throw new SslException( SR.Format(SR.net_ssl_encryptionpolicy_notsupported, policy)); } protocols = SslProtocols.Tls13; } // Configure allowed protocols. It's ok to use DangerousGetHandle here without AddRef/Release as we just // create the handle, it's rooted by the using, no one else has a reference to it, etc. Ssl.SetProtocolOptions(innerContext.DangerousGetHandle(), protocols); // Sets policy and security level if (!Ssl.SetEncryptionPolicy(innerContext, policy)) { throw new SslException( SR.Format(SR.net_ssl_encryptionpolicy_notsupported, policy)); } // The logic in SafeSslHandle.Disconnect is simple because we are doing a quiet // shutdown (we aren't negotiating for session close to enable later session // restoration). // // If you find yourself wanting to remove this line to enable bidirectional // close-notify, you'll probably need to rewrite SafeSslHandle.Disconnect(). // https://www.openssl.org/docs/manmaster/ssl/SSL_shutdown.html Ssl.SslCtxSetQuietShutdown(innerContext); byte[] cipherList = CipherSuitesPolicyPal.GetOpenSslCipherList(sslAuthenticationOptions.CipherSuitesPolicy, protocols, policy); Debug.Assert(cipherList == null || (cipherList.Length >= 1 && cipherList[cipherList.Length - 1] == 0)); byte[] cipherSuites = CipherSuitesPolicyPal.GetOpenSslCipherSuites(sslAuthenticationOptions.CipherSuitesPolicy, protocols, policy); Debug.Assert(cipherSuites == null || (cipherSuites.Length >= 1 && cipherSuites[cipherSuites.Length - 1] == 0)); unsafe { fixed(byte *cipherListStr = cipherList) fixed(byte *cipherSuitesStr = cipherSuites) { if (!Ssl.SetCiphers(innerContext, cipherListStr, cipherSuitesStr)) { Crypto.ErrClearError(); throw new PlatformNotSupportedException(SR.Format(SR.net_ssl_encryptionpolicy_notsupported, policy)); } } } bool hasCertificateAndKey = certHandle != null && !certHandle.IsInvalid && certKeyHandle != null && !certKeyHandle.IsInvalid; if (hasCertificateAndKey) { SetSslCertificate(innerContext, certHandle, certKeyHandle); } if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired) { Ssl.SslCtxSetVerify(innerContext, s_verifyClientCertificate); } GCHandle alpnHandle = default; try { if (sslAuthenticationOptions.ApplicationProtocols != null) { if (sslAuthenticationOptions.IsServer) { alpnHandle = GCHandle.Alloc(sslAuthenticationOptions.ApplicationProtocols); Interop.Ssl.SslCtxSetAlpnSelectCb(innerContext, s_alpnServerCallback, GCHandle.ToIntPtr(alpnHandle)); } else { if (Interop.Ssl.SslCtxSetAlpnProtos(innerContext, sslAuthenticationOptions.ApplicationProtocols) != 0) { throw CreateSslException(SR.net_alpn_config_failed); } } } context = SafeSslHandle.Create(innerContext, sslAuthenticationOptions.IsServer); Debug.Assert(context != null, "Expected non-null return value from SafeSslHandle.Create"); if (context.IsInvalid) { context.Dispose(); throw CreateSslException(SR.net_allocate_ssl_context_failed); } if (!sslAuthenticationOptions.IsServer) { // The IdnMapping converts unicode input into the IDNA punycode sequence. string punyCode = s_idnMapping.GetAscii(sslAuthenticationOptions.TargetHost); // Similar to windows behavior, set SNI on openssl by default for client context, ignore errors. if (!Ssl.SslSetTlsExtHostName(context, punyCode)) { Crypto.ErrClearError(); } } if (hasCertificateAndKey) { bool hasCertReference = false; try { certHandle.DangerousAddRef(ref hasCertReference); using (X509Certificate2 cert = new X509Certificate2(certHandle.DangerousGetHandle())) { X509Chain chain = null; try { chain = TLSCertificateExtensions.BuildNewChain(cert, includeClientApplicationPolicy: false); if (chain != null && !Ssl.AddExtraChainCertificates(context, chain)) { throw CreateSslException(SR.net_ssl_use_cert_failed); } } finally { if (chain != null) { int elementsCount = chain.ChainElements.Count; for (int i = 0; i < elementsCount; i++) { chain.ChainElements[i].Certificate.Dispose(); } chain.Dispose(); } } } } finally { if (hasCertReference) { certHandle.DangerousRelease(); } } } context.AlpnHandle = alpnHandle; } catch { if (alpnHandle.IsAllocated) { alpnHandle.Free(); } throw; } } return(context); }
internal static partial int EvpPKeySize(SafeEvpPKeyHandle pkey);
internal static partial int UpRefEvpPkey(SafeEvpPKeyHandle handle);
internal static extern int SSL_CTX_use_PrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);
internal static extern bool EVP_PKEY_set1_EC_KEY(SafeEvpPKeyHandle pkey, SafeEcKeyHandle rsa);
internal static extern SafeEcKeyHandle EVP_PKEY_get1_EC_KEY(SafeEvpPKeyHandle pkey);
public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle);
internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX509Handle certHandle, SafeEvpPKeyHandle certKeyHandle, EncryptionPolicy policy, bool isServer, bool remoteCertRequired) { SafeSslHandle context = null; IntPtr method = GetSslMethod(protocols); using (SafeSslContextHandle innerContext = Ssl.SslCtxCreate(method)) { if (innerContext.IsInvalid) { throw CreateSslException(SR.net_allocate_ssl_context_failed); } Ssl.SetProtocolOptions(innerContext, protocols); Ssl.SslCtxSetQuietShutdown(innerContext); Ssl.SetEncryptionPolicy(innerContext, policy); if (certHandle != null && certKeyHandle != null) { SetSslCertificate(innerContext, certHandle, certKeyHandle); } if (remoteCertRequired) { Debug.Assert(isServer, "isServer flag should be true"); Ssl.SslCtxSetVerify(innerContext, s_verifyClientCertificate); //update the client CA list UpdateCAListFromRootStore(innerContext); } context = SafeSslHandle.Create(innerContext, isServer); Debug.Assert(context != null, "Expected non-null return value from SafeSslHandle.Create"); if (context.IsInvalid) { context.Dispose(); throw CreateSslException(SR.net_allocate_ssl_context_failed); } } return(context); }
private int TlsClientCertCallback(IntPtr ssl, out IntPtr certHandle, out IntPtr privateKeyHandle) { Interop.Crypto.CheckValidOpenSslHandle(ssl); using (SafeSslHandle sslHandle = new SafeSslHandle(ssl, false)) { certHandle = IntPtr.Zero; privateKeyHandle = IntPtr.Zero; ISet <string> issuerNames = GetRequestCertificateAuthorities(sslHandle); X509Certificate2 certificate; X509Chain chain; if (!GetClientCertificate(issuerNames, out certificate, out chain)) { EventSourceTrace("No certificate or chain"); return(0); } Interop.Crypto.CheckValidOpenSslHandle(certificate.Handle); using (RSAOpenSsl rsa = certificate.GetRSAPrivateKey() as RSAOpenSsl) { if (rsa != null) { _privateKeyHandle = rsa.DuplicateKeyHandle(); EventSourceTrace("RSA key"); } else { using (ECDsaOpenSsl ecdsa = certificate.GetECDsaPrivateKey() as ECDsaOpenSsl) { if (ecdsa != null) { _privateKeyHandle = ecdsa.DuplicateKeyHandle(); EventSourceTrace("ECDsa key"); } } } } if (_privateKeyHandle == null || _privateKeyHandle.IsInvalid) { EventSourceTrace("Invalid private key"); return(0); } _certHandle = Interop.Crypto.X509Duplicate(certificate.Handle); Interop.Crypto.CheckValidOpenSslHandle(_certHandle); if (chain != null) { for (int i = chain.ChainElements.Count - 2; i > 0; i--) { SafeX509Handle dupCertHandle = Interop.Crypto.X509Duplicate(chain.ChainElements[i].Certificate.Handle); Interop.Crypto.CheckValidOpenSslHandle(dupCertHandle); if (!Interop.Ssl.SslAddExtraChainCert(sslHandle, dupCertHandle)) { EventSourceTrace("Failed to add extra chain certificate"); return(-1); } } } certHandle = _certHandle.DangerousGetHandle(); privateKeyHandle = _privateKeyHandle.DangerousGetHandle(); return(1); } }
internal static partial int SslUsePrivateKey(SafeSslHandle ssl, SafeEvpPKeyHandle keyPtr);
internal static partial SafeEcKeyHandle EvpPkeyGetEcKey(SafeEvpPKeyHandle pkey);
internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX509Handle certHandle, SafeEvpPKeyHandle certKeyHandle, EncryptionPolicy policy, bool isServer, bool remoteCertRequired) { SafeSslHandle context = null; IntPtr method = GetSslMethod(protocols); using (SafeSslContextHandle innerContext = Ssl.SslCtxCreate(method)) { if (innerContext.IsInvalid) { throw CreateSslException(SR.net_allocate_ssl_context_failed); } // Configure allowed protocols. It's ok to use DangerousGetHandle here without AddRef/Release as we just // create the handle, it's rooted by the using, no one else has a reference to it, etc. Ssl.SetProtocolOptions(innerContext.DangerousGetHandle(), protocols); // The logic in SafeSslHandle.Disconnect is simple because we are doing a quiet // shutdown (we aren't negotiating for session close to enable later session // restoration). // // If you find yourself wanting to remove this line to enable bidirectional // close-notify, you'll probably need to rewrite SafeSslHandle.Disconnect(). // https://www.openssl.org/docs/manmaster/ssl/SSL_shutdown.html Ssl.SslCtxSetQuietShutdown(innerContext); if (!Ssl.SetEncryptionPolicy(innerContext, policy)) { throw new PlatformNotSupportedException(SR.Format(SR.net_ssl_encryptionpolicy_notsupported, policy)); } if (certHandle != null && certKeyHandle != null) { SetSslCertificate(innerContext, certHandle, certKeyHandle); } if (remoteCertRequired) { Debug.Assert(isServer, "isServer flag should be true"); Ssl.SslCtxSetVerify(innerContext, s_verifyClientCertificate); //update the client CA list UpdateCAListFromRootStore(innerContext); } context = SafeSslHandle.Create(innerContext, isServer); Debug.Assert(context != null, "Expected non-null return value from SafeSslHandle.Create"); if (context.IsInvalid) { context.Dispose(); throw CreateSslException(SR.net_allocate_ssl_context_failed); } } return(context); }
private static void SetSslCertificate(SafeSslContextHandle contextPtr, SafeX509Handle certPtr, SafeEvpPKeyHandle keyPtr) { Debug.Assert(certPtr != null && !certPtr.IsInvalid, "certPtr != null && !certPtr.IsInvalid"); Debug.Assert(keyPtr != null && !keyPtr.IsInvalid, "keyPtr != null && !keyPtr.IsInvalid"); int retVal = Ssl.SslCtxUseCertificate(contextPtr, certPtr); if (1 != retVal) { throw CreateSslException(SR.net_ssl_use_cert_failed); } retVal = Ssl.SslCtxUsePrivateKey(contextPtr, keyPtr); if (1 != retVal) { throw CreateSslException(SR.net_ssl_use_private_key_failed); } //check private key retVal = Ssl.SslCtxCheckPrivateKey(contextPtr); if (1 != retVal) { throw CreateSslException(SR.net_ssl_check_private_key_failed); } }
internal static SafeSslHandle AllocateSslContext(SslProtocols protocols, SafeX509Handle certHandle, SafeEvpPKeyHandle certKeyHandle, EncryptionPolicy policy, SslAuthenticationOptions sslAuthenticationOptions) { SafeSslHandle context = null; // Always use SSLv23_method, regardless of protocols. It supports negotiating to the highest // mutually supported version and can thus handle any of the set protocols, and we then use // SetProtocolOptions to ensure we only allow the ones requested. using (SafeSslContextHandle innerContext = Ssl.SslCtxCreate(Ssl.SslMethods.SSLv23_method)) { if (innerContext.IsInvalid) { throw CreateSslException(SR.net_allocate_ssl_context_failed); } // Configure allowed protocols. It's ok to use DangerousGetHandle here without AddRef/Release as we just // create the handle, it's rooted by the using, no one else has a reference to it, etc. Ssl.SetProtocolOptions(innerContext.DangerousGetHandle(), protocols); // The logic in SafeSslHandle.Disconnect is simple because we are doing a quiet // shutdown (we aren't negotiating for session close to enable later session // restoration). // // If you find yourself wanting to remove this line to enable bidirectional // close-notify, you'll probably need to rewrite SafeSslHandle.Disconnect(). // https://www.openssl.org/docs/manmaster/ssl/SSL_shutdown.html Ssl.SslCtxSetQuietShutdown(innerContext); if (!Ssl.SetEncryptionPolicy(innerContext, policy)) { throw new PlatformNotSupportedException(SR.Format(SR.net_ssl_encryptionpolicy_notsupported, policy)); } bool hasCertificateAndKey = certHandle != null && !certHandle.IsInvalid && certKeyHandle != null && !certKeyHandle.IsInvalid; if (hasCertificateAndKey) { SetSslCertificate(innerContext, certHandle, certKeyHandle); } if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired) { Ssl.SslCtxSetVerify(innerContext, s_verifyClientCertificate); //update the client CA list UpdateCAListFromRootStore(innerContext); } if (sslAuthenticationOptions.ApplicationProtocols != null) { if (sslAuthenticationOptions.IsServer) { byte[] protos = Interop.Ssl.ConvertAlpnProtocolListToByteArray(sslAuthenticationOptions.ApplicationProtocols); sslAuthenticationOptions.AlpnProtocolsHandle = GCHandle.Alloc(protos); Interop.Ssl.SslCtxSetAlpnSelectCb(innerContext, s_alpnServerCallback, GCHandle.ToIntPtr(sslAuthenticationOptions.AlpnProtocolsHandle)); } else { if (Interop.Ssl.SslCtxSetAlpnProtos(innerContext, sslAuthenticationOptions.ApplicationProtocols) != 0) { throw CreateSslException(SR.net_alpn_config_failed); } } } context = SafeSslHandle.Create(innerContext, sslAuthenticationOptions.IsServer); Debug.Assert(context != null, "Expected non-null return value from SafeSslHandle.Create"); if (context.IsInvalid) { context.Dispose(); throw CreateSslException(SR.net_allocate_ssl_context_failed); } if (hasCertificateAndKey) { bool hasCertReference = false; try { certHandle.DangerousAddRef(ref hasCertReference); using (X509Certificate2 cert = new X509Certificate2(certHandle.DangerousGetHandle())) { using (X509Chain chain = TLSCertificateExtensions.BuildNewChain(cert, includeClientApplicationPolicy: false)) { if (chain != null && !Ssl.AddExtraChainCertificates(context, chain)) { throw CreateSslException(SR.net_ssl_use_cert_failed); } } } } finally { if (hasCertReference) { certHandle.DangerousRelease(); } } } } return(context); }
//TODO (Issue #3362) Set remote certificate options internal static SafeSslHandle AllocateSslContext(long options, SafeX509Handle certHandle, SafeEvpPKeyHandle certKeyHandle, bool isServer, bool remoteCertRequired) { SafeSslHandle context = null; IntPtr method = GetSslMethod(isServer, options); using (libssl.SafeSslContextHandle innerContext = new libssl.SafeSslContextHandle(method)) { if (innerContext.IsInvalid) { throw CreateSslException("Failed to allocate SSL/TLS context"); } libssl.SSL_CTX_ctrl(innerContext, libssl.SSL_CTRL_OPTIONS, options, IntPtr.Zero); libssl.SSL_CTX_set_quiet_shutdown(innerContext, 1); if (certHandle != null && certKeyHandle != null) { SetSslCertificate(innerContext, certHandle, certKeyHandle); } context = SafeSslHandle.Create(innerContext, isServer); Debug.Assert(context != null, "Expected non-null return value from SafeSslHandle.Create"); if (context.IsInvalid) { context.Dispose(); throw CreateSslException("Failed to create SSL object from SSL context"); } } return(context); }
private byte[] ExportPfx(SafePasswordHandle password) { using (SafeX509StackHandle publicCerts = Interop.Crypto.NewX509Stack()) { SafeX509Handle privateCertHandle = SafeX509Handle.InvalidHandle; SafeEvpPKeyHandle privateCertKeyHandle = InvalidPKeyHandle; if (_singleCertPal != null) { var certPal = (OpenSslX509CertificateReader)_singleCertPal; if (_singleCertPal.HasPrivateKey) { privateCertHandle = certPal.SafeHandle; privateCertKeyHandle = certPal.PrivateKeyHandle; } else { PushHandle(certPal.Handle, publicCerts); } GC.KeepAlive(certPal); // ensure reader's safe handle isn't finalized while raw handle is in use } else { X509Certificate2 privateCert = null; // Walk the collection backwards, because we're pushing onto a stack. // This will cause the read order later to be the same as it was now. for (int i = _certs.Count - 1; i >= 0; --i) { X509Certificate2 cert = _certs[i]; if (cert.HasPrivateKey) { if (privateCert != null) { // OpenSSL's PKCS12 accelerator (PKCS12_create) only supports one // private key. The data structure supports more than one, but // being able to use that functionality requires a lot more code for // a low-usage scenario. throw new PlatformNotSupportedException(SR.NotSupported_Export_MultiplePrivateCerts); } privateCert = cert; var certPal = (OpenSslX509CertificateReader)cert.Pal; privateCertHandle = certPal.SafeHandle; privateCertKeyHandle = certPal.PrivateKeyHandle; } else { PushHandle(cert.Handle, publicCerts); } } } using (SafePkcs12Handle pkcs12 = Interop.Crypto.Pkcs12Create( password, privateCertKeyHandle, privateCertHandle, publicCerts)) { if (pkcs12.IsInvalid) { throw Interop.Crypto.CreateOpenSslCryptographicException(); } var result = Interop.Crypto.OpenSslEncode( Interop.Crypto.GetPkcs12DerSize, Interop.Crypto.EncodePkcs12, pkcs12); // ensure certs handle isn't finalized while raw handle(s) is in use GC.KeepAlive(_certs); return(result); } } }
internal static extern int EvpPKeySize(SafeEvpPKeyHandle pkey);
//TODO (Issue #3362) Set remote certificate options internal static IntPtr AllocateSslContext(long options, SafeX509Handle certHandle, SafeEvpPKeyHandle certKeyHandle, bool isServer, bool remoteCertRequired) { SslContext sslContext = new SslContext { isServer = isServer, }; try { IntPtr method = GetSslMethod(isServer, options); IntPtr contextPtr = libssl.SSL_CTX_new(method); if (IntPtr.Zero == contextPtr) { throw CreateSslException("Failed to allocate SSL/TLS context"); } libssl.SSL_CTX_ctrl(contextPtr, libssl.SSL_CTRL_OPTIONS, options, IntPtr.Zero); libssl.SSL_CTX_set_quiet_shutdown(contextPtr, 1); if (certHandle != null && certKeyHandle != null) { SetSslCertificate(contextPtr, certHandle, certKeyHandle); } sslContext.sslPtr = libssl.SSL_new(contextPtr); libssl.SSL_CTX_free(contextPtr); if (IntPtr.Zero == sslContext.sslPtr) { throw CreateSslException("Failed to create SSSL object from SSL context"); } IntPtr memMethod = libcrypto.BIO_s_mem(); if (IntPtr.Zero == memMethod) { throw CreateSslException("Failed to return memory BIO method function"); } sslContext.readBioPtr = libssl.BIO_new(memMethod); sslContext.writeBioPtr = libssl.BIO_new(memMethod); if ((IntPtr.Zero == sslContext.readBioPtr) || (IntPtr.Zero == sslContext.writeBioPtr)) { FreeBio(sslContext); throw CreateSslException("Failed to retun new BIO for a given method type"); } if (isServer) { libssl.SSL_set_accept_state(sslContext.sslPtr); } else { libssl.SSL_set_connect_state(sslContext.sslPtr); } libssl.SSL_set_bio(sslContext.sslPtr, sslContext.readBioPtr, sslContext.writeBioPtr); } catch { Disconnect(sslContext.sslPtr); throw; } IntPtr sslContextPtr = Marshal.AllocHGlobal(Marshal.SizeOf <SslContext>()); Marshal.StructureToPtr(sslContext, sslContextPtr, false); return(sslContextPtr); }
public static void VerifyDuplicateKey_NullHandle() { SafeEvpPKeyHandle pkey = null; Assert.Throws <ArgumentNullException>(() => new RSAOpenSsl(pkey)); }
internal static extern int SSL_CTX_use_PrivateKey(IntPtr ssl, SafeEvpPKeyHandle keyPtr);
private static partial SafeEvpPKeyHandle CryptoNative_EvpPKeyDuplicate( SafeEvpPKeyHandle currentKey, EvpAlgorithmId algorithmId);
internal static extern SafeEcKeyHandle EvpPkeyGetEcKey(SafeEvpPKeyHandle pkey);
public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle);
internal static extern bool EvpPkeySetEcKey(SafeEvpPKeyHandle pkey, SafeEcKeyHandle key);
public ECDsaOpenSsl (SafeEvpPKeyHandle pkeyHandle) { throw new NotImplementedException (); }
public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle) { throw new NotImplementedException(); }