public RSA GetRSAPrivateKey()
        {
            if (_privateKey == null || _privateKey.IsInvalid)
            {
                return(null);
            }

            using (SafeRsaHandle rsaHandle = Interop.libcrypto.EVP_PKEY_get1_RSA(_privateKey))
            {
                return(new RSAOpenSsl(rsaHandle.DangerousGetHandle()));
            }
        }
Пример #2
0
        internal static unsafe RSAParameters ExportRsaParameters(SafeRsaHandle key, bool includePrivateParameters)
        {
            Debug.Assert(
                key != null && !key.IsInvalid,
                "Callers should check the key is invalid and throw an exception with a message");

            if (key == null || key.IsInvalid)
            {
                throw new CryptographicException();
            }

            RSAParameters rsaParameters;
            bool          addedRef = false;

            try
            {
                key.DangerousAddRef(ref addedRef);
                RSA_ST *rsaStructure = (RSA_ST *)key.DangerousGetHandle();

                int modulusSize = RSA_size(key);

                // RSACryptoServiceProvider expects P, DP, Q, DQ, and InverseQ to all
                // be padded up to half the modulus size.
                int halfModulus = modulusSize / 2;

                rsaParameters = new RSAParameters
                {
                    Modulus  = Crypto.ExtractBignum(rsaStructure->n, modulusSize),
                    Exponent = Crypto.ExtractBignum(rsaStructure->e, 0),
                };

                if (includePrivateParameters)
                {
                    rsaParameters.D        = Crypto.ExtractBignum(rsaStructure->d, modulusSize);
                    rsaParameters.P        = Crypto.ExtractBignum(rsaStructure->p, halfModulus);
                    rsaParameters.DP       = Crypto.ExtractBignum(rsaStructure->dmp1, halfModulus);
                    rsaParameters.Q        = Crypto.ExtractBignum(rsaStructure->q, halfModulus);
                    rsaParameters.DQ       = Crypto.ExtractBignum(rsaStructure->dmq1, halfModulus);
                    rsaParameters.InverseQ = Crypto.ExtractBignum(rsaStructure->iqmp, halfModulus);
                }
            }
            finally
            {
                if (addedRef)
                {
                    key.DangerousRelease();
                }
            }

            return(rsaParameters);
        }
Пример #3
0
        public override unsafe void ImportParameters(RSAParameters parameters)
        {
            ValidateParameters(ref parameters);

            SafeRsaHandle key      = Interop.libcrypto.RSA_new();
            bool          imported = false;

            CheckInvalidNewKey(key);

            try
            {
                Interop.libcrypto.RSA_ST *rsaStructure = (Interop.libcrypto.RSA_ST *)key.DangerousGetHandle();

                // RSA_free is going to take care of freeing any of these as long as they successfully
                // get assigned.

                // CreateBignumPtr returns IntPtr.Zero for null input, so this just does the right thing
                // on a public-key-only set of RSAParameters.
                rsaStructure->n    = Interop.libcrypto.CreateBignumPtr(parameters.Modulus);
                rsaStructure->e    = Interop.libcrypto.CreateBignumPtr(parameters.Exponent);
                rsaStructure->d    = Interop.libcrypto.CreateBignumPtr(parameters.D);
                rsaStructure->p    = Interop.libcrypto.CreateBignumPtr(parameters.P);
                rsaStructure->dmp1 = Interop.libcrypto.CreateBignumPtr(parameters.DP);
                rsaStructure->q    = Interop.libcrypto.CreateBignumPtr(parameters.Q);
                rsaStructure->dmq1 = Interop.libcrypto.CreateBignumPtr(parameters.DQ);
                rsaStructure->iqmp = Interop.libcrypto.CreateBignumPtr(parameters.InverseQ);

                imported = true;
            }
            finally
            {
                if (!imported)
                {
                    key.Dispose();
                }
            }

            FreeKey();
            _key = new Lazy <SafeRsaHandle>(() => key, LazyThreadSafetyMode.None);

            // Set base.KeySize directly, since we don't want to free the key
            // (which we would do if the keysize changed on import)
            base.KeySize = 8 * Interop.libcrypto.RSA_size(key);
        }