Example #1
0
        public async Task <ActionResult> Index(string userfile)
        {
            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures.
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient())
            {
                // Specify that we want an audit package to be generated, and that the signed file should be
                // included in the package.
                GenerateAuditPackage            = true,
                IncludeSignedFileInAuditPackage = true,
                // In order to generate an audit package, we must also pass Validate = true.
                Validate = true,
                // Specify the parameters for the signature validation:
                // Accept any PAdES signature as long as the signer has an ICP-Brasil certificate.
                DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
                // We have encapsulated the security context choice on Util.cs.
                SecurityContextId = Util.GetSecurityContextId()
            };

            // Set the PDF file.
            if (string.IsNullOrEmpty(userfile))
            {
                // If no file is passed, we use a previously signed and B-Stamped file.
                sigExplorer.SetSignatureFile(Server.MapPath("~/Content/bstamped.pdf"));
            }
            else
            {
                sigExplorer.SetSignatureFile(Server.MapPath("~/App_Data/" + userfile.Replace("_", ".")));
                // Note: we're receiving the userfile argument with "_" as "." because of limitations of
                // ASP.NET MVC.
            }

            // Call the OpenAsync() method, which returns the signature file's information.
            var signature = await sigExplorer.OpenAsync();

            // If the document has been B-Stamped, store the "digest index file" to show a link on the page.
            if (signature.BStamp != null)
            {
                string indexFileId;
                using (var indexFileStream = signature.BStamp.IndexFile.OpenRead()) {
                    indexFileId = StorageMock.Store(indexFileStream, ".txt");
                }
                ViewBag.BStampIndexFile = indexFileId;
            }

            // Store the generated audit package. Notice that although we asked for its generation, the
            // signature might not have been B-Stamped yet, so an audit package might not be returned.
            if (signature.AuditPackage != null)
            {
                string auditPkgId;
                using (var auditPkgStream = signature.AuditPackage.OpenRead()) {
                    auditPkgId = StorageMock.Store(auditPkgStream, ".zip");
                }
                ViewBag.AuditPackageFile = auditPkgId;
            }

            // Render the information. (see file Views/OpenPadesSignatureBStamp/Index.html for more
            // information on the information returned)
            return(View(signature));
        }
        public ActionResult Index(string userfile)
        {
            // Our action only works if a userfile is given to work with
            if (string.IsNullOrEmpty(userfile))
            {
                return(HttpNotFound());
            }
            var filename = userfile.Replace("_", ".");             // Note: we're passing the filename argument with "." as "_" because of limitations of ASP.NET MVC

            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient())
            {
                Validate = true                 // Specify that we want to validate the signatures in the file, not only inspect them
            };

            // Set the PDF file
            sigExplorer.SetSignatureFile(Server.MapPath("~/App_Data/" + filename));

            // Parameters for the signature validation. We have encapsulated this code in a method to include several
            // possibilities depending on the argument passed. Experiment changing the argument to see different validation
            // configurations. Once you decide which is best for your case, you can place the code directly here.
            setValidationParameters(sigExplorer, 1);
            // try changing this number ---------^ for different validation parameters

            // Call the Open() method, which returns the signature file's information
            var signature = sigExplorer.Open();

            // Render the information (see file Views/OpenPadesSignature/Index.html for more information on the information returned)
            return(View(signature));
        }
        public ActionResult Index(string userfile)
        {
            // Our action only works if a userfile is given to work with
            if (string.IsNullOrEmpty(userfile)) {
                return HttpNotFound();
            }
            var filename = userfile.Replace("_", "."); // Note: we're passing the filename argument with "." as "_" because of limitations of ASP.NET MVC

            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient()) {
                Validate = true // Specify that we want to validate the signatures in the file, not only inspect them
            };

            // Set the PDF file
            sigExplorer.SetSignatureFile(Server.MapPath("~/App_Data/" + filename));

            // Parameters for the signature validation. We have encapsulated this code in a method to include several
            // possibilities depending on the argument passed. Experiment changing the argument to see different validation
            // configurations. Once you decide which is best for your case, you can place the code directly here.
            setValidationParameters(sigExplorer, 1);
            // try changing this number ---------^ for different validation parameters

            // Call the Open() method, which returns the signature file's information
            var signature = sigExplorer.Open();

            // Render the information (see file Views/OpenPadesSignature/Index.html for more information on the information returned)
            return View(signature);
        }
