Exemplo n.º 1
0
        //
        // Common helper for SignHash() and VerifyHash(). Creates the necessary PADDING_INFO structure based on the chosen padding mode and then passes it
        // to "signOrVerify" which performs the actual signing or verification.
        //
        private static unsafe void SignOrVerify(RSASignaturePadding padding, HashAlgorithmName hashAlgorithm, byte[] hash, SignOrVerifyAction signOrVerify)
        {
            string hashAlgorithmName = hashAlgorithm.Name;
            if (string.IsNullOrEmpty(hashAlgorithmName))
                throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, "hashAlgorithm");

            if (padding == null)
                throw new ArgumentNullException("padding");

            switch (padding.Mode)
            {
                case RSASignaturePaddingMode.Pkcs1:
                    {
                        using (SafeUnicodeStringHandle safeHashAlgorithmName = new SafeUnicodeStringHandle(hashAlgorithmName))
                        {
                            BCRYPT_PKCS1_PADDING_INFO paddingInfo = new BCRYPT_PKCS1_PADDING_INFO()
                            {
                                pszAlgId = safeHashAlgorithmName.DangerousGetHandle(),
                            };
                            signOrVerify(AsymmetricPaddingMode.NCRYPT_PAD_PKCS1_FLAG, &paddingInfo);
                        }
                        break;
                    }

                case RSASignaturePaddingMode.Pss:
                    {
                        using (SafeUnicodeStringHandle safeHashAlgorithmName = new SafeUnicodeStringHandle(hashAlgorithmName))
                        {
                            BCRYPT_PSS_PADDING_INFO paddingInfo = new BCRYPT_PSS_PADDING_INFO()
                            {
                                pszAlgId = safeHashAlgorithmName.DangerousGetHandle(),
                                cbSalt = hash.Length,
                            };
                            signOrVerify(AsymmetricPaddingMode.NCRYPT_PAD_PSS_FLAG, &paddingInfo);
                        }
                        break;
                    }

                default:
                    throw new CryptographicException(SR.Cryptography_UnsupportedPaddingMode);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Performs a signing or verification operation.
        /// </summary>
        /// <param name="action">The delegate that will actually perform the cryptographic operation.</param>
        /// <remarks>
        /// This method should not throw an error when verifying a signature and
        /// the signature is invalid. Rather, the delegate should retain the result of
        /// verification and the caller of this method should share that closure and
        /// return the result.
        /// </remarks>
        protected unsafe void SignOrVerify(SignOrVerifyAction action)
        {
            Requires.NotNull(action, nameof(action));

            if (this.SignaturePadding.Value == AsymmetricSignaturePadding.None)
            {
                action(null, NCryptSignHashFlags.None);
            }
            else
            {
                char[] hashAlgorithmName = HashAlgorithmProviderFactory.GetHashAlgorithmName(this.SignatureHash.Value).ToCharArrayWithNullTerminator();
                fixed(char *hashAlgorithmNamePointer = &hashAlgorithmName[0])
                {
                    switch (this.SignaturePadding.Value)
                    {
                    case AsymmetricSignaturePadding.Pkcs1:
                        var pkcs1PaddingInfo = new BCrypt.BCRYPT_PKCS1_PADDING_INFO
                        {
                            pszAlgId = hashAlgorithmNamePointer,
                        };
                        action(&pkcs1PaddingInfo, NCryptSignHashFlags.BCRYPT_PAD_PKCS1);
                        break;

                    case AsymmetricSignaturePadding.Pss:
                        var pssPaddingInfo = new BCrypt.BCRYPT_PSS_PADDING_INFO
                        {
                            pszAlgId = hashAlgorithmNamePointer,
                            cbSalt   = hashAlgorithmName.Length,
                        };
                        action(&pssPaddingInfo, NCryptSignHashFlags.BCRYPT_PAD_PSS);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
        }
Exemplo n.º 3
0
        //
        // Common helper for SignHash() and VerifyHash(). Creates the necessary PADDING_INFO structure based on the chosen padding mode and then passes it
        // to "signOrVerify" which performs the actual signing or verification.
        //
        private static unsafe void SignOrVerify(RSASignaturePadding padding, HashAlgorithmName hashAlgorithm, byte[] hash, SignOrVerifyAction signOrVerify)
        {
            string hashAlgorithmName = hashAlgorithm.Name;

            if (string.IsNullOrEmpty(hashAlgorithmName))
            {
                throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
            }

            if (padding == null)
            {
                throw new ArgumentNullException(nameof(padding));
            }

            switch (padding.Mode)
            {
            case RSASignaturePaddingMode.Pkcs1:
            {
                using (SafeUnicodeStringHandle safeHashAlgorithmName = new SafeUnicodeStringHandle(hashAlgorithmName))
                {
                    BCRYPT_PKCS1_PADDING_INFO paddingInfo = new BCRYPT_PKCS1_PADDING_INFO()
                    {
                        pszAlgId = safeHashAlgorithmName.DangerousGetHandle(),
                    };
                    signOrVerify(AsymmetricPaddingMode.NCRYPT_PAD_PKCS1_FLAG, &paddingInfo);
                }
                break;
            }

            case RSASignaturePaddingMode.Pss:
            {
                using (SafeUnicodeStringHandle safeHashAlgorithmName = new SafeUnicodeStringHandle(hashAlgorithmName))
                {
                    BCRYPT_PSS_PADDING_INFO paddingInfo = new BCRYPT_PSS_PADDING_INFO()
                    {
                        pszAlgId = safeHashAlgorithmName.DangerousGetHandle(),
                        cbSalt   = hash.Length,
                    };
                    signOrVerify(AsymmetricPaddingMode.NCRYPT_PAD_PSS_FLAG, &paddingInfo);
                }
                break;
            }

            default:
                throw new CryptographicException(SR.Cryptography_UnsupportedPaddingMode);
            }
        }