Exemple #1
0
        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()));
            }
        }
Exemple #2
0
        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;
            }
        }
Exemple #3
0
        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);
        }