protected void SubmitButton_Click(object sender, EventArgs e)
        {
            // Get an instance of the PadesSignatureFinisher class, responsible for completing the signature process
            var signatureFinisher = Util.GetRestPkiClient().GetPadesSignatureFinisher();

            // Set the token for this signature (rendered in a hidden input field, see the view)
            signatureFinisher.SetToken((string)ViewState["Token"]);

            // Call the Finish() method, which finalizes the signature process and returns the signed PDF
            var signedPdf = signatureFinisher.Finish();

            // Get information about the certificate used by the user to sign the file. This method must only be called after
            // calling the Finish() method.
            var signerCert = signatureFinisher.GetCertificateInfo();

            // At this point, you'd typically store the signed PDF on your database. For demonstration purposes, we'll
            // store the PDF on the App_Data folder and render a page with a link to download the signed PDF and with the
            // signer's certificate details.

            var appDataPath = Server.MapPath("~/App_Data");
            if (!Directory.Exists(appDataPath)) {
                Directory.CreateDirectory(appDataPath);
            }
            var id = Guid.NewGuid();
            var filename = id + ".pdf";
            System.IO.File.WriteAllBytes(Path.Combine(appDataPath, filename), signedPdf);

            this.SignatureFilename = filename;
            this.SignerCertificate = signerCert;
            Server.Transfer("PadesSignatureInfo.aspx");
        }
 protected void Page_Load(object sender, EventArgs e)
 {
     this.signatureFilename = PreviousPage.SignatureFilename;
     this.signerCertificate = PreviousPage.SignerCertificate;
 }
 public CertificateSummary(PKCertificate cert)
 {
     SubjectCommonName  = cert.SubjectName.CommonName;
     SubjectDisplayName = cert.SubjectDisplayName;
     Thumbprint         = string.Join("", cert.ThumbprintSHA1.Select(b => b.ToString("X2")));
 }
 protected void Page_Load(object sender, EventArgs e)
 {
     this.certificate = PreviousPage.Certificate;
 }
        public ActionResult Index(SignatureStartModel model)
        {
            byte[]             toSignBytes, transferData;
            SignatureAlgorithm signatureAlg;

            try {
                // Decode the user's certificate
                var cert = PKCertificate.Decode(model.CertContent);

                // Instantiate a PadesSigner class
                var padesSigner = new PadesSigner();

                // Set the PDF to sign, which in the case of this example is a fixed sample document
                padesSigner.SetPdfToSign(Storage.GetSampleDocContent());

                // Set the signer certificate
                padesSigner.SetSigningCertificate(cert);

                // Set the signature policy
                padesSigner.SetPolicy(getSignaturePolicy());

                // Set the signature's visual representation options (this is optional). For more information, see
                // http://pki.lacunasoftware.com/Help/html/98095ec7-2742-4d1f-9709-681c684eb13b.htm
                var visual = new PadesVisualRepresentation2()
                {
                    // Text of the visual representation
                    Text = new PadesVisualText()
                    {
                        // Compose the message
                        CustomText = String.Format("Assinado digitalmente por {0}", cert.SubjectDisplayName),

                        // Specify that the signing time should also be rendered
                        IncludeSigningTime = true,

                        // Optionally set the horizontal alignment of the text ('Left' or 'Right'), if not set the default is Left
                        HorizontalAlign = PadesTextHorizontalAlign.Left
                    },
                    // Background image of the visual representation
                    Image = new PadesVisualImage()
                    {
                        // We'll use as background the image in Content/PdfStamp.png
                        Content = Storage.GetPdfStampContent(),

                        // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque).
                        Opacity = 50,

                        // Align the image to the right
                        HorizontalAlign = PadesHorizontalAlign.Right
                    },
                    // Set the position of the visual representation
                    Position = PadesVisualAutoPositioning.GetFootnote()
                };
                padesSigner.SetVisualRepresentation(visual);

                // Generate the "to-sign-bytes". This method also yields the signature algorithm that must
                // be used on the client-side, based on the signature policy, as well as the "transfer data",
                // a byte-array that will be needed on the next step.
                toSignBytes = padesSigner.GetToSignBytes(out signatureAlg, out transferData);
            } catch (ValidationException ex) {
                // Some of the operations above may throw a ValidationException, for instance if the certificate
                // encoding cannot be read or if the certificate is expired.
                ModelState.AddModelError("", ex.ValidationResults.ToString());
                return(View());
            }

            // On the next step (Complete action), we'll need once again some information:
            // - The content of the selected certificate only used to render the user's certificate information
            //  after the signature is completed. It is no longer needed for the signature process.
            // - The thumbprint of the selected certificate.
            // - The "transfer data" used to validate the signature in complete action.
            // - The "to-sign-hash" (digest of the "to-sign-bytes") to be signed. (see signature-complete-form.js)
            // - The OID of the digest algorithm to be used during the signature operation.
            // We'll store these values on TempData, which is a dictionary shared between actions.
            TempData["SignatureCompleteModel"] = new SignatureCompleteModel()
            {
                CertContent        = model.CertContent,
                CertThumb          = model.CertThumb,
                TransferData       = transferData,
                ToSignHash         = signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes),
                DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid
            };

            return(RedirectToAction("Complete"));
        }
