/// <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); }
// *********************** 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); }
/************************* 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); }