private void ImportKeyBlob(byte[] ecKeyBlob, string curveName, bool includePrivateParameters) { string blobType = includePrivateParameters ? Interop.BCrypt.KeyBlobType.BCRYPT_ECCPRIVATE_BLOB : Interop.BCrypt.KeyBlobType.BCRYPT_ECCPUBLIC_BLOB; SafeNCryptKeyHandle keyHandle = CngKeyLite.ImportKeyBlob(blobType, ecKeyBlob, curveName); Debug.Assert(!keyHandle.IsInvalid); _key.SetHandle(keyHandle, ECCng.EcdhCurveNameToAlgorithm(curveName)); ForceSetKeySize(_key.KeySize); }
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; }