Ejemplo n.º 6
0
 protected void Page_Load(object sender, EventArgs e)
 {
     this.signatureFilename = PreviousPage.SignatureFilename;
     this.signerCertificate = PreviousPage.SignerCertificate;
 }
Ejemplo n.º 7
0
        private void startNextSignature()
        {
            // Increment the index of the document currently being signed.
            DocumentIndex += 1;

            // Check if we have reached the end of the batch, in which case we fill the hidden field
            // "ToSignHashField" with value "(end)", which signals to the javascript on batch-signature-form.js
            // that the process is completed and the page can be unblocked.
            if (DocumentIndex == DocumentIds.Count)
            {
                ToSignHashField.Value = "(end)";
                return;
            }

            // Get the ID of the document currently being signed.
            var docId = DocumentIds[DocumentIndex];

            byte[]             toSignBytes;
            SignatureAlgorithm signatureAlg;

            try {
                // Decode the user's certificate.
                var cert = PKCertificate.Decode(Convert.FromBase64String(CertificateField.Value));

                // Instantiate a CadesSigner class.
                var cadesSigner = new CadesSigner();

                // Set the data to sign, which in the case of this example is a fixed sample document.
                cadesSigner.SetDataToSign(Storage.GetBatchDocContent(docId));

                // Set the signer certificate.
                cadesSigner.SetSigningCertificate(cert);

                // Set the signature policy.
                cadesSigner.SetPolicy(getSignaturePolicy());

                // Generate the "to-sign-bytes". This method also yields the signature algorithm that must be
                // used on the client-side, based on the signature policy.
                toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg);
            }
            catch (ValidationException ex) {
                // One or more validations failed. We log the error, update the page with a summary of what
                // happened to this document and start the next signature.
                logger.Error(ex, "Validation error starting the signature of a batch document");
                setValidationError(ex.ValidationResults);
                startNextSignature();
                return;
            }
            catch (Exception ex) {
                // An error has occurred. We log the error, update the page with a summary of what happened to
                // this document and start the next signature.
                logger.Error(ex, "Error starting the signature of a batch document");
                setError(ex.Message);
                startNextSignature();
                return;
            }

            // Send to the javascript the "to sign hash" of the document (digest of the "to-sign-bytes") and the
            // digest algorithm that must be used on the signature algorithm computation.
            ToSignBytesField.Value     = Convert.ToBase64String(toSignBytes);
            ToSignHashField.Value      = Convert.ToBase64String(signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes));
            DigestAlgorithmField.Value = signatureAlg.DigestAlgorithm.Oid;
        }
