/// <summary> /// Export the public RSA keyinfo from the current crypto provider /// </summary> /// <param name="key">RSA Key</param> /// <returns>An IntPtr pointing to the public key info structure</returns> private IntPtr ExportPublicKeyInfo(RSACryptoServiceProvider key) { IntPtr ret = IntPtr.Zero; CryptoApiMethods.SafeCryptProviderHandle hProv = null; try { hProv = OpenRSAProvider(key.CspKeyContainerInfo.ProviderName, key.CspKeyContainerInfo.KeyContainerName); ret = ExportPublicKeyInfo(hProv, key.CspKeyContainerInfo.KeyNumber == KeyNumber.Signature ? true : false); } finally { if (hProv != null) { if (!hProv.IsInvalid) { hProv.Close(); } } } return(ret); }
/// <summary> /// Hash public key info of a specified RSA key /// </summary> /// <param name="key"></param> /// <returns></returns> private byte[] HashPublicKeyInfo(RSACryptoServiceProvider key) { CryptoApiMethods.SafeCryptProviderHandle hProv = new CryptoApiMethods.SafeCryptProviderHandle(); IntPtr publicKeyInfoPtr = IntPtr.Zero; byte[] ret = null; uint len = 0; try { publicKeyInfoPtr = ExportPublicKeyInfo(key); CryptoApiMethods.CERT_PUBLIC_KEY_INFO publicKeyInfo = (CryptoApiMethods.CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(publicKeyInfoPtr, typeof(CryptoApiMethods.CERT_PUBLIC_KEY_INFO)); hProv = OpenRSAProvider(key.CspKeyContainerInfo.ProviderName, key.CspKeyContainerInfo.KeyContainerName); if (!CryptoApiMethods.CryptHashPublicKeyInfo(hProv, 0, 0, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, publicKeyInfo, null, out len)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } ret = new byte[len]; if (!CryptoApiMethods.CryptHashPublicKeyInfo(hProv, 0, 0, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, publicKeyInfo, ret, out len)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (!hProv.IsInvalid) { hProv.Close(); } if (publicKeyInfoPtr != IntPtr.Zero) { Marshal.FreeHGlobal(publicKeyInfoPtr); } } return(ret); }
/// <summary> /// Encode and sign a CERT_INFO structure /// </summary> /// <param name="key">Key to sign the certificate with</param> /// <param name="certInfo">The CERT_INFO structure to sign</param> /// <param name="hashAlgorithm"></param> /// <returns></returns> private byte[] EncodeAndSignCertInfo(RSACryptoServiceProvider key, CryptoApiMethods.CERT_INFO certInfo, CertificateHashAlgorithm hashAlgorithm) { byte[] ret = null; CryptoApiMethods.SafeCryptProviderHandle hProv = new CryptoApiMethods.SafeCryptProviderHandle(); try { hProv = OpenRSAProvider(key.CspKeyContainerInfo.ProviderName, key.CspKeyContainerInfo.KeyContainerName); ret = EncodeAndSignCertInfo(hProv, certInfo, key.CspKeyContainerInfo.KeyNumber == KeyNumber.Signature ? true : false, hashAlgorithm); } finally { if (!hProv.IsInvalid) { hProv.Close(); } } return(ret); }
/// <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); }
/// <summary> /// Export the public RSA keyinfo from the current crypto provider /// </summary> /// <param name="hProv">Handle to the crypto provider</param> /// <param name="signature">Set to true for AT_SIGNATURE, false for AT_KEYEXCHANGE</param> /// <returns>An IntPtr pointing to the public key info structure</returns> private IntPtr ExportPublicKeyInfo(CryptoApiMethods.SafeCryptProviderHandle hProv, bool signature) { CryptoApiMethods.CALG type = signature ? CryptoApiMethods.CALG.AT_SIGNATURE : CryptoApiMethods.CALG.AT_KEYEXCHANGE; IntPtr ret = IntPtr.Zero; uint infoLen = 0; if (!CryptoApiMethods.CryptExportPublicKeyInfoEx(hProv, type, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, CryptoApiMethods.szOID_RSA_RSA, 0, IntPtr.Zero, ret, ref infoLen)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } ret = Marshal.AllocHGlobal((int)infoLen); if (!CryptoApiMethods.CryptExportPublicKeyInfoEx(hProv, type, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, CryptoApiMethods.szOID_RSA_RSA, 0, IntPtr.Zero, ret, ref infoLen)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(ret); }
/// <summary> /// Hash public key info of a specified RSA key /// </summary> /// <param name="key"></param> /// <returns></returns> private byte[] HashPublicKeyInfo(RSACryptoServiceProvider key) { CryptoApiMethods.SafeCryptProviderHandle hProv = new CryptoApiMethods.SafeCryptProviderHandle(); IntPtr publicKeyInfoPtr = IntPtr.Zero; byte[] ret = null; uint len = 0; try { publicKeyInfoPtr = ExportPublicKeyInfo(key); CryptoApiMethods.CERT_PUBLIC_KEY_INFO publicKeyInfo = (CryptoApiMethods.CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(publicKeyInfoPtr, typeof(CryptoApiMethods.CERT_PUBLIC_KEY_INFO)); hProv = OpenRSAProvider(key.CspKeyContainerInfo.ProviderName, key.CspKeyContainerInfo.KeyContainerName); if (!CryptoApiMethods.CryptHashPublicKeyInfo(hProv, 0, 0, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, publicKeyInfo, null, out len)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } ret = new byte[len]; if (!CryptoApiMethods.CryptHashPublicKeyInfo(hProv, 0, 0, CryptoApiMethods.CertEncoding.X509_ASN_ENCODING, publicKeyInfo, ret, out len)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (!hProv.IsInvalid) { hProv.Close(); } if (publicKeyInfoPtr != IntPtr.Zero) { Marshal.FreeHGlobal(publicKeyInfoPtr); } } return ret; }
/// <summary> /// Encode and sign a CERT_INFO structure /// </summary> /// <param name="key">Key to sign the certificate with</param> /// <param name="certInfo">The CERT_INFO structure to sign</param> /// <param name="hashAlgorithm"></param> /// <returns></returns> private byte[] EncodeAndSignCertInfo(RSACryptoServiceProvider key, CryptoApiMethods.CERT_INFO certInfo, CertificateHashAlgorithm hashAlgorithm) { byte[] ret = null; CryptoApiMethods.SafeCryptProviderHandle hProv = new CryptoApiMethods.SafeCryptProviderHandle(); try { hProv = OpenRSAProvider(key.CspKeyContainerInfo.ProviderName, key.CspKeyContainerInfo.KeyContainerName); ret = EncodeAndSignCertInfo(hProv, certInfo, key.CspKeyContainerInfo.KeyNumber == KeyNumber.Signature ? true : false, hashAlgorithm); } finally { if (!hProv.IsInvalid) { hProv.Close(); } } return ret; }