Exemple #1
0
        private static SscECParameters ConvertToECParameters(KVECParameters inputParameters)
        {
            var curve = inputParameters.Curve switch
            {
                "P-256" => ECCurve.NamedCurves.nistP256,
                "P-384" => ECCurve.NamedCurves.nistP384,
                "P521" => ECCurve.NamedCurves.nistP521,
                _ => throw new NotSupportedException(),
            };

            return(new SscECParameters
            {
                Curve = curve,
                D = inputParameters.D,
                Q = new ECPoint
                {
                    X = inputParameters.X,
                    Y = inputParameters.Y
                }
            });
        }
        internal static ECParameters FromEcdsa(ECDsaCng ecdsa, bool includePrivateParameters)
        {
            if (ecdsa == null)
            {
                throw new ArgumentNullException(nameof(ecdsa));
            }

            var keyBlobFormat = includePrivateParameters ? CngKeyBlobFormat.EccPrivateBlob : CngKeyBlobFormat.EccPublicBlob;
            var keyBlob       = ecdsa.Key.Export(keyBlobFormat);

            // If curve is generic, we need to export again to get the full blob.
            var dwMagic = BitConverter.ToInt32(keyBlob, 0);

            switch (dwMagic)
            {
            case BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC:
                keyBlob = ecdsa.Key.Export(CngKeyBlobFormat_EccFullPublicBlob);
                break;

            case BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC:
                keyBlob = ecdsa.Key.Export(CngKeyBlobFormat_EccFullPrivateBlob);
                break;
            }

            var result = new ECParameters();

            using (var reader = new BinaryReader(new MemoryStream(keyBlob)))
            {
                dwMagic = reader.ReadInt32();
                switch (dwMagic)
                {
                case BCRYPT_ECDSA_PUBLIC_P256_MAGIC:
                    ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_P256_MAGIC, dwMagic);
                    ReadNistBlob(reader, 32, result, false);
                    result.Curve = JsonWebKeyCurveName.P256;
                    break;

                case BCRYPT_ECDSA_PRIVATE_P256_MAGIC:
                    ReadNistBlob(reader, 32, result, true);
                    result.Curve = JsonWebKeyCurveName.P256;
                    break;

                case BCRYPT_ECDSA_PUBLIC_P384_MAGIC:
                    ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_P384_MAGIC, dwMagic);
                    ReadNistBlob(reader, 48, result, false);
                    result.Curve = JsonWebKeyCurveName.P384;
                    break;

                case BCRYPT_ECDSA_PRIVATE_P384_MAGIC:
                    ReadNistBlob(reader, 48, result, true);
                    result.Curve = JsonWebKeyCurveName.P384;
                    break;

                case BCRYPT_ECDSA_PUBLIC_P521_MAGIC:
                    ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_P521_MAGIC, dwMagic);
                    ReadNistBlob(reader, 66, result, false);
                    result.Curve = JsonWebKeyCurveName.P521;
                    break;

                case BCRYPT_ECDSA_PRIVATE_P521_MAGIC:
                    ReadNistBlob(reader, 66, result, true);
                    result.Curve = JsonWebKeyCurveName.P521;
                    break;

                case BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC:
                    ThrowIfPrivateParametersNeeded(includePrivateParameters, BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC, dwMagic);
                    ReadGenericBlob(reader, 32, result, false);
                    break;

                case BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC:
                    ReadGenericBlob(reader, 32, result, true);
                    break;

                default:
                    throw new NotSupportedException($"Unexpected CNG key blob type. Magic number: 0x{dwMagic:X}.");
                }
            }

            return(result);
        }
        /// <summary>
        /// Exports EC parameters from a CNG object.
        /// </summary>
        /// <param name="ecdsa">The CNG object initialized with desired key</param>
        /// <param name="includePrivateParameters">Determines whether the private key part is to be exported.</param>
        /// <returns></returns>
        public static ECParameters ExportParameters(this ECDsa ecdsa, bool includePrivateParameters)
        {
            var ecdsaCng = GetEcdsaCng(ecdsa);

            return(ECParameters.FromEcdsa(ecdsaCng, includePrivateParameters));
        }