Ejemplo n.º 8
0
        private void completeSignature()
        {
            // Get the ID of the document currently being signed.
            var docId = DocumentIds[DocumentIndex];

            PKCertificate cert;

            byte[] signatureContent;

            try {
                // Decode the user's certificate.
                cert = PKCertificate.Decode(Convert.FromBase64String(CertificateField.Value));

                // Instantiate a CadesSigner class.
                var cadesSigner = new CadesSigner();

                // Set the document to be signed and the policy, exactly like in the previous action
                // (SubmitCertificateButton_Click).
                cadesSigner.SetDataToSign(Storage.GetBatchDocContent(docId));
                cadesSigner.SetPolicy(getSignaturePolicy());

                // Set the signer certificate.
                cadesSigner.SetSigningCertificate(cert);

                // Optionally, set whether the content should be encapsulated in the resulting CMS.
                cadesSigner.SetEncapsulatedContent(false);

                // Set the signature computed on the client-side, along with the "to-sign-bytes" recovered from
                // the page.
                cadesSigner.SetPrecomputedSignature(Convert.FromBase64String(SignatureField.Value), Convert.FromBase64String(ToSignBytesField.Value));

                // 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) {
                // One or more validations failed. We log the error and update the page with a summary of what
                // happened to this document.
                logger.Error(ex, "Validation error completing the signature of a batch document");
                setValidationError(ex.ValidationResults);
                return;
            }
            catch (Exception ex) {
                // An error has occurred. We log the error and update the page with a summary of what happened to
                // this document.
                logger.Error(ex, "Error completing the signature of a batch document");
                setError(ex.Message);
                return;
            }

            // Store the signed file.
            var file = Storage.StoreFile(signatureContent, ".p7s");

            // Update the page with a link to the signed file.
            var docItem = DocumentsListView.Items[DocumentIndex];

            docItem.DataItem = new DocumentItem()
            {
                Id           = DocumentIds[DocumentIndex],
                DownloadLink = "Download?file=" + file
            };
            docItem.DataBind();
        }
        private void startNextSignature()
        {
            // Increment the index of the document currently being signed.
            DocumentIndex += 1;

            // Check if we have reached the end of the batch, in which case we fill the hidden field
            // "ToSignHashField" with value "(end)", which signals to the javascript on batch-signature-form.js
            // that the process is completed and the page can be unblocked.
            if (DocumentIndex == DocumentIds.Count)
            {
                ToSignHashField.Value = "(end)";
                return;
            }

            // Get the ID of the document currently being signed.
            var docId = DocumentIds[DocumentIndex];

            byte[]             toSignBytes, transferData;
            SignatureAlgorithm signatureAlg;

            try {
                // Decode the user's certificate.
                var cert = PKCertificate.Decode(Convert.FromBase64String(CertificateField.Value));

                // Instantiate a PadesSigner class.
                var padesSigner = new PadesSigner();

                // Set the PDF to sign.
                padesSigner.SetPdfToSign(Storage.GetBatchDocContent(docId));

                // Set the signer certificate.
                padesSigner.SetSigningCertificate(cert);

                // Set the signature policy.
                padesSigner.SetPolicy(getSignaturePolicy());

                // Set the signature's visual representation options (optional).
                padesSigner.SetVisualRepresentation(getVisualRepresentation(cert));

                // Generate the "to-sign-bytes". This method also yields the signature algorithm that must
                // be used on the client-side, based on the signature policy, as well as the "transfer data",
                // a byte-array that will be needed on the next step.
                toSignBytes = padesSigner.GetToSignBytes(out signatureAlg, out transferData);
            }
            catch (ValidationException ex) {
                // One or more validations failed. We log the error, update the page with a summary of what
                // happened to this document and start the next signature.
                logger.Error(ex, "Validation error starting the signature of a batch document");
                setValidationError(ex.ValidationResults);
                startNextSignature();
                return;
            }
            catch (Exception ex) {
                // An error has occurred. We log the error, update the page with a summary of what happened to
                // this document and start the next signature.
                logger.Error(ex, "Error starting the signature of a batch document");
                setError(ex.Message);
                startNextSignature();
                return;
            }

            // The "transfer data" for PDF signatures can be as large as the original PDF itself. Therefore, we
            // mustn't use a hidden field on the page to store it. Here we're using our storage mock
            // (see file Classes\Storage.cs) to simulate storing the transfer data on a database and saving on a
            // hidden field on the page only the ID that can be used later to retrieve it. Another option would
            // be to store the transfer data on the Session dictionary.
            TransferDataFileIdField.Value = Storage.StoreFile(transferData);

            // Send to the javascript the "to sign hash" of the document (digest of the "to-sign-bytes") and the
            // digest algorithm that must be used on the signature algorithm computation
            ToSignHashField.Value      = Convert.ToBase64String(signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes));
            DigestAlgorithmField.Value = signatureAlg.DigestAlgorithm.Oid;
        }
        public ActionResult Start(SignatureStartModel model)
        {
            byte[]             toSignBytes, transferData;
            SignatureAlgorithm signatureAlg;

            try {
                // Verify if the userfile exists and get its absolute path.
                string userfilePath;
                if (!StorageMock.TryGetFile(model.UserFile, out userfilePath))
                {
                    return(HttpNotFound());
                }

                // Decode the user's certificate.
                var cert = PKCertificate.Decode(model.CertContent);

                // Get an instance of the PadesSigner class.
                var padesSigner = new PadesSigner();

                // Set the file to be signed.
                padesSigner.SetPdfToSign(userfilePath);

                // REQUIRED!
                // Provide the signer's certificate. You must sign with a valid digital
                // certificate of a doctor, who was registered on CRM. In this sample,
                // we used a sample certificate stored on server to do the execute this
                // sample.
                padesSigner.SetSigningCertificate(cert);

                // REQUIRED!
                // Define the trust arbitrator, which will configure the signer to
                // some kind of certificate. In the case of this sample, only
                // ICP-Brasil certificates will be accepted in the defined standard.
                var trustArbitrator = new LinkedTrustArbitrator(TrustArbitrators.PkiBrazil);
#if DEBUG
                // For development purposes, we also trust in Lacuna Software's test certificates.
                var lacunaRoot = Lacuna.Pki.PKCertificate.Decode(Convert.FromBase64String("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"));
                trustArbitrator.Add(new TrustedRoots(lacunaRoot));
#endif
                // REQUIRED!
                // Use a policy accepted by ICP-Brasil. We use the trust arbitrator
                // defined above to configure the policy.
                padesSigner.SetPolicy(PadesPoliciesForGeneration.GetPadesBasic(trustArbitrator));

                // REQUIRED!
                // Use a custom signature field name. This field MUST have the
                // "Emitente" keyword as the last keyword.
                padesSigner.SetCustomSignatureFieldName("Signature1 Emitente");

                // REQUIRED!
                // Set Certification Level to not allow changes after signed.
                padesSigner.SetCertificationLevel(PadesCertificationLevel.CertifiedNoChangesAllowed);

                // Set a visual representation for the signature.
                padesSigner.SetVisualRepresentation(PadesVisualElements.GetVisualRepresentationForPkiSdk(cert));

                // Generate the "to-sign-bytes". This method also yields the signature algorithm that must
                // be used on the client-side, based on the signature policy, as well as the "transfer data",
                // a byte-array that will be needed on the next step.
                toSignBytes = padesSigner.GetToSignBytes(out signatureAlg, out transferData);
            } catch (ValidationException ex) {
                // Some of the operations above may throw a ValidationException, for instance if the certificate
                // encoding cannot be read or if the certificate is expired.
                ModelState.AddModelError("", ex.ValidationResults.ToString());
                return(View());
            }

            // On the next step (Complete action), we'll need once again some information:
            // - The thumbprint of the selected certificate.
            // - The "transfer data" used to validate the signature in complete action. Its content is stored in
            //   a temporary file (with extension .bin) to be shared with the Complete action.
            // - The "to-sign-hash" (digest of the "to-sign-bytes") to be signed. (see signature-complete-form.js)
            // - The OID of the digest algorithm to be used during the signature operation.
            // We'll store these values on TempData, which is a dictionary shared between actions.
            TempData["SignatureCompleteModel"] = new SignatureCompleteModel()
            {
                CertThumb          = model.CertThumb,
                TransferDataFileId = StorageMock.Store(transferData, ".bin"),
                ToSignHash         = signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes),
                DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid
            };

            return(RedirectToAction("Complete", new { userfile = model.UserFile }));
        }
