Inheritance: System.Runtime.InteropServices.SafeHandle
        /// <summary>
        /// Create another instance of SafeEvpPKeyHandle which has an independent lifetime
        /// from this instance, but tracks the same resource.
        /// </summary>
        /// <returns>An equivalent SafeEvpPKeyHandle with a different lifetime</returns>
        public SafeEvpPKeyHandle DuplicateHandle()
        {
            if (IsInvalid)
                throw new InvalidOperationException(SR.Cryptography_OpenInvalidHandle);

            // Reliability: Allocate the SafeHandle before calling UpRefEvpPkey so
            // that we don't lose a tracked reference in low-memory situations.
            SafeEvpPKeyHandle safeHandle = new SafeEvpPKeyHandle();

            int newRefCount = Interop.Crypto.UpRefEvpPkey(this);

            // UpRefEvpPkey returns the number of references to this key, if it's less than 2
            // (the incoming handle, and this one) then someone has already Disposed() this key
            // into non-existence.
            if (newRefCount < 2)
            {
                Debug.Fail("Called UpRefEvpPkey on a key which was already marked for destruction");
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }

            // Since we didn't actually create a new handle, copy the handle
            // to the new SafeHandle.
            safeHandle.SetHandle(handle);
            return safeHandle;
        }
        public void Dispose()
        {
            if (_caStackHandle != null)
            {
                _caStackHandle.Dispose();
                _caStackHandle = null;
            }

            if (_x509Handle != null)
            {
                _x509Handle.Dispose();
                _x509Handle = null;
            }

            if (_evpPkeyHandle != null)
            {
                _evpPkeyHandle.Dispose();
                _evpPkeyHandle = null;
            }

            if (_pkcs12Handle != null)
            {
                _pkcs12Handle.Dispose();
            }
        }
        //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(SR.net_allocate_ssl_context_failed);
                }

                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(SR.net_allocate_ssl_context_failed);
                }
            }

            return context;
        }
        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;
        }
 internal static extern SafePkcs12Handle PKCS12_create(
     string pass,
     string name,
     SafeEvpPKeyHandle pkey,
     SafeX509Handle cert,
     SafeX509StackHandle ca,
     int nid_key,
     int nid_cert,
     int iter,
     int mac_iter,
     int keytype);
Exemple #6
0
        /// <summary>
        /// Create an ECDsaOpenSsl from an <see cref="SafeEvpPKeyHandle"/> whose value is an existing
        /// OpenSSL <c>EVP_PKEY*</c> wrapping an <c>EC_KEY*</c>
        /// </summary>
        /// <param name="pkeyHandle">A SafeHandle for an OpenSSL <c>EVP_PKEY*</c></param>
        /// <exception cref="ArgumentNullException"><paramref name="pkeyHandle"/> is <c>null</c></exception>
        /// <exception cref="ArgumentException"><paramref name="pkeyHandle"/> <see cref="SafeHandle.IsInvalid" /></exception>
        /// <exception cref="CryptographicException"><paramref name="pkeyHandle"/> is not a valid enveloped <c>EC_KEY*</c></exception>
        public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle)
        {
            if (pkeyHandle == null)
                throw new ArgumentNullException(nameof(pkeyHandle));
            if (pkeyHandle.IsInvalid)
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));

            // If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is.
            SafeEcKeyHandle key = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle);
            if (key.IsInvalid)
                throw Interop.Crypto.CreateOpenSslCryptographicException();

            SetKey(key);
        }
