/// <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\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);
        }
Esempio n. 3
0
        // *********************** CONSTRUCTORS *************************

        internal CryptoAPITransform(String strName, int algid, int cArgs, int[] rgArgIds,
                                    Object[] rgArgValues, byte[] rgbKey,
                                    CspParameters param, PaddingMode padding,
                                    CipherMode cipherChainingMode, int blockSize,
                                    int feedbackSize, CryptoAPITransformMode encDecMode)
        {
            int dwValue;
            int hr;
            int i;

            byte[] rgbValue;

            State             = 0;
            NameValue         = strName;
            BlockSizeValue    = blockSize;
            FeedbackSizeValue = feedbackSize;
            ModeValue         = cipherChainingMode;
            PaddingValue      = padding;
            KeySizeValue      = rgbKey.Length * 8;
            _algid            = algid;
            encryptOrDecrypt  = encDecMode;

            // Copy the input args
            _cArgs    = cArgs;
            _rgArgIds = new int[rgArgIds.Length];
            Array.Copy(rgArgIds, _rgArgIds, rgArgIds.Length);
            _rgbKey = new byte[rgbKey.Length];
            Array.Copy(rgbKey, _rgbKey, rgbKey.Length);
            _rgArgValues = new Object[rgArgValues.Length];
            // an element of rgArgValues can only be an int or a byte[]
            for (int j = 0; j < rgArgValues.Length; j++)
            {
                if (rgArgValues[j] is byte[])
                {
                    byte[] rgbOrig = (byte[])rgArgValues[j];
                    byte[] rgbNew  = new byte[rgbOrig.Length];
                    Array.Copy(rgbOrig, rgbNew, rgbOrig.Length);
                    _rgArgValues[j] = rgbNew;
                    continue;
                }
                if (rgArgValues[j] is int)
                {
                    _rgArgValues[j] = (int)rgArgValues[j];
                    continue;
                }
                if (rgArgValues[j] is CipherMode)
                {
                    _rgArgValues[j] = (int)rgArgValues[j];
                    continue;
                }
            }

            _hCSP = IntPtr.Zero;
            //_hMasterKey = IntPtr.Zero;
            _hKey = IntPtr.Zero;

            //  If we have no passed in CSP parameters, use the default ones

            if (param == null)
            {
                _parameters = new CspParameters();
            }
            else
            {
                _parameters = param;
            }

            //
            // Try and open the CSP.
            // On downlevel crypto platforms, we have to create a key container because we can't
            // use the exponent-of-one trick on a CRYPT_VERIFYONLY keyset
            // see URT bug #15957
            //
            if (_runningWin2KOrLaterCrypto)
            {
                hr = _AcquireCSP(_parameters, ref _hCSP);
            }
            else
            {
                hr = _CreateCSP(_parameters, ref _hCSP);
            }
            if ((hr != 0) || (_hCSP == IntPtr.Zero))
            {
#if _DEBUG
                if (debug)
                {
                    Console.WriteLine("_CreateCSP failed in CSP_Encryptor, hr = {0:X} hCSP = {1:X}", hr, _hCSP);
                }
#endif
                throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_CouldNotAcquire"));
            }

            // Check to see if this alg & key size are supported
            // Commented out for now until I can fix the DES/3DES 56/64 problem

            /* {
             * int hasAlgHR;
             * Console.WriteLine("Keysizevalue = " + KeySizeValue);
             * hasAlgHR = _SearchForAlgorithm(_hCSP, algid, KeySizeValue);
             * if (hasAlgHR != 0) {
             * throw new CryptographicException(String.Format(Environment.GetResourceString("Cryptography_CSP_AlgKeySizeNotAvailable"),KeySizeValue));
             * }
             * }
             */

#if _DEBUG
            if (debug)
            {
                Console.WriteLine("Got back _hCSP = {0}", _hCSP);
            }
#endif

#if _DEBUG
            if (debug)
            {
                Console.WriteLine("Calling _ImportBulkKey({0}, {1}, {2})", _hCSP, algid, rgbKey);
            }
#endif
            _hKey = _ImportBulkKey(_hCSP, algid, _rgbKey);
            if (_hKey == IntPtr.Zero)
            {
                throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_ImportBulkKey"));
            }
            //hr = _DuplicateKey(_hMasterKey, ref _hKey);
#if _DEBUG
            if (debug)
            {
                Console.WriteLine("Got back _hKey = {0}", _hKey);
            }
#endif
            for (i = 0; i < cArgs; i++)
            {
                switch (rgArgIds[i])
                {
                case 1: // KP_IV
                    IVValue  = (byte[])_rgArgValues[i];
                    rgbValue = IVValue;
SetAsByteArray:
                    _SetKeyParamRgb(_hKey, _rgArgIds[i], rgbValue);
                    break;

                case 4: // KP_MODE
                    ModeValue = (CipherMode)_rgArgValues[i];
                    dwValue   = (Int32)_rgArgValues[i];
SetAsDWord:
#if _DEBUG
                    if (debug)
                    {
                        Console.WriteLine("Calling _SetKeyParamDw({0}, {1}, {2})", _hKey, _rgArgIds[i], dwValue);
                    }
#endif
                    _SetKeyParamDw(_hKey, _rgArgIds[i], dwValue);
                    break;

                case 5: // KP_MODE_BITS
                    FeedbackSizeValue = (Int32)_rgArgValues[i];
                    dwValue           = FeedbackSizeValue;
                    goto SetAsDWord;

                case 19: // KP_EFFECTIVE_KEYLEN
                    EffectiveKeySizeValue = (Int32)_rgArgValues[i];
                    dwValue = EffectiveKeySizeValue;
                    goto SetAsDWord;

                default:
                    throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeyParameter"), "_rgArgIds[i]");
                }
            }

            _KeyHandleProtector = new __KeyHandleProtector(_hKey);
        }
