/// <summary> /// Encode and sign a CERT_INFO structure /// </summary> /// <param name="hProv"></param> /// <param name="certInfo"></param> /// <param name="signature">True encodes with a AT_SIGNATURE key, otherwise AT_EXCHANGE</param> /// <param name="hashAlgorithm"></param> /// <returns></returns> private byte[] EncodeAndSignCertInfo(CryptoApiMethods.SafeCryptProviderHandle hProv, CryptoApiMethods.CERT_INFO certInfo, bool signature, CertificateHashAlgorithm hashAlgorithm) { CryptoApiMethods.CALG keyType = signature ? CryptoApiMethods.CALG.AT_SIGNATURE : CryptoApiMethods.CALG.AT_KEYEXCHANGE; byte[] ret = null; uint certLen = 0; IntPtr certInfoPtr = IntPtr.Zero; CryptoApiMethods.CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm = new CryptoApiMethods.CRYPT_ALGORITHM_IDENTIFIER(); //SignatureAlgorithm.pszObjId = CryptoApiMethods.szOID_OIWSEC_sha1RSASign; //SignatureAlgorithm.pszObjId = CryptoApiMethods.szOID_RSA_SHA1RSA; //SignatureAlgorithm.pszObjId = CryptoApiMethods.szOID_RSA_SHA512RSA; SignatureAlgorithm.pszObjId = HashAlgorithmToOID(hashAlgorithm); try { certInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(certInfo)); Marshal.StructureToPtr(certInfo, certInfoPtr, false); if (!CryptoApiMethods.CryptSignAndEncodeCertificate(hProv, keyType, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, new IntPtr((int)CryptoApiMethods.StructType.X509_CERT_TO_BE_SIGNED), certInfoPtr, SignatureAlgorithm, IntPtr.Zero, null, ref certLen)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } ret = new byte[certLen]; if (!CryptoApiMethods.CryptSignAndEncodeCertificate(hProv, keyType, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, new IntPtr((int)CryptoApiMethods.StructType.X509_CERT_TO_BE_SIGNED), certInfoPtr, SignatureAlgorithm, IntPtr.Zero, ret, ref certLen)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { Marshal.DestroyStructure(certInfoPtr, certInfo.GetType()); Marshal.FreeHGlobal(certInfoPtr); } return(ret); }