Exemple #7
0
        internal static SafeSslHandle AllocateSslContext(long options, SafeX509Handle certHandle, SafeEvpPKeyHandle certKeyHandle, string encryptionPolicy, bool isServer, bool remoteCertRequired)
        {
            SafeSslHandle context = null;

            IntPtr method = GetSslMethod(isServer, options);

            using (libssl.SafeSslContextHandle innerContext = Ssl.SslCtxCreate(method))
            {
                if (innerContext.IsInvalid)
                {
                    throw CreateSslException(SR.net_allocate_ssl_context_failed);
                }

                libssl.SSL_CTX_ctrl(innerContext, libssl.SSL_CTRL_OPTIONS, options, IntPtr.Zero);

                libssl.SSL_CTX_set_quiet_shutdown(innerContext, 1);

                libssl.SSL_CTX_set_cipher_list(innerContext, encryptionPolicy);

                if (certHandle != null && certKeyHandle != null)
                {
                    SetSslCertificate(innerContext, certHandle, certKeyHandle);
                }

                if (remoteCertRequired)
                {
                    Debug.Assert(isServer, "isServer flag should be true");
                    libssl.SSL_CTX_set_verify(innerContext,
                        (int)libssl.ClientCertOption.SSL_VERIFY_PEER |
                        (int)libssl.ClientCertOption.SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                        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;
        }
        public SafeFreeSslCredentials(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy)
            : base(IntPtr.Zero, true)
        {
            Debug.Assert(
                certificate == null || certificate is X509Certificate2,
                "Only X509Certificate2 certificates are supported at this time");

            X509Certificate2 cert = (X509Certificate2)certificate;

            if (cert != null)
            {
                Debug.Assert(cert.HasPrivateKey, "cert.HasPrivateKey");

                using (RSAOpenSsl rsa = (RSAOpenSsl)cert.GetRSAPrivateKey())
                {
                    if (rsa != null)
                    {
                        _certKeyHandle = rsa.DuplicateKeyHandle();
                        Interop.Crypto.CheckValidOpenSslHandle(_certKeyHandle);
                    }
                }

                if (_certKeyHandle == null)
                {
                    using (ECDsaOpenSsl ecdsa = (ECDsaOpenSsl)cert.GetECDsaPrivateKey())
                    {
                        if (ecdsa != null)
                        {
                            _certKeyHandle = ecdsa.DuplicateKeyHandle();
                            Interop.Crypto.CheckValidOpenSslHandle(_certKeyHandle);
                        }
                    }
                }

                if (_certKeyHandle == null)
                {
                    throw new NotSupportedException(SR.net_ssl_io_no_server_cert);
                }

                _certHandle = Interop.Crypto.X509UpRef(cert.Handle);
                Interop.Crypto.CheckValidOpenSslHandle(_certHandle);
            }

            _protocols = protocols;
            _policy = policy;
        }
        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;
        }
Exemple #10
0
        /// <summary>
        /// Create an RSAOpenSsl from an <see cref="SafeEvpPKeyHandle"/> whose value is an existing
        /// OpenSSL <c>EVP_PKEY*</c> wrapping an <c>RSA*</c>
        /// </summary>
        /// <param name="pkeyHandle">A SafeHandle for an OpenSSL <c>EVP_PKEY*</c></param>
        /// <exception cref="ArgumentNullException"><paramref name="pkeyHandle"/> is <c>null</c></exception>
        /// <exception cref="ArgumentException">
        ///   <paramref name="pkeyHandle"/> <see cref="Runtime.InteropServices.SafeHandle.IsInvalid" />
        /// </exception>
        /// <exception cref="CryptographicException"><paramref name="pkeyHandle"/> is not a valid enveloped <c>RSA*</c></exception>
        public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle)
        {
            if (pkeyHandle == null)
                throw new ArgumentNullException(nameof(pkeyHandle));
            if (pkeyHandle.IsInvalid)
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));

            // If rsa is valid it has already been up-ref'd, so we can just use this handle as-is.
            SafeRsaHandle rsa = Interop.Crypto.EvpPkeyGetRsa(pkeyHandle);

            if (rsa.IsInvalid)
            {
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }

            // Set base.KeySize rather than this.KeySize to avoid an unnecessary Lazy<> allocation.
            base.KeySize = BitsPerByte * Interop.Crypto.RsaSize(rsa);
            _key = new Lazy<SafeRsaHandle>(() => rsa);
        }
