Пример #1
0
        internal static ECParameters ExportNamedCurveParameters(CngKey key, bool includePrivateParameters)
        {
            byte[] ecBlob = ExportKeyBlob(key, includePrivateParameters);
            // We now have a buffer laid out as follows:
            //     BCRYPT_ECCKEY_BLOB   header
            //     byte[cbKey]          Q.X
            //     byte[cbKey]          Q.Y
            //     -- Private only --
            //     byte[cbKey]          D

            ECParameters ecParams = new ECParameters();

            KeyBlobMagicNumber magic = (KeyBlobMagicNumber)BitConverter.ToInt32(ecBlob, 0);

            // Check the magic value in the key blob header. If the blob does not have the required magic,
            // then throw a CryptographicException.
            CheckMagicValueOfKey(magic, includePrivateParameters);

            unsafe
            {
                // Fail-fast if a rogue provider gave us a blob that isn't even the size of the blob header.
                if (ecBlob.Length < sizeof(BCRYPT_ECCKEY_BLOB))
                    throw ErrorCode.E_FAIL.ToCryptographicException();

                fixed(byte *pEcBlob = ecBlob)
                {
                    BCRYPT_ECCKEY_BLOB *pBcryptBlob = (BCRYPT_ECCKEY_BLOB *)pEcBlob;

                    int offset = sizeof(BCRYPT_ECCKEY_BLOB);

                    ecParams.Q = new ECPoint
                    {
                        X = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey),
                        Y = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey)
                    };

                    if (includePrivateParameters)
                    {
                        ecParams.D = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey);
                    }
                }
            }

            ecParams.Curve = ECCurve.CreateFromFriendlyName(key.GetCurveName());

            return(ecParams);
        }
Пример #2
0
        internal static void ExportParameters(
            CngKey key,
            bool includePrivateParameters,
            ref ECParameters ecparams)
        {
            string curveName = key.GetCurveName();

            if (string.IsNullOrEmpty(curveName))
            {
                byte[] fullKeyBlob = ECCng.ExportFullKeyBlob(key, includePrivateParameters);
                ECCng.ExportPrimeCurveParameters(ref ecparams, fullKeyBlob, includePrivateParameters);
            }
            else
            {
                byte[] keyBlob = ECCng.ExportKeyBlob(key, includePrivateParameters);
                ECCng.ExportNamedCurveParameters(ref ecparams, keyBlob, includePrivateParameters);
                ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName);
            }
        }
        /// <summary>
        ///  Exports the key used by the ECC object into an <see cref="ECParameters"/> object.
        ///  If the key was created as a named curve, the Curve property will contain named curve parameters
        ///  otherwise it will contain explicit parameters.
        /// </summary>
        /// <exception cref="CryptographicException">
        ///  if there was an issue obtaining the curve values.
        /// </exception>
        /// <returns>The key and named curve parameters used by the ECC object.</returns>
        public override ECParameters ExportParameters()
        {
            using (CngKey key = Import())
            {
                ECParameters ecparams  = default;
                string?      curveName = key.GetCurveName(out _);

                if (string.IsNullOrEmpty(curveName))
                {
                    byte[] fullKeyBlob = ECCng.ExportFullKeyBlob(key, includePrivateParameters: false);
                    ECCng.ExportPrimeCurveParameters(ref ecparams, fullKeyBlob, includePrivateParameters: false);
                }
                else
                {
                    byte[] keyBlob = ECCng.ExportKeyBlob(key, includePrivateParameters: false);
                    ECCng.ExportNamedCurveParameters(ref ecparams, keyBlob, includePrivateParameters: false);
                    ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName);
                }

                return(ecparams);
            }
        }
Пример #4
0
        internal static byte[] ExportKeyBlob(
            CngKey key,
            bool includePrivateParameters,
            out CngKeyBlobFormat format,
            out string?curveName)
        {
            curveName = key.GetCurveName(out _);
            bool forceGenericBlob = false;

            if (string.IsNullOrEmpty(curveName))
            {
                // Normalize curveName to null.
                curveName = null;

                forceGenericBlob = true;
                format           = includePrivateParameters ?
                                   CngKeyBlobFormat.EccFullPrivateBlob :
                                   CngKeyBlobFormat.EccFullPublicBlob;
            }
            else
            {
                format = includePrivateParameters ?
                         CngKeyBlobFormat.EccPrivateBlob :
                         CngKeyBlobFormat.EccPublicBlob;
            }

            byte[] blob = key.Export(format);

            // Importing a known NIST curve as explicit parameters NCryptExportKey may
            // cause it to export with the dwMagic of the known curve and a generic blob body.
            // This combination can't be re-imported. So correct the dwMagic value to allow it
            // to import.
            if (forceGenericBlob)
            {
                FixupGenericBlob(blob);
            }

            return(blob);
        }