예제 #1
0
        void getCngHandleFromLegacy(SafeHandle phCryptProvOrNCryptKey)
        {
            // attempt to translate legacy HCRYPTPROV handle to CNG key handle
            Int32 hresult = nCrypt.NCryptTranslateHandle(
                IntPtr.Zero,
                out SafeNCryptKeyHandle cngKey,
                phCryptProvOrNCryptKey.DangerousGetHandle(),
                IntPtr.Zero,
                (UInt32)X509KeySpecFlags.AT_SIGNATURE,
                0);

            // release legacy HCRYPTPROV handle
            AdvAPI.CryptReleaseContext(phCryptProvOrNCryptKey.DangerousGetHandle(), 0);
            if (hresult == 0)
            {
                // if key is successfully translated, assign new CNG key handle to phPrivKey
                phPrivKey = cngKey;
                isCng     = true;
            }
            else
            {
                // if key translation failed, then switch to legacy RSA/DSACryptoServiceProvider
                isCng     = false;
                legacyKey = SignerCertificate.PrivateKey;
            }
        }
예제 #2
0
파일: Csp.cs 프로젝트: nhtha/pkix.net
        static CspCollection m_enumprovs()
        {
            Hashtable     ProvTypes   = get_provtypes();
            StringBuilder pszProvName = new StringBuilder();
            CspCollection csps        = new CspCollection();

            UInt32 dwIndex     = 0;
            UInt32 pdwProvType = 0;
            UInt32 pcbProvName = 0;

            while (AdvAPI.CryptEnumProviders(dwIndex, 0, 0, ref pdwProvType, null, ref pcbProvName))
            {
                pszProvName.Length = (Int32)pcbProvName;
                // retrieve CSP
                if (!AdvAPI.CryptEnumProviders(dwIndex++, 0, 0, ref pdwProvType, pszProvName, ref pcbProvName))
                {
                    throw new Win32Exception(Error.InvalidDataException);
                }
                String name   = pszProvName.ToString();
                String pType  = (String)ProvTypes[pdwProvType];
                IntPtr phProv = IntPtr.Zero;
                // retrieve CSP context
                if (!AdvAPI.CryptAcquireContext(ref phProv, null, name, pdwProvType, Wincrypt.CRYPT_VERIFYCONTEXT))
                {
                    throw new Win32Exception(Error.InavlidHandleException);
                }
                Int32            pdwDataLen = 0;
                ALG_IDCollection algs       = new ALG_IDCollection();
                if (AdvAPI.CryptGetProvParam(phProv, 0x16, null, ref pdwDataLen, Wincrypt.CRYPT_FIRST))
                {
                    Byte[] pbData = new Byte[Marshal.SizeOf(typeof(Wincrypt.PROV_ENUMALGS_EX))];
                    while (AdvAPI.CryptGetProvParam(phProv, 0x16, pbData, ref pdwDataLen, Wincrypt.CRYPT_NEXT))
                    {
                        IntPtr ptr = Marshal.AllocHGlobal(pbData.Length);
                        Marshal.Copy(pbData, 0, ptr, pbData.Length);
                        Wincrypt.PROV_ENUMALGS_EX AlgStructure =
                            (Wincrypt.PROV_ENUMALGS_EX)Marshal.PtrToStructure(ptr, typeof(Wincrypt.PROV_ENUMALGS_EX));
                        Marshal.FreeHGlobal(ptr);
                        ALG_ID alg = get_algparams(AlgStructure);
                        algs.Add(alg);
                    }
                    csps.Add(new CspLegacy(name, pType, algs));
                }
                else
                {
                    csps.Add(new CspLegacy(name, pType, algs));
                }
                AdvAPI.CryptReleaseContext(phProv, 0);
            }
            return(csps);
        }
예제 #3
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.</param>
        /// <returns>The signature for the specified data.</returns>
        public static Byte[] SignMessage(X509Certificate2 certificate, Byte[] message, Oid hashAlgorithm)
        {
            IntPtr  phCryptProv      = IntPtr.Zero;
            UInt32  pdwKeySpec       = 0;
            Boolean pfCallerFreeProv = false;

            if (!Crypt32.CryptAcquireCertificatePrivateKey(certificate.Handle, 0x00010000, IntPtr.Zero, ref phCryptProv, ref pdwKeySpec, ref pfCallerFreeProv))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            Oid2 hashalgorithm = new Oid2(
                hashAlgorithm.FriendlyName.ToLower()
                .Replace("rsa", null)
                .Replace("ecdsa", null),
                OidGroupEnum.HashAlgorithm, true);
            String hashAlg;

            // true -> CNG, false -> legacy
            if (pdwKeySpec == UInt32.MaxValue)
            {
                Byte[] hashBytes = calculateHash(message, hashalgorithm, false, out hashAlg);
                try {
                    UInt32 pcbResult;
                    Int32  hresult = nCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, (UInt32)hashBytes.Length, null, 0, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    Byte[] pbSignature = new byte[pcbResult];
                    hresult = nCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, (UInt32)hashBytes.Length, pbSignature, (UInt32)pbSignature.Length, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    return(pbSignature);
                } finally {
                    if (pfCallerFreeProv)
                    {
                        nCrypt.NCryptFreeObject(phCryptProv);
                    }
                }
            }
            if (pfCallerFreeProv)
            {
                AdvAPI.CryptReleaseContext(phCryptProv, 0);
            }
            calculateHash(message, hashalgorithm, false, out hashAlg);
            RSACryptoServiceProvider key = (RSACryptoServiceProvider)certificate.PrivateKey;

            return(key.SignData(message, hashAlg));
        }
예제 #4
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));
        }