Exemple #11
0
        /// <summary>
        /// Create an ECDsaOpenSsl from an <see cref="SafeEvpPKeyHandle"/> whose value is an existing
        /// OpenSSL <c>EVP_PKEY*</c> wrapping an <c>EC_KEY*</c>
        /// </summary>
        /// <param name="pkeyHandle">A SafeHandle for an OpenSSL <c>EVP_PKEY*</c></param>
        /// <exception cref="ArgumentNullException"><paramref name="pkeyHandle"/> is <c>null</c></exception>
        /// <exception cref="ArgumentException"><paramref name="pkeyHandle"/> <see cref="SafeHandle.IsInvalid" /></exception>
        /// <exception cref="CryptographicException"><paramref name="pkeyHandle"/> is not a valid enveloped <c>EC_KEY*</c></exception>
        public ECDsaOpenSsl(SafeEvpPKeyHandle pkeyHandle)
        {
            if (pkeyHandle == null)
                throw new ArgumentNullException("pkeyHandle");
            if (pkeyHandle.IsInvalid)
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, "pkeyHandle");

            // If ecKey is valid it has already been up-ref'd, so we can just use this handle as-is.
            SafeEcKeyHandle ecKey = Interop.Crypto.EvpPkeyGetEcKey(pkeyHandle);

            if (ecKey.IsInvalid)
            {
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }

            // Set base.KeySize rather than this.KeySize to avoid an unnecessary Lazy<> allocation.
            base.KeySize = GetKeySize(ecKey);
            _key = new Lazy<SafeEcKeyHandle>(() => ecKey);
        }
Exemple #12
0
        /// <summary>
        /// Create an RSAOpenSsl from an <see cref="SafeEvpPKeyHandle"/> whose value is an existing
        /// OpenSSL <c>EVP_PKEY*</c> wrapping an <c>RSA*</c>
        /// </summary>
        /// <param name="pkeyHandle">A SafeHandle for an OpenSSL <c>EVP_PKEY*</c></param>
        /// <exception cref="ArgumentNullException"><paramref name="pkeyHandle"/> is <c>null</c></exception>
        /// <exception cref="ArgumentException">
        ///   <paramref name="pkeyHandle"/> <see cref="Runtime.InteropServices.SafeHandle.IsInvalid" />
        /// </exception>
        /// <exception cref="CryptographicException"><paramref name="pkeyHandle"/> is not a valid enveloped <c>RSA*</c></exception>
        public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle)
        {
            if (pkeyHandle == null)
                throw new ArgumentNullException(nameof(pkeyHandle));
            if (pkeyHandle.IsInvalid)
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(pkeyHandle));

            // If rsa is valid it has already been up-ref'd, so we can just use this handle as-is.
            SafeRsaHandle rsa = Interop.Crypto.EvpPkeyGetRsa(pkeyHandle);

            if (rsa.IsInvalid)
            {
                throw Interop.Crypto.CreateOpenSslCryptographicException();
            }

            // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere
            // with the already loaded key.
            ForceSetKeySize(BitsPerByte * Interop.Crypto.RsaSize(rsa));
            _key = new Lazy<SafeRsaHandle>(() => rsa);
        }
Exemple #13
0
        /// <summary>
        /// Create an ECDsaOpenSsl from an <see cref="SafeEvpPKeyHandle"/> whose value is an existing
        /// OpenSSL <c>EVP_PKEY*</c> wrapping an <c>RSA*</c>
        /// </summary>
        /// <param name="pkeyHandle">A SafeHandle for an OpenSSL <c>EVP_PKEY*</c></param>
        /// <exception cref="ArgumentNullException"><paramref name="pkeyHandle"/> is <c>null</c></exception>
        /// <exception cref="ArgumentException">
        ///   <paramref name="pkeyHandle"/> <see cref="Runtime.InteropServices.SafeHandle.IsInvalid" />
        /// </exception>
        /// <exception cref="CryptographicException"><paramref name="pkeyHandle"/> is not a valid enveloped <c>RSA*</c></exception>
        public RSAOpenSsl(SafeEvpPKeyHandle pkeyHandle)
        {
            if (pkeyHandle == null)
                throw new ArgumentNullException("pkeyHandle");
            if (pkeyHandle.IsInvalid)
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, "pkeyHandle");

            // If rsa is valid it has already been up-ref'd, so we can just use this handle as-is.
            SafeRsaHandle rsa = Interop.libcrypto.EVP_PKEY_get1_RSA(pkeyHandle);

            if (rsa.IsInvalid)
            {
                throw Interop.libcrypto.CreateOpenSslCryptographicException();
            }

            _legalKeySizesValue = new[] { s_legalKeySizes };

            // Set base.KeySize rather than this.KeySize to avoid an unnecessary Lazy<> allocation.
            base.KeySize = BitsPerByte * Interop.libcrypto.RSA_size(rsa);
            _key = new Lazy<SafeRsaHandle>(() => rsa);
        }
 internal static extern bool EvpPkeySetRsa(SafeEvpPKeyHandle pkey, SafeRsaHandle rsa);
 internal static extern SafeRsaHandle EvpPkeyGetRsa(SafeEvpPKeyHandle pkey);
