/// <include file='doc\DSACryptoServiceProvider.uex' path='docs/doc[@for="DSACryptoServiceProvider.ImportParameters"]/*' />
        public override void ImportParameters(DSAParameters parameters)
        {
            if (_CSPHandleProtector.IsClosed || _KeyHandleProtector.IsClosed)
            {
                throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic_ObjectName1"));
            }

            DSACspObject dsaKey = new DSACspObject();

            // P, Q, G are required
            if (parameters.P == null)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_MissingField"));
            }
            dsaKey.P = (byte[])parameters.P.Clone();
            if (parameters.Q == null)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_MissingField"));
            }
            dsaKey.Q = (byte[])parameters.Q.Clone();
            if (parameters.G == null)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_MissingField"));
            }
            dsaKey.G = (byte[])parameters.G.Clone();

            //  Y is not required
            dsaKey.Y = (parameters.Y == null ? null : ((byte[])parameters.Y.Clone()));
            //  J is not required
            dsaKey.J = (parameters.J == null ? null : ((byte[])parameters.J.Clone()));

            //  seed is not required
            dsaKey.seed = (parameters.Seed == null ? null : ((byte[])parameters.Seed.Clone()));
            //  counter is not required
            dsaKey.counter = parameters.Counter;
            //  X is not required -- private component
            dsaKey.X = (parameters.X == null ? null : ((byte[])parameters.X.Clone()));

            // NOTE: We must reverse the dsaKey before importing!
            ReverseDSACspObject(dsaKey);
            // Free the current key handle
            _KeyHandleProtector.Close();
            // Now, import the key into the CSP
            bool incremented = false;

            try {
                if (_CSPHandleProtector.TryAddRef(ref incremented))
                {
                    _hKey = _ImportKey(_CSPHandleProtector.Handle, CALG_DSA_SIGN, dsaKey);
                }
                else
                {
                    throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic_ObjectName1"));
                }
            }
            finally {
                if (incremented)
                {
                    _CSPHandleProtector.Release();
                }
            }

            _KeyHandleProtector   = new __KeyHandleProtector(_hKey);
            _parameters.KeyNumber = AT_SIGNATURE;
            if (dsaKey.X == null)
            {
                // If no X, then only have the public
                _containerContents = KeyContainerContents.PublicOnly;
            }
            else
            {
                // Our key pairs are always exportable
                _containerContents = KeyContainerContents.PublicAndExportablePrivate;
            }
            // zeroize private key material
            if (dsaKey.X != null)
            {
                Array.Clear(dsaKey.X, 0, dsaKey.X.Length);
            }
        }
        /// <include file='doc\RSACryptoServiceProvider.uex' path='docs/doc[@for="RSACryptoServiceProvider.ImportParameters"]/*' />
        public override void ImportParameters(RSAParameters parameters)
        {
            if (_CSPHandleProtector.IsClosed || _KeyHandleProtector.IsClosed)
            {
                throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic_ObjectName1"));
            }

            RSACspObject rsaKey = new RSACspObject();

            // Modulus is required for both public & private keys
            if (parameters.Modulus == null)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_MissingField"));
            }
            rsaKey.Modulus = (byte[])parameters.Modulus.Clone();
            // Exponent is required
            byte[] rgbExponent = parameters.Exponent;
            if (rgbExponent == null)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_MissingField"));
            }
            rsaKey.Exponent = ConvertByteArrayToInt(rgbExponent);
            // p is optional
            rsaKey.P = (parameters.P == null ? null : ((byte[])parameters.P.Clone()));
            // q is optional
            rsaKey.Q = (parameters.Q == null ? null : ((byte[])parameters.Q.Clone()));
            // dp is optional
            rsaKey.dp = (parameters.DP == null ? null : ((byte[])parameters.DP.Clone()));
            // dq is optional
            rsaKey.dq = (parameters.DQ == null ? null : ((byte[])parameters.DQ.Clone()));
            // InverseQ is optional
            rsaKey.InverseQ = (parameters.InverseQ == null ? null : ((byte[])parameters.InverseQ.Clone()));
            // d is optional
            rsaKey.d = (parameters.D == null ? null : ((byte[])parameters.D.Clone()));

            // NOTE: We must reverse the rsaKey before importing!
            ReverseRSACspObject(rsaKey);
            // Free the current key handle
            _KeyHandleProtector.Close();
            // Now, import the key into the CSP
            bool incremented = false;

            try {
                if (_CSPHandleProtector.TryAddRef(ref incremented))
                {
                    _hKey = _ImportKey(_CSPHandleProtector.Handle, CALG_RSA_KEYX, rsaKey);
                }
                else
                {
                    throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic_ObjectName1"));
                }
            }
            finally {
                if (incremented)
                {
                    _CSPHandleProtector.Release();
                }
            }

            _KeyHandleProtector   = new __KeyHandleProtector(_hKey);
            _parameters.KeyNumber = AT_KEYEXCHANGE;
            // reset _containerContents
            if (rsaKey.P == null)
            {
                _containerContents = KeyContainerContents.PublicOnly;
            }
            else
            {
                // Our key pairs are always exportable
                _containerContents = KeyContainerContents.PublicAndExportablePrivate;
            }
            // zeroize private info
            if (rsaKey.d != null)
            {
                Array.Clear(rsaKey.d, 0, rsaKey.d.Length);
            }
            if (rsaKey.P != null)
            {
                Array.Clear(rsaKey.P, 0, rsaKey.P.Length);
            }
            if (rsaKey.Q != null)
            {
                Array.Clear(rsaKey.Q, 0, rsaKey.Q.Length);
            }
            if (rsaKey.dp != null)
            {
                Array.Clear(rsaKey.dp, 0, rsaKey.dp.Length);
            }
            if (rsaKey.dq != null)
            {
                Array.Clear(rsaKey.dq, 0, rsaKey.dq.Length);
            }
            if (rsaKey.InverseQ != null)
            {
                Array.Clear(rsaKey.InverseQ, 0, rsaKey.InverseQ.Length);
            }
        }
        /// <include file='doc\DSACryptoServiceProvider.uex' path='docs/doc[@for="DSACryptoServiceProvider.DSACryptoServiceProvider3"]/*' />
        public DSACryptoServiceProvider(int dwKeySize, CspParameters parameters)
        {
            int hr;

            //
            //  Save the CSP Parameters
            //

            if (parameters == null)
            {
                _parameters = new CspParameters(PROV_DSS_DH, null, null, m_UseMachineKeyStore);
            }
            else
            {
                // Check the parameter options: specifying either a key container name or UseDefaultKeyContainer flag
                // requires unmanaged code permission
                if (((parameters.Flags & CspProviderFlags.UseDefaultKeyContainer) != 0) ||
                    ((parameters.KeyContainerName != null) && (parameters.KeyContainerName.Length > 0)))
                {
                    _UCpermission.Demand();
                    // If we specified a key container name for this key, then mark it persisted
                    if ((parameters.KeyContainerName != null) && (parameters.KeyContainerName.Length > 0))
                    {
                        // CAPI doesn't accept Container Names longer than 260 characters
                        if (parameters.KeyContainerName.Length > 260)
                        {
                            throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeyContainerName"));
                        }
                        _persistKeyInCSP = true;
                    }
                }
                _parameters = parameters;
            }

            //
            //  Create the CSP container for this set of keys
            //

            _hCSP = IntPtr.Zero;
            _hKey = IntPtr.Zero;
            hr    = _CreateCSP(_parameters, ref _hCSP);
            if (hr != 0)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CouldNotAcquire"));
            }
            if (_hCSP == IntPtr.Zero)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CouldNotAcquire"));
            }

            //
            //  If no key spec has been specified, then set it to be
            //      AT_KEYEXCHANGE,  if a CALG_* has been specified, then
            //      map that to AT_* value
            if (_parameters.KeyNumber == -1)
            {
                _parameters.KeyNumber = AT_SIGNATURE;
            }
            else if (_parameters.KeyNumber == CALG_DSA_SIGN)
            {
                _parameters.KeyNumber = AT_SIGNATURE;
            }

            // If the key already exists, use it, else generate a new one
            hr = _GetUserKey(_hCSP, _parameters.KeyNumber, ref _hKey);
            if (hr != 0)
            {
                _hKey = _GenerateKey(_hCSP, _parameters.KeyNumber, dwKeySize << 16);
                if (_hKey == IntPtr.Zero)
                {
                    throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CreateKey"));
                }
                // We just gen'd a new key pair, so we have both halves.
                _containerContents = KeyContainerContents.PublicAndExportablePrivate;
            }
            else
            {
                // If the key already exists, make sure to persist it
                _persistKeyInCSP   = true;
                _containerContents = KeyContainerContents.Unknown;
            }

            _dwKeySize = dwKeySize;

            // Create the Hash instance
            sha1 = SHA1.Create();

            _CSPHandleProtector = new __CSPHandleProtector(_hCSP, _persistKeyInCSP, _parameters);
            _KeyHandleProtector = new __KeyHandleProtector(_hKey);
        }
        internal RSACryptoServiceProvider(int dwKeySize, CspParameters parameters, bool useDefaultKeySize)
        {
            int hr;

            //
            //  Save the CSP Parameters
            //

            if (parameters == null)
            {
                _parameters = new CspParameters(1, null, null, m_UseMachineKeyStore);
            }
            else
            {
                // Check the parameter options: specifying either a key container name or UseDefaultKeyContainer flag
                // requires unmanaged code permission
                if (((parameters.Flags & CspProviderFlags.UseDefaultKeyContainer) != 0) ||
                    ((parameters.KeyContainerName != null) && (parameters.KeyContainerName.Length > 0)))
                {
                    _UCpermission.Demand();
                    // If we specified a key container name for this key, then mark it persisted
                    if ((parameters.KeyContainerName != null) && (parameters.KeyContainerName.Length > 0))
                    {
                        // CAPI doesn't accept Container Names longer than 260 characters
                        if (parameters.KeyContainerName.Length > 260)
                        {
                            throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeyContainerName"));
                        }

                        _persistKeyInCSP = true;
                    }
                }
                _parameters = parameters;
            }


            //
            //  If no key spec has been specified, then set it to be
            //      AT_KEYEXCHANGE,  if a CALG_* has been specified, then
            //      map that to AT_* value
            if (_parameters.KeyNumber == -1)
            {
                _parameters.KeyNumber = AT_KEYEXCHANGE;
            }
            else if (_parameters.KeyNumber == CALG_RSA_KEYX)
            {
                _parameters.KeyNumber = AT_KEYEXCHANGE;
            }
            else if (_parameters.KeyNumber == CALG_RSA_SIGN)
            {
                _parameters.KeyNumber = AT_SIGNATURE;
            }

            // See if we have the Enhanced RSA provider on this machine
            _hasEnhancedProvider = HasEnhancedProvider();

            // Now determine legal key sizes.  If AT_SIGNATURE, then 384 -- 16386.  Otherwise, depends on
            // whether the strong provider is present.

            if (_parameters.KeyNumber == AT_SIGNATURE)
            {
                LegalKeySizesValue = new KeySizes[1] {
                    new KeySizes(384, 16384, 8)
                };
            }
            else if (_hasEnhancedProvider)
            {
                // it is, we have the strong provider
                LegalKeySizesValue = new KeySizes[1] {
                    new KeySizes(384, 16384, 8)
                };
            }
            else
            {
                // nope, all we have is the base provider
                LegalKeySizesValue = new KeySizes[1] {
                    new KeySizes(384, 512, 8)
                };
                // tone down the default key size
                _defaultKeySize = 512;
            }
            // Set the key size; this will throw an exception if dwKeySize is invalid.
            // Don't check if dwKeySize == 0, since that's the "default size", however
            // *our* default should be 1024 if the CSP can handle it.  So, if the
            // key size was unspecified in a constructor to us, it'll be -1 here and
            // change it to the default size.  If the user really put in a 0 give him back
            // the default for the CSP whatever it is.
            if (useDefaultKeySize)
            {
                dwKeySize = _defaultKeySize;
            }
            if (dwKeySize != 0)
            {
                KeySize = dwKeySize;
            }
            _dwKeySize = dwKeySize;

            //
            //  Create the CSP container for this set of keys
            //
            _hCSP = IntPtr.Zero;
            _hKey = IntPtr.Zero;
            hr    = _CreateCSP(_parameters, ref _hCSP);
            if (hr != 0)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CouldNotAcquire"));
            }
            if (_hCSP == IntPtr.Zero)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CouldNotAcquire"));
            }

            // If the key already exists, use it, else generate a new one
            hr = _GetUserKey(_hCSP, _parameters.KeyNumber, ref _hKey);
            if (hr != 0)
            {
                _hKey = _GenerateKey(_hCSP, _parameters.KeyNumber, dwKeySize << 16);
                if (_hKey == IntPtr.Zero)
                {
                    throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CreateKey"));
                }
                // We just gen'd a new key pair, so we have both halves.
                _containerContents = KeyContainerContents.PublicAndExportablePrivate;
            }
            else
            {
                // If the key already exists, make sure to persist it
                _persistKeyInCSP = true;
                // we have both halves, but we don't know if it's exportable or not
                _containerContents = KeyContainerContents.Unknown;
            }

            _CSPHandleProtector = new __CSPHandleProtector(_hCSP, _persistKeyInCSP, _parameters);
            _KeyHandleProtector = new __KeyHandleProtector(_hKey);
        }