示例#1
0
        public static CngKey Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
        {
            Contract.Ensures(Contract.Result <CngKey>() != null);

            if (keyName == null)
            {
                throw new ArgumentNullException("keyName");
            }
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            // Make sure that NCrypt is supported on this platform
            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
            }

            // Ensure the user has access to the key name
            KeyContainerPermissionAccessEntry access = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Open);

            access.ProviderName = provider.Provider;

            KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);

            permission.AccessEntries.Add(access);
            permission.Demand();

            // Open the key
            SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(provider.Provider);
            SafeNCryptKeyHandle      keyHandle = NCryptNative.OpenKey(kspHandle, keyName, openOptions);

            return(new CngKey(kspHandle, keyHandle));
        }
示例#2
0
        public static CngKey Create(CngAlgorithm algorithm, string?keyName, CngKeyCreationParameters?creationParameters)
        {
            ArgumentNullException.ThrowIfNull(algorithm);

            creationParameters ??= new CngKeyCreationParameters();

            SafeNCryptProviderHandle providerHandle = creationParameters.Provider !.OpenStorageProvider();
            SafeNCryptKeyHandle      keyHandle;
            ErrorCode errorCode = Interop.NCrypt.NCryptCreatePersistedKey(providerHandle, out keyHandle, algorithm.Algorithm, keyName, 0, creationParameters.KeyCreationOptions);

            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                // For ecc, the exception may be caught and re-thrown as PlatformNotSupportedException
                throw errorCode.ToCryptographicException();
            }

            InitializeKeyProperties(keyHandle, creationParameters);

            errorCode = Interop.NCrypt.NCryptFinalizeKey(keyHandle, 0);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                // For ecc, the exception may be caught and re-thrown as PlatformNotSupportedException
                throw errorCode.ToCryptographicException();
            }

            CngKey key = new CngKey(providerHandle, keyHandle);

            // No name translates to an ephemeral key
            if (keyName == null)
            {
                key.IsEphemeral = true;
            }

            return(key);
        }
示例#3
0
 public static extern Int32 NCryptEnumAlgorithms(
     SafeNCryptProviderHandle hProvider,
     UInt32 dwAlgOperations,
     ref Int32 pdwAlgCount,
     ref IntPtr ppAlgList,
     UInt32 dwFlags
     );
示例#4
0
        /// <summary>
        /// Gets all key containers from Cng provider.
        /// </summary>
        /// <param name="containers">List of containers</param>
        /// <param name="hProvider">Provider handle</param>
        /// <param name="getMachineKeys">Indicates whether to obtain machine keys</param>
        internal static void GetContainersFromCngProvider(List <string> containers, SafeNCryptProviderHandle hProvider, bool getMachineKeys)
        {
            int flags = getMachineKeys ? NCryptMethods.NCRYPT_MACHINE_KEY_FLAG : 0;

            unsafe
            {
                void *enumState = null;
                int   status;

                while (true)
                {
                    // Potentially display a UI.
                    status = NCryptMethods.NCryptEnumKeys(hProvider, null, out NCryptMethods.NCryptKeyName * keyName, ref enumState, flags);
                    if (status == NCryptMethods.NTE_NO_MORE_ITEMS ||
                        status == NCryptMethods.NTE_BAD_FLAGS ||     // some providers don't support Machine keys
                        status == NCryptMethods.SCARD_E_NO_READERS_AVAILABLE ||
                        status == NCryptMethods.SCARD_W_CANCELLED_BY_USER)
                    {
                        // Done with this provider, or the user cancelled the UI.
                        break;
                    }
                    else if (status != 0)
                    {
                        // Failed to read this one, read the next key.
                        continue;
                    }
                    containers.Add(keyName[0].Name);
                    NCryptMethods.NCryptFreeBuffer(keyName);
                }
            }
        }
