Пример #1
0
        private static byte[] GetNamedCurveBlob(
            ref ECParameters parameters,
            Func <string, bool, KeyBlobMagicNumber> magicResolver)
        {
            Debug.Assert(parameters.Curve.IsNamed);

            bool includePrivateParameters = (parameters.D != null);

            byte[] blob;
            int    offset;
            int    blobSize;

            // We need to build a key blob structured as follows:
            //     BCRYPT_ECCKEY_BLOB   header
            //     byte[cbKey]          Q.X
            //     byte[cbKey]          Q.Y
            //     -- Only if "includePrivateParameters" is true --
            //     byte[cbKey]          D

            unsafe
            {
                blobSize = sizeof(BCRYPT_ECCKEY_BLOB) +
                           parameters.Q.X.Length +
                           parameters.Q.Y.Length;

                if (includePrivateParameters)
                {
                    blobSize += parameters.D.Length;
                }

                blob = new byte[blobSize];

                fixed(byte *pBlob = blob)
                {
                    // Build the header
                    BCRYPT_ECCKEY_BLOB *pBcryptBlob = (BCRYPT_ECCKEY_BLOB *)pBlob;

                    pBcryptBlob->Magic = magicResolver(parameters.Curve.Oid.FriendlyName, includePrivateParameters);
                    pBcryptBlob->cbKey = parameters.Q.X.Length;
                }

                offset = sizeof(BCRYPT_ECCKEY_BLOB);
            }

            // Emit the blob
            Interop.BCrypt.Emit(blob, ref offset, parameters.Q.X);
            Interop.BCrypt.Emit(blob, ref offset, parameters.Q.Y);
            if (includePrivateParameters)
            {
                Interop.BCrypt.Emit(blob, ref offset, parameters.D);
            }

            // We better have computed the right allocation size above!
            Debug.Assert(offset == blobSize, "offset == blobSize");
            return(blob);
        }
Пример #2
0
        internal static byte[] GetNamedCurveBlob(ref ECParameters parameters, bool ecdh)
        {
            Debug.Assert(parameters.Curve.IsNamed);

            bool includePrivateParameters = (parameters.D != null);

            byte[] blob;
            unsafe
            {
                // We need to build a key blob structured as follows:
                //     BCRYPT_ECCKEY_BLOB   header
                //     byte[cbKey]          Q.X
                //     byte[cbKey]          Q.Y
                //     -- Only if "includePrivateParameters" is true --
                //     byte[cbKey]          D

                int blobSize = sizeof(BCRYPT_ECCKEY_BLOB) +
                               parameters.Q.X !.Length +
                               parameters.Q.Y !.Length;
                if (includePrivateParameters)
                {
                    blobSize += parameters.D !.Length;
                }

                blob = new byte[blobSize];
                fixed(byte *pBlob = &blob[0])
                {
                    // Build the header
                    BCRYPT_ECCKEY_BLOB *pBcryptBlob = (BCRYPT_ECCKEY_BLOB *)pBlob;

                    pBcryptBlob->Magic = ecdh ?
                                         EcdhCurveNameToMagicNumber(parameters.Curve.Oid.FriendlyName, includePrivateParameters) :
                                         EcdsaCurveNameToMagicNumber(parameters.Curve.Oid.FriendlyName, includePrivateParameters);
                    pBcryptBlob->cbKey = parameters.Q.X.Length;

                    // Emit the blob
                    int offset = sizeof(BCRYPT_ECCKEY_BLOB);

                    Interop.BCrypt.Emit(blob, ref offset, parameters.Q.X);
                    Interop.BCrypt.Emit(blob, ref offset, parameters.Q.Y);
                    if (includePrivateParameters)
                    {
                        Interop.BCrypt.Emit(blob, ref offset, parameters.D !);
                    }

                    // We better have computed the right allocation size above!
                    Debug.Assert(offset == blobSize, "offset == blobSize");
                }
            }
            return(blob);
        }
Пример #3
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);
        }
Пример #4
0
        private static unsafe void FixupGenericBlob(byte[] blob)
        {
            if (blob.Length > sizeof(BCRYPT_ECCKEY_BLOB))
            {
                fixed(byte *pBlob = blob)
                {
                    BCRYPT_ECCKEY_BLOB *pBcryptBlob = (BCRYPT_ECCKEY_BLOB *)pBlob;

                    switch ((KeyBlobMagicNumber)pBcryptBlob->Magic)
                    {
                    case KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P256_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P384_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_P521_MAGIC:
                        pBcryptBlob->Magic = KeyBlobMagicNumber.BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC;
                        break;

                    case KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P256_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P384_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_P521_MAGIC:
                        pBcryptBlob->Magic = KeyBlobMagicNumber.BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC;
                        break;

                    case KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P256_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P384_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_P521_MAGIC:
                        pBcryptBlob->Magic = KeyBlobMagicNumber.BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC;
                        break;

                    case KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P256_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P384_MAGIC:
                    case KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_P521_MAGIC:
                        pBcryptBlob->Magic = KeyBlobMagicNumber.BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC;
                        break;
                    }
                }
            }
        }
Пример #5
0
            private unsafe CngKey BuildEcKey(byte[] x, byte[] y, Asn1Token.KnownOid curve)
            {
                int headerSize = Marshal.SizeOf(typeof(BCRYPT_ECCKEY_BLOB));
                int blobSize   = headerSize + x.Length + y.Length;

                byte[] blobBytes = new byte[blobSize];

                fixed(byte *pBlobBytes = blobBytes)
                {
                    BCRYPT_ECCKEY_BLOB *pBcryptEccBlob = (BCRYPT_ECCKEY_BLOB *)pBlobBytes;

                    pBcryptEccBlob->KeyBlobMagicNumber = GetMagicNumber(curve);
                    pBcryptEccBlob->KeySizeBytes       = x.Length;

                    Buffer.BlockCopy(x, 0, blobBytes, headerSize, x.Length);
                    Buffer.BlockCopy(y, 0, blobBytes, headerSize + x.Length, y.Length);
                }

                new KeyContainerPermission(KeyContainerPermissionFlags.Import).Assert();
                var key = CngKey.Import(blobBytes, CngKeyBlobFormat.EccPublicBlob);

                CodeAccessPermission.RevertAssert();
                return(key);
            }