private static void SignFileImpl(string filename, X509Certificate2 certificate, string timeStampUrl) { // Variables // var digitalSignInfo = default(DigitalSignInfo); // var signContext = default(DigitalSignContext); var pSignContext = IntPtr.Zero; // Prepare signing info: exe and cert // digitalSignInfo = new DigitalSignInfo(); digitalSignInfo.dwSize = Marshal.SizeOf(digitalSignInfo); digitalSignInfo.dwSubjectChoice = DigitalSignSubjectChoice.File; digitalSignInfo.pwszFileName = filename; digitalSignInfo.dwSigningCertChoice = DigitalSigningCertificateChoice.Certificate; digitalSignInfo.pSigningCertContext = certificate.Handle; digitalSignInfo.pwszTimestampURL = timeStampUrl; // it's sometimes dying when we give it a timestamp url.... digitalSignInfo.dwAdditionalCertChoice = DigitalSignAdditionalCertificateChoice.AddChainNoRoot; digitalSignInfo.pSignExtInfo = IntPtr.Zero; var digitalSignExtendedInfo = new DigitalSignExtendedInfo("description", "http://moerinfo"); var ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(digitalSignExtendedInfo)); Marshal.StructureToPtr(digitalSignExtendedInfo, ptr, false); // digitalSignInfo.pSignExtInfo = ptr; // Sign exe // if ((!CryptUi.CryptUIWizDigitalSign(DigitalSignFlags.NoUI, IntPtr.Zero, null, ref digitalSignInfo, ref pSignContext))) { var rc = (uint)Marshal.GetLastWin32Error(); if (rc == 0x8007000d) { // this is caused when the timestamp server fails; which seems intermittent for any timestamp service. throw new FailedTimestampException(filename, timeStampUrl); } throw new DigitalSignFailure(filename, rc); } // Free blob // if ((!CryptUi.CryptUIWizFreeDigitalSignContext(pSignContext))) { throw new Win32Exception(Marshal.GetLastWin32Error(), "CryptUIWizFreeDigitalSignContext"); } // Free additional Info Marshal.FreeCoTaskMem(ptr); }
public static extern bool CryptUIWizDigitalSign(DigitalSignFlags dwFlags, IntPtr hwndParent, string pwszWizardTitle, ref DigitalSignInfo pDigitalSignInfo, ref IntPtr ppSignContext);
public static extern bool CryptUIWizDigitalSign(DigitalSignFlags dwFlags, IntPtr hwndParent, string pwszWizardTitle, ref DigitalSignInfo pDigitalSignInfo, ref IntPtr ppSignContext);