protected override bool ReleaseHandle()
 {
     if (!_callerFree)
     {
         return(true);
     }
     if (IsNCryptKey)
     {
         return(NCrypt.NCryptFreeObject(handle) == SECURITY_STATUS.ERROR_SUCCESS);
     }
     else
     {
         return(AdvApi32.CryptReleaseContext(handle, 0u));
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Computes the hash value of the specified byte array using the specified hash algorithm, and signs the resulting hash value.
        /// </summary>
        /// <param name="certificate">An <see cref="X509Certificate2"/> object of the signer certificate.</param>
        /// <param name="message">Message to be signed.</param>
        /// <param name="hashAlgorithm">The name of the hash algorithm to use in the signature. For example, 'SHA256'</param>
        /// <returns>The signature for the specified data.</returns>
        public static Byte[] SignMessage(X509Certificate2 certificate, Byte[] message, Oid hashAlgorithm)
        {
            SafeNCryptKeyHandle phCryptProv = new SafeNCryptKeyHandle();
            UInt32  pdwKeySpec       = 0;
            Boolean pfCallerFreeProv = false;

            if (!Crypt32.CryptAcquireCertificatePrivateKey(certificate.Handle, Wincrypt.CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, IntPtr.Zero, out phCryptProv, out pdwKeySpec, out pfCallerFreeProv))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            // true -> CNG, false -> legacy
            if (pdwKeySpec == UInt32.MaxValue)
            {
                Byte[] hashBytes = calculateHash(message, hashAlgorithm.FriendlyName, false);
                try {
                    Int32 hresult = NCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, hashBytes.Length, null, 0, out Int32 pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    Byte[] pbSignature = new Byte[pcbResult];
                    hresult = NCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, hashBytes.Length, pbSignature, pbSignature.Length, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    return(pbSignature);
                } finally {
                    if (pfCallerFreeProv)
                    {
                        NCrypt.NCryptFreeObject(phCryptProv.DangerousGetHandle());
                    }
                }
            }
            if (pfCallerFreeProv)
            {
                AdvAPI.CryptReleaseContext(phCryptProv.DangerousGetHandle(), 0);
            }
            calculateHash(message, hashAlgorithm.FriendlyName, false);
            RSACryptoServiceProvider key = (RSACryptoServiceProvider)certificate.PrivateKey;

            return(key.SignData(message, hashAlgorithm.Value));
        }
 protected override bool ReleaseHandle()
 {
     return(NCrypt.NCryptFreeObject(handle) == SECURITY_STATUS.ERROR_SUCCESS);
 }