Example #4
0
        public ActionResult Index(string userfile)
        {
            // Our action only works if a userfile is given to work with.
            if (string.IsNullOrEmpty(userfile))
            {
                return(HttpNotFound());
            }
            var filename = userfile.Replace("_", ".");
            // Note: we're receiving the userfile argument with "_" as "." because of limitations of
            // ASP.NET MVC.

            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures.
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient())
            {
                // Specify that we want to validate the signatures in the file, not only inspect them.
                Validate = true,
                // Specify the parameters for the signature validation:
                // Accept any PAdES signature as long as the signer has an ICP-Brasil certificate.
                DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
                // We have encapsulated the security context choice on Util.cs.
                SecurityContextId = Util.GetSecurityContextId()
            };

            // Set the PDF file
            sigExplorer.SetSignatureFile(Server.MapPath("~/App_Data/" + filename));

            // Call the Open() method, which returns the signature file's information
            var signature = sigExplorer.Open();

            // Render the information (see file Views/OpenPadesSignature/Index.html for more information on
            // the information returned)
            return(View(signature));
        }
Example #5
0
        public async Task <ActionResult> Index(string userfile)
        {
            // Our action only works if a userfile is given to work with.
            if (!StorageMock.TryGetFile(userfile, out string userfilePath))
            {
                return(HttpNotFound());
            }

            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures.
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient())
            {
                // Specify that we want to validate the signatures in the file, not only inspect them.
                Validate = true,
                // Specify the parameters for the signature validation:
                // Accept any PAdES signature as long as the signer has an ICP-Brasil certificate.
                DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
                // Specify the security context to be used to determine trust in the certificate chain. We
                // have encapsulated the security context choice on Util.cs.
                SecurityContextId = Util.GetSecurityContextId()
            };

            // Set the PAdES signature file.
            sigExplorer.SetSignatureFile(userfilePath);

            // Call the Open() method, which returns the signature file's information.
            var signature = await sigExplorer.OpenAsync();

            // Render the information (see file OpenPadesSignature/Index.html for more information on
            // the information returned).
            return(View(new OpenPadesSignatureModel()
            {
                Signature = signature
            }));
        }
Example #6
0
        // GET: CheckPadesRest?c={id}
        public ActionResult Index(string c)
        {
            // On PrinterFriendlyVersionController, we stored the unformatted version of the verification
            // code (without hyphens) but used the formatted version (with hiphens) on the printer-friendly
            // PDF. Now, we remove the hyphens before looking it up.
            var verificationCode = AlphaCode.Parse(c);

            // Get document associated with verification code.
            var fileId = StorageMock.LookupVerificationCode(verificationCode);

            if (fileId == null)
            {
                // Invalid code give!
                // Small delay to slow down brute-force attacks (if you want to be extra careful you might
                // want to add a CAPTCHA to the process).
                Thread.Sleep(TimeSpan.FromSeconds(2));
                // Return Not Found
                return(HttpNotFound());
            }

            // Read document from storage.
            var fileContent = StorageMock.Read(fileId);

            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures.
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient())
            {
                // Specify that we want to validate the signatures in the file, not only inspect them.
                Validate = true,
                // Specify the parameters for the signature validation:
                // Accept any PAdES signature as long as the signer has an ICP-Brasil certificate.
                DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
                // Specify the security context to be used to determine trust in the certificate chain. We
                // have encapsulated the security context choice on Util.cs.
                SecurityContextId = Util.GetSecurityContextId()
            };

            // Set the PDF file.
            sigExplorer.SetSignatureFile(fileContent);

            // Call the Open() method, which returns the signature file's information.
            var signature = sigExplorer.Open();

            // Render the information (see file Check/Index.html for more information on
            // the information returned).
            return(View(new OpenPadesSignatureModel()
            {
                Signature = signature,
                File = fileId
            }));
        }