示例#5
0
        public static bool Exists(string keyName, CngProvider provider, CngKeyOpenOptions options)
        {
            bool flag2;

            if (keyName == null)
            {
                throw new ArgumentNullException("keyName");
            }
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported"));
            }
            using (SafeNCryptProviderHandle handle = NCryptNative.OpenStorageProvider(provider.Provider))
            {
                using (SafeNCryptKeyHandle handle2 = null)
                {
                    NCryptNative.ErrorCode code = NCryptNative.UnsafeNativeMethods.NCryptOpenKey(handle, out handle2, keyName, 0, options);
                    bool flag = (code == NCryptNative.ErrorCode.KeyDoesNotExist) || (code == NCryptNative.ErrorCode.NotFound);
                    if ((code != NCryptNative.ErrorCode.Success) && !flag)
                    {
                        throw new CryptographicException((int)code);
                    }
                    flag2 = code == NCryptNative.ErrorCode.Success;
                }
            }
            return(flag2);
        }
示例#6
0
 public static extern Int32 NCryptOpenKey(
     [In] SafeNCryptProviderHandle hProvider,
     [Out] out SafeNCryptKeyHandle phKey,
     [MarshalAs(UnmanagedType.LPWStr)][In] String pszKeyName,
     [In] UInt32 dwLegacyKeySpec,
     [In] UInt32 dwFlags
     );
示例#7
0
        public static CngKey Import(byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider)
        {
            if (keyBlob == null)
            {
                throw new ArgumentNullException("keyBlob");
            }
            if (format == null)
            {
                throw new ArgumentNullException("format");
            }
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported"));
            }
            if ((format != CngKeyBlobFormat.EccPublicBlob) && (format != CngKeyBlobFormat.GenericPublicBlob))
            {
                new KeyContainerPermission(KeyContainerPermissionFlags.Import).Demand();
            }
            SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(provider.Provider);

            return(new CngKey(kspHandle, NCryptNative.ImportKey(kspHandle, keyBlob, format.Format))
            {
                IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob
            });
        }
示例#8
0
        public static CngKey Open(string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
        {
            if (keyName == null)
            {
                throw new ArgumentNullException("keyName");
            }
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }
            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported"));
            }
            KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Open)
            {
                ProviderName = provider.Provider
            };
            KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);

            permission.AccessEntries.Add(accessEntry);
            permission.Demand();
            SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(provider.Provider);

            return(new CngKey(kspHandle, NCryptNative.OpenKey(kspHandle, keyName, openOptions)));
        }
示例#9
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();
                    }
                }
            }
        }
示例#10
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);
        }
 private static extern SECURITY_STATUS NCryptCreatePersistedKey(
     SafeNCryptProviderHandle hProvider,
     [Out] out SafeNCryptKeyHandle phKey,
     string pszAlgId,
     string pszKeyName,
     int dwLegacyKeySpec,
     CngKeyCreationOptions dwFlags);