Esempio n. 4
0
        /************************* PRIVATE METHODS ************************/

        // This routine resets the internal state of the CryptoAPITransform and the
        // underlying CAPI mechanism.  The trick is to guarantee that we've always called
        // CAPI (CryptEncryt/CryptDecrytp) with the Final flag==TRUE.  This always happens when
        // we're in PKCS#7 mode because it's also the signal to CAPI to do the padding, but in
        // other modes we don't do it, so we need to fake it here.
        private void Reset(bool usingPKCSPadding)
        {
            _depadBuffer = null;
            if (usingPKCSPadding)
            {
                return;
            }
            if (encryptOrDecrypt == CryptoAPITransformMode.Encrypt)
            {
                byte[] tempInput   = new byte[InputBlockSize];
                bool   incremented = false;
                try {
                    if (_KeyHandleProtector.TryAddRef(ref incremented))
                    {
                        byte[] ignore = _EncryptData(_KeyHandleProtector.Handle, tempInput, 0, InputBlockSize, true);
                    }
                    else
                    {
                        throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic_ObjectName1"));
                    }
                }
                finally {
                    if (incremented)
                    {
                        _KeyHandleProtector.Release();
                    }
                }
            }
            else
            {
                // Yuk!! For decryption, if we're not using PKCS7 padding then we have to
                // get a new key context, because CAPI only knows about PKCS7 padding and
                // we have no way reset things.  We can't just call CryptDuplicateKey
                // because that doesn't exist on NT4.  So, let's just free the key & re-
                // create it...
                byte[] rgbValue;
                int    dwValue;

                if (_KeyHandleProtector != null && !_KeyHandleProtector.IsClosed)
                {
                    _KeyHandleProtector.Close();
                }
                _hKey = _ImportBulkKey(_hCSP, _algid, _rgbKey);
                if (_hKey == IntPtr.Zero)
                {
                    throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_ImportBulkKey"));
                }
                for (int i = 0; i < _cArgs; i++)
                {
                    switch (_rgArgIds[i])
                    {
                    case 1: // KP_IV
                        IVValue  = (byte[])_rgArgValues[i];
                        rgbValue = IVValue;
SetAsByteArray:
                        _SetKeyParamRgb(_hKey, _rgArgIds[i], rgbValue);
                        break;

                    case 4: // KP_MODE
                        ModeValue = (CipherMode)_rgArgValues[i];
                        dwValue   = (Int32)_rgArgValues[i];
SetAsDWord:
                        _SetKeyParamDw(_hKey, _rgArgIds[i], dwValue);
                        break;

                    case 5: // KP_MODE_BITS
                        FeedbackSizeValue = (Int32)_rgArgValues[i];
                        dwValue           = FeedbackSizeValue;
                        goto SetAsDWord;

                    case 19: // KP_EFFECTIVE_KEYLEN
                        EffectiveKeySizeValue = (Int32)_rgArgValues[i];
                        dwValue = EffectiveKeySizeValue;
                        goto SetAsDWord;

                    default:
                        throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeyParameter"), "_rgArgIds[i]");
                    }
                }
                _KeyHandleProtector = new __KeyHandleProtector(_hKey);
            }
            return;
        }
        /// <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);
            }
        }
        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);
        }