Example #7
0
        protected void Page_Load(object sender, EventArgs e)
        {
            // Get verification code from query string
            var formattedVerificationCode = Request.QueryString["code"];

            // On PrinterFriendlyVersion.aspx, we stored the unformatted version of the verification code (without hyphens) but
            // used the formatted version (with hyphens) on the printer-friendly PDF. Now, we remove the hyphens before looking it up.
            var verificationCode = AlphaCode.Parse(formattedVerificationCode);

            // Get document associated with verification code
            var fileId = StorageMock.LookupVerificationCode(verificationCode);

            if (fileId == null)
            {
                // Invalid code given!
                // Small delay to slow down brute-force attacks (if you want to be extra careful you might want to add a CAPTCHA to the process)
                Thread.Sleep(TimeSpan.FromSeconds(2));
                // Return Not Found
                Response.StatusCode = 404;
                Response.End();
                return;
            }

            // Read document from storage
            var fileContent = StorageMock.Read(fileId);

            // Open and validate signatures with Rest PKI
            var client      = Util.GetRestPkiClient();
            var sigExplorer = new PadesSignatureExplorer(client)
            {
                Validate = true,
                DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
                SecurityContextId        = Util.GetSecurityContextId(),
            };

            sigExplorer.SetSignatureFile(fileContent);
            var signature = sigExplorer.Open();

            // Set properties for rendering on page (see aspx file)
            this.FileId = fileId;
            this.Model  = signature;
        }
        private byte[] generatePrinterFriendlyVersion(byte[] pdfContent, string verificationCode)
        {
            var client = Util.GetRestPkiClient();

            // The verification code is generated without hyphens to save storage space and avoid
            // copy-and-paste problems. On the PDF generation, we use the "formatted" version, with hyphens
            // (which will later be discarded on the verification page).
            var formattedVerificationCode = Util.FormatVerificationCode(verificationCode);

            // Build the verification link from the constant "VerificationLinkFormat" (see above) and the
            // formatted verification code.
            var verificationLink = string.Format(VerificationLinkFormat, formattedVerificationCode);

            // 1. Upload the PDF
            var blob = client.UploadFile(pdfContent);

            // 2. Inspect signatures on the uploaded PDF
            var sigExplorer = new PadesSignatureExplorer(client)
            {
                Validate = true,
                DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
                SecurityContextId        = Util.GetSecurityContextId(),
            };

            sigExplorer.SetSignatureFile(blob);
            var signature = sigExplorer.Open();

            // 3. Create PDF with verification information from uploaded PDF

            var pdfMarker = new PdfMarker(client);

            pdfMarker.SetFile(blob);

            // Build string with joined names of signers (see method getDisplayName below)
            var signerNames     = Util.JoinStringsPt(signature.Signers.Select(s => getDisplayName(s.Certificate)));
            var allPagesMessage = string.Format("This document was digitally signed by {0}.\nTo verify the signatures go to {1} on {2} and inform the code {3}", signerNames, VerificationSiteNameWithArticle, VerificationSite, formattedVerificationCode);

            // PdfHelper is a class from the Rest PKI Client "fluent API" that helps to create elements and
            // parameters for the PdfMarker.
            var pdf = new PdfHelper();

            // ICP-Brasil logo on bottom-right corner of every page (except on the page which will be created
            // at the end of the document).
            pdfMarker.Marks.Add(
                pdf.Mark()
                .OnAllPages()
                .OnContainer(pdf.Container().Width(1).AnchorRight(1).Height(1).AnchorBottom(1))
                .AddElement(
                    pdf.ImageElement()
                    .WithOpacity(75)
                    .WithImage(StorageMock.GetIcpBrasilLogoContent(), "image/png")
                    )
                );

            // Summary on bottom margin of every page (except on the page which will be created at the end of
            // the document).
            pdfMarker.Marks.Add(
                pdf.Mark()
                .OnAllPages()
                .OnContainer(pdf.Container().Height(2).AnchorBottom().VarWidth().Margins(1.5, 3.5))
                .AddElement(
                    pdf.TextElement()
                    .WithOpacity(75)
                    .AddSection(allPagesMessage)
                    )
                );

            // Summary on right margin of every page (except on the page which will be created at the end of
            // the document), rotated 90 degrees counterclockwise (text goes up).
            pdfMarker.Marks.Add(
                pdf.Mark()
                .OnAllPages()
                .OnContainer(pdf.Container().Width(2).AnchorRight().VarHeight().Margins(1.5, 3.5))
                .AddElement(
                    pdf.TextElement()
                    .Rotate90Counterclockwise()
                    .WithOpacity(75)
                    .AddSection(allPagesMessage)
                    )
                );

            // Create a "manifest" mark on a new page added on the end of the document. We'll add several
            // elements to this mark.
            var manifestMark = pdf.Mark()
                               .OnNewPage()
                               // This mark's container is the whole page with 1-inch margins.
                               .OnContainer(pdf.Container().VarWidthAndHeight().Margins(2.54, 2.54));

            // We'll keep track of our "vertical offset" as we add elements to the mark.
            double verticalOffset = 0;
            double elementHeight;

            elementHeight = 3;
            manifestMark
            // ICP-Brasil logo on the upper-left corner.
            .AddElement(
                pdf.ImageElement()
                .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).Width(elementHeight /* using elementHeight as width because the image is square */).AnchorLeft())
                .WithImage(StorageMock.GetIcpBrasilLogoContent(), "image/png")
                )
            // QR Code with the verification link on the upper-right corner.
            .AddElement(
                pdf.QRCodeElement()
                .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).Width(elementHeight /* using elementHeight as width because QR Codes are square */).AnchorRight())
                .WithQRCodeData(verificationLink)
                )
            // Header "VERIFICAÇÃO DAS ASSINATURAS" centered between ICP-Brasil logo and QR Code.
            .AddElement(
                pdf.TextElement()
                .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset + 0.2).FullWidth())
                .AlignTextCenter()
                .AddSection(pdf.TextSection().WithFontSize(NormalFontSize * 1.6).WithText("SIGNATURE\nVERIFICATION"))
                );
            verticalOffset += elementHeight;

            // Vertical padding.
            verticalOffset += 1.7;

            // Header with verification code.
            elementHeight = 2;
            manifestMark.AddElement(
                pdf.TextElement()
                .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth())
                .AlignTextCenter()
                .AddSection(pdf.TextSection().WithFontSize(NormalFontSize * 1.2).WithText(string.Format("Verification Code: {0}", formattedVerificationCode)))
                );
            verticalOffset += elementHeight;

            // Paragraph saying "this document was signed by the following signers etc" and mentioning the
            // time zone of the date/times below.
            elementHeight = 2.5;
            manifestMark.AddElement(
                pdf.TextElement()
                .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth())
                .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(string.Format("This document was digitally signed by the following signers on the indicated dates ({0}):", TimeZoneDisplayName)))
                );
            verticalOffset += elementHeight;

            // Iterate signers.
            foreach (var signer in signature.Signers)
            {
                elementHeight = 1.5;

                manifestMark
                // Green "check" or red "X" icon depending on result of validation for this signer.
                .AddElement(
                    pdf.ImageElement()
                    .OnContainer(pdf.Container().Height(0.5).AnchorTop(verticalOffset + 0.2).Width(0.5).AnchorLeft())
                    .WithImage(StorageMock.GetValidationResultIcon(signer.ValidationResults.IsValid), "image/png")
                    )
                // Description of signer (see method getSignerDescription() below).
                .AddElement(
                    pdf.TextElement()
                    .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).VarWidth().Margins(0.8, 0))
                    .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(getSignerDescription(signer)))
                    );

                verticalOffset += elementHeight;
            }

            // Some vertical padding from last signer.
            verticalOffset += 1;

            // Paragraph with link to verification site and citing both the verification code above and the
            // verification link below.
            elementHeight = 2.5;
            manifestMark.AddElement(
                pdf.TextElement()
                .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth())
                .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(string.Format("To verify the signatures, go to {0} on ", VerificationSiteNameWithArticle)))
                .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithColor(Color.Blue).WithText(VerificationSite))
                .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(" and inform the code above or follow the link below:"))
                );
            verticalOffset += elementHeight;

            // Verification link.
            elementHeight = 1.5;
            manifestMark.AddElement(
                pdf.TextElement()
                .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth())
                .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithColor(Color.Blue).WithText(verificationLink))
                .AlignTextCenter()
                );

            // Apply marks.
            pdfMarker.Marks.Add(manifestMark);
            var result = pdfMarker.Apply();

            // Return result.
            return(result.GetContent());
        }