Exemple #16
0
        public List<OpenSslX509CertificateReader> ReadCertificates()
        {
            var certs = new List<OpenSslX509CertificateReader>();

            if (_caStackHandle != null && !_caStackHandle.IsInvalid)
            {
                int caCertCount = Interop.Crypto.GetX509StackFieldCount(_caStackHandle);

                for (int i = 0; i < caCertCount; i++)
                {
                    IntPtr certPtr = Interop.Crypto.GetX509StackField(_caStackHandle, i);

                    if (certPtr != IntPtr.Zero)
                    {
                        // The STACK_OF(X509) still needs to be cleaned up, so upref the handle out of it.
                        certs.Add(new OpenSslX509CertificateReader(Interop.Crypto.X509UpRef(certPtr)));
                    }
                }
            }

            if (_x509Handle != null && !_x509Handle.IsInvalid)
            {
                // The certificate and (if applicable) private key handles will be given over
                // to the OpenSslX509CertificateReader, and the fields here are thus nulled out to
                // prevent double-Dispose.
                OpenSslX509CertificateReader reader = new OpenSslX509CertificateReader(_x509Handle);
                _x509Handle = null;

                if (_evpPkeyHandle != null && !_evpPkeyHandle.IsInvalid)
                {
                    reader.SetPrivateKey(_evpPkeyHandle);
                    _evpPkeyHandle = null;
                }

                certs.Add(reader);
            }

            return certs;
        }
Exemple #17
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);
            }
        }
 internal void SetPrivateKey(SafeEvpPKeyHandle privateKey)
 {
     _privateKey = privateKey;
 }
Exemple #19
0
        private static void SetSslCertificate(IntPtr 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");
            }
        }
            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;
                    VerboseTrace("libssl's client certificate callback");

                    ISet<string> issuerNames = GetRequestCertificateAuthorities(sslHandle);
                    X509Certificate2 certificate;
                    X509Chain chain;
                    if (!GetClientCertificate(issuerNames, out certificate, out chain))
                    {
                        VerboseTrace("no cert or chain");
                        return 0;
                    }

                    Interop.Crypto.CheckValidOpenSslHandle(certificate.Handle);
                    using (RSAOpenSsl rsa = certificate.GetRSAPrivateKey() as RSAOpenSsl)
                    {
                        if (rsa != null)
                        {
                            _privateKeyHandle = rsa.DuplicateKeyHandle();
                        }
                        else
                        {
                            using (ECDsaOpenSsl ecdsa = certificate.GetECDsaPrivateKey() as ECDsaOpenSsl)
                            {
                                if (ecdsa != null)
                                {
                                    _privateKeyHandle = ecdsa.DuplicateKeyHandle();
                                }
                            }
                        }
                    }

                    if (_privateKeyHandle == null || _privateKeyHandle.IsInvalid)
                    {
                        VerboseTrace("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))
                            {
                                VerboseTrace("failed to add extra chain cert");
                                return -1;
                            }
                        }
                    }

                    certHandle = _certHandle.DangerousGetHandle();
                    privateKeyHandle = _privateKeyHandle.DangerousGetHandle();
                    return 1;
                }
            }
