[System.Security.SecuritySafeCritical] // auto-generated public RNGCryptoServiceProvider(CspParameters cspParams) { if (cspParams != null) { m_safeProvHandle = Utils.AcquireProvHandle(cspParams); m_ownsHandle = true; } else { m_safeProvHandle = Utils.StaticProvHandle; m_ownsHandle = false; } }
protected override void Dispose(bool disposing) { if (disposing) { SafeKeyHandle hKey = _hKey; _hKey = null; if (hKey != null) { hKey.Dispose(); } SafeProvHandle hProvider = _hProvider; _hProvider = null; if (hProvider != null) { hProvider.Dispose(); } } base.Dispose(disposing); }
protected override void Dispose(bool disposing) { if (disposing) { SafeCapiKeyHandle hKey = _hKey; if (hKey != null) { _hKey = null !; hKey.Dispose(); } SafeProvHandle hProvider = _hProvider; if (hProvider != null) { _hProvider = null !; hProvider.Dispose(); } } base.Dispose(disposing); }
/// <summary> /// Imports a blob that represents RSA key information /// </summary> /// <param name="keyBlob"></param> public void ImportCspBlob(byte[] keyBlob) { ThrowIfDisposed(); SafeKeyHandle safeKeyHandle; if (IsPublic(keyBlob)) { SafeProvHandle safeProvHandleTemp = AcquireSafeProviderHandle(); CapiHelper.ImportKeyBlob(safeProvHandleTemp, (CspProviderFlags)0, false, keyBlob, out safeKeyHandle); // The property set will take care of releasing any already-existing resources. SafeProvHandle = safeProvHandleTemp; } else { CapiHelper.ImportKeyBlob(SafeProvHandle, _parameters.Flags, false, keyBlob, out safeKeyHandle); } // The property set will take care of releasing any already-existing resources. SafeKeyHandle = safeKeyHandle; }
public BasicSymmetricCipherCsp(int algId, CipherMode cipherMode, int blockSizeInBytes, byte[] key, int effectiveKeyLength, bool addNoSaltFlag, byte[] iv, bool encrypting) : base(cipherMode.GetCipherIv(iv), blockSizeInBytes) { _encrypting = encrypting; _hProvider = AcquireSafeProviderHandle(); _hKey = ImportCspBlob(_hProvider, algId, key, addNoSaltFlag); SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_MODE, (int)cipherMode); byte[] currentIv = cipherMode.GetCipherIv(iv); if (currentIv != null) { SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_IV, currentIv); } if (effectiveKeyLength != 0) { SetKeyParameter(_hKey, CryptGetKeyParamQueryType.KP_EFFECTIVE_KEYLEN, effectiveKeyLength); } }
public byte[] CryptDeriveKey(string algname, string alghashname, int keySize, byte[] rgbIV) { if (keySize < 0) { throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeySize")); } int algId1 = X509Utils.NameOrOidToAlgId(alghashname, OidGroup.HashAlgorithm); if (algId1 == 0) { throw new CryptographicException(Environment.GetResourceString("Cryptography_PasswordDerivedBytes_InvalidAlgorithm")); } int algId2 = X509Utils.NameOrOidToAlgId(algname, OidGroup.AllGroups); if (algId2 == 0) { throw new CryptographicException(Environment.GetResourceString("Cryptography_PasswordDerivedBytes_InvalidAlgorithm")); } if (rgbIV == null) { throw new CryptographicException(Environment.GetResourceString("Cryptography_PasswordDerivedBytes_InvalidIV")); } byte[] o = (byte[])null; SafeProvHandle provHandle = this.ProvHandle; int algid = algId2; int algidHash = algId1; byte[] password = this.m_password; int length1 = this.m_password.Length; int dwFlags = keySize << 16; byte[] IV = rgbIV; int length2 = IV.Length; ObjectHandleOnStack objectHandleOnStack = JitHelpers.GetObjectHandleOnStack <byte[]>(ref o); Rfc2898DeriveBytes.DeriveKey(provHandle, algid, algidHash, password, length1, dwFlags, IV, length2, objectHandleOnStack); return(o); }
private ICryptoTransform CreateTransform(bool encrypting) { // При обращении к KeyHandle возможна генерация ключа. SafeKeyHandle hDupKey = CapiHelper.DuplicateKey( SafeKeyHandle.DangerousGetHandle(), SafeProvHandle); // Добавляем ссылку на провайдер bool success = false; SafeProvHandle.DangerousAddRef(ref success); // При обращении к IV возможна генерация синхропосылки. return(CreateTransformCore( SafeProvHandle, hDupKey, base.ModeValue, base.PaddingValue, IV, base.BlockSizeValue, base.FeedbackSizeValue, encrypting)); }
internal static extern void SetPersistKeyInCsp(SafeProvHandle hProv, bool fPersistKeyInCsp);
internal static extern SafeHashHandle CreateHash(SafeProvHandle hProv, int algid);
internal static extern void _AcquireCSP(CspParameters param, ref SafeProvHandle hProv);
internal static extern void _ImportBulkKey(SafeProvHandle hProv, int algid, bool useSalt, byte[] key, ref SafeKeyHandle hKey);
internal static extern void _GenerateKey(SafeProvHandle hProv, int algid, CspProviderFlags flags, int keySize, ref SafeKeyHandle hKey);
internal static void ImportCspBlobHelper(CspAlgorithmType keyType, byte[] keyBlob, bool publicOnly, ref CspParameters parameters, bool randomKeyContainer, ref SafeProvHandle safeProvHandle, ref SafeKeyHandle safeKeyHandle) { if ((safeKeyHandle != null) && !safeKeyHandle.IsClosed) { safeKeyHandle.Dispose(); } safeKeyHandle = SafeKeyHandle.InvalidHandle; if (publicOnly) { parameters.KeyNumber = _ImportCspBlob(keyBlob, (keyType == CspAlgorithmType.Dss) ? StaticDssProvHandle : StaticProvHandle, CspProviderFlags.NoFlags, ref safeKeyHandle); } else { KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Import); permission.AccessEntries.Add(accessEntry); permission.Demand(); if (safeProvHandle == null) { safeProvHandle = CreateProvHandle(parameters, randomKeyContainer); } parameters.KeyNumber = _ImportCspBlob(keyBlob, safeProvHandle, parameters.Flags, ref safeKeyHandle); } }
internal static void GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, bool randomKeyContainer, int dwKeySize, ref SafeProvHandle safeProvHandle, ref SafeKeyHandle safeKeyHandle) { SafeProvHandle hProv = CreateProvHandle(parameters, randomKeyContainer); if (parameters.CryptoKeySecurity != null) { KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.ChangeAcl); permission.AccessEntries.Add(accessEntry); permission.Demand(); SetKeySetSecurityInfo(hProv, parameters.CryptoKeySecurity, parameters.CryptoKeySecurity.ChangedAccessControlSections); } if (parameters.ParentWindowHandle != IntPtr.Zero) { SetProviderParameter(hProv, parameters.KeyNumber, 10, parameters.ParentWindowHandle); } else if (parameters.KeyPassword != null) { IntPtr pbData = Marshal.SecureStringToCoTaskMemAnsi(parameters.KeyPassword); try { SetProviderParameter(hProv, parameters.KeyNumber, 11, pbData); } finally { if (pbData != IntPtr.Zero) { Marshal.ZeroFreeCoTaskMemAnsi(pbData); } } } safeProvHandle = hProv; SafeKeyHandle invalidHandle = SafeKeyHandle.InvalidHandle; int hr = _GetUserKey(safeProvHandle, parameters.KeyNumber, ref invalidHandle); if (hr != 0) { if (((parameters.Flags & CspProviderFlags.UseExistingKey) != CspProviderFlags.NoFlags) || (hr != -2146893811)) { throw new CryptographicException(hr); } _GenerateKey(safeProvHandle, parameters.KeyNumber, parameters.Flags, dwKeySize, ref invalidHandle); } byte[] buffer = _GetKeyParameter(invalidHandle, 9); int num2 = ((buffer[0] | (buffer[1] << 8)) | (buffer[2] << 0x10)) | (buffer[3] << 0x18); if ((((keyType == CspAlgorithmType.Rsa) && (num2 != 0xa400)) && (num2 != 0x2400)) || ((keyType == CspAlgorithmType.Dss) && (num2 != 0x2200))) { invalidHandle.Dispose(); throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_WrongKeySpec")); } safeKeyHandle = invalidHandle; }
private static ICryptoTransform CreateTransformCore( SafeProvHandle hProv, SafeKeyHandle hKey, CipherMode mode, PaddingMode padding, byte[] rgbIV, int blockSize, int feedbackSize, bool encrypting) { //#Q_ ToDo выжечь огнём этот ад с двумя масивами для передачи параметров в GostCryptoAPITransform // переделать на словарь, или в идеале просто явно передавать параметры через структуру, но не этот ужас int num1 = 0; int[] numArray1 = new int[10]; object[] objArray1 = new object[10]; // Не поддерживаем CTS. Выдаем приличное исключение. if (mode == CipherMode.CTS) { throw new ArgumentException( SR.Argument_InvalidValue, nameof(mode)); //SR.Cryptography_CSP_CTSNotSupported } // Поддерживаем только правильные пары Padding - mode if (mode == CipherMode.OFB || mode == CipherMode.CFB) { if (padding != PaddingMode.None) { throw new CryptographicException( SR.Cryptography_InvalidPaddingMode); } } // Сбрасываем Pading, мы сами его поддерживаем. numArray1[num1] = GostConstants.KP_PADDING; objArray1[num1] = GostConstants.WINCRYPT_PADDING_ZERO; num1++; // Поддерживаем только CFB с feedback по ГОСТ. if ((mode == CipherMode.CFB) && (feedbackSize != DefFeedbackSize)) { throw new ArgumentException(SR.Argument_InvalidValue, nameof(feedbackSize)); } // Нет ключа, генерим. if (hKey == null) { CapiHelper.GenerateKey(hProv, GostConstants.CALG_G28147, CspProviderFlags.NoFlags, GostConstants.G28147_KEYLEN * BitsPerByte, out hKey); } // Ключ приходит как Handle, поэтому длины не проверяем. // Mode ставим всегда, так как при создании ключа по Handle // он может быть другим. numArray1[num1] = GostConstants.KP_MODE; objArray1[num1] = mode; num1++; // Для всех mode кроме ECB требуется синхропосылка. Устанавливаем. if (mode != CipherMode.ECB) { // Если ее нет, то генерим. if (rgbIV == null) { if (!encrypting) { // при расшифровании IV должен быть задан throw new CryptographicException(SR.Cryptography_MissingIV); } // Не используем GenerateIV: классовая и переданная // IV могут отличаться. rgbIV = new byte[IVSize / 8]; using (var rng = new GostRngCryptoServiceProvider(hProv)) { rng.GetBytes(rgbIV); } } // проверяем достаточность по длине. if (rgbIV.Length < IVSize / BitsPerByte) { throw new CryptographicException( SR.Cryptography_InvalidIVSize); } numArray1[num1] = GostConstants.KP_SV; objArray1[num1] = rgbIV; num1++; } // Можно еще установить для CFB количество бит зацепления, но // оно всегда равно 64 и его установка не поддерживается CSP. return(new GostCryptoAPITransform(num1, numArray1, objArray1, hKey, hProv, padding, mode, blockSize, encrypting)); }
/// <summary> /// Returns PersistKeyInCsp value /// </summary> /// <param name="safeProvHandle">Safe Prov Handle. Expects a valid handle</param> /// <returns>true if key is persisted otherwise false</returns> internal static bool GetPersistKeyInCsp(SafeProvHandle safeProvHandle) { VerifyValidHandle(safeProvHandle); return safeProvHandle.PersistKeyInCsp; }
/// <summary> /// Helper for Import CSP /// </summary> internal static void ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, byte[] keyBlob, out SafeKeyHandle safeKeyHandle) { // Compat note: This isn't the same check as the one done by the CLR _ImportCspBlob QCall, // but this does match the desktop CLR behavior and the only scenarios it // affects are cases where a corrupt blob is passed in. bool isPublic = keyBlob.Length > 0 && keyBlob[0] == CapiHelper.PUBLICKEYBLOB; int dwCapiFlags = MapCspKeyFlags((int)flags); if (isPublic) { dwCapiFlags &= ~(int)(CryptGenKeyFlags.CRYPT_EXPORTABLE); } SafeKeyHandle hKey; if (!Interop.CryptImportKey(saveProvHandle, keyBlob, keyBlob.Length, SafeKeyHandle.InvalidHandle, dwCapiFlags, out hKey)) { int hr = Marshal.GetHRForLastWin32Error(); hKey.Dispose(); throw hr.ToCryptographicException(); } hKey.PublicOnly = isPublic; safeKeyHandle = hKey; return; }
internal static void SetKeySetSecurityInfo(SafeProvHandle hProv, CryptoKeySecurity cryptoKeySecurity, AccessControlSections accessControlSections) { SecurityInfos securityInfo = 0; Privilege privilege = null; if (((accessControlSections & AccessControlSections.Owner) != AccessControlSections.None) && (cryptoKeySecurity._securityDescriptor.Owner != null)) { securityInfo |= SecurityInfos.Owner; } if (((accessControlSections & AccessControlSections.Group) != AccessControlSections.None) && (cryptoKeySecurity._securityDescriptor.Group != null)) { securityInfo |= SecurityInfos.Group; } if ((accessControlSections & AccessControlSections.Audit) != AccessControlSections.None) { securityInfo |= SecurityInfos.SystemAcl; } if (((accessControlSections & AccessControlSections.Access) != AccessControlSections.None) && cryptoKeySecurity._securityDescriptor.IsDiscretionaryAclPresent) { securityInfo |= SecurityInfos.DiscretionaryAcl; } if (securityInfo != 0) { int hr = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { if ((securityInfo & SecurityInfos.SystemAcl) != 0) { privilege = new Privilege("SeSecurityPrivilege"); privilege.Enable(); } byte[] securityDescriptorBinaryForm = cryptoKeySecurity.GetSecurityDescriptorBinaryForm(); if ((securityDescriptorBinaryForm != null) && (securityDescriptorBinaryForm.Length > 0)) { hr = SetKeySetSecurityInfo(hProv, securityInfo, securityDescriptorBinaryForm); } } finally { if (privilege != null) { privilege.Revert(); } } switch (hr) { case 5: case 0x51b: case 0x51c: throw new UnauthorizedAccessException(); case 0x522: throw new PrivilegeNotHeldException("SeSecurityPrivilege"); case 6: throw new NotSupportedException(Environment.GetResourceString("AccessControl_InvalidHandle")); } if (hr != 0) { throw new CryptographicException(hr); } } }
[System.Security.SecurityCritical] // auto-generated internal CryptoAPITransform(int algid, int cArgs, int[] rgArgIds, Object[] rgArgValues, byte[] rgbKey, PaddingMode padding, CipherMode cipherChainingMode, int blockSize, int feedbackSize, bool useSalt, CryptoAPITransformMode encDecMode) { int dwValue; byte[] rgbValue; BlockSizeValue = blockSize; ModeValue = cipherChainingMode; PaddingValue = padding; encryptOrDecrypt = encDecMode; // Copy the input args int _cArgs = cArgs; int[] _rgArgIds = new int[rgArgIds.Length]; Array.Copy(rgArgIds, _rgArgIds, rgArgIds.Length); _rgbKey = new byte[rgbKey.Length]; Array.Copy(rgbKey, _rgbKey, rgbKey.Length); Object[] _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; } } _safeProvHandle = Utils.AcquireProvHandle(new CspParameters(Utils.DefaultRsaProviderType)); SafeKeyHandle safeKeyHandle = SafeKeyHandle.InvalidHandle; // _ImportBulkKey will check for failures and throw an exception Utils._ImportBulkKey(_safeProvHandle, algid, useSalt, _rgbKey, ref safeKeyHandle); _safeKeyHandle = safeKeyHandle; for (int i=0; i<cArgs; i++) { switch (rgArgIds[i]) { case Constants.KP_IV: IVValue = (byte[]) _rgArgValues[i]; rgbValue = IVValue; Utils.SetKeyParamRgb(_safeKeyHandle, _rgArgIds[i], rgbValue, rgbValue.Length); break; case Constants.KP_MODE: ModeValue = (CipherMode) _rgArgValues[i]; dwValue = (Int32) _rgArgValues[i]; SetAsDWord: Utils.SetKeyParamDw(_safeKeyHandle, _rgArgIds[i], dwValue); break; case Constants.KP_MODE_BITS: dwValue = (Int32) _rgArgValues[i]; goto SetAsDWord; case Constants.KP_EFFECTIVE_KEYLEN: dwValue = (Int32) _rgArgValues[i]; goto SetAsDWord; default: throw new CryptographicException(Environment.GetResourceString("Cryptography_InvalidKeyParameter"), "_rgArgIds[i]"); } } }
/// <summary> /// This method helps Acquire the default CSP and avoids the need for static SafeProvHandle /// in CapiHelper class /// </summary> /// <param name="safeProvHandle"> SafeProvHandle. Intialized if successful</param> /// <returns>does not return. AcquireCSP throw exception</returns> private void AcquireSafeProviderHandle(ref SafeProvHandle safeProvHandle) { CapiHelper.AcquireCsp(new CspParameters(CapiHelper.DefaultRsaProviderType), ref safeProvHandle); }
internal static extern object _GetProviderParameter(SafeProvHandle hProv, int keyNumber, uint paramID);
/// <summary> /// Creates a new key container /// </summary> private static void CreateCSP(CspParameters parameters, bool randomKeyContainer, out SafeProvHandle safeProvHandle) { uint dwFlags = (uint)CryptAcquireContextFlags.CRYPT_NEWKEYSET; if (randomKeyContainer) { dwFlags |= (uint)CryptAcquireContextFlags.CRYPT_VERIFYCONTEXT; } SafeProvHandle hProv; int ret = OpenCSP(parameters, dwFlags, out hProv); if (S_OK != ret) { hProv.Dispose(); throw new CryptographicException(SR.Format(SR.OpenCSP_Failed, Convert.ToString(ret))); } safeProvHandle = hProv; }
internal static extern void _ImportKey(SafeProvHandle hCSP, int keyNumber, CspProviderFlags flags, object cspObject, ref SafeKeyHandle hKey);
public static extern bool CryptAcquireContext(out SafeProvHandle psafeProvHandle, string pszContainer, string pszProvider, int dwProvType, uint dwFlags);
internal static void GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, bool randomKeyContainer, int dwKeySize, ref SafeProvHandle safeProvHandle, ref SafeKeyHandle safeKeyHandle) { SafeProvHandle provHandle = Utils.CreateProvHandle(parameters, randomKeyContainer); if (parameters.CryptoKeySecurity != null) { KeyContainerPermission containerPermission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.ChangeAcl); containerPermission.AccessEntries.Add(accessEntry); containerPermission.Demand(); Utils.SetKeySetSecurityInfo(provHandle, parameters.CryptoKeySecurity, parameters.CryptoKeySecurity.ChangedAccessControlSections); } if (parameters.ParentWindowHandle != IntPtr.Zero) { Utils.SetProviderParameter(provHandle, parameters.KeyNumber, 10U, parameters.ParentWindowHandle); } else if (parameters.KeyPassword != null) { IntPtr coTaskMemAnsi = Marshal.SecureStringToCoTaskMemAnsi(parameters.KeyPassword); try { Utils.SetProviderParameter(provHandle, parameters.KeyNumber, 11U, coTaskMemAnsi); } finally { if (coTaskMemAnsi != IntPtr.Zero) { Marshal.ZeroFreeCoTaskMemAnsi(coTaskMemAnsi); } } } safeProvHandle = provHandle; SafeKeyHandle invalidHandle = SafeKeyHandle.InvalidHandle; int userKey = Utils._GetUserKey(safeProvHandle, parameters.KeyNumber, ref invalidHandle); if (userKey != 0) { if ((parameters.Flags & CspProviderFlags.UseExistingKey) != CspProviderFlags.NoFlags || userKey != -2146893811) { throw new CryptographicException(userKey); } Utils._GenerateKey(safeProvHandle, parameters.KeyNumber, parameters.Flags, dwKeySize, ref invalidHandle); } byte[] keyParameter = Utils._GetKeyParameter(invalidHandle, 9U); int num = (int)keyParameter[0] | (int)keyParameter[1] << 8 | (int)keyParameter[2] << 16 | (int)keyParameter[3] << 24; if (keyType == CspAlgorithmType.Rsa && num != 41984 && num != 9216 || keyType == CspAlgorithmType.Dss && num != 8704) { invalidHandle.Dispose(); throw new CryptographicException(Environment.GetResourceString("Cryptography_CSP_WrongKeySpec")); } safeKeyHandle = invalidHandle; }
public static extern bool CryptGetProvParam(SafeProvHandle safeProvHandle, int dwParam, byte[] pbData, ref int dwDataLen, int dwFlags);
private static extern bool SearchForAlgorithm(SafeProvHandle hProv, int algID, int keyLength);
public static extern bool CryptSetProvParam(SafeProvHandle safeProvHandle, CryptGetProvParam dwParam, ref IntPtr pbData, int dwFlags);
private static extern void GetNonZeroBytes(SafeProvHandle hProv, byte[] randomBytes, int count);
private static extern bool _CryptGetUserKey(SafeProvHandle safeProvHandle, int dwKeySpec, out SafeKeyHandle safeKeyHandle);
/// <summary> /// Helper function to get the key pair /// </summary> internal static SafeKeyHandle GetKeyPairHelper( CspAlgorithmType keyType, CspParameters parameters, int keySize, SafeProvHandle safeProvHandle) { // If the key already exists, use it, else generate a new one SafeKeyHandle hKey; int hr = CapiHelper.GetUserKey(safeProvHandle, parameters.KeyNumber, out hKey); if (hr != S_OK) { hKey.Dispose(); if (IsFlagBitSet((uint)parameters.Flags, (uint)CspProviderFlags.UseExistingKey) || (uint)hr != (uint)CryptKeyError.NTE_NO_KEY) { throw new CryptographicException(SR.Format(SR.CryptGetUserKey_Failed, Convert.ToString(hr))); } // GenerateKey will check for failures and throw an exception CapiHelper.GenerateKey(safeProvHandle, parameters.KeyNumber, (int)parameters.Flags, (uint)keySize, out hKey); } // check that this is indeed an RSA/DSS key. byte[] algid = CapiHelper.GetKeyParameter(hKey, Constants.CLR_ALGID); int dwAlgId = (algid[0] | (algid[1] << 8) | (algid[2] << 16) | (algid[3] << 24)); if ((keyType == CspAlgorithmType.Rsa && dwAlgId != CALG_RSA_KEYX && dwAlgId != CALG_RSA_SIGN) || (keyType == CspAlgorithmType.Dss && dwAlgId != CALG_DSS_SIGN)) { hKey.Dispose(); throw new CryptographicException(SR.Format(SR.Cryptography_CSP_WrongKeySpec, Convert.ToString(keyType))); } return hKey; }
private static extern bool _CryptGenKey(SafeProvHandle safeProvHandle, int Algid, int dwFlags, out SafeKeyHandle safeKeyHandle);
/// <summary> /// Sets the PersistKeyInCsp /// </summary> /// <param name="safeProvHandle">Safe Prov Handle. Expects a valid handle</param> /// <param name="fPersistKeyInCsp">Sets the PersistKeyInCsp value</param> internal static void SetPersistKeyInCsp(SafeProvHandle safeProvHandle, bool fPersistKeyInCsp) { VerifyValidHandle(safeProvHandle); safeProvHandle.PersistKeyInCsp = fPersistKeyInCsp; }
private static extern bool _CryptImportKey(SafeProvHandle hProv, byte[] pbData, int dwDataLen, SafeKeyHandle hPubKey, int dwFlags, out SafeKeyHandle phKey);
private static extern bool _CryptCreateHash(SafeProvHandle hProv, int algId, SafeKeyHandle hKey, CryptCreateHashFlags dwFlags, out SafeHashHandle phHash);
private static extern void DeriveKey(SafeProvHandle hProv, int algid, int algidHash, byte[] password, int cbPassword, int dwFlags, byte[] IV, int cbIV, ObjectHandleOnStack retKey);
public static bool CryptGetUserKey( SafeProvHandle safeProvHandle, int dwKeySpec, out SafeKeyHandle safeKeyHandle) { bool response = _CryptGetUserKey(safeProvHandle, dwKeySpec, out safeKeyHandle); safeKeyHandle.SetParent(safeProvHandle); return response; }
internal static extern void _CreateCSP(CspParameters param, bool randomKeyContainer, ref SafeProvHandle hProv);
public static bool CryptGenKey( SafeProvHandle safeProvHandle, int algId, int dwFlags, out SafeKeyHandle safeKeyHandle) { bool response = _CryptGenKey(safeProvHandle, algId, dwFlags, out safeKeyHandle); safeKeyHandle.SetParent(safeProvHandle); return response; }
internal static extern byte[] _GetKeySetSecurityInfo(SafeProvHandle hProv, SecurityInfos securityInfo, out int error);
public static bool CryptImportKey( SafeProvHandle hProv, byte[] pbData, int dwDataLen, SafeKeyHandle hPubKey, int dwFlags, out SafeKeyHandle phKey) { bool response = _CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, out phKey); phKey.SetParent(hProv); return response; }
internal static extern int _GetUserKey(SafeProvHandle hProv, int keyNumber, ref SafeKeyHandle hKey);
public static bool CryptCreateHash( SafeProvHandle hProv, int algId, SafeKeyHandle hKey, CryptCreateHashFlags dwFlags, out SafeHashHandle phHash) { bool response = _CryptCreateHash(hProv, algId, hKey, dwFlags, out phHash); phHash.SetParent(hProv); return response; }
internal static extern int _ImportCspBlob(byte[] keyBlob, SafeProvHandle hProv, CspProviderFlags flags, ref SafeKeyHandle hKey);
/// <summary> /// Acquire a handle to a crypto service provider and optionally a key container /// This function implements the WszCryptAcquireContext_SO_TOLERANT /// </summary> private static int AcquireCryptContext(out SafeProvHandle safeProvHandle, string keyContainer, string providerName, int providerType, uint flags) { const uint VerifyContextFlag = (uint)CryptAcquireContextFlags.CRYPT_VERIFYCONTEXT; const uint MachineContextFlag = (uint)CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET; int ret = S_OK; // Specifying both verify context (for an ephemeral key) and machine keyset (for a persisted machine key) // does not make sense. Additionally, Windows is beginning to lock down against uses of MACHINE_KEYSET // (for instance in the app container), even if verify context is present. Therefore, if we're using // an ephemeral key, strip out MACHINE_KEYSET from the flags. if (((flags & VerifyContextFlag) == VerifyContextFlag) && ((flags & MachineContextFlag) == MachineContextFlag)) { flags &= ~MachineContextFlag; } //Do not throw in this function. Just return the error code if (!Interop.CryptAcquireContext(out safeProvHandle, keyContainer, providerName, providerType, flags)) { ret = GetErrorCode(); } return ret; }
internal static extern int _OpenCSP(CspParameters param, uint flags, ref SafeProvHandle hProv);
/// <summary> /// Acquire a handle to a crypto service provider and optionally a key container /// </summary> public static bool CryptAcquireContext(out SafeProvHandle psafeProvHandle, string pszContainer, string pszProvider, int dwProvType, uint dwFlags) { return Interop.CryptAcquireContext(out psafeProvHandle, pszContainer, pszProvider, dwProvType, dwFlags); }
internal static void SetKeySetSecurityInfo(SafeProvHandle hProv, CryptoKeySecurity cryptoKeySecurity, AccessControlSections accessControlSections) { SecurityInfos securityInfo = (SecurityInfos)0; Privilege privilege = (Privilege)null; if ((accessControlSections & AccessControlSections.Owner) != AccessControlSections.None && cryptoKeySecurity._securityDescriptor.Owner != (SecurityIdentifier)null) { securityInfo |= SecurityInfos.Owner; } if ((accessControlSections & AccessControlSections.Group) != AccessControlSections.None && cryptoKeySecurity._securityDescriptor.Group != (SecurityIdentifier)null) { securityInfo |= SecurityInfos.Group; } if ((accessControlSections & AccessControlSections.Audit) != AccessControlSections.None) { securityInfo |= SecurityInfos.SystemAcl; } if ((accessControlSections & AccessControlSections.Access) != AccessControlSections.None && cryptoKeySecurity._securityDescriptor.IsDiscretionaryAclPresent) { securityInfo |= SecurityInfos.DiscretionaryAcl; } if (securityInfo == (SecurityInfos)0) { return; } int hr = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { if ((securityInfo & SecurityInfos.SystemAcl) != (SecurityInfos)0) { privilege = new Privilege("SeSecurityPrivilege"); privilege.Enable(); } byte[] descriptorBinaryForm = cryptoKeySecurity.GetSecurityDescriptorBinaryForm(); if (descriptorBinaryForm != null) { if (descriptorBinaryForm.Length != 0) { hr = Utils.SetKeySetSecurityInfo(hProv, securityInfo, descriptorBinaryForm); } } } finally { if (privilege != null) { privilege.Revert(); } } if (hr == 5 || hr == 1307 || hr == 1308) { throw new UnauthorizedAccessException(); } if (hr == 1314) { throw new PrivilegeNotHeldException("SeSecurityPrivilege"); } if (hr == 6) { throw new NotSupportedException(Environment.GetResourceString("AccessControl_InvalidHandle")); } if (hr != 0) { throw new CryptographicException(hr); } }
/// <summary> /// This method opens the CSP using CRYPT_VERIFYCONTEXT /// KeyContainer must be null for the flag CRYPT_VERIFYCONTEXT /// This method asserts if keyContainer is not null /// </summary> /// <param name="cspParameters">CSPParameter to use</param> /// <param name="safeProvHandle">Safe provider handle</param> internal static void AcquireCsp(CspParameters cspParameters, out SafeProvHandle safeProvHandle) { Debug.Assert(cspParameters != null); Debug.Assert(cspParameters.KeyContainerName == null); SafeProvHandle hProv; // // We want to just open this CSP. Passing in verify context will // open it and, if a container is given, map to open the container. // int ret = OpenCSP(cspParameters, (uint)CryptAcquireContextFlags.CRYPT_VERIFYCONTEXT, out hProv); if (S_OK != ret) { hProv.Dispose(); throw new CryptographicException(SR.Format(SR.OpenCSP_Failed, Convert.ToString(ret))); } safeProvHandle = hProv; }
internal static void ImportCspBlobHelper(CspAlgorithmType keyType, byte[] keyBlob, bool publicOnly, ref CspParameters parameters, bool randomKeyContainer, ref SafeProvHandle safeProvHandle, ref SafeKeyHandle safeKeyHandle) { if (safeKeyHandle != null && !safeKeyHandle.IsClosed) { safeKeyHandle.Dispose(); } safeKeyHandle = SafeKeyHandle.InvalidHandle; if (publicOnly) { parameters.KeyNumber = Utils._ImportCspBlob(keyBlob, keyType == CspAlgorithmType.Dss ? Utils.StaticDssProvHandle : Utils.StaticProvHandle, CspProviderFlags.NoFlags, ref safeKeyHandle); } else { if (!CompatibilitySwitches.IsAppEarlierThanWindowsPhone8) { KeyContainerPermission containerPermission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags); KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(parameters, KeyContainerPermissionFlags.Import); containerPermission.AccessEntries.Add(accessEntry); containerPermission.Demand(); } if (safeProvHandle == null) { safeProvHandle = Utils.CreateProvHandle(parameters, randomKeyContainer); } parameters.KeyNumber = Utils._ImportCspBlob(keyBlob, safeProvHandle, parameters.Flags, ref safeKeyHandle); } }
/// <summary> /// OpenCSP performs the core work of opening and creating CSPs and containers in CSPs /// </summary> public static int OpenCSP(CspParameters cspParameters, uint flags, out SafeProvHandle safeProvHandle) { string providerName = null; string containerName = null; if (null == cspParameters) { throw new ArgumentException(SR.Format(SR.CspParameter_invalid, "cspParameters")); } //look for provider type in the cspParameters int providerType = cspParameters.ProviderType; //look for provider name in the cspParamters //if CSP provider is not null then use the provider name from cspParameters if (null != cspParameters.ProviderName) { providerName = cspParameters.ProviderName; } else //Get the default provider name { providerName = GetDefaultProvider(providerType); cspParameters.ProviderName = providerName; } // look to see if the user specified that we should pass // CRYPT_MACHINE_KEYSET to CAPI to use machine key storage instead // of user key storage int cspProviderFlags = (int)cspParameters.Flags; // If the user specified CSP_PROVIDER_FLAGS_USE_DEFAULT_KEY_CONTAINER, // then ignore the key container name and hand back the default container if (!IsFlagBitSet((uint)cspProviderFlags, (uint)CspProviderFlags.UseDefaultKeyContainer)) { //look for key container name in the cspParameters if (null != cspParameters.KeyContainerName) { containerName = cspParameters.KeyContainerName; } } SafeProvHandle hProv; // Go ahead and try to open the CSP. If we fail, make sure the CSP // returned is 0 as that is going to be the error check in the caller. flags |= MapCspProviderFlags((int)cspParameters.Flags); if (S_OK != AcquireCryptContext(out hProv, containerName, providerName, providerType, flags)) { hProv.Dispose(); safeProvHandle = SafeProvHandle.InvalidHandle; return GetErrorCode(); } hProv.ContainerName = containerName; hProv.ProviderName = providerName; hProv.Types = providerType; hProv.Flags = flags; // We never want to delete a key container if it's already there. if (IsFlagBitSet(flags, (uint)CryptAcquireContextFlags.CRYPT_VERIFYCONTEXT)) { hProv.PersistKeyInCsp = false; } safeProvHandle = hProv; return S_OK; }
internal static extern bool GetPersistKeyInCsp(SafeProvHandle hProv);
/// <summary> /// This method helps reduce the duplicate code in the GetProviderParameter method /// </summary> internal static int GetProviderParameterWorker(SafeProvHandle safeProvHandle, byte[] impType, ref int cb, CryptGetProvParam flags) { int impTypeReturn = 0; if (!Interop.CryptGetProvParam(safeProvHandle, (int)flags, impType, ref cb, 0)) { throw new CryptographicException(SR.Format(SR.CryptGetProvParam_Failed, Convert.ToString(GetErrorCode()))); } if (null != impType && cb == Constants.SIZE_OF_DWORD) { impTypeReturn = BitConverter.ToInt32(impType, 0); } return impTypeReturn; }
private static extern int SetKeySetSecurityInfo(SafeProvHandle hProv, SecurityInfos securityInfo, byte[] sd);
/// <summary> /// This method queries the key container and get some of it's properties. /// Those properties should never cause UI to display. /// </summary> public static object GetProviderParameter(SafeProvHandle safeProvHandle, int keyNumber, int keyParam) { VerifyValidHandle(safeProvHandle); byte[] impType = new byte[Constants.SIZE_OF_DWORD]; int cb = sizeof(byte) * Constants.SIZE_OF_DWORD; SafeKeyHandle safeKeyHandle = SafeKeyHandle.InvalidHandle; int impTypeReturn = 0; int returnType = 0; //using 0 for bool and 1 for string return types bool retVal = false; string retStr = null; try { switch (keyParam) { case Constants.CLR_EXPORTABLE: { impTypeReturn = GetProviderParameterWorker(safeProvHandle, impType, ref cb, CryptGetProvParam.PP_IMPTYPE); //If implementation type is not HW if (!IsFlagBitSet((uint)impTypeReturn, (uint)CryptGetProvParamPPImpTypeFlags.CRYPT_IMPL_HARDWARE)) { if (!Interop.CryptGetUserKey(safeProvHandle, keyNumber, out safeKeyHandle)) { throw new CryptographicException(SR.Format(SR.CryptGetUserKey_Failed, Convert.ToString(GetErrorCode()))); } byte[] permissions = null; int permissionsReturn = 0; permissions = new byte[Constants.SIZE_OF_DWORD]; cb = sizeof(byte) * Constants.SIZE_OF_DWORD; if (!Interop.CryptGetKeyParam(safeKeyHandle, (int)CryptGetKeyParamFlags.KP_PERMISSIONS, permissions, ref cb, 0)) { throw new CryptographicException(SR.Format(SR.CryptGetKeyParam_Failed, Convert.ToString(GetErrorCode()))); } permissionsReturn = BitConverter.ToInt32(permissions, 0); retVal = IsFlagBitSet((uint)permissionsReturn, (uint)CryptGetKeyParamFlags.CRYPT_EXPORT); } else { //Assumption HW keys are not exportable. retVal = false; } break; } case Constants.CLR_REMOVABLE: { impTypeReturn = GetProviderParameterWorker(safeProvHandle, impType, ref cb, CryptGetProvParam.PP_IMPTYPE); retVal = IsFlagBitSet((uint)impTypeReturn, (uint)CryptGetProvParamPPImpTypeFlags.CRYPT_IMPL_REMOVABLE); break; } case Constants.CLR_HARDWARE: case Constants.CLR_PROTECTED: { impTypeReturn = GetProviderParameterWorker(safeProvHandle, impType, ref cb, CryptGetProvParam.PP_IMPTYPE); retVal = IsFlagBitSet((uint)impTypeReturn, (uint)CryptGetProvParamPPImpTypeFlags.CRYPT_IMPL_HARDWARE); break; } case Constants.CLR_ACCESSIBLE: { retVal = Interop.CryptGetUserKey(safeProvHandle, keyNumber, out safeKeyHandle) ? true : false; break; } case Constants.CLR_UNIQUE_CONTAINER: { returnType = 1; byte[] pb = null; impTypeReturn = GetProviderParameterWorker(safeProvHandle, pb, ref cb, CryptGetProvParam.PP_UNIQUE_CONTAINER); pb = new byte[cb]; impTypeReturn = GetProviderParameterWorker(safeProvHandle, pb, ref cb, CryptGetProvParam.PP_UNIQUE_CONTAINER); // GetProviderParameterWorker allocated the null character, we want to not interpret that. Debug.Assert(cb > 0); Debug.Assert(pb[cb - 1] == 0); retStr = Encoding.ASCII.GetString(pb, 0, cb - 1); break; } default: { Debug.Assert(false); break; } } } finally { safeKeyHandle.Dispose(); } if (returnType == 0) { return retVal; } else if (returnType == 1) { return retStr; } return null; }
internal static extern void SetProviderParameter(SafeProvHandle hProv, int keyNumber, uint paramID, IntPtr pbData);
/// <summary> /// Retrieves the handle for user public / private key pair. /// </summary> internal static int GetUserKey(SafeProvHandle safeProvHandle, int keySpec, out SafeKeyHandle safeKeyHandle) { int hr = S_OK; VerifyValidHandle(safeProvHandle); if (!Interop.CryptGetUserKey(safeProvHandle, keySpec, out safeKeyHandle)) { hr = GetErrorCode(); } if (hr == S_OK) { safeKeyHandle.KeySpec = keySpec; } return hr; }
/// <summary> /// Generates the key if provided CSP handle is valid /// </summary> internal static int GenerateKey(SafeProvHandle safeProvHandle, int algID, int flags, uint keySize, out SafeKeyHandle safeKeyHandle) { int hr = S_OK; VerifyValidHandle(safeProvHandle); int capiFlags = (int)((uint)MapCspKeyFlags(flags) | ((uint)keySize << 16)); if (!Interop.CryptGenKey(safeProvHandle, algID, capiFlags, out safeKeyHandle)) { hr = GetErrorCode(); } if (hr != S_OK) { throw new CryptographicException(SR.Format(SR.CryptGenKey_Failed, Convert.ToString(GetErrorCode()))); } safeKeyHandle.KeySpec = algID; return hr; }