示例#12
0
        internal static SafeNCryptKeyHandle ImportKeyBlob(
            string blobType,
            ReadOnlySpan <byte> keyBlob,
            string curveName,
            SafeNCryptProviderHandle provider)
        {
            ErrorCode           errorCode;
            SafeNCryptKeyHandle keyHandle;

            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(
                        provider,
                        IntPtr.Zero,
                        blobType,
                        descPtr,
                        out keyHandle,
                        ref MemoryMarshal.GetReference(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;
            }

            return(keyHandle);
        }
示例#13
0
 internal static extern int NCryptImportKey(SafeNCryptProviderHandle hProvider,
                                            IntPtr hImportKey,
                                            [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType,
                                            [In, MarshalAs(UnmanagedType.LPArray)] byte[] pParameterList,
                                            out SafeNCryptKeyHandle phKey,
                                            [In, MarshalAs(UnmanagedType.LPArray)] byte[] pbData,
                                            int cbData,
                                            int dwFlags);
示例#14
0
        private CngKey(SafeNCryptProviderHandle providerHandle, SafeNCryptKeyHandle keyHandle)
        {
            Debug.Assert(keyHandle != null && !keyHandle.IsInvalid && !keyHandle.IsClosed);
            Debug.Assert(providerHandle != null && !providerHandle.IsInvalid && !providerHandle.IsClosed);

            _providerHandle = providerHandle;
            _keyHandle      = keyHandle;
        }
 internal static extern int NCryptImportKey(
     SafeNCryptProviderHandle hProvider,
     IntPtr hImportKey,     // NCRYPT_KEY_HANDLE
     string pszBlobType,
     IntPtr pParameterList, // NCryptBufferDesc *
     [Out] out SafeNCryptKeyHandle phKey,
     [MarshalAs(UnmanagedType.LPArray)] byte[] pbData,
     int cbData,
     int dwFlags);
示例#16
0
 public static extern int NCryptImportKey(
     SafeNCryptProviderHandle hProvider,
     IntPtr hImportKey,
     string pszBlobType,
     ref NCryptBufferDesc pParameterList,
     out SafeNCryptKeyHandle phKey,
     IntPtr pbData,
     int cbData,
     NCryptImportFlags dwFlags);
示例#17
0
        internal static SafeNCryptKeyHandle ImportKeyBlob(
            string blobType,
            byte[] keyBlob,
            string curveName,
            SafeNCryptProviderHandle provider)
        {
            SafeNCryptKeyHandle keyHandle;

            var desc = new Interop.BCrypt.BCryptBufferDesc();
            var buff = new Interop.BCrypt.BCryptBuffer();

            IntPtr descPtr      = IntPtr.Zero;
            IntPtr buffPtr      = IntPtr.Zero;
            IntPtr curveNamePtr = IntPtr.Zero;

            try
            {
                curveNamePtr    = Marshal.StringToHGlobalUni(curveName);
                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   = curveNamePtr;
                Marshal.StructureToPtr(buff, buffPtr, false);

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

                keyHandle = NCryptNative.ImportKey(
                    provider,
                    keyBlob,
                    blobType,
                    descPtr);
            }
            catch (CryptographicException e)
            {
                if (e.HResult == (int)ErrorCode.NTE_INVALID_PARAMETER)
                {
                    throw new PlatformNotSupportedException(
                              SR.GetString(SR.Cryptography_CurveNotSupported, curveName),
                              e);
                }

                throw;
            }
            finally
            {
                Marshal.FreeHGlobal(descPtr);
                Marshal.FreeHGlobal(buffPtr);
                Marshal.FreeHGlobal(curveNamePtr);
            }

            return(keyHandle);
        }
示例#18
0
 public static IEnumerable <CngKey> GetKeys(this CngProvider provider, CngKeyOpenOptions openOptions)
 {
     using (SafeNCryptProviderHandle providerHandle = provider.OpenProvider())
     {
         foreach (var key in NCryptNative.EnumerateKeys(providerHandle, openOptions))
         {
             yield return(CngKey.Open(key.pszName, provider));
         }
     }
 }
示例#19
0
        private CngKey(SafeNCryptProviderHandle kspHandle, SafeNCryptKeyHandle keyHandle)
        {
            Contract.Requires(keyHandle != null && !keyHandle.IsInvalid && !keyHandle.IsClosed);
            Contract.Requires(kspHandle != null && !kspHandle.IsInvalid && !kspHandle.IsClosed);
            Contract.Ensures(m_keyHandle != null && !m_keyHandle.IsInvalid && !m_keyHandle.IsClosed);
            Contract.Ensures(kspHandle != null && !kspHandle.IsInvalid && !kspHandle.IsClosed);

            m_keyHandle = keyHandle;
            m_kspHandle = kspHandle;
        }
示例#20
0
        internal static CngKey Import(byte[] keyBlob, string curveName, CngKeyBlobFormat format, CngProvider provider)
        {
            Contract.Ensures(Contract.Result <CngKey>() != null);
            if (keyBlob == null)
            {
                throw new ArgumentNullException("keyBlob");
            }
            if (format == null)
            {
                throw new ArgumentNullException("format");
            }
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            // Make sure that NCrypt is supported on this platform
            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
            }

            // If we don't know for sure that the key will be ephemeral, then we need to demand Import
            // permission.  Since we won't know the name of the key until it's too late, we demand a full Import
            // rather than one scoped to the key.
            bool safeKeyImport = format == CngKeyBlobFormat.EccPublicBlob ||
                                 format == CngKeyBlobFormat.EccFullPublicBlob ||
                                 format == CngKeyBlobFormat.GenericPublicBlob;

            if (!safeKeyImport)
            {
                new KeyContainerPermission(KeyContainerPermissionFlags.Import).Demand();
            }

            // Import the key into the KSP
            SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(provider.Provider);
            SafeNCryptKeyHandle      keyHandle;

            if (curveName == null)
            {
                keyHandle = NCryptNative.ImportKey(kspHandle, keyBlob, format.Format);
            }
            else
            {
                keyHandle = ECCng.ImportKeyBlob(format.Format, keyBlob, curveName, kspHandle);
            }

            // Prepare the key for use
            CngKey key = new CngKey(kspHandle, keyHandle);

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

            return(key);
        }
示例#21
0
        public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters)
        {
            Contract.Ensures(Contract.Result <CngKey>() != null);

            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            if (creationParameters == null)
            {
                creationParameters = new CngKeyCreationParameters();
            }

            // Make sure that NCrypt is supported on this platform
            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
            }

            // If we're not creating an ephemeral key, then we need to ensure the user has access to the key name
            if (keyName != null)
            {
                KeyContainerPermissionAccessEntry access = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Create);
                access.ProviderName = creationParameters.Provider.Provider;

                KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
                permission.AccessEntries.Add(access);
                permission.Demand();
            }

            //
            // Create the native handles representing the new key, setup the creation parameters on it, and
            // finalize it for use.
            //

            SafeNCryptProviderHandle kspHandle = NCryptNative.OpenStorageProvider(creationParameters.Provider.Provider);
            SafeNCryptKeyHandle      keyHandle = NCryptNative.CreatePersistedKey(kspHandle,
                                                                                 algorithm.Algorithm,
                                                                                 keyName,
                                                                                 creationParameters.KeyCreationOptions);

            SetKeyProperties(keyHandle, creationParameters);
            NCryptNative.FinalizeKey(keyHandle);

            CngKey key = new CngKey(kspHandle, keyHandle);

            // No name translates to an ephemeral key
            if (keyName == null)
            {
                key.IsEphemeral = true;
            }

            return(key);
        }
