public override void GenerateKey(ECCurve curve) { curve.Validate(); _core.DisposeKey(); 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 CngAlgorithm alg = CngKey.EcdhCurveNameToAlgorithm(curve.Oid.FriendlyName); if (CngKey.IsECNamedCurve(alg.Algorithm)) { CngKey key = _core.GetOrGenerateKey(curve); ForceSetKeySize(key.KeySize); } else { int keySize = 0; // Get the proper KeySize from algorithm name if (alg == CngAlgorithm.ECDiffieHellmanP256) { keySize = 256; } else if (alg == CngAlgorithm.ECDiffieHellmanP384) { keySize = 384; } else if (alg == CngAlgorithm.ECDiffieHellmanP521) { keySize = 521; } else { Debug.Fail(string.Format("Unknown algorithm {0}", alg.ToString())); throw new ArgumentException(SR.Cryptography_InvalidKeySize); } CngKey key = _core.GetOrGenerateKey(keySize, alg); ForceSetKeySize(keySize); } } else if (curve.IsExplicit) { CngKey key = _core.GetOrGenerateKey(curve); ForceSetKeySize(key.KeySize); } else { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); } }
internal static CngKey Create(ECCurve curve, Func <string, CngAlgorithm> algorithmResolver) { System.Diagnostics.Debug.Assert(algorithmResolver != null); curve.Validate(); CngKeyCreationParameters creationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowPlaintextExport, }; CngAlgorithm alg; 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 alg = algorithmResolver(curve.Oid.FriendlyName); if (CngKey.IsECNamedCurve(alg.Algorithm)) { creationParameters.Parameters.Add(GetPropertyFromNamedCurve(curve)); } else { if (alg == CngAlgorithm.ECDsaP256 || alg == CngAlgorithm.ECDiffieHellmanP256 || alg == CngAlgorithm.ECDsaP384 || alg == CngAlgorithm.ECDiffieHellmanP384 || alg == CngAlgorithm.ECDsaP521 || alg == CngAlgorithm.ECDiffieHellmanP521) { // No parameters required, the algorithm ID has everything built-in. } else { Debug.Fail(string.Format("Unknown algorithm {0}", alg.ToString())); throw new ArgumentException(SR.Cryptography_InvalidKeySize); } } } else if (curve.IsPrime) { byte[] parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref curve); CngProperty prop = new CngProperty( KeyPropertyName.ECCParameters, parametersBlob, CngPropertyOptions.None); creationParameters.Parameters.Add(prop); alg = algorithmResolver(null); } else { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString())); } try { return(Create(alg, null, creationParameters)); } catch (CryptographicException e) { Interop.NCrypt.ErrorCode errorCode = (Interop.NCrypt.ErrorCode)e.HResult; if (errorCode == Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER || errorCode == Interop.NCrypt.ErrorCode.NTE_NOT_SUPPORTED) { string target = curve.IsNamed ? curve.Oid.FriendlyName : curve.CurveType.ToString(); throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, target), e); } throw; } }
private CngKey GetKey( #if !NETNATIVE ECCurve?curve = null #endif ) { CngKey key = null; CngAlgorithm algorithm = null; int keySize = 0; #if !NETNATIVE if (curve != null) { if (curve.Value.IsNamed) { // Map curve name to algorithm to support pre-Win10 curves CngAlgorithm alg = CngKey.EcdsaCurveNameToAlgorithm(curve.Value.Oid.FriendlyName); if (CngKey.IsECNamedCurve(alg.Algorithm)) { key = _core.GetOrGenerateKey(curve.Value); } else { // Get the proper KeySize from algorithm name if (alg == CngAlgorithm.ECDsaP256) { keySize = 256; } else if (alg == CngAlgorithm.ECDsaP384) { keySize = 384; } else if (alg == CngAlgorithm.ECDsaP521) { keySize = 521; } else { Debug.Fail(string.Format("Unknown algorithm {0}", alg.ToString())); throw new ArgumentException(SR.Cryptography_InvalidKeySize); } key = _core.GetOrGenerateKey(keySize, alg); } ForceSetKeySize(key.KeySize); } else if (curve.Value.IsExplicit) { key = _core.GetOrGenerateKey(curve.Value); ForceSetKeySize(key.KeySize); } else { throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Value.CurveType.ToString())); } } else if (_core.IsKeyGeneratedNamedCurve()) { key = _core.GetOrGenerateKey(null); } else #endif { // Map the current key size to a CNG algorithm name keySize = KeySize; switch (keySize) { case 256: algorithm = CngAlgorithm.ECDsaP256; break; case 384: algorithm = CngAlgorithm.ECDsaP384; break; case 521: algorithm = CngAlgorithm.ECDsaP521; break; default: Debug.Fail("Should not have invalid key size"); throw new ArgumentException(SR.Cryptography_InvalidKeySize); } key = _core.GetOrGenerateKey(keySize, algorithm); } return(key); }