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"));
        }
Beispiel #2
0
        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"));
        }
Beispiel #5
0
        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));
 }