示例#22
0
 public static IEnumerable <CngAlgorithm> GetSupportedAlgorithms(this CngProvider provider,
                                                                 NCryptAlgorithmOperations operations)
 {
     using (SafeNCryptProviderHandle providerHandle = provider.OpenProvider())
     {
         foreach (NCryptNative.NCryptAlgorithmName algorithm in NCryptNative.EnumerateAlgorithms(providerHandle, operations))
         {
             yield return(new CngAlgorithm(algorithm.pszName));
         }
     }
 }
示例#23
0
 public static extern Int32 NCryptImportKey(
     [In] SafeNCryptProviderHandle hProvider,
     [In, Optional] IntPtr hImportKey,
     [MarshalAs(UnmanagedType.LPWStr)]
     [In] String pszBlobType,
     [In, Optional] IntPtr pParameterList,
     [Out] out SafeNCryptKeyHandle phKey,
     [In] Byte[] pbData,
     [In] Int32 cbData,
     [In] UInt32 dwFlags
     );
        internal static SafeNCryptKeyHandle OpenKey(SafeNCryptProviderHandle provider, string name, CngKeyOpenOptions options)
        {
            SafeNCryptKeyHandle phKey = null;
            ErrorCode           code  = UnsafeNativeMethods.NCryptOpenKey(provider, out phKey, name, 0, options);

            if (code != ErrorCode.Success)
            {
                throw new CryptographicException((int)code);
            }
            return(phKey);
        }
        internal static SafeNCryptKeyHandle ImportKey(SafeNCryptProviderHandle provider, byte[] keyBlob, string format)
        {
            SafeNCryptKeyHandle phKey = null;
            ErrorCode           code  = UnsafeNativeMethods.NCryptImportKey(provider, IntPtr.Zero, format, IntPtr.Zero, out phKey, keyBlob, keyBlob.Length, 0);

            if (code != ErrorCode.Success)
            {
                throw new CryptographicException((int)code);
            }
            return(phKey);
        }
示例#26
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);
        }
