示例#1
0
        public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider)
        {
            if (keyBlob == null)
            {
                throw new ArgumentNullException(nameof(keyBlob));
            }
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }
            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

            SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider();
            SafeNCryptKeyHandle      keyHandle;
            ErrorCode errorCode = Interop.NCrypt.NCryptImportKey(providerHandle, IntPtr.Zero, format.Format, IntPtr.Zero, out keyHandle, keyBlob, keyBlob.Length, 0);

            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }

            CngKey key = new CngKey(providerHandle, keyHandle);

            // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not
            key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob;

            return(key);
        }
示例#2
0
        public static bool Exists(string keyName, CngProvider provider, CngKeyOpenOptions options)
        {
            ArgumentNullException.ThrowIfNull(keyName);
            ArgumentNullException.ThrowIfNull(provider);

            using (SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider())
            {
                SafeNCryptKeyHandle?keyHandle = null;
                try
                {
                    ErrorCode errorCode = Interop.NCrypt.NCryptOpenKey(providerHandle, out keyHandle, keyName, 0, options);
                    if (errorCode == ErrorCode.NTE_BAD_KEYSET)
                    {
                        return(false);
                    }
                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        throw errorCode.ToCryptographicException();
                    }
                    return(true);
                }
                finally
                {
                    if (keyHandle != null)
                    {
                        keyHandle.Dispose();
                    }
                }
            }
        }
示例#3
0
        internal static unsafe CngKey ImportEncryptedPkcs8(
            ReadOnlySpan <byte> keyBlob,
            ReadOnlySpan <char> password,
            CngProvider provider)
        {
            SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider();
            SafeNCryptKeyHandle      keyHandle;

            using (SafeUnicodeStringHandle passwordHandle = new SafeUnicodeStringHandle(password))
            {
                Interop.NCrypt.NCryptBuffer *buffers = stackalloc Interop.NCrypt.NCryptBuffer[1];

                buffers[0] = new Interop.NCrypt.NCryptBuffer
                {
                    BufferType = Interop.NCrypt.BufferType.PkcsSecret,
                    cbBuffer   = checked (2 * (password.Length + 1)),
                    pvBuffer   = passwordHandle.DangerousGetHandle(),
                };

                if (buffers[0].pvBuffer == IntPtr.Zero)
                {
                    buffers[0].cbBuffer = 0;
                }

                Interop.NCrypt.NCryptBufferDesc desc = new Interop.NCrypt.NCryptBufferDesc
                {
                    cBuffers  = 1,
                    pBuffers  = (IntPtr)buffers,
                    ulVersion = 0,
                };

                ErrorCode errorCode = Interop.NCrypt.NCryptImportKey(
                    providerHandle,
                    IntPtr.Zero,
                    Interop.NCrypt.NCRYPT_PKCS8_PRIVATE_KEY_BLOB,
                    ref desc,
                    out keyHandle,
                    ref MemoryMarshal.GetReference(keyBlob),
                    keyBlob.Length,
                    0);

                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    keyHandle.Dispose();
                    providerHandle.Dispose();
                    throw errorCode.ToCryptographicException();
                }
            }

            CngKey key = new CngKey(providerHandle, keyHandle);

            key.IsEphemeral = true;
            return(key);
        }
示例#4
0
        internal static CngKey Import(
            ReadOnlySpan <byte> keyBlob,
            string?curveName,
            CngKeyBlobFormat format,
            CngProvider provider)
        {
            ArgumentNullException.ThrowIfNull(format);
            ArgumentNullException.ThrowIfNull(provider);

            SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider();
            SafeNCryptKeyHandle?     keyHandle      = null;

            try
            {
                ErrorCode errorCode;

                if (curveName == null)
                {
                    errorCode = Interop.NCrypt.NCryptImportKey(
                        providerHandle,
                        IntPtr.Zero,
                        format.Format,
                        IntPtr.Zero,
                        out keyHandle,
                        ref MemoryMarshal.GetReference(keyBlob),
                        keyBlob.Length,
                        0);

                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        providerHandle.Dispose();
                        keyHandle.Dispose();
                        throw errorCode.ToCryptographicException();
                    }
                }
                else
                {
                    keyHandle = ECCng.ImportKeyBlob(format.Format, keyBlob, curveName, providerHandle);
                }

                CngKey key = new CngKey(providerHandle, keyHandle);

                // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not
                key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob;

                return(key);
            }
            catch
            {
                keyHandle?.Dispose();
                providerHandle.Dispose();
                throw;
            }
        }