Example #9
0
        public ActionResult Index(string userfile)
        {
            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient())
            {
                // Specify that we want an audit package to be generated, and that the signed file should be included in the package
                GenerateAuditPackage            = true,
                IncludeSignedFileInAuditPackage = true,
                // In order to generate an audit package, we must also pass Validate = true
                Validate = true,
            };

            // Set the PDF file
            if (string.IsNullOrEmpty(userfile))
            {
                // If no file is passed, we use a previously signed and B-Stamped file
                sigExplorer.SetSignatureFile(Server.MapPath("~/Content/bstamped.pdf"));
            }
            else
            {
                var filename = userfile.Replace("_", ".");                 // Note: we're passing the filename argument with "." as "_" because of limitations of ASP.NET MVC
                sigExplorer.SetSignatureFile(Server.MapPath("~/App_Data/" + filename));
            }

            // Parameters for the signature validation. We have encapsulated this code in a method to include several
            // possibilities depending on the argument passed. Experiment changing the argument to see different validation
            // configurations. Once you decide which is best for your case, you can place the code directly here.
            setValidationParameters(sigExplorer, 1);
            // try changing this number ---------^ for different validation parameters

            // Call the Open() method, which returns the signature file's information
            var signature = sigExplorer.Open();

            // If the document has been B-Stamped, store the "digest index file" to show a link on the page
            if (signature.BStamp != null)
            {
                var appDataPath = Server.MapPath("~/App_Data");
                if (!Directory.Exists(appDataPath))
                {
                    Directory.CreateDirectory(appDataPath);
                }
                var id       = Guid.NewGuid();
                var filename = id + ".txt";
                signature.BStamp.IndexFile.WriteToFile(Path.Combine(appDataPath, filename));
                ViewBag.BStampIndexFile = filename.Replace(".", "_");
            }

            // Store the generated audit package. Notice that although we asked for its generation,
            // the signature might not have been B-Stamped yet, so an audit package might not be returned.
            if (signature.AuditPackage != null)
            {
                var appDataPath = Server.MapPath("~/App_Data");
                if (!Directory.Exists(appDataPath))
                {
                    Directory.CreateDirectory(appDataPath);
                }
                var id       = Guid.NewGuid();
                var filename = id + ".zip";
                signature.AuditPackage.WriteToFile(Path.Combine(appDataPath, filename));
                ViewBag.AuditPackageFile = filename.Replace(".", "_");
            }

            // Render the information (see file Views/OpenPadesSignatureBStamp/Index.html for more information on the information returned)
            return(View(signature));
        }
        public async Task <ActionResult> Index(string userfile)
        {
            // Get an instance of the PadesSignatureExplorer class, used to open/validate PDF signatures.
            var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient())
            {
                // Specify that we want an audit package to be generated, and that the signed file should be
                // included in the package.
                GenerateAuditPackage            = true,
                IncludeSignedFileInAuditPackage = true,
                // In order to generate an audit package, we must also pass Validate = true.
                Validate = true,
                // Specify the parameters for the signature validation:
                // Accept any PAdES signature as long as the signer has an ICP-Brasil certificate.
                DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
                // Specify the security context to be used to determine trust in the certificate chain. We
                // have encapsulated the security context choice on Util.cs.
                SecurityContextId = Util.GetSecurityContextId()
            };

            // Set the PDF file.
            if (!string.IsNullOrEmpty(userfile))
            {
                // Verify if the provided userfile exits and get its absolute path.
                string userfilePath;
                if (!StorageMock.TryGetFile(userfile, out userfilePath))
                {
                    return(HttpNotFound());
                }

                // Set the userfile's absolute path to the PadesSignatureExplorer instance.
                sigExplorer.SetSignatureFile(userfilePath);
            }
            else
            {
                // If no userfile is passed, we use a previously signed and B-Stamped file.
                sigExplorer.SetSignatureFile(StorageMock.GetSampleBStampedPath());
            }

            // Call the Open() method, which returns the signature file's information.
            var signature = await sigExplorer.OpenAsync();

            // If the document has been B-Stamped, store the "digest index file" to show a link on the page.
            string indexFileId = null;

            if (signature.BStamp != null)
            {
                using (var indexFileStream = signature.BStamp.IndexFile.OpenRead()) {
                    indexFileId = StorageMock.Store(indexFileStream, ".txt");
                }
            }

            // Store the generated audit package. Notice that although we asked for its generation, the
            // signature might not have been B-Stamped yet, so an audit package might not be returned.
            string auditPkgId = null;

            if (signature.AuditPackage != null)
            {
                using (var auditPkgStream = signature.AuditPackage.OpenRead()) {
                    auditPkgId = StorageMock.Store(auditPkgStream, ".zip");
                }
            }

            // Render the information (see file OpenPadesSignatureBStamp/Index.html for more
            // information on the information returned).
            return(View(new OpenPadesSignatureBStampModel()
            {
                Signature = signature,
                BStampIndexFile = indexFileId,
                AuditPackageFile = auditPkgId
            }));
        }