private static unsafe void SetPrivateKeyProperty (SafeCertContextHandle safeCertContextHandle, ICspAsymmetricAlgorithm asymmetricAlgorithm) { SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle; if (asymmetricAlgorithm != null) { CAPI.CRYPT_KEY_PROV_INFO keyProvInfo = new CAPI.CRYPT_KEY_PROV_INFO(); keyProvInfo.pwszContainerName = asymmetricAlgorithm.CspKeyContainerInfo.KeyContainerName; keyProvInfo.pwszProvName = asymmetricAlgorithm.CspKeyContainerInfo.ProviderName; keyProvInfo.dwProvType = (uint) asymmetricAlgorithm.CspKeyContainerInfo.ProviderType; keyProvInfo.dwFlags = asymmetricAlgorithm.CspKeyContainerInfo.MachineKeyStore ? CAPI.CRYPT_MACHINE_KEYSET : 0; keyProvInfo.cProvParam = 0; keyProvInfo.rgProvParam = IntPtr.Zero; keyProvInfo.dwKeySpec = (uint) asymmetricAlgorithm.CspKeyContainerInfo.KeyNumber; ptr = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_KEY_PROV_INFO)))); Marshal.StructureToPtr(keyProvInfo, ptr.DangerousGetHandle(), false); } try { if (!CAPI.CertSetCertificateContextProperty(safeCertContextHandle, CAPI.CERT_KEY_PROV_INFO_PROP_ID, 0, ptr)) throw new CryptographicException(Marshal.GetLastWin32Error()); } finally { if (!ptr.IsInvalid) { Marshal.DestroyStructure(ptr.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO)); ptr.Dispose(); } } }
internal static unsafe X509Certificate2 CreateDummyCertificate (CspParameters parameters) { SafeCertContextHandle handle = SafeCertContextHandle.InvalidHandle; // hProv SafeCryptProvHandle hProv = SafeCryptProvHandle.InvalidHandle; UInt32 dwFlags = 0; if (0 != (parameters.Flags & CspProviderFlags.UseMachineKeyStore)) { dwFlags |= CAPI.CRYPT_MACHINE_KEYSET; } if (0 != (parameters.Flags & CspProviderFlags.UseDefaultKeyContainer)) { dwFlags |= CAPI.CRYPT_VERIFYCONTEXT; } if (0 != (parameters.Flags & CspProviderFlags.NoPrompt)) { dwFlags |= CAPI.CRYPT_SILENT; } bool rc = CAPI.CryptAcquireContext(ref hProv, parameters.KeyContainerName, parameters.ProviderName, (uint)parameters.ProviderType, dwFlags); if (!rc) throw new CryptographicException(Marshal.GetLastWin32Error()); // pKeyProvInfo CAPI.CRYPT_KEY_PROV_INFO KeyProvInfo = new CAPI.CRYPT_KEY_PROV_INFO(); KeyProvInfo.pwszProvName = parameters.ProviderName; KeyProvInfo.pwszContainerName = parameters.KeyContainerName; KeyProvInfo.dwProvType = (uint)parameters.ProviderType; KeyProvInfo.dwKeySpec = (uint)parameters.KeyNumber ; KeyProvInfo.dwFlags = (uint)((parameters.Flags & CspProviderFlags.UseMachineKeyStore) == CspProviderFlags.UseMachineKeyStore ? CAPI.CRYPT_MACHINE_KEYSET : 0); SafeLocalAllocHandle pKeyProvInfo = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr(Marshal.SizeOf(typeof(CAPI.CRYPT_KEY_PROV_INFO)))); Marshal.StructureToPtr(KeyProvInfo, pKeyProvInfo.DangerousGetHandle(), false); // Signature CAPI.CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm = new CAPI.CRYPT_ALGORITHM_IDENTIFIER(); SignatureAlgorithm.pszObjId = CAPI.szOID_OIWSEC_sha1RSASign; SafeLocalAllocHandle pSignatureAlgorithm = CAPI.LocalAlloc(CAPI.LPTR, new IntPtr( Marshal.SizeOf(typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER)))); Marshal.StructureToPtr(SignatureAlgorithm, pSignatureAlgorithm.DangerousGetHandle(), false); // pSubjectIssuerBlob X500DistinguishedName subjectName = new X500DistinguishedName("cn=CMS Signer Dummy Certificate"); fixed (byte * pbOctets = subjectName.RawData) { CAPI.CRYPTOAPI_BLOB SubjectIssuerBlob = new CAPI.CRYPTOAPI_BLOB(); SubjectIssuerBlob.cbData = (uint)subjectName.RawData.Length; SubjectIssuerBlob.pbData = new IntPtr(pbOctets); handle = CAPI.CAPIUnsafe.CertCreateSelfSignCertificate(hProv, new IntPtr(&SubjectIssuerBlob), 1, pKeyProvInfo.DangerousGetHandle(), pSignatureAlgorithm.DangerousGetHandle(), IntPtr.Zero, //StartTime IntPtr.Zero, //EndTime IntPtr.Zero); //Extensions } Marshal.DestroyStructure(pKeyProvInfo.DangerousGetHandle(), typeof(CAPI.CRYPT_KEY_PROV_INFO)); pKeyProvInfo.Dispose(); Marshal.DestroyStructure(pSignatureAlgorithm.DangerousGetHandle(), typeof(CAPI.CRYPT_ALGORITHM_IDENTIFIER)); pSignatureAlgorithm.Dispose(); if (handle == null || handle.IsInvalid) throw new CryptographicException(Marshal.GetLastWin32Error()); X509Certificate2 certificate = new X509Certificate2(handle.DangerousGetHandle()); handle.Dispose(); return certificate; }