Exemple #21
0
        public override bool TryDecrypt(
            ReadOnlySpan <byte> data,
            Span <byte> destination,
            RSAEncryptionPadding padding,
            out int bytesWritten)
        {
            if (padding == null)
            {
                throw new ArgumentNullException(nameof(padding));
            }

            ValidatePadding(padding);
            SafeEvpPKeyHandle key = GetKey();
            int keySizeBytes      = Interop.Crypto.EvpPKeySize(key);

            // OpenSSL requires that the decryption buffer be at least as large as EVP_PKEY_size.
            // So if the destination is too small, use a temporary buffer so we can match
            // Windows behavior of succeeding so long as the buffer can hold the final output.
            if (destination.Length < keySizeBytes)
            {
                // RSA up through 4096 bits use a stackalloc
                Span <byte> tmp = stackalloc byte[512];
                byte[]? rent = null;

                if (keySizeBytes > tmp.Length)
                {
                    rent = CryptoPool.Rent(keySizeBytes);
                    tmp  = rent;
                }

                int  written = Decrypt(key, data, tmp, padding);
                bool ret;

                if (destination.Length < written)
                {
                    bytesWritten = 0;
                    ret          = false;
                }
                else
                {
                    tmp.Slice(0, written).CopyTo(destination);
                    bytesWritten = written;
                    ret          = true;
                }

                // Whether a stackalloc or a rented array, clear our copy of
                // the decrypted content.
                CryptographicOperations.ZeroMemory(tmp.Slice(0, written));

                if (rent != null)
                {
                    // Already cleared.
                    CryptoPool.Return(rent, clearSize: 0);
                }

                return(ret);
            }

            bytesWritten = Decrypt(key, data, destination, padding);
            return(true);
        }
Exemple #22
0
 internal static extern SafePkcs12Handle Pkcs12Create(
     string pass,
     SafeEvpPKeyHandle pkey,
     SafeX509Handle cert,
     SafeX509StackHandle ca);
Exemple #23
0
 internal static extern int SSL_CTX_use_PrivateKey(IntPtr ssl, SafeEvpPKeyHandle keyPtr);
Exemple #24
0
 internal static extern int SslCtxUsePrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);
        public SafeFreeCredentials(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy)
            : base(IntPtr.Zero, true)
        {
            Debug.Assert(
                certificate == null || certificate is X509Certificate2,
                "Only X509Certificate2 certificates are supported at this time");

            X509Certificate2 cert = (X509Certificate2)certificate;

            if (cert != null)
            {
                Debug.Assert(cert.HasPrivateKey, "cert.HasPrivateKey");

                using (RSAOpenSsl rsa = (RSAOpenSsl)cert.GetRSAPrivateKey())
                {
                    if (rsa != null)
                    {
                        _certKeyHandle = rsa.DuplicateKeyHandle();
                        Interop.libcrypto.CheckValidOpenSslHandle(_certKeyHandle);
                    }
                }

                // TODO (3390): Add support for ECDSA.

                Debug.Assert(_certKeyHandle != null, "Failed to extract a private key handle");

                _certHandle = Interop.libcrypto.X509_dup(cert.Handle);
                Interop.libcrypto.CheckValidOpenSslHandle(_certHandle);
            }

            _protocols = protocols;
            _policy = policy;
        }
 internal static extern SafeEcKeyHandle EVP_PKEY_get1_EC_KEY(SafeEvpPKeyHandle pkey);
 internal static extern bool EVP_PKEY_set1_EC_KEY(SafeEvpPKeyHandle pkey, SafeEcKeyHandle rsa);
        public void Dispose()
        {
            if (_privateKey != null)
            {
                _privateKey.Dispose();
                _privateKey = null;
            }

            if (_cert != null)
            {
                _cert.Dispose();
                _cert = null;
            }
        }
Exemple #29
0
 internal static extern int UpRefEvpPkey(SafeEvpPKeyHandle handle);
Exemple #30
0
 internal static extern bool Pkcs12Parse(
     SafePkcs12Handle p12,
     string pass,
     out SafeEvpPKeyHandle pkey,
     out SafeX509Handle cert,
     out SafeX509StackHandle ca);
Exemple #31
0
 internal static extern int SSL_CTX_use_PrivateKey(SafeSslContextHandle ctx, SafeEvpPKeyHandle keyPtr);