Ejemplo n.º 1
0
        /// <summary>
        ///     Setup the key properties specified in the key creation parameters
        /// </summary>
        private static void InitializeKeyProperties(SafeNCryptKeyHandle keyHandle, CngKeyCreationParameters creationParameters)
        {
            unsafe
            {
                if (creationParameters.ExportPolicy.HasValue)
                {
                    CngExportPolicies exportPolicy = creationParameters.ExportPolicy.Value;
                    keyHandle.SetExportPolicy(exportPolicy);
                }

                if (creationParameters.KeyUsage.HasValue)
                {
                    CngKeyUsages keyUsage  = creationParameters.KeyUsage.Value;
                    ErrorCode    errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.KeyUsage, &keyUsage, sizeof(CngKeyUsages), CngPropertyOptions.Persist);
                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        throw errorCode.ToCryptographicException();
                    }
                }

                if (creationParameters.ParentWindowHandle != IntPtr.Zero)
                {
                    IntPtr    parentWindowHandle = creationParameters.ParentWindowHandle;
                    ErrorCode errorCode          = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.ParentWindowHandle, &parentWindowHandle, sizeof(IntPtr), CngPropertyOptions.None);
                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        throw errorCode.ToCryptographicException();
                    }
                }

                CngUIPolicy uiPolicy = creationParameters.UIPolicy;
                if (uiPolicy != null)
                {
                    InitializeKeyUiPolicyProperties(keyHandle, uiPolicy);
                }

                // Iterate over the custom properties, setting those as well.
                foreach (CngProperty property in creationParameters.Parameters)
                {
                    byte[] value       = property.GetValueWithoutCopying();
                    int    valueLength = (value == null) ? 0 : value.Length;
                    fixed(byte *pValue = value.MapZeroLengthArrayToNonNullPointer())
                    {
                        ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, property.Name, pValue, valueLength, property.Options);

                        if (errorCode != ErrorCode.ERROR_SUCCESS)
                        {
                            throw errorCode.ToCryptographicException();
                        }
                    }
                }
            }
        }
Ejemplo 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();
                    throw errorCode.ToCryptographicException();
                }
            }

            CngKey key = new CngKey(providerHandle, keyHandle);

            key.IsEphemeral = true;
            return(key);
        }
Ejemplo n.º 3
0
        public static SafeNCryptProviderHandle OpenStorageProvider(this CngProvider provider)
        {
            string providerName = provider.Provider;
            SafeNCryptProviderHandle providerHandle;
            ErrorCode errorCode = Interop.NCrypt.NCryptOpenStorageProvider(out providerHandle, providerName, 0);

            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }
            return(providerHandle);
        }
