private void SetKeyHandle(SafeNCryptKeyHandle keyHandle) { Debug.Assert(!keyHandle.IsInvalid); _keyHandle = keyHandle; int newKeySize = CngKeyLite.GetKeyLength(keyHandle); // Our LegalKeySizes value stores the values that we encoded as being the correct // legal key size limitations for this algorithm, as documented on MSDN. // // But on a new OS version we might not question if our limit is accurate, or MSDN // could have been inaccurate to start with. // // Since the key is already loaded, we know that Windows thought it to be valid; // therefore we should set KeySizeValue directly to bypass the LegalKeySizes conformance // check. ForceSetKeySize(newKeySize); _lastKeySize = newKeySize; }
internal void GenerateKey(ECCurve curve) { curve.Validate(); ThrowIfDisposed(); if (_keyHandle != null) { DisposeKey(); } string algorithm; int keySize = 0; if (curve.IsNamed) { if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) { throw new PlatformNotSupportedException( SR.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); } // Map curve name to algorithm to support pre-Win10 curves if (_algorithmGroup == BCryptNative.AlgorithmName.ECDsa) { algorithm = ECCng.EcdsaCurveNameToAlgorithm(curve.Oid.FriendlyName); } else { Debug.Assert(_algorithmGroup == BCryptNative.AlgorithmName.ECDH); algorithm = ECCng.EcdhCurveNameToAlgorithm(curve.Oid.FriendlyName); } if (ECCng.IsECNamedCurve(algorithm)) { try { _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, curve.Oid.FriendlyName); keySize = CngKeyLite.GetKeyLength(_keyHandle); } catch (CryptographicException e) { // Map to PlatformNotSupportedException if appropriate Interop.NCrypt.ErrorCode errorCode = (Interop.NCrypt.ErrorCode)e.HResult; if (curve.IsNamed && errorCode == Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER || errorCode == Interop.NCrypt.ErrorCode.NTE_NOT_SUPPORTED) { throw new PlatformNotSupportedException( SR.Format(SR.Cryptography_CurveNotSupported, curve.Oid.FriendlyName), e); } throw; } } else { // Get the proper KeySize from algorithm name switch (algorithm) { case BCryptNative.AlgorithmName.ECDsaP256: case BCryptNative.AlgorithmName.ECDHP256: keySize = 256; break; case BCryptNative.AlgorithmName.ECDsaP384: case BCryptNative.AlgorithmName.ECDHP384: keySize = 384; break; case BCryptNative.AlgorithmName.ECDsaP521: case BCryptNative.AlgorithmName.ECDHP521: keySize = 521; break; default: Debug.Fail($"Unknown algorithm {algorithm}"); throw new ArgumentException(SR.Cryptography_InvalidKeySize); } _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, keySize); } } else if (curve.IsExplicit) { algorithm = _algorithmGroup; _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, ref curve); keySize = CngKeyLite.GetKeyLength(_keyHandle); } else { throw new PlatformNotSupportedException( SR.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); } _lastAlgorithm = algorithm; _lastKeySize = keySize; KeySize = keySize; }
public override void GenerateKey(ECCurve curve) { curve.Validate(); if (_keyHandle != null) { DisposeKey(); } string algorithm = null; int keySize = 0; if (curve.IsNamed) { if (string.IsNullOrEmpty(curve.Oid.FriendlyName)) { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value)); } // Map curve name to algorithm to support pre-Win10 curves algorithm = ECCng.EcdsaCurveNameToAlgorithm(curve.Oid.FriendlyName); if (IsECNamedCurve(algorithm)) { try { _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, curve.Oid.FriendlyName); keySize = CngKeyLite.GetKeyLength(_keyHandle); } catch (CryptographicException e) { // Map to PlatformNotSupportedException if appropriate ErrorCode errorCode = (ErrorCode)e.HResult; if (curve.IsNamed && errorCode == ErrorCode.NTE_INVALID_PARAMETER || errorCode == ErrorCode.NTE_NOT_SUPPORTED) { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Oid.FriendlyName), e); } throw; } } else { // Get the proper KeySize from algorithm name if (algorithm == AlgorithmName.ECDsaP256) { keySize = 256; } else if (algorithm == AlgorithmName.ECDsaP384) { keySize = 384; } else if (algorithm == AlgorithmName.ECDsaP521) { keySize = 521; } else { Debug.Fail(string.Format("Unknown algorithm {0}", algorithm.ToString())); throw new ArgumentException(SR.Cryptography_InvalidKeySize); } _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, keySize); } } else if (curve.IsExplicit) { algorithm = AlgorithmName.ECDsa; _keyHandle = CngKeyLite.GenerateNewExportableKey(algorithm, ref curve); keySize = CngKeyLite.GetKeyLength(_keyHandle); } else { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); } _lastAlgorithm = algorithm; _lastKeySize = keySize; ForceSetKeySize(keySize); }