static public ValueGenerator Exponential(double mn, double mx, SignMode signMode = SignMode.Direct) { Debug.Assert(Math.Sign(mn) == Math.Sign(mx)); Debug.Assert(Math.Abs(mn) < Math.Abs(mx)); double ratio = Math.Log(mx / mn, 2.0); return((Random rnd, int count) => { double[] values = new double[count]; switch (signMode) { case SignMode.Direct: for (int i = 0; i < count; i++) { values[i] = mn * Math.Pow(2.0, ratio * rnd.NextDouble()); } break; case SignMode.Negate: for (int i = 0; i < count; i++) { values[i] = -mn *Math.Pow(2.0, ratio *rnd.NextDouble()); } break; case SignMode.Random: for (int i = 0; i < count; i++) { values[i] = ((i & 2) - 1) * mn * Math.Pow(2.0, ratio * rnd.NextDouble()); } break; } return values; }); }
public XElement ReceivePaymentNotification(string guid, XElement paymentNotification) { MFEPMessage <PaymentNotificationTransaction> deserializedResponse = new MFEPMessage <PaymentNotificationTransaction>(); XElement serializedResponse = null; string fileName = Guid.NewGuid().ToString(); try { MFEPMessage <PaymentNotificationTransaction> deserializedRequest = paymentNotification.FromXElement <MFEPMessage <PaymentNotificationTransaction> >(); deserializedResponse.Header.TimeStamp = DateTime.Now.ToString("s"); deserializedResponse.Header.Guid = guid; deserializedResponse.Header.TransmitInfo = new TransmitInfo() { SenderCode = deserializedRequest.Header.TransmitInfo.ReceiverCode, ResponseType = ProcessesCodes.BLRPMTNTFRS }; deserializedResponse.Header.Result = new Result(); fileName = deserializedRequest.Body.Transactions[0].ServiceType.SrvsTypValue.ToString() + fileName; if (!IsTestReponse) { // Verifying if (EnableSecuity) { if (deserializedRequest == null || deserializedRequest.Footer.Security == null || deserializedRequest.Footer.Security.Signature == null || string.IsNullOrWhiteSpace(deserializedRequest.Footer.Security.Signature.Trim())) { Result result = new Result(); result.ErrorCode = (int)ServiceErrors.InvalidSignature; result.ErrorDesc = ServiceErrors.InvalidSignature.ToString(); result.Severity = Severity.Error; deserializedResponse.Header.Result = result; WriteToPhysicalPath(paymentNotification, FailedPMTNotiRequestPath, fileName); // Write to failed notifications serializedResponse = deserializedResponse.ToXElement <MFEPMessage <PaymentNotificationTransaction> >(); WriteToPhysicalPath(serializedResponse, FailedPMTNotiResponsePath, fileName); return(serializedResponse); } else { VerifyMode verifyMode = VerifyMode.WithFormat; if (SecurityMode.Equals("WithOutFormat", StringComparison.CurrentCultureIgnoreCase)) { verifyMode = VerifyMode.WithOutFormat; } Collection <string> xPath = new Collection <string> { XPath }; bool verifiedSuccessfully = CertificateManager.VerifyMessageSignature(paymentNotification, xPath, deserializedRequest.Footer.Security.Signature, BillerCertificateSerialNumber, verifyMode); if (!verifiedSuccessfully) { Result result = new Result(); result.ErrorCode = (int)ServiceErrors.InvalidSignature; result.ErrorDesc = ServiceErrors.InvalidSignature.ToString(); result.Severity = Severity.Error; deserializedResponse.Header.Result = result; WriteToPhysicalPath(paymentNotification, FailedPMTNotiRequestPath, fileName); // Write to failed notifications serializedResponse = deserializedResponse.ToXElement <MFEPMessage <PaymentNotificationTransaction> >(); WriteToPhysicalPath(serializedResponse, FailedPMTNotiResponsePath, fileName); return(serializedResponse); } } } // Validation // Validate MFEP code if (deserializedRequest.Header.TransmitInfo.SenderCode != MFEPCode) { Result result = new Result(); result.ErrorCode = (int)ServiceErrors.InvalidSenderCode; result.ErrorDesc = ServiceErrors.InvalidSenderCode.ToString(); result.Severity = Severity.Error; deserializedResponse.Header.Result = result; WriteToPhysicalPath(paymentNotification, FailedPMTNotiRequestPath, fileName); // Write to failed notifications serializedResponse = deserializedResponse.ToXElement <MFEPMessage <PaymentNotificationTransaction> >(); WriteToPhysicalPath(serializedResponse, FailedPMTNotiResponsePath, fileName); return(serializedResponse); } // Validate Biller code if (deserializedRequest.Header.TransmitInfo.ReceiverCode != BillerCode) { Result result = new Result(); result.ErrorCode = (int)ServiceErrors.UnsuccessfulPaymentNotification; result.ErrorDesc = ServiceErrors.UnsuccessfulPaymentNotification.ToString(); result.Severity = Severity.Error; deserializedResponse.Header.Result = result; WriteToPhysicalPath(paymentNotification, FailedPMTNotiRequestPath, fileName); // Write to failed notifications serializedResponse = deserializedResponse.ToXElement <MFEPMessage <PaymentNotificationTransaction> >(); WriteToPhysicalPath(serializedResponse, FailedPMTNotiResponsePath, fileName); return(serializedResponse); } // if the serviceType is IndividualSecurity then insert it to database otherwise just write it ti physical directory if (ServiceType.Equals(deserializedRequest.Body.Transactions[0].ServiceType.SrvsTypValue.ToString(), StringComparison.CurrentCultureIgnoreCase)) { // Insert this payment DAL dal = new DAL(); dal.InsertPaymentNotification(deserializedRequest.Body.Transactions[0].AccountInfo.BillingNumber); } PaymentNotificationTransaction transaction = new PaymentNotificationTransaction { Transactions = new Collection <PaymentNotificationEntity>() }; foreach (PaymentNotificationEntity pne in deserializedRequest.Body.Transactions) { PaymentNotificationEntity notificationEntity = new PaymentNotificationEntity { JOEBPPSTrx = pne.JOEBPPSTrx, ProcessDate = pne.ProcessDate, STMTDate = pne.STMTDate, Result = new Result() }; transaction.Transactions.Add(notificationEntity); } deserializedResponse.Body = transaction; // Sign the response if (EnableSecuity) { SignMode signMode = SignMode.WithFormat; if (SecurityMode.Equals("WithOutFormat", StringComparison.CurrentCultureIgnoreCase)) { signMode = SignMode.WithOutFormat; } Collection <string> xPath = new Collection <string> { XPath }; deserializedResponse.Footer = new MFEPFooter(); deserializedResponse.Footer.Security.Signature = CertificateManager.SignMessage(deserializedResponse.ToXElement <MFEPMessage <PaymentNotificationTransaction> >(), xPath, BillerCertificateSerialNumber, signMode); } else { deserializedResponse.Footer = new MFEPFooter(); } WriteToPhysicalPath(paymentNotification, SuccessPMTNotiRequestPath, fileName); // Write to success notifications serializedResponse = deserializedResponse.ToXElement <MFEPMessage <PaymentNotificationTransaction> >(); WriteToPhysicalPath(serializedResponse, SuccessPMTNotiResponsePath, fileName); return(serializedResponse); } else { return(GenerateAutoResponse(guid, deserializedRequest, guid)); } } catch (Exception exception) { string ex = exception.Message + "\n" + exception.StackTrace; WriteException(ex, ExceptionPath); Result result = new Result(); result.ErrorCode = (int)ServiceErrors.InternalError; result.ErrorDesc = ServiceErrors.InternalError.ToString(); result.Severity = Severity.Error; deserializedResponse.Header.Result = result; WriteToPhysicalPath(paymentNotification, FailedPMTNotiRequestPath, fileName); // Write to success notifications serializedResponse = deserializedResponse.ToXElement <MFEPMessage <PaymentNotificationTransaction> >(); WriteToPhysicalPath(serializedResponse, FailedPMTNotiResponsePath, fileName); return(serializedResponse); } }
public XElement BillPull(string guid, XElement billPullRequest) { MFEPMessage <BillsRecord> deserializedResponse = new MFEPMessage <BillsRecord>(); XElement serializedResponse = null; string fileGuid = Guid.NewGuid().ToString(); try { // Write the request to physical path WriteToPhysicalPath(billPullRequest, BillPullRequestPath, fileGuid); MFEPMessage <BillInquiryRequestEntity> deserializedRequest = billPullRequest.FromXElement <MFEPMessage <BillInquiryRequestEntity> >(); deserializedResponse.Header.TimeStamp = DateTime.Now.ToString("s"); deserializedResponse.Header.Guid = guid; deserializedResponse.Header.TransmitInfo = new TransmitInfo() { SenderCode = deserializedRequest.Header.TransmitInfo.ReceiverCode, ResponseType = ProcessesCodes.BILPULRS }; deserializedResponse.Header.Result = new Result(); bool isTestReponse = IsTestReponse; if (!isTestReponse) { // Verifying if (EnableSecuity) { if (deserializedRequest == null || deserializedRequest.Footer.Security == null || deserializedRequest.Footer.Security.Signature == null || string.IsNullOrWhiteSpace(deserializedRequest.Footer.Security.Signature.Trim())) { Result result_1 = new Result(); result_1.ErrorCode = (int)ServiceErrors.InvalidSignature; result_1.ErrorDesc = ServiceErrors.InvalidSignature.ToString(); result_1.Severity = Severity.Error; deserializedResponse.Header.Result = result_1; serializedResponse = deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(); // Write the request to physical path WriteToPhysicalPath(serializedResponse, BillPullResponsePath, fileGuid); return(serializedResponse); } else { VerifyMode verifyMode = VerifyMode.WithFormat; if (SecurityMode.Equals("WithOutFormat", StringComparison.CurrentCultureIgnoreCase)) { verifyMode = VerifyMode.WithOutFormat; } Collection <string> xPath = new Collection <string> { XPath }; bool verifiedSuccessfully = CertificateManager.VerifyMessageSignature(deserializedRequest.ToXElement <MFEPMessage <BillInquiryRequestEntity> >(), xPath, deserializedRequest.Footer.Security.Signature, BillerCertificateSerialNumber, verifyMode); if (!verifiedSuccessfully) { Result result_2 = new Result(); result_2.ErrorCode = (int)ServiceErrors.InvalidSignature; result_2.ErrorDesc = ServiceErrors.InvalidSignature.ToString(); result_2.Severity = Severity.Error; deserializedResponse.Header.Result = result_2; serializedResponse = deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(); WriteToPhysicalPath(serializedResponse, BillPullResponsePath, fileGuid); return(serializedResponse); } } if (deserializedRequest.Header.TransmitInfo.SenderCode != MFEPCode) { Result result_3 = new Result(); result_3.ErrorCode = (int)ServiceErrors.InvalidSenderCode; result_3.ErrorDesc = ServiceErrors.InvalidSenderCode.ToString(); result_3.Severity = Severity.Error; deserializedResponse.Header.Result = result_3; serializedResponse = deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(); // Write the request to physical path WriteToPhysicalPath(serializedResponse, BillPullResponsePath, fileGuid); return(serializedResponse); } // Validate Biller code if (deserializedRequest.Header.TransmitInfo.ReceiverCode != BillerCode) { Result result_4 = new Result(); result_4.ErrorCode = (int)ServiceErrors.UnsuccessfulBillPullRequest; result_4.ErrorDesc = ServiceErrors.UnsuccessfulBillPullRequest.ToString(); result_4.Severity = Severity.Error; deserializedResponse.Header.Result = result_4; serializedResponse = deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(); // Write the request to physical path WriteToPhysicalPath(serializedResponse, BillPullResponsePath, fileGuid); return(serializedResponse); } // Validate Service Type if (!ServiceType.Equals(deserializedRequest.Body.ServiceType, StringComparison.CurrentCultureIgnoreCase)) { Result result_5 = new Result(); result_5.ErrorCode = (int)ServiceErrors.UnrecognizedServiceType; result_5.ErrorDesc = ServiceErrors.UnrecognizedServiceType.ToString(); result_5.Severity = Severity.Error; deserializedResponse.Header.Result = result_5; serializedResponse = deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(); // Write the request to physical path WriteToPhysicalPath(serializedResponse, BillPullResponsePath, fileGuid); return(serializedResponse); } // Get Bill and generate the response DAL dal = new DAL(); BillRecord billRecord = dal.GetBillInfo(deserializedRequest.Body.AccountInfo.BillNumber, deserializedRequest.Body.AccountInfo.BillingNumber, deserializedRequest.Body.ServiceType); if (billRecord != null) { billRecord.IssueDate = billRecord.IssueDate.Value.AddMinutes(TimeDifference); billRecord.DueDate = billRecord.DueDate.Value.AddMinutes(TimeDifference); deserializedResponse.Body = new BillsRecord() { RecCount = 1 }; deserializedResponse.Body.BillRecords.Add(billRecord); } else { deserializedResponse.Body = new BillsRecord() { RecCount = 0, BillRecords = null }; } // Sign the response if (EnableSecuity) { SignMode signMode = SignMode.WithFormat; if (SecurityMode.Equals("WithOutFormat", StringComparison.CurrentCultureIgnoreCase)) { signMode = SignMode.WithOutFormat; } Collection <string> xPath = new Collection <string> { XPath }; deserializedResponse.Footer = new MFEPFooter(); deserializedResponse.Footer.Security.Signature = CertificateManager.SignMessage(deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(), xPath, BillerCertificateSerialNumber, signMode); } else { SignMode signMode = SignMode.WithFormat; if (SecurityMode.Equals("WithOutFormat", StringComparison.CurrentCultureIgnoreCase)) { signMode = SignMode.WithOutFormat; } Collection <string> xPath = new Collection <string> { XPath }; deserializedResponse.Footer = new MFEPFooter(); deserializedResponse.Footer.Security.Signature = CertificateManager.SignMessage(deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(), xPath, BillerCertificateSerialNumber, signMode); } serializedResponse = deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >(); // Write the request to physical path WriteToPhysicalPath(serializedResponse, BillPullResponsePath, fileGuid); return(serializedResponse); } // Sign the response return(GenerateAutoResponse(guid, billPullRequest)); /* serializedResponse = deserializedResponse.ToXElement<MFEPMessage<BillsRecord>>(); * // Write the request to physical path * WriteToPhysicalPath(serializedResponse, BillPullResponsePath, fileGuid); * */ /*return serializedResponse;*/ } else { return(GenerateAutoResponse(guid, billPullRequest)); } } catch (Exception exception) { string ex = exception.Message + "\n" + exception.StackTrace; WriteException(ex, ExceptionPath); Result result = new Result(); result.ErrorCode = (int)ServiceErrors.InternalError; result.ErrorDesc = ServiceErrors.InternalError.ToString(); result.Severity = Severity.Error; deserializedResponse.Header.Result = result; return(deserializedResponse.ToXElement <MFEPMessage <BillsRecord> >()); } }
private static SIGNER_SIGN_EX2_PARAMS GetSignerSignEx2ParametersPointer(string timestampUrl, SignMode type, IntPtr subjectInfo, IntPtr signerCertificate, IntPtr provider, out GCHandle?signerSignHandle, string timestampAlgorithmOid) { // signature info var signatureInfo = new SIGNER_SIGNATURE_INFO { cbSize = (uint)Marshal.SizeOf <SIGNER_SIGNATURE_INFO>(), algidHash = Constants.CALG_SHA_256, dwAttrChoice = Constants.DONT_CARE, pAttrAuthCode = IntPtr.Zero, psAuthenticated = IntPtr.Zero, psUnauthenticated = IntPtr.Zero, }; var signatureHandle = Marshal.AllocHGlobal(Marshal.SizeOf <SIGNER_SIGNATURE_INFO>()); Marshal.StructureToPtr(signatureInfo, signatureHandle, false); // signer sign ex params var signerSignEx2Params = new SIGNER_SIGN_EX2_PARAMS { dwFlags = Constants.DONT_CARE, pSubjectInfo = subjectInfo, pSigningCert = signerCertificate, pSignatureInfo = signatureHandle, pProviderInfo = provider, }; if (!string.IsNullOrEmpty(timestampUrl)) { signerSignEx2Params.pwszTimestampURL = Marshal.StringToHGlobalUni(timestampUrl); if (string.IsNullOrEmpty(timestampAlgorithmOid)) { signerSignEx2Params.dwTimestampFlags = Constants.SIGNER_TIMESTAMP_AUTHENTICODE; } else { signerSignEx2Params.dwTimestampFlags = Constants.SIGNER_TIMESTAMP_RFC3161; signerSignEx2Params.pszAlgorithmOid = Marshal.StringToHGlobalAnsi(timestampAlgorithmOid); } } signerSignHandle = null; if (type == SignMode.APPX) { var sipData = new APPX_SIP_CLIENT_DATA(); signerSignHandle = GCHandle.Alloc(signerSignEx2Params, GCHandleType.Pinned); sipData.pSignerParams = signerSignHandle.Value.AddrOfPinnedObject(); var sipHandle = Marshal.AllocHGlobal(Marshal.SizeOf <APPX_SIP_CLIENT_DATA>()); Marshal.StructureToPtr(sipData, sipHandle, false); signerSignEx2Params.pSipData = sipHandle; } return(signerSignEx2Params); }
private static void SignFile(IntPtr certificate, string path, string timestampUrl, SignMode type, string containerName, string dllPath, Logger logger, string timestampAlgorithmOid) { logger.WriteLine("Beginning the signing process", true); var subjectInfo = GetSubjectInfoPointer(path); var signerCertificate = GetSignerCertificatePointer(certificate); var provider = GetProviderPointer(containerName); var signerSignEx2Params = GetSignerSignEx2ParametersPointer(timestampUrl, type, subjectInfo, signerCertificate, provider, out var signerSignHandle, timestampAlgorithmOid); try { IntPtr signModule; if (string.IsNullOrEmpty(dllPath)) { logger.WriteLine("Loading MSSign32.dll from default path", true); signModule = NativeMethods.LoadLibraryEx("MSSign32.dll", IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_SEARCH_SYSTEM32); } else { logger.WriteLine($"Loading MSSign32.dll from specific path: {dllPath}", true); signModule = NativeMethods.LoadLibraryEx(dllPath, IntPtr.Zero, LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH); } if (signModule == IntPtr.Zero) { var errorResult = Marshal.GetHRForLastWin32Error(); throw new SigningException($"Win32 error in LoadLibraryEx: {errorResult}", Marshal.GetExceptionForHR(errorResult)); } logger.WriteLine("Getting SignerSignEx2 pointer", true); var signerSignEx2Pointer = NativeMethods.GetProcAddress(signModule, "SignerSignEx2"); if (signModule == IntPtr.Zero) { var errorResult = Marshal.GetHRForLastWin32Error(); throw new SigningException($"Win32 error in GetProcAddress: {errorResult}", Marshal.GetExceptionForHR(errorResult)); } NativeMethods.SignerSignEx2Delegate signerSignEx2; try { logger.WriteLine("Marshalling SignerSignEx2 pointer to a delegate", true); signerSignEx2 = Marshal.GetDelegateForFunctionPointer <NativeMethods.SignerSignEx2Delegate>( signerSignEx2Pointer); } catch (Exception e) { throw new SigningException("Error while marshalling SignerSignEx2 pointer to a managed delegate.", e); } logger.WriteLine("Invoking SignerSignEx2", true); var result = signerSignEx2(signerSignEx2Params.dwFlags, signerSignEx2Params.pSubjectInfo, signerSignEx2Params.pSigningCert, signerSignEx2Params.pSignatureInfo, signerSignEx2Params.pProviderInfo, signerSignEx2Params.dwTimestampFlags, signerSignEx2Params.pszAlgorithmOid, signerSignEx2Params.pwszTimestampURL, signerSignEx2Params.pCryptAttrs, signerSignEx2Params.pSipData, signerSignEx2Params.pSignerContext, signerSignEx2Params.pCryptoPolicy, signerSignEx2Params.pReserved); Marshal.FreeHGlobal(signerSignEx2Params.pwszTimestampURL); Marshal.FreeHGlobal(signerSignEx2Params.pszAlgorithmOid); if (type == SignMode.APPX) { var sipData = Marshal.PtrToStructure <APPX_SIP_CLIENT_DATA>(signerSignEx2Params.pSipData); if (sipData.pAppxSipState != IntPtr.Zero) { Marshal.Release(sipData.pAppxSipState); } } if (result != 0) { throw new SigningException("Win32 error in SignerSignEx2:", Marshal.GetExceptionForHR(result)); } logger.WriteLine("DONE", true); } finally { signerSignHandle?.Free(); } }
public static void SignFile(string certificateThumbprint, string pin, string containerName, CertificateStore store, string path, string timestampUrl, SignMode mode, string dllPath, Logger logger, string timestampAlgorithmOid = null) { logger.WriteLine("Validating certificate thumbprint", true); if (certificateThumbprint?.Length != 40 || !ValidateThumbprint(certificateThumbprint)) { throw new SigningException( $"Invalid certificate thumbprint provided: {certificateThumbprint}. The thumbprint must be a valid SHA1 thumbprint - 40 characters long and consisting of only hexadecimal characters (0-9 and A-F)"); } logger.WriteLine("Converting thumbprint to bytes", true); var binaryHash = StringToByteArray(certificateThumbprint); var cryptoProvider = AcquireContext(containerName, Constants.CryptoProviderName, logger); try { SetPin(cryptoProvider, pin, logger); var certStore = OpenCertificateStore(store, logger); try { var certificate = RetrieveCertificate(binaryHash, certStore, out var hashHandle, out var hashBlobHandle, logger); try { SignFile(certificate, path, timestampUrl, mode, containerName, dllPath, logger, timestampAlgorithmOid); } finally { hashHandle?.Free(); hashBlobHandle?.Free(); NativeMethods.CertFreeCertificateContext(certificate); } } finally { NativeMethods.CertCloseStore(certStore, 0); } } finally { NativeMethods.CryptReleaseContext(cryptoProvider, 0); } }
private static void SignFile(IntPtr certificate, string path, string timestampUrl, SignMode type, Action <string> logger) { logger("Beginning the signing process"); var subjectInfo = GetSubjectInfoPointer(path); var signerCertificate = GetSignerCertificatePointer(certificate); GCHandle?signerSignHandle = null; try { var signerSignEx2Params = GetsignersignEx2ParametersPointer(timestampUrl, type, subjectInfo, signerCertificate, out signerSignHandle); logger("Loading MSSign32.dll"); var signModule = NativeMethods.LoadLibraryEx("MSSign32.dll", IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_SEARCH_SYSTEM32); if (signModule == IntPtr.Zero) { var errorResult = Marshal.GetHRForLastWin32Error(); throw new SigningException($"Win32 error in LoadLibraryEx: {errorResult}", Marshal.GetExceptionForHR(errorResult)); } logger("Getting SignerSignEx2 pointer"); var signerSignEx2Pointer = NativeMethods.GetProcAddress(signModule, "SignerSignEx2"); if (signModule == IntPtr.Zero) { var errorResult = Marshal.GetHRForLastWin32Error(); throw new SigningException($"Win32 error in GetProcAddress: {errorResult}", Marshal.GetExceptionForHR(errorResult)); } NativeMethods.SignerSignEx2Delegate signerSignEx2; try { logger("Marshalling SignerSignEx2 pointer to a delegate"); signerSignEx2 = Marshal.GetDelegateForFunctionPointer <NativeMethods.SignerSignEx2Delegate>( signerSignEx2Pointer); } catch (Exception e) { throw new SigningException("Error while marshalling SignerSignEx2 pointer to a managed delegate.", e); } logger("Invoking SignerSignEx2"); var result = signerSignEx2(signerSignEx2Params.dwFlags, signerSignEx2Params.pSubjectInfo, signerSignEx2Params.pSigningCert, signerSignEx2Params.pSignatureInfo, signerSignEx2Params.pProviderInfo, signerSignEx2Params.dwTimestampFlags, signerSignEx2Params.pszAlgorithmOid, signerSignEx2Params.pwszTimestampURL, signerSignEx2Params.pCryptAttrs, signerSignEx2Params.pSipData, signerSignEx2Params.pSignerContext, signerSignEx2Params.pCryptoPolicy, signerSignEx2Params.pReserved); if (result != 0) { throw new SigningException($"Win32 error in SignerSignEx2:", Marshal.GetExceptionForHR(result)); } logger("DONE"); } finally { signerSignHandle?.Free(); } }
public static void SignFile(string certificateThumbprint, string pin, string containerName, CertificateStore store, string path, string timestampUrl, SignMode mode, Action <string> logger) { logger("Validating certificate thumbprint"); if (certificateThumbprint?.Length != 40 || !ValidateThumbprint(certificateThumbprint)) { throw new SigningException( $"Invalid certificate thumbprint provided: {certificateThumbprint}. The thumbprint must be a valid SHA1 thumbprint - 40 characters long and consisting of only hexadecimal characters (0-9 and A-F)"); } logger("Converting thumbprint to bytes"); var binaryHash = StringToByteArray(certificateThumbprint); UnlockToken(containerName, Constants.CryptoProviderName, pin, logger); var systemStore = GetSystemStore(store); logger($"Opening system-level cryptographic store {systemStore}/{Constants.CryptoStoreName}"); var certStore = NativeMethods.CertOpenStore(new IntPtr(Constants.CERT_STORE_PROV_SYSTEM), Constants.DONT_CARE, IntPtr.Zero, systemStore, Constants.CryptoStoreName); if (certStore == IntPtr.Zero) { var errorResult = Marshal.GetHRForLastWin32Error(); throw new SigningException($"Win32 error in CertOpenStore: {errorResult}", Marshal.GetExceptionForHR(errorResult)); } GCHandle?h1 = null; GCHandle?h2 = null; try { var certificate = RetrieveCertificate(binaryHash, certStore, out h1, out h2, logger); SignFile(certificate, path, timestampUrl, mode, logger); } finally { h1?.Free(); h2?.Free(); } }