public static extern IntPtr CertCreateSelfSignCertificate( IntPtr hProv, ref CRYPT_DATA_BLOB pSubjectIssuerBlob, uint dwFlagsm, IntPtr pinfo, IntPtr pSignatureAlgorithm, Native.SYSTEMTIME pStartTime, Native.SYSTEMTIME pEndTime, IntPtr other);
static void MakeNewCert(IntPtr hCPContext, string szCertName, string szPassword, ref Crypt.CRYPT_DATA_BLOB pPFX, ref IntPtr Info) { Crypt.CRYPT_DATA_BLOB certNameBlob = new Crypt.CRYPT_DATA_BLOB(); IntPtr hCertContext = IntPtr.Zero; Native.SYSTEMTIME certExpireDate; IntPtr hTempStore = IntPtr.Zero; try { if (!Crypt.CertStrToName(Crypt.X509Encoding.ASN_Encodings, szCertName, Crypt.CertNameType.CERT_OID_NAME_STR, IntPtr.Zero, null, ref certNameBlob.cbData, IntPtr.Zero)) { throw new Win32Exception("CertStrToName"); } certNameBlob.pbData = Crypt.CryptMemAlloc(sizeof(byte) * certNameBlob.cbData); if (!Crypt.CertStrToName(Crypt.X509Encoding.ASN_Encodings, szCertName, Crypt.CertNameType.CERT_OID_NAME_STR, IntPtr.Zero, certNameBlob.pbData, ref certNameBlob.cbData, IntPtr.Zero)) { throw new Win32Exception("CertStrToName2"); } //var buffer = new char[1024]; char[] buffer = new char[1024]; int d; if ((d = Crypt.CertNameToStr(Crypt.X509Encoding.ASN_Encodings, ref certNameBlob, Crypt.CertNameType.CERT_X500_NAME_STR, buffer, 1024 * sizeof(char))) != 0) { Console.WriteLine("CertNameToStr: {0} [{1}]", buffer, d); } var renewDate = DateTime.Now.AddYears(YearsToExtend); certExpireDate = new Native.SYSTEMTIME(renewDate); Console.WriteLine(" Renewing to expire at {0:g}", renewDate); // For some reason, evaluating this next line makes the create cert work var junk = string.Format(" {0}, {1}/{2}, {3}, {4}", hCPContext, certNameBlob.cbData, certNameBlob.pbData, Info, certExpireDate.ToDate()); hCertContext = Crypt.CertCreateSelfSignCertificate(hCPContext, ref certNameBlob, 0, Info, IntPtr.Zero, null, certExpireDate, IntPtr.Zero); if (hCertContext == IntPtr.Zero) { throw new Win32Exception("CertCreateSelfSignCertificate"); } hTempStore = Crypt.CertOpenStore(new IntPtr(Crypt.CERT_STORE_PROV_MEMORY), 0, IntPtr.Zero, Crypt.CERT_STORE_CREATE_NEW_FLAG, null); if (hTempStore == IntPtr.Zero) { throw new Win32Exception("CertOpenStore"); } if (!Crypt.CertAddCertificateContextToStore(hTempStore, hCertContext, Crypt.CERT_STORE_ADD_NEW, IntPtr.Zero)) { throw new Win32Exception("CertAddCertificateContextToStore"); } if (Crypt.PFXExportCertStoreEx(hTempStore, ref pPFX, szPassword, IntPtr.Zero, Crypt.ExportCertStoreFlags.EXPORT_PRIVATE_KEYS | Crypt.ExportCertStoreFlags.REPORT_NO_PRIVATE_KEY | Crypt.ExportCertStoreFlags.REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY) == 0) { throw new Win32Exception("PFXExportCertStoreEx"); } pPFX.pbData = Crypt.CryptMemAlloc(sizeof(byte) * pPFX.cbData); if (Crypt.PFXExportCertStoreEx(hTempStore, ref pPFX, szPassword, IntPtr.Zero, Crypt.ExportCertStoreFlags.EXPORT_PRIVATE_KEYS) == 0) { throw new Win32Exception("PFXExportCertStoreEx2"); } } finally { if (certNameBlob.pbData != IntPtr.Zero) { Crypt.CryptMemFree(certNameBlob.pbData); } if (hTempStore != IntPtr.Zero) { Crypt.CertCloseStore(hTempStore, 0); } if (hCertContext != IntPtr.Zero) { Crypt.CertFreeCertificateContext(hCertContext); } } }