Ejemplo n.º 4
0
        private static SafeNCryptProviderHandle OpenNCryptProvider(string providerName)
        {
            SafeNCryptProviderHandle providerHandle;
            ErrorCode errorCode = Interop.NCrypt.NCryptOpenStorageProvider(out providerHandle, providerName, 0);

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

            Debug.Assert(!providerHandle.IsInvalid);
            return(providerHandle);
        }
 protected sealed override bool ReleaseHandle()
 {
     if (_isNcrypt)
     {
         ErrorCode errorCode = Interop.NCrypt.NCryptFreeObject(handle);
         return(errorCode == ErrorCode.ERROR_SUCCESS);
     }
     else
     {
         bool success = Interop.Crypt32.CryptReleaseContext(handle, 0);
         return(success);
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        ///     Delete this key
        /// </summary>
        public void Delete()
        {
            ErrorCode errorCode = Interop.NCrypt.NCryptDeleteKey(_keyHandle, 0);

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

            // Once the key is deleted, the handles are no longer valid so dispose of this instance
            Dispose();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Returns a CNG key property.
        /// </summary>
        /// <returns>
        /// null - if property not defined on key.
        /// throws - for any other type of error.
        /// </returns>
        internal static byte[]? GetProperty(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options)
        {
            Debug.Assert(!ncryptHandle.IsInvalid);
            unsafe
            {
                ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(
                    ncryptHandle,
                    propertyName,
                    null,
                    0,
                    out int numBytesNeeded,
                    options);

                if (errorCode == ErrorCode.NTE_NOT_FOUND)
                {
                    return(null);
                }

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

                byte[] propertyValue = new byte[numBytesNeeded];

                fixed(byte *pPropertyValue = propertyValue)
                {
                    errorCode = Interop.NCrypt.NCryptGetProperty(
                        ncryptHandle,
                        propertyName,
                        pPropertyValue,
                        propertyValue.Length,
                        out numBytesNeeded,
                        options);
                }

                if (errorCode == ErrorCode.NTE_NOT_FOUND)
                {
                    return(null);
                }

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

                Array.Resize(ref propertyValue, numBytesNeeded);
                return(propertyValue);
            }
        }
Ejemplo n.º 8
0
        // Now that the padding mode and information have been marshaled to their native counterparts, perform the encryption or decryption.
        private unsafe byte[] EncryptOrDecrypt(SafeNCryptKeyHandle key, ReadOnlySpan <byte> input, AsymmetricPaddingMode paddingMode, void *paddingInfo, bool encrypt)
        {
            int estimatedSize = KeySize / 8;

#if DEBUG
            estimatedSize = 2;  // Make sure the NTE_BUFFER_TOO_SMALL scenario gets exercised.
#endif

            byte[] output         = new byte[estimatedSize];
            int    numBytesNeeded = 0;

            ErrorCode errorCode = 0;

            for (int i = 0; i <= StatusUnsuccessfulRetryCount; i++)
            {
                errorCode =
                    EncryptOrDecrypt(key, input, output, paddingMode, paddingInfo, encrypt, out numBytesNeeded);

                if (errorCode != ErrorCode.STATUS_UNSUCCESSFUL)
                {
                    break;
                }
            }

            if (errorCode == ErrorCode.NTE_BUFFER_TOO_SMALL)
            {
                output = new byte[numBytesNeeded];

                for (int i = 0; i <= StatusUnsuccessfulRetryCount; i++)
                {
                    errorCode =
                        EncryptOrDecrypt(key, input, output, paddingMode, paddingInfo, encrypt, out numBytesNeeded);

                    if (errorCode != ErrorCode.STATUS_UNSUCCESSFUL)
                    {
                        break;
                    }
                }
            }

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

            Array.Resize(ref output, numBytesNeeded);
            return(output);
        }
Ejemplo n.º 9
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));
        }
Ejemplo n.º 10
0
        internal bool TryExportKeyBlob(
            string blobType,
            Span <byte> destination,
            out int bytesWritten)
        {
            // Sanity check the current bounds
            Span <byte> empty = default;

            ErrorCode errorCode = Interop.NCrypt.NCryptExportKey(
                _keyHandle,
                IntPtr.Zero,
                blobType,
                IntPtr.Zero,
                ref MemoryMarshal.GetReference(empty),
                empty.Length,
                out int written,
                0);

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

            if (written > destination.Length)
            {
                bytesWritten = 0;
                return(false);
            }

            errorCode = Interop.NCrypt.NCryptExportKey(
                _keyHandle,
                IntPtr.Zero,
                blobType,
                IntPtr.Zero,
                ref MemoryMarshal.GetReference(destination),
                destination.Length,
                out written,
                0);

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

            bytesWritten = written;
            return(true);
        }