Ejemplo n.º 11
0
        public ActionResult Index(SignatureStartModel model)
        {
            byte[]             toSignBytes;
            SignatureAlgorithm signatureAlg;

            try {
                // Instantiate a CadesSigner class
                var cadesSigner = new CadesSigner();

                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);
                }

                // Decode the user's certificate and set as the signer certificate.
                var cert = PKCertificate.Decode(model.CertContent);
                cadesSigner.SetSigningCertificate(cert);

                // Set the signature policy
                cadesSigner.SetPolicy(getSignaturePolicy());

                // Generate the "to-sign-bytes". This method also yields the signature algorithm that must
                // be used on the client-side, based on the signature policy.
                toSignBytes = cadesSigner.GenerateToSignBytes(out signatureAlg);
            } catch (ValidationException ex) {
                // Some of the operations above may throw a ValidationException, for instance if the certificate
                // encoding cannot be read or if the certificate is expired.
                ModelState.AddModelError("", ex.ValidationResults.ToString());
                return(View());
            }

            // On the next step (Complete action), we'll need once again some information:
            // - The content of the selected certificate used to validate the signature in complete action.
            // - The thumbprint of the selected certificate.
            // - The "to-sign-bytes" used to validate the signature in complete action.
            // - The "to-sign-hash" (digest of the "to-sign-bytes") to be signed. (see signature-complete-form.js)
            // - The OID of the digest algorithm to be used during the signature operation.
            // We'll store these values on TempData, which is a dictionary shared between actions.
            TempData["SignatureCompleteModel"] = new SignatureCompleteModel()
            {
                UserFile           = model.UserFile,
                CmsFile            = model.CmsFile,
                CertContent        = model.CertContent,
                CertThumb          = model.CertThumb,
                ToSignBytes        = toSignBytes,
                ToSignHash         = signatureAlg.DigestAlgorithm.ComputeHash(toSignBytes),
                DigestAlgorithmOid = signatureAlg.DigestAlgorithm.Oid
            };

            return(RedirectToAction("Complete", new { userfile = model.UserFile, cmsfile = model.CmsFile }));
        }
