/// <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> /// 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; }