public ActionResult Complete(SignatureCompleteModel model) { byte[] signedPdf; try { // Recover session data from Index action var sessionModel = Session["ITextSessionModel"] as ITextSessionModel; if (sessionModel == null) { // This should not happen return(RedirectToAction("Index")); } // Decode Certificate var certificate = new X509CertificateParser().ReadCertificate(model.CertContent); // Compute the external digest var pkcs7 = new PdfPKCS7(null, new X509Certificate[] { certificate }, DigestAlgorithm, false); pkcs7.SetExternalDigest(model.Signature, null, "RSA"); // Get a padded PKCS#7 byte[] pkcs7Encoded = pkcs7.GetEncodedPKCS7(sessionModel.RangeDigest); if (pkcs7Encoded.Length > 8192) // It shouldn't happen { throw new InvalidOperationException("PKCS37 encoded shouldn't be bigger than the space reserved for it"); } byte[] pkcs7Padded = new byte[8192]; pkcs7Encoded.CopyTo(pkcs7Padded, 0); // Instanciate a PDF dictionary var sigDictionary = new PdfDictionary(); // Write the PKCS#7 padded on the signature dictionary sigDictionary.Put(PdfName.CONTENTS, new PdfString(pkcs7Padded).SetHexWriting(true)); // Finally, close the PDF appearance to finish the signature process sessionModel.SignatureApperance.Close(sigDictionary); // Receive the signed PDF bytes from the its stream, which was storage by the session variable signedPdf = sessionModel.SignedPdfStream.ToArray(); // Close the signed PDF stream sessionModel.SignedPdfStream.Close(); } catch (Exception ex) { ModelState.AddModelError("", ex.ToString()); return(View()); } finally { // Clear the object stored on the Session Session.Remove("SignatureCompleteModel"); } TempData["SignatureInfoModel"] = new SignatureInfoModel() { File = Storage.StoreFile(signedPdf, ".pdf") }; return(RedirectToAction("SignatureInfo")); }
public ActionResult SignCodehComplete(string id, SignatureCompleteModel model) { // Recover XML envelope with signed COD element from "storage" based on its ID byte[] content; if (!StorageMock.TryGetFile(id, out content)) { return(HttpNotFound()); } byte[] signatureContent; try { // Recover the "transfer data" content stored in a temporary file. byte[] transferDataContent; if (!StorageMock.TryGetFile(model.TransferDataFileId, out transferDataContent)) { return(HttpNotFound()); } // Get an instance of the XmlElementSigner class. var signer = new XmlElementSigner(); // Set the document to be signed and the policy, exactly like in the SignCodeh method signer.SetXml(content); signer.SetPolicy(getSignaturePolicy()); // Set the signature computed on the client-side, along with the "transfer data" signer.SetPrecomputedSignature(model.Signature, transferDataContent); // Call ComputeSignature(), which validates the signature of the "to-sign-hash" and finishes the signature process signer.ComputeSignature(); // Get the signed XML as an array of bytes signatureContent = signer.GetSignedXml(); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate is revoked. ModelState.AddModelError("", ex.ValidationResults.ToString()); return(View()); } // On the next step (SignatureInfo action), we'll render the following information: // - The filename to be available to download in next action. // We'll store these values on TempData, which is a dictionary shared between actions. TempData["SignatureInfoModel"] = new SignatureInfoModel() { // Store the signature file on the folder "App_Data/" and redirect to the SignCodehResult action with the filename. File = StorageMock.Store(signatureContent, ".xml") }; return(RedirectToAction("SignCodehSignatureInfo")); }
public ActionResult Complete(SignatureCompleteModel model) { byte[] signatureContent; try { // Recover the "transfer data" content stored in a temporary file. byte[] transferDataContent; if (!StorageMock.TryGetFile(model.TransferDataFileId, out transferDataContent)) { return(HttpNotFound()); } // Get an instance of the PadesSigner class. var padesSigner = new PadesSigner(); // Set the signature policy. padesSigner.SetPolicy(GetSignaturePolicy()); // Set the signature computed on the client-side, along with the "transfer data" (rendered in a hidden field, see the view) padesSigner.SetPreComputedSignature(model.Signature, transferDataContent); // Call ComputeSignature(), which does all the work, including validation of the signer's certificate and of the resulting signature padesSigner.ComputeSignature(); // Get the signed PDF as an array of bytes signatureContent = padesSigner.GetPadesSignature(); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate is revoked. ModelState.AddModelError("", ex.ValidationResults.ToString()); // Return userfile to continue the signature with the same file. return(View(model)); } // On the next step (SignatureInfo action), we'll render the following information: // - The filename to be available to download in next action. // - The signer's certificate information to be rendered. // We'll store these values on TempData, which is a dictionary shared between actions. TempData["SignatureInfoModel"] = new SignatureInfoModel() { // Store the signature file on the folder "App_Data/" and redirects to the SignatureInfo action with the filename. // With this filename, it can show a link to download the signature file. File = StorageMock.Store(signatureContent, ".pdf") }; return(RedirectToAction("SignatureInfo")); }
public ActionResult Complete(SignatureCompleteModel model) { byte[] signatureContent; try { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Set the document to be signed and the policy, exactly like in the Start method cadesSigner.SetDataToSign(Storage.GetSampleDocContent()); cadesSigner.SetPolicy(getSignaturePolicy()); // Set signer's certificate cadesSigner.SetSigningCertificate(PKCertificate.Decode(model.CertContent)); // Set the signature computed on the client-side, along with the "to-sign-bytes" (rendered in a hidden input field, see the view) cadesSigner.SetPrecomputedSignature(model.Signature, model.ToSignBytes); // Call ComputeSignature(), which does all the work, including validation of the signer's certificate and of the resulting signature cadesSigner.ComputeSignature(); // Get the signature as an array of bytes signatureContent = cadesSigner.GetSignature(); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate is revoked. ModelState.AddModelError("", ex.ValidationResults.ToString()); return(View()); } // On the next step (SignatureInfo action), we'll render the following information:] // - The filename to be available to download in next action. // - The signer's certificate information to be rendered. // We'll store these values on TempData, which is a dictionary shared between actions. TempData["SignatureInfoModel"] = new SignatureInfoModel() { // Store the signature file on the folder "App_Data/" and redirects to the SignatureInfo action with the filename. // With this filename, it can show a link to download the signature file. Filename = Storage.StoreFile(signatureContent, ".p7s"), UserCert = PKCertificate.Decode(model.CertContent) }; return(RedirectToAction("SignatureInfo")); }
public ActionResult Complete(SignatureCompleteModel model) { byte[] signatureContent; try { // Instantiate a CadesSigner class var cadesSigner = new CadesSigner(); // Set the document to be signed, exactly like in the Start method if (!string.IsNullOrEmpty(model.CmsFile)) { // Verify if the cmsfile exists and get the content of the cmsfile. byte[] cmsfileContent; if (!StorageMock.TryGetFile(model.CmsFile, out cmsfileContent)) { return(HttpNotFound()); } // If the URL argument "cmsfile" is filled, the user has asked to co-sign a previously signed // CMS. We'll set the path to the CMS to be co-signed, which was perviously saved in the // App_Data folder by the POST action on this controller. cadesSigner.SetSignatureToCoSign(cmsfileContent); } else { // Verify if the userfile exists and get the content of the userfile. byte[] userfileContent; if (!StorageMock.TryGetFile(model.UserFile, out userfileContent)) { return(HttpNotFound()); } // If the URL argument "userfile" is filled, it means the user was redirected here by // UploadController (signature with file uploaded by user). We'll set the path of the file to // be signed, which was saved in the App_Data folder by UploadController. cadesSigner.SetDataToSign(userfileContent); } // Set the signature policy, exactly like in the Start method. cadesSigner.SetPolicy(getSignaturePolicy()); // Decode the user's certificate and set as the signer certificate. var cert = PKCertificate.Decode(model.CertContent); cadesSigner.SetSigningCertificate(cert); // Set the signature computed on the client-side, along with the "to-sign-bytes" (rendered in a hidden input field, see the view) cadesSigner.SetPrecomputedSignature(model.Signature, model.ToSignBytes); // Call ComputeSignature(), which does all the work, including validation of the signer's certificate and of the resulting signature cadesSigner.ComputeSignature(); // Get the signature as an array of bytes signatureContent = cadesSigner.GetSignature(); } catch (ValidationException ex) { // Some of the operations above may throw a ValidationException, for instance if the certificate is revoked. ModelState.AddModelError("", ex.ValidationResults.ToString()); // Return userfile to continue the signature with the same file. return(View("Complete", model)); } // On the next step (SignatureInfo action), we'll render the following information:] // - The filename to be available to download in next action. // We'll store these values on TempData, which is a dictionary shared between actions. TempData["SignatureInfoModel"] = new SignatureInfoModel() { // Store the signature file on the folder "App_Data/" and redirects to the SignatureInfo action with the filename. // With this filename, it can show a link to download the signature file. File = StorageMock.Store(signatureContent, ".p7s") }; return(RedirectToAction("SignatureInfo")); }
public ActionResult SignCodehResult(SignatureInfoModel model) { return(View(model)); }