Exemplo n.º 1
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;
            }
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        public void Dispose()
        {
            if (m_kspHandle != null)
            {
                m_kspHandle.Dispose();
            }

            if (m_keyHandle != null)
            {
                m_keyHandle.Dispose();
            }
        }
Exemplo n.º 4
0
        public void Dispose()
        {
            if (_providerHandle != null)
            {
                _providerHandle.Dispose();
            }

            if (_keyHandle != null)
            {
                _keyHandle.Dispose();
            }
        }
Exemplo n.º 5
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;
            }
        }
Exemplo n.º 6
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)
            {
                keyHandle.Dispose();
                providerHandle.Dispose();
                throw errorCode.ToCryptographicException();
            }

            return(new CngKey(providerHandle, keyHandle));
        }
Exemplo n.º 7
0
        public static CngKey Create(CngAlgorithm algorithm, string?keyName, CngKeyCreationParameters?creationParameters)
        {
            ArgumentNullException.ThrowIfNull(algorithm);

            creationParameters ??= new CngKeyCreationParameters();

            SafeNCryptProviderHandle providerHandle = creationParameters.Provider !.OpenStorageProvider();
            SafeNCryptKeyHandle?     keyHandle      = null;

            try
            {
                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);
            }
            catch
            {
                keyHandle?.Dispose();
                providerHandle.Dispose();
                throw;
            }
        }
Exemplo n.º 8
0
 public void Dispose()
 {
     _providerHandle?.Dispose();
     _keyHandle?.Dispose();
 }