예제 #1
0
 public static void VerifyDuplicateKey_NeverValidHandle()
 {
     using (SafeEvpPKeyHandle pkey = new SafeEvpPKeyHandle(IntPtr.Zero, false))
     {
         Assert.Throws<ArgumentException>(() => new DSAOpenSsl(pkey));
     }
 }
예제 #2
0
 internal static extern int UpRefEvpPkey(SafeEvpPKeyHandle handle);
 internal static extern int SslCtxUsePrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);
예제 #4
0
 internal static partial SafeEvpPKeyCtxHandle EvpPKeyCtxCreate(SafeEvpPKeyHandle pkey, SafeEvpPKeyHandle peerkey, out uint secretLength);
예제 #5
0
        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");
            }
        }
예제 #6
0
 internal void SetPrivateKey(SafeEvpPKeyHandle privateKey)
 {
     _privateKey = privateKey;
 }
예제 #7
0
 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);
        }
예제 #10
0
 internal static partial int EvpPKeySize(SafeEvpPKeyHandle pkey);
예제 #11
0
 internal static partial int UpRefEvpPkey(SafeEvpPKeyHandle handle);
예제 #12
0
 internal static extern int SSL_CTX_use_PrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);
예제 #13
0
 internal static extern bool EVP_PKEY_set1_EC_KEY(SafeEvpPKeyHandle pkey, SafeEcKeyHandle rsa);
예제 #14
0
 internal static extern SafeEcKeyHandle EVP_PKEY_get1_EC_KEY(SafeEvpPKeyHandle pkey);
 public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle);
예제 #16
0
        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);
        }
예제 #17
0
            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);
                }
            }
예제 #18
0
 internal static partial int SslUsePrivateKey(SafeSslHandle ssl, SafeEvpPKeyHandle keyPtr);
예제 #19
0
 internal static partial SafeEcKeyHandle EvpPkeyGetEcKey(SafeEvpPKeyHandle pkey);
예제 #20
0
        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);
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
        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);
        }
예제 #23
0
        //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);
        }
예제 #24
0
        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);
                }
            }
        }
예제 #25
0
 internal static extern int EvpPKeySize(SafeEvpPKeyHandle pkey);
예제 #26
0
        //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);
        }
예제 #27
0
        public static void VerifyDuplicateKey_NullHandle()
        {
            SafeEvpPKeyHandle pkey = null;

            Assert.Throws <ArgumentNullException>(() => new RSAOpenSsl(pkey));
        }
예제 #28
0
 internal static extern int SSL_CTX_use_PrivateKey(IntPtr ssl, SafeEvpPKeyHandle keyPtr);
예제 #29
0
 private static partial SafeEvpPKeyHandle CryptoNative_EvpPKeyDuplicate(
     SafeEvpPKeyHandle currentKey,
     EvpAlgorithmId algorithmId);
예제 #30
0
 internal static extern SafeEcKeyHandle EvpPkeyGetEcKey(SafeEvpPKeyHandle pkey);
 public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle);
예제 #32
0
 internal static extern bool EvpPkeySetEcKey(SafeEvpPKeyHandle pkey, SafeEcKeyHandle key);
예제 #33
0
		public ECDsaOpenSsl (SafeEvpPKeyHandle pkeyHandle)
		{
			throw new NotImplementedException ();
		}
예제 #34
0
 public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle)
 {
     throw new NotImplementedException();
 }