示例#5
0
        public static CngKey Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
        {
            ArgumentNullException.ThrowIfNull(keyName);
            ArgumentNullException.ThrowIfNull(provider);

            SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider();
            SafeNCryptKeyHandle      keyHandle;
            ErrorCode errorCode = Interop.NCrypt.NCryptOpenKey(providerHandle, out keyHandle, keyName, 0, openOptions);

            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }

            return(new CngKey(providerHandle, keyHandle));
        }
示例#6
0
        internal static CngKey Import(byte[] keyBlob, ECCurve?curve, CngKeyBlobFormat format, CngProvider provider)
        {
#endif //!NETNATIVE
            if (keyBlob == null)
            {
                throw new ArgumentNullException(nameof(keyBlob));
            }
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }
            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

            SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider();
            SafeNCryptKeyHandle      keyHandle;
            ErrorCode errorCode;

#if !NETNATIVE
            if (curve == null)
#endif //!NETNATIVE
            {
                errorCode = Interop.NCrypt.NCryptImportKey(providerHandle, IntPtr.Zero, format.Format, IntPtr.Zero, out keyHandle, keyBlob, keyBlob.Length, 0);
                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
            }
#if !NETNATIVE
            else
            {
                // Call with Oid.FriendlyName because .Value will result in an invalid parameter error
                Debug.Assert(curve.Value.IsNamed);
                string curveName = curve.Value.Oid.FriendlyName;
                using (SafeUnicodeStringHandle safeCurveName = new SafeUnicodeStringHandle(curveName))
                {
                    var desc = new Interop.BCrypt.BCryptBufferDesc();
                    var buff = new Interop.BCrypt.BCryptBuffer();

                    IntPtr descPtr = IntPtr.Zero;
                    IntPtr buffPtr = IntPtr.Zero;
                    try
                    {
                        descPtr         = Marshal.AllocHGlobal(Marshal.SizeOf(desc));
                        buffPtr         = Marshal.AllocHGlobal(Marshal.SizeOf(buff));
                        buff.cbBuffer   = (curveName.Length + 1) * 2; // Add 1 for null terminator
                        buff.BufferType = Interop.BCrypt.NCryptBufferDescriptors.NCRYPTBUFFER_ECC_CURVE_NAME;
                        buff.pvBuffer   = safeCurveName.DangerousGetHandle();
                        Marshal.StructureToPtr(buff, buffPtr, false);

                        desc.cBuffers  = 1;
                        desc.pBuffers  = buffPtr;
                        desc.ulVersion = Interop.BCrypt.BCRYPTBUFFER_VERSION;
                        Marshal.StructureToPtr(desc, descPtr, false);

                        errorCode = Interop.NCrypt.NCryptImportKey(providerHandle, IntPtr.Zero, format.Format, descPtr, out keyHandle, keyBlob, keyBlob.Length, 0);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(descPtr);
                        Marshal.FreeHGlobal(buffPtr);
                    }
                }

                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    Exception e = errorCode.ToCryptographicException();
                    if (errorCode == ErrorCode.NTE_INVALID_PARAMETER)
                    {
                        throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curveName), e);
                    }
                    throw e;
                }
            }
#endif //!NETNATIVE

            CngKey key = new CngKey(providerHandle, keyHandle);

            // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not
            key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob;

            return(key);
        }