コード例 #1
0
 public static unsafe bool VerifyHash(this CngKey key, byte[] hash, byte[] signature, AsymmetricPaddingMode paddingMode, void* pPaddingInfo)
 {
     SafeNCryptKeyHandle keyHandle = key.Handle;
     ErrorCode errorCode = Interop.NCrypt.NCryptVerifySignature(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, paddingMode);
     bool verified = (errorCode == ErrorCode.ERROR_SUCCESS);  // For consistency with other AsymmetricAlgorithm-derived classes, return "false" for any error code rather than making the caller catch an exception.
     return verified;
 }
コード例 #2
0
 private static unsafe ErrorCode EncryptOrDecrypt(
     SafeNCryptKeyHandle key,
     ReadOnlySpan <byte> input,
     Span <byte> output,
     AsymmetricPaddingMode paddingMode,
     void *paddingInfo,
     bool encrypt,
     out int bytesNeeded)
 {
     return(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));
 }
コード例 #3
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;
        }
コード例 #4
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);
        }
コード例 #5
0
        public static unsafe byte[] SignHash(this CngKey key, byte[] hash, AsymmetricPaddingMode paddingMode, void *pPaddingInfo, int estimatedSize)
        {
#if DEBUG
            estimatedSize = 2;  // Make sure the NTE_BUFFER_TOO_SMALL scenario gets exercised.
#endif
            SafeNCryptKeyHandle keyHandle = key.Handle;

            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);
        }
コード例 #6
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)
        {
            for (int i = 0; i <= StatusUnsuccessfulRetryCount; i++)
            {
                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);

                case ErrorCode.STATUS_UNSUCCESSFUL:
                    break;

                default:
                    throw errorCode.ToCryptographicException();
                }
            }

            throw ErrorCode.STATUS_UNSUCCESSFUL.ToCryptographicException();
        }
コード例 #7
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)
            {
                CryptographicOperations.ZeroMemory(output);
                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();
            }

            if (numBytesNeeded != output.Length)
            {
                byte[] ret = output.AsSpan(0, numBytesNeeded).ToArray();
                CryptographicOperations.ZeroMemory(output);
                output = ret;
            }

            return(output);
        }
コード例 #8
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 = encrypt ?
                                  Interop.NCrypt.NCryptEncrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode) :
                                  Interop.NCrypt.NCryptDecrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode);

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

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

            default:
                throw errorCode.ToCryptographicException();
            }
        }
コード例 #9
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, 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;
            ErrorCode errorCode = encrypt ?
                                  Interop.NCrypt.NCryptEncrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode) :
                                  Interop.NCrypt.NCryptDecrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode);

            if (errorCode == ErrorCode.NTE_BUFFER_TOO_SMALL)
            {
                output    = new byte[numBytesNeeded];
                errorCode = encrypt ?
                            Interop.NCrypt.NCryptEncrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode) :
                            Interop.NCrypt.NCryptDecrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode);
            }
            if (errorCode != ErrorCode.ERROR_SUCCESS)
            {
                throw errorCode.ToCryptographicException();
            }

            Array.Resize(ref output, numBytesNeeded);
            return(output);
        }
コード例 #10
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, byte[] input, AsymmetricPaddingMode paddingMode, void* paddingInfo, EncryptOrDecryptAction encryptOrDecrypt)
        {
            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;
            ErrorCode errorCode = encryptOrDecrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode);
            if (errorCode == ErrorCode.NTE_BUFFER_TOO_SMALL)
            {
                output = new byte[numBytesNeeded];
                errorCode = encryptOrDecrypt(key, input, input.Length, paddingInfo, output, output.Length, out numBytesNeeded, paddingMode);
            }
            if (errorCode != ErrorCode.ERROR_SUCCESS)
                throw errorCode.ToCryptographicException();

            Array.Resize(ref output, numBytesNeeded);
            return output;
        }
コード例 #11
0
        public static unsafe bool VerifyHash(this SafeNCryptKeyHandle keyHandle, ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, AsymmetricPaddingMode paddingMode, void *pPaddingInfo)
        {
            ErrorCode errorCode = Interop.NCrypt.NCryptVerifySignature(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, paddingMode);

            if (errorCode == ErrorCode.STATUS_UNSUCCESSFUL)
            {
                errorCode = Interop.NCrypt.NCryptVerifySignature(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, paddingMode);
            }

            return(errorCode == ErrorCode.ERROR_SUCCESS);  // For consistency with other AsymmetricAlgorithm-derived classes, return "false" for any error code rather than making the caller catch an exception.
        }
コード例 #12
0
        public static unsafe bool TrySignHash(this SafeNCryptKeyHandle keyHandle, ReadOnlySpan <byte> hash, Span <byte> signature, AsymmetricPaddingMode paddingMode, void *pPaddingInfo, out int bytesWritten)
        {
            for (int i = 0; i <= StatusUnsuccessfulRetryCount; i++)
            {
                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);

                case ErrorCode.STATUS_UNSUCCESSFUL:
                    // Retry
                    break;

                default:
                    throw error.ToCryptographicException();
                }
            }

            throw ErrorCode.STATUS_UNSUCCESSFUL.ToCryptographicException();
        }
コード例 #13
0
ファイル: CngCommon.SignVerify.cs プロジェクト: jnm2/corefx
        public static unsafe bool VerifyHash(this SafeNCryptKeyHandle keyHandle, byte[] hash, byte[] signature, AsymmetricPaddingMode paddingMode, void *pPaddingInfo)
        {
            ErrorCode errorCode = Interop.NCrypt.NCryptVerifySignature(keyHandle, pPaddingInfo, hash, hash.Length, signature, signature.Length, paddingMode);
            bool      verified  = (errorCode == ErrorCode.ERROR_SUCCESS); // For consistency with other AsymmetricAlgorithm-derived classes, return "false" for any error code rather than making the caller catch an exception.

            return(verified);
        }
コード例 #14
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;
        }
コード例 #15
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);
        }