public static void Sign(Signature signature, PDFMetadata metadata, string input, string output) { if (signature == null) { throw new NullReferenceException(); } if (signature.Store == null) { throw new NullReferenceException(); } /* Get Store Private Key and Certificate Chain */ var name = GetPrivateKeyName(signature.Store); if (string.IsNullOrEmpty(name)) { throw new InvalidOperationException("No private key available"); } var privateKey = signature.Store.GetKey(name).Key; X509Certificate[] certificateChain = GetCertificateChain(signature.Store, name); if (certificateChain == null) { throw new InvalidOperationException("No private key available"); } /* Prepare file input/output */ var reader = new PdfReader(input, null); var outputFile = new FileStream(output, FileMode.Create, FileAccess.Write); var stamper = PdfStamper.CreateSignature(reader, outputFile, '\0', null, true); stamper.MoreInfo = metadata.InfoHashtable; stamper.XmpMetadata = metadata.XmpMetadata; /* Create Siganture Appearance */ PdfSignatureAppearance signatureAppearance = CreateSignatureAppearance(stamper, signature); signatureAppearance.SetCrypto(privateKey, certificateChain, null, PdfSignatureAppearance.WINCER_SIGNED); signatureAppearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS; PdfSignature pdfSignature = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); pdfSignature.Reason = signatureAppearance.Reason; pdfSignature.Location = signatureAppearance.Location; pdfSignature.Contact = signatureAppearance.Contact; pdfSignature.Date = new PdfDate(signatureAppearance.SignDate); signatureAppearance.CryptoDictionary = pdfSignature; // Preallocate excluded byte-range for the signature content (hex encoded) var excludedByteRange = new Dictionary <PdfName, int> (); excludedByteRange[PdfName.CONTENTS] = ContentEstimated * 2 + 2; signatureAppearance.PreClose(new Hashtable(excludedByteRange)); // Sign the document PKCS7SignDocument(privateKey, certificateChain, signatureAppearance, "SHA-256"); }
public async Task <IActionResult> Sign(string uuid, string password, string description) { if (string.IsNullOrEmpty(uuid) || string.IsNullOrEmpty(password)) { return(View("OperationNotAllowed")); } var document = await DBContext.Document .SingleOrDefaultAsync(m => m.Uuid == uuid); if (document == null) { return(NotFound()); } if (document.MimeType != "application/pdf") { return(View("InvalidDocument")); } var x509certificate = HttpContext.Connection.ClientCertificate; if (x509certificate == null) { return(View("OperationNotAllowed")); } var certificate = await DBContext.Certificate .SingleOrDefaultAsync(r => r.SerialNumber == x509certificate.SerialNumber); if (certificate == null || certificate.ReviewerUuid != document.ReviewerUuid) { return(View("OperationNotAllowed")); } if (certificate.ExpireDate < DateTime.Now.Date) { certificate.Revoked = true; certificate.RevokeDate = DateTime.UtcNow.Date; DBContext.Certificate.Update(certificate); await DBContext.SaveChangesAsync(); } if (certificate.Revoked == true) { return(RedirectToAction("CertificateExpired", "Certificates")); } var pkcs12store = TrustManager.LoadPkcs12Store(certificate.Uuid, password, CertificateType.ReviewerCertificate); if (pkcs12store == null) { return(View("OperationNotAllowed")); } var reviewer = await DBContext.Reviewer .SingleOrDefaultAsync(r => r.Uuid == certificate.ReviewerUuid); var metadata = new PDFMetadata() { Title = "PDF Signed Document" + document.Name, Author = certificate.Reviewer.Name, Creator = certificate.Reviewer.Name, Producer = certificate.Reviewer.Name, Keywords = "UUID:" + document.Uuid, Subject = "Signed Document" }; var signature = new Signature() { Store = pkcs12store, Reason = "Document Aproved, Date:" + DateTime.UtcNow.Date, Page = 1, Contact = certificate.Reviewer.Email, CustomText = "Signed by " + reviewer.Name + " on " + DateTime.UtcNow.Date.ToString("dd-MM-yyyy") + " - " + description, Top = 10, Left = 10, Width = 200, Height = 50, Multi = false, Visible = true }; SignatureManager.Sign( signature, metadata, FileManager.DocumentRoot + "/" + document.Uuid, FileManager.DocumentRoot + "/" + document.Uuid + "-signed"); document.SignatureDate = DateTime.UtcNow.Date; DBContext.Document.Update(document); await DBContext.SaveChangesAsync(); var message = await RenderService .RenderToStringAsync("Email/DocumentSigned", document); var attachments = new List <Attachment> (); attachments.Add( await EmailManager.LoadAttachment( FileManager.DocumentRoot + "/" + document.Uuid + "-signed", "Signed by " + reviewer.Name + "-" + document.Name, document.MimeType)); attachments.Add( await EmailManager.LoadAttachment( TrustManager.CertificatePath( certificate.Uuid, CertificateType.ReviewerCertificate, StoreFormat.CRT), "public.crt", "application/x-x509-ca-cert")); attachments.Add( await EmailManager.LoadAttachment( TrustManager.CertificatePath( "root", CertificateType.AuthorityCertificate, StoreFormat.CRT), "authority.crt", "application/x-x509-ca-cert")); var response = await EmailManager.SendEmailHTML( message, EmailManager.Sender, certificate.Reviewer.Email, "Your signed document is ready", attachments ); if (!response.Successful) { return(View("ErrorSendingDocument", document)); } return(View("DocumentSigned", document)); }