示例#27
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;
            }
        }
        internal static SafeNCryptProviderHandle OpenStorageProvider(string providerName)
        {
            SafeNCryptProviderHandle phProvider = null;
            ErrorCode code = UnsafeNativeMethods.NCryptOpenStorageProvider(out phProvider, providerName, 0);

            if (code != ErrorCode.Success)
            {
                throw new CryptographicException((int)code);
            }
            return(phProvider);
        }
示例#29
0
        internal static CngKey OpenNoDuplicate(SafeNCryptKeyHandle keyHandle, CngKeyHandleOpenOptions keyHandleOpenOptions)
        {
            SafeNCryptProviderHandle?providerHandle = null;

            try
            {
                // Get a handle to the key's provider.
                providerHandle = new SafeNCryptProviderHandle();
                IntPtr rawProviderHandle = keyHandle.GetPropertyAsIntPtr(KeyPropertyName.ProviderHandle, CngPropertyOptions.None);
                Marshal.InitHandle(providerHandle, rawProviderHandle);

                // If we're wrapping a handle to an ephemeral key, we need to make sure that IsEphemeral is
                // set up to return true.  In the case that the handle is for an ephemeral key that was created
                // by the CLR, then we don't have anything to do as the IsEphemeral CLR property will already
                // be setup.  However, if the key was created outside of the CLR we will need to setup our
                // ephemeral detection property.
                //
                // This enables consumers of CngKey objects to always be able to rely on the result of
                // calling IsEphemeral, and also allows them to safely access the Name property.
                //
                // Finally, if we detect that this is an ephemeral key that the CLR created but we were not
                // told that it was an ephemeral key we'll throw an exception.  This prevents us from having
                // to decide who to believe -- the key property or the caller of the API.  Since other code
                // relies on the ephemeral flag being set properly to avoid tripping over bugs in CNG, we
                // need to reject the case that we suspect that the flag is incorrect.

                var key = new CngKey(providerHandle, keyHandle);

                bool openingEphemeralKey = (keyHandleOpenOptions & CngKeyHandleOpenOptions.EphemeralKey) == CngKeyHandleOpenOptions.EphemeralKey;
                if (!key.IsEphemeral)
                {
                    if (openingEphemeralKey)
                    {
                        key.IsEphemeral = true;
                    }
                }
                else if (!openingEphemeralKey)
                {
                    throw new ArgumentException(SR.Cryptography_OpenEphemeralKeyHandleWithoutEphemeralFlag, nameof(keyHandleOpenOptions));
                }

                return(key);
            }
            catch
            {
                // Make sure that we don't leak the handles
                providerHandle?.Dispose();
                keyHandle.Dispose();
                throw;
            }
        }
示例#30
0
        internal static NCryptKeyName[] EnumerateKeys(SafeNCryptProviderHandle provider,
                                                      CngKeyOpenOptions openOptions)
        {
            Debug.Assert(provider != null && !provider.IsClosed && !provider.IsInvalid, "Invalid provider");

            IntPtr           enumState       = IntPtr.Zero;
            SafeNCryptBuffer algorithmBuffer = null;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                List <NCryptKeyName> keys = new List <NCryptKeyName>();

                ErrorCode enumStatus = ErrorCode.Success;

                // Loop over the NCryptEnumKeys until it tells us that there are no more keys to enumerate
                do
                {
                    enumStatus = UnsafeNativeMethods.NCryptEnumKeys(provider,
                                                                    null,
                                                                    out algorithmBuffer,
                                                                    ref enumState,
                                                                    openOptions);

                    if (enumStatus == ErrorCode.Success)
                    {
                        keys.Add(algorithmBuffer.ReadArray <NCryptKeyName>(0));
                    }
                    else if (enumStatus != ErrorCode.NoMoreItems)
                    {
                        throw new CryptographicException((int)enumStatus);
                    }
                }while (enumStatus == ErrorCode.Success);

                return(keys.ToArray());
            }
            finally
            {
                if (enumState != IntPtr.Zero)
                {
                    UnsafeNativeMethods.NCryptFreeBuffer(enumState);
                }

                if (algorithmBuffer != null)
                {
                    algorithmBuffer.Dispose();
                }
            }
        }