Ejemplo n.º 12
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"));
        }
Ejemplo n.º 13
0
        public void ValidateAttributeCert()
        {
            if (!checkLicenseLoaded())
            {
                return;
            }

            try {
                var certFileDialog = new OpenFileDialog()
                {
                    DefaultExt = ".ac",
                    Filter     = "X.509 attribute certificate (.ac)|*.ac"
                };
                if (certFileDialog.ShowDialog() != true)
                {
                    return;
                }

                // Read and decode the attribute certificate
                var certContent = File.ReadAllBytes(certFileDialog.FileName);
                var cert        = AttributeCertificate.Decode(certContent);

                // If the certificate is issued without a link to its issuer (AIA extension), the validation will fail because the issuer will not be found. In this
                // case, have to provide the issuer certificate when decoding the attribute certificate.
                if (cert.IssuerNotFound)
                {
                    MessageBox.Show("Could not find the issuer of the certificate. This usually happens with certificates that do not have a valid Authority Information Access (AIA) extension.\n\nTo continue, you will need to provide the .cer file of the issuer.", "Issuer not found");
                    var issuerFileDialog = new OpenFileDialog()
                    {
                        DefaultExt = ".cer",
                        Filter     = "X.509 certificate|*.cer;*.crt"
                    };
                    if (issuerFileDialog.ShowDialog() != true)
                    {
                        return;
                    }

                    // Read and decode the issuer certificate
                    var issuerContent = File.ReadAllBytes(issuerFileDialog.FileName);
                    var issuerCert    = PKCertificate.Decode(issuerContent);

                    // Re-open the attribute certificate providing the issuer certificate
                    cert = AttributeCertificate.Decode(certContent, new MemoryCertificateStore(new[] { issuerCert }));
                }

                CieStudentIdentity cieStudentIdentity = null;
                if (cert.Attributes.GetOids().Contains(CieStudentIdentity.Oid))
                {
                    cieStudentIdentity = CieStudentIdentity.Decode(cert.Attributes);
                }

                CieStudentData cieStudentData = null;
                if (cert.Attributes.GetOids().Contains(CieStudentData.Oid))
                {
                    cieStudentData = CieStudentData.Decode(cert.Attributes);
                }

                // Validate the certificate
                var vr = cert.Validate(App.GetTrustArbitrator());

                // Show the validation results
                new ValidationResultsDialog("Attribute certificate validation results", vr).ShowDialog();
            } catch (Exception ex) {
                MessageBox.Show(ex.ToString(), "An error has occurred");
            }
        }