Ejemplo n.º 11
0
        public static void SetExportPolicy(this SafeNCryptKeyHandle keyHandle, CngExportPolicies exportPolicy)
        {
            unsafe
            {
                ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(
                    keyHandle,
                    KeyPropertyName.ExportPolicy,
                    &exportPolicy,
                    sizeof(CngExportPolicies),
                    CngPropertyOptions.Persist);

                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Retrieve a well-known CNG pointer property. (Note: .NET Framework compat: this helper likes to return special values rather than throw exceptions for missing
 /// or ill-formatted property values. Only use it for well-known properties that are unlikely to be ill-formatted.)
 /// </summary>
 public static IntPtr GetPropertyAsIntPtr(this SafeNCryptHandle ncryptHandle, string propertyName, CngPropertyOptions options)
 {
     unsafe
     {
         IntPtr    value;
         ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(ncryptHandle, propertyName, &value, IntPtr.Size, out _, options);
         if (errorCode == ErrorCode.NTE_NOT_FOUND)
         {
             return(IntPtr.Zero);
         }
         if (errorCode != ErrorCode.ERROR_SUCCESS)
         {
             throw errorCode.ToCryptographicException();
         }
         return(value);
     }
 }
Ejemplo n.º 13
0
        private static void SetKeyLength(SafeNCryptKeyHandle keyHandle, int keySize)
        {
            unsafe
            {
                ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(
                    keyHandle,
                    KeyPropertyName.Length,
                    &keySize,
                    sizeof(int),
                    CngPropertyOptions.Persist);

                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        ///     Determine if a property exists on the key
        /// </summary>
        public bool HasProperty(string name, CngPropertyOptions options)
        {
            ArgumentNullException.ThrowIfNull(name);

            unsafe
            {
                ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(_keyHandle, name, null, 0, out _, options);
                if (errorCode == ErrorCode.NTE_NOT_FOUND)
                {
                    return(false);
                }
                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
                return(true);
            }
        }
Ejemplo n.º 15
0
        public static unsafe bool TrySignHash(this SafeNCryptKeyHandle keyHandle, ReadOnlySpan <byte> hash, Span <byte> signature, AsymmetricPaddingMode paddingMode, void *pPaddingInfo, out int bytesWritten)
        {
            ErrorCode error = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, out int numBytesNeeded, paddingMode);

            switch (error)
            {
            case ErrorCode.ERROR_SUCCESS:
                bytesWritten = numBytesNeeded;
                return(true);

            case ErrorCode.NTE_BUFFER_TOO_SMALL:
                bytesWritten = 0;
                return(false);

            default:
                throw error.ToCryptographicException();
            }
        }
Ejemplo n.º 16
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;
            }
        }
Ejemplo n.º 17
0
        private static void SetExportable(SafeNCryptKeyHandle keyHandle)
        {
            CngExportPolicies exportPolicy = CngExportPolicies.AllowPlaintextExport;

            unsafe
            {
                ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(
                    keyHandle,
                    KeyPropertyName.ExportPolicy,
                    &exportPolicy,
                    sizeof(CngExportPolicies),
                    CngPropertyOptions.Persist);

                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
            }
        }
Ejemplo n.º 18
0
        //
        // Now that the padding mode and information have been marshaled to their native counterparts, perform the encryption or decryption.
        //
        private static unsafe byte[] EncryptOrDecrypt(SafeNCryptKeyHandle key, byte[] input, AsymmetricPaddingMode paddingMode, void *paddingInfo, EncryptOrDecryptAction encryptOrDecrypt)
        {
            int       numBytesNeeded;
            ErrorCode errorCode = encryptOrDecrypt(key, input, input.Length, paddingInfo, null, 0, out numBytesNeeded, paddingMode);

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

            byte[] output = new byte[numBytesNeeded];
            errorCode = encryptOrDecrypt(key, input, input.Length, paddingInfo, output, numBytesNeeded, out numBytesNeeded, paddingMode);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }

            return(output);
        }
Ejemplo n.º 19
0
        /// <summary>
        ///     Setup the UIPolicy key properties specified in the key creation parameters
        /// </summary>
        private static void InitializeKeyUiPolicyProperties(SafeNCryptKeyHandle keyHandle, CngUIPolicy uiPolicy)
        {
            unsafe
            {
                fixed(char *pinnedCreationTitle = uiPolicy.CreationTitle,
                      pinnedFriendlyName        = uiPolicy.FriendlyName,
                      pinnedDescription         = uiPolicy.Description)
                {
                    NCRYPT_UI_POLICY ncryptUiPolicy = new NCRYPT_UI_POLICY()
                    {
                        dwVersion        = 1,
                        dwFlags          = uiPolicy.ProtectionLevel,
                        pszCreationTitle = new IntPtr(pinnedCreationTitle),
                        pszFriendlyName  = new IntPtr(pinnedFriendlyName),
                        pszDescription   = new IntPtr(pinnedDescription),
                    };

                    ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.UIPolicy, &ncryptUiPolicy, sizeof(NCRYPT_UI_POLICY), CngPropertyOptions.Persist);

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

                string useContext = uiPolicy.UseContext;

                if (useContext != null)
                {
                    int useContextByteLength = checked ((useContext.Length + 1) * sizeof(char));
                    fixed(char *pinnedUseContext = useContext)
                    {
                        ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.UseContext, pinnedUseContext, useContextByteLength, CngPropertyOptions.Persist);

                        if (errorCode != ErrorCode.ERROR_SUCCESS)
                        {
                            throw errorCode.ToCryptographicException();
                        }
                    }
                }
            }
        }
Ejemplo n.º 20
0
        // Now that the padding mode and information have been marshaled to their native counterparts, perform the encryption or decryption.
        private unsafe bool TryEncryptOrDecrypt(SafeNCryptKeyHandle key, ReadOnlySpan <byte> input, Span <byte> output, AsymmetricPaddingMode paddingMode, void *paddingInfo, bool encrypt, out int bytesWritten)
        {
            int       numBytesNeeded;
            ErrorCode errorCode =
                EncryptOrDecrypt(key, input, output, paddingMode, paddingInfo, encrypt, out numBytesNeeded);

            switch (errorCode)
            {
            case ErrorCode.ERROR_SUCCESS:
                bytesWritten = numBytesNeeded;
                return(true);

            case ErrorCode.NTE_BUFFER_TOO_SMALL:
                bytesWritten = 0;
                return(false);

            default:
                throw errorCode.ToCryptographicException();
            }
        }
 protected sealed override bool ReleaseHandle()
 {
     if (_parentHandle != null)
     {
         _parentHandle.DangerousRelease();
         _parentHandle = null;
         SetHandle(IntPtr.Zero);
         return(true);
     }
     else if (_isNcrypt)
     {
         ErrorCode errorCode = Interop.NCrypt.NCryptFreeObject(handle);
         return(errorCode == ErrorCode.ERROR_SUCCESS);
     }
     else
     {
         bool success = Interop.Advapi32.CryptReleaseContext(handle, 0);
         return(success);
     }
 }
Ejemplo n.º 22
0
        internal static byte[] ExportKeyBlob(SafeNCryptKeyHandle keyHandle, string blobType)
        {
            Debug.Assert(!keyHandle.IsInvalid);

            int numBytesNeeded;

            ErrorCode errorCode = Interop.NCrypt.NCryptExportKey(
                keyHandle,
                IntPtr.Zero,
                blobType,
                IntPtr.Zero,
                null,
                0,
                out numBytesNeeded,
                0);

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

            byte[] buffer = new byte[numBytesNeeded];

            errorCode = Interop.NCrypt.NCryptExportKey(
                keyHandle,
                IntPtr.Zero,
                blobType,
                IntPtr.Zero,
                buffer,
                buffer.Length,
                out numBytesNeeded,
                0);

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

            Array.Resize(ref buffer, numBytesNeeded);
            return(buffer);
        }
Ejemplo n.º 23
0
        private static void SetProperty(SafeNCryptHandle ncryptHandle, string propertyName, byte[] value)
        {
            Debug.Assert(!ncryptHandle.IsInvalid);
            unsafe
            {
                fixed(byte *pBlob = value)
                {
                    ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(
                        ncryptHandle,
                        propertyName,
                        pBlob,
                        value.Length,
                        CngPropertyOptions.None);

                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        throw errorCode.ToCryptographicException();
                    }
                }
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        ///     Set an arbitrary property on the key
        /// </summary>
        public void SetProperty(CngProperty property)
        {
            unsafe
            {
                byte[] propertyValue = property.GetValueWithoutCopying();

                // .NET Framework compat. It would have nicer to throw an ArgumentNull exception or something...
                if (propertyValue == null)
                    throw ErrorCode.NTE_INVALID_PARAMETER.ToCryptographicException();

                fixed(byte *pinnedPropertyValue = propertyValue.MapZeroLengthArrayToNonNullPointer())
                {
                    ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(_keyHandle, property.Name, pinnedPropertyValue, propertyValue.Length, property.Options);

                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        throw errorCode.ToCryptographicException();
                    }
                }
            }
        }
Ejemplo n.º 25
0
        private static unsafe ErrorCode EncryptOrDecrypt(
            SafeNCryptKeyHandle key,
            ReadOnlySpan <byte> input,
            Span <byte> output,
            AsymmetricPaddingMode paddingMode,
            void *paddingInfo,
            bool encrypt,
            out int bytesNeeded)
        {
            ErrorCode errorCode = encrypt ?
                                  Interop.NCrypt.NCryptEncrypt(key, input, input.Length, paddingInfo, output, output.Length, out bytesNeeded, paddingMode) :
                                  Interop.NCrypt.NCryptDecrypt(key, input, input.Length, paddingInfo, output, output.Length, out bytesNeeded, paddingMode);

            // Windows 10.1903 can return success when it meant NTE_BUFFER_TOO_SMALL.
            if (errorCode == ErrorCode.ERROR_SUCCESS && bytesNeeded > output.Length)
            {
                errorCode = ErrorCode.NTE_BUFFER_TOO_SMALL;
            }

            return(errorCode);
        }
Ejemplo n.º 26
0
        internal static unsafe int GetKeyLength(SafeNCryptKeyHandle keyHandle)
        {
            int keySize = 0;
            int bytesWritten;

            ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(
                keyHandle,
                KeyPropertyName.Length,
                &keySize,
                sizeof(int),
                out bytesWritten,
                CngPropertyOptions.None);

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

            Debug.Assert(bytesWritten == sizeof(int));
            return(keySize);
        }
Ejemplo n.º 27
0
        public static unsafe byte[] SignHash(this SafeNCryptKeyHandle keyHandle, byte[] hash, AsymmetricPaddingMode paddingMode, void *pPaddingInfo, int estimatedSize)
        {
#if DEBUG
            estimatedSize = 2;  // Make sure the NTE_BUFFER_TOO_SMALL scenario gets exercised.
#endif
            byte[]    signature = new byte[estimatedSize];
            int       numBytesNeeded;
            ErrorCode errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, out numBytesNeeded, paddingMode);
            if (errorCode == ErrorCode.NTE_BUFFER_TOO_SMALL)
            {
                signature = new byte[numBytesNeeded];
                errorCode = Interop.NCrypt.NCryptSignHash(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, out numBytesNeeded, paddingMode);
            }
            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }

            Array.Resize(ref signature, numBytesNeeded);
            return(signature);
        }
Ejemplo n.º 28
0
        public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException(nameof(algorithm));
            }

            if (creationParameters == null)
            {
                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)
            {
                throw errorCode.ToCryptographicException();
            }

            InitializeKeyProperties(keyHandle, creationParameters);

            errorCode = Interop.NCrypt.NCryptFinalizeKey(keyHandle, 0);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }

            CngKey key = new CngKey(providerHandle, keyHandle);

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

            return(key);
        }
Ejemplo n.º 29
0
        /// <summary>
        ///     Export the key out of the KSP
        /// </summary>
        public byte[] Export(CngKeyBlobFormat format)
        {
            ArgumentNullException.ThrowIfNull(format);

            int       numBytesNeeded;
            ErrorCode errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, null, 0, out numBytesNeeded, 0);

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

            byte[] buffer = new byte[numBytesNeeded];
            errorCode = Interop.NCrypt.NCryptExportKey(_keyHandle, IntPtr.Zero, format.Format, IntPtr.Zero, buffer, buffer.Length, out numBytesNeeded, 0);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }

            Array.Resize(ref buffer, numBytesNeeded);
            return(buffer);
        }
Ejemplo n.º 30
0
        /// <summary>
        ///     Determine if a property exists on the key
        /// </summary>
        public bool HasProperty(string name, CngPropertyOptions options)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            unsafe
            {
                int       numBytesNeeded;
                ErrorCode errorCode = Interop.NCrypt.NCryptGetProperty(_keyHandle, name, null, 0, out numBytesNeeded, options);
                if (errorCode == ErrorCode.NTE_NOT_FOUND)
                {
                    return(false);
                }
                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
                return(true);
            }
        }