Example #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;
            }
        }
Example #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.</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));
        }
Example #3
0
        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);
        }
        static Boolean deleteLegacyKey(AsymmetricAlgorithm privateKey)
        {
            if (privateKey == null)
            {
                return(false);
            }
            String keyContainer;
            String provName;
            UInt32 provType;

            switch (privateKey)
            {
            case RSACryptoServiceProvider rsaProv:
                keyContainer = rsaProv.CspKeyContainerInfo.KeyContainerName;
                provName     = rsaProv.CspKeyContainerInfo.ProviderName;
                provType     = (UInt32)rsaProv.CspKeyContainerInfo.ProviderType;
                break;

            case DSACryptoServiceProvider dsaProv:
                keyContainer = dsaProv.CspKeyContainerInfo.KeyContainerName;
                provName     = dsaProv.CspKeyContainerInfo.ProviderName;
                provType     = (UInt32)dsaProv.CspKeyContainerInfo.ProviderType;
                break;

            default:
                privateKey.Dispose();
                return(false);
            }
            IntPtr  phProv  = IntPtr.Zero;
            Boolean status2 = false;
            Boolean status1 = AdvAPI.CryptAcquireContext(
                ref phProv,
                keyContainer,
                provName,
                provType,
                Wincrypt.CRYPT_DELETEKEYSET | nCrypt2.NCRYPT_MACHINE_KEY_FLAG);

            if (!status1)
            {
                status2 = AdvAPI.CryptAcquireContext(
                    ref phProv,
                    keyContainer,
                    provName,
                    provType,
                    Wincrypt.CRYPT_DELETEKEYSET);
            }
            privateKey.Dispose();
            return(status1 || status2);
        }
Example #5
0
        static Hashtable get_provtypes()
        {
            UInt32        dwIndex     = 0;
            UInt32        pdwProvType = 0;
            UInt32        pcbTypeName = 0;
            StringBuilder pszTypeName = new StringBuilder();
            Hashtable     ProvTypes   = new Hashtable();

            while (AdvAPI.CryptEnumProviderTypes(dwIndex, 0, 0, ref pdwProvType, null, ref pcbTypeName))
            {
                pszTypeName.Length = (Int32)pcbTypeName;
                if (AdvAPI.CryptEnumProviderTypes(dwIndex++, 0, 0, ref pdwProvType, pszTypeName, ref pcbTypeName))
                {
                    String pType = pszTypeName.ToString();
                    ProvTypes.Add(pdwProvType, pType);
                }
            }
            return(ProvTypes);
        }
Example #6
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));
        }