private static void ValidSignatureDate(PdfPkcs7 pkcs7)
 {
     if (pkcs7.SignDate == null && pkcs7.SignDate <= DateTime.Now)
     {
         throw new Exception("A assinatura digital deste documento possui uma data de assinatura inválida." + message);
     }
 }
 /// <summary>
 /// Sets the crypto information to sign.
 /// </summary>
 /// <param name="privKey">the private key</param>
 /// <param name="certChain">the certificate chain</param>
 /// <param name="crlList">the certificate revocation list. It can be  null </param>
 public void SetSignInfo(ICipherParameters privKey, X509Certificate[] certChain, object[] crlList)
 {
     Pkcs = new PdfPkcs7(privKey, certChain, crlList, HashAlgorithm, PdfName.AdbePkcs7Sha1.Equals(Get(PdfName.Subfilter)));
     Pkcs.SetExternalDigest(_externalDigest, _externalRsAdata, _digestEncryptionAlgorithm);
     if (PdfName.AdbeX509RsaSha1.Equals(Get(PdfName.Subfilter)))
     {
         MemoryStream bout = new MemoryStream();
         for (int k = 0; k < certChain.Length; ++k)
         {
             byte[] tmp = certChain[k].GetEncoded();
             bout.Write(tmp, 0, tmp.Length);
         }
         Cert     = bout.ToArray();
         Contents = Pkcs.GetEncodedPkcs1();
     }
     else
     {
         Contents = Pkcs.GetEncodedPkcs7();
     }
     name = PdfPkcs7.GetSubjectFields(Pkcs.SigningCertificate).GetField("CN");
     if (name != null)
     {
         Put(PdfName.Name, new PdfString(name, TEXT_UNICODE));
     }
     Pkcs = new PdfPkcs7(privKey, certChain, crlList, HashAlgorithm, PdfName.AdbePkcs7Sha1.Equals(Get(PdfName.Subfilter)));
     Pkcs.SetExternalDigest(_externalDigest, _externalRsAdata, _digestEncryptionAlgorithm);
 }
        private static void ValidDigitalCertificate(CertificadoDigital cert, PdfPkcs7 pkcs7)
        {
            bool timestampImprint = pkcs7.VerifyTimestampImprint();

            if (!timestampImprint && !cert.PeriodoValido)
            {
                throw new Exception("Este documento possui uma assinatura ICPBrasil inválida.");
            }
        }
 private static void IsDocumentUnadulterated(PdfPkcs7 pkcs7)
 {
     try
     {
         pkcs7.Verify();
     }
     catch
     {
         throw new Exception("Este documento teve seu conteúdo alterado, portanto sua assinatura tornou-se inválida." + message);
     }
 }
        private async Task <IEnumerable <CertificadoDigital> > SignatureValidation(byte[] file, bool ignoreExpired = false)
        {
            PdfReader reader = new PdfReader(file);

            DocumentoPossuiAssinaturaDigital(reader);

            var digitalCertificateList = new List <CertificadoDigital>();
            var signatureNameList      = reader.AcroFields.GetSignatureNames();

            foreach (string signatureName in signatureNameList)
            {
                PdfPkcs7 pkcs7 = reader.AcroFields.VerifySignature(signatureName);

                // validação do certificado via outbound
                var messages = await OnlineChainValidation(
                    pkcs7.SigningCertificate.GetEncoded(),
                    ignoreExpired
                    );

                if (!string.IsNullOrWhiteSpace(messages))
                {
                    throw new Exception(messages);
                }

                CertificadoDigital cert = new CertificadoDigital(pkcs7);

                // validations
                ValidCertificateChain(cert);
                if (!ignoreExpired)
                {
                    ValidDigitalCertificate(cert, pkcs7);
                }
                ValidSignatureType(cert);
                ValidSignatureDate(pkcs7);
                IsDocumentUnadulterated(pkcs7);

                // cpf-cnpj, name, signature's date
                PessoaFisica pessoaFisica = cert.PessoaJuridica?.Responsavel ?? cert.PessoaFisica;
                string       pessoa       = $"{pessoaFisica.Nome.ToUpper()}";
                if (cert.PessoaJuridica != null)
                {
                    pessoa += $" ({cert.PessoaJuridica.RazaoSocial.ToUpper()})";
                }

                digitalCertificateList.Add(cert);
            }

            return(digitalCertificateList);
        }
        public async Task <bool> ValidateDigitalSignatures(byte[] file)
        {
            try
            {
                PdfReader reader = new PdfReader(file);

                // ordenar a lista de assinaturas
                var orderedSignatureNames = GetOrderedSignatureNames(reader);

                // ordernar as posições das tabelas de referência cruzada
                List <int> XrefByteOffsetOrdered = reader.XrefByteOffset.Cast <int>().ToList();
                XrefByteOffsetOrdered.Sort();

                var assinaramTodoDocumentoSN = reader.SignaturesCoverWholeDocument().Cast <string>().ToList();

                List <KeyValuePair <string, string> > naoAssinaramTodoDocumento = new List <KeyValuePair <string, string> >();
                List <KeyValuePair <string, string> > assinaramTodoDocumento    = new List <KeyValuePair <string, string> >();
                foreach (string signatureName in orderedSignatureNames)
                {
                    PdfPkcs7 pkcs7 = reader.AcroFields.VerifySignature(signatureName);

                    var messages = await OnlineChainValidation(pkcs7.SigningCertificate.GetEncoded());

                    if (!string.IsNullOrWhiteSpace(messages))
                    {
                        throw new Exception(messages);
                    }

                    CertificadoDigital cert = new CertificadoDigital(pkcs7.SigningCertificate.GetEncoded());

                    // validations
                    ValidCertificateChain(cert);
                    ValidDigitalCertificate(cert, pkcs7);
                    ValidSignatureType(cert);
                    ValidSignatureDate(pkcs7);
                    IsDocumentUnadulterated(pkcs7);

                    // cpf-cnpj, name, signature's date
                    PessoaFisica pessoaFisica = cert.PessoaJuridica?.Responsavel ?? cert.PessoaFisica;
                    string       pessoa       = $"{pessoaFisica.Nome.ToUpper()}";
                    if (cert.PessoaJuridica != null)
                    {
                        pessoa += $" ({cert.PessoaJuridica.RazaoSocial.ToUpper()})";
                    }

                    if (!assinaramTodoDocumentoSN.Contains(signatureName))
                    {
                        naoAssinaramTodoDocumento.Add(new KeyValuePair <string, string>(pessoa, signatureName));
                    }
                    else
                    {
                        assinaramTodoDocumento.Add(new KeyValuePair <string, string>(pessoa, signatureName));
                    }
                }

                // Deixar apenas a última assinatura de cada pessoa/cnpj
                var distinctSignersList = RemoverAssinaturasDuplicadas(assinaramTodoDocumento);
                var distinctNaoAssinaramTodoDocumento = RemoverAssinaturasDuplicadas(naoAssinaramTodoDocumento);

                TodosAssinaramDocumentoPorInteiro(distinctNaoAssinaramTodoDocumento);

                return(true);
            }
            catch (Exception e)
            {
                throw new Exception($"Ocorreu um erro: {e.Message}");
            }
        }
        private void CompletionPdf(byte[] invoiceMemoryStream, List <FileStream> attachmentFiles, string fileName)
        {
            var reader          = new PdfReader(invoiceMemoryStream);
            var document        = new Document(reader.GetPageSizeWithRotation(1));
            var pdfMerge        = new MemoryStream();
            var pdfCopyProvider = new PdfCopy(document, pdfMerge);

            document.Open();

            var pages = new List <PdfImportedPage>();

            GetAllPages(reader, pdfCopyProvider, pages);
            foreach (var attachmentReader in attachmentFiles.Select(attachmentFile => new PdfReader(attachmentFile)))
            {
                GetAllPages(attachmentReader, pdfCopyProvider, pages);
                attachmentReader.Close();
            }

            foreach (var pdfImportedPage in pages)
            {
                pdfCopyProvider.AddPage(pdfImportedPage);
            }
            document.Close();
            reader.Close();
            pdfCopyProvider.Close();

            pdfMerge.Seek(0, SeekOrigin.Begin);

            var readerWithoutSign = new PdfReader(pdfMerge);
            var finalOutput       = new FileStream(fileName, FileMode.Create, FileAccess.Write);


            var tsa = new TsaClientBouncyCastle("https://freetsa.org/tsr");
            int contentEstimated = (int)pdfMerge.Length;

            var st = PdfStamper.CreateSignature(readerWithoutSign, finalOutput, '\0', null, true);

            var sap = st.SignatureAppearance;

            var cert = new Cert("EFZ.pfx", "Lea10985");

            sap.SetCrypto(cert.Akp, cert.Chain, null, PdfSignatureAppearance.SelfSigned);
            sap.Reason   = "Archived digital signature";
            sap.Contact  = "EFZ";
            sap.Location = "EFZ";

            sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;

            sap.SetCrypto(null, cert.Chain, null, PdfSignatureAppearance.VerisignSigned);

            var dic = new PdfSignature(PdfName.AdobePpklite, PdfName.AdbePkcs7Detached);

            dic.Put(PdfName.TYPE, PdfName.Stamp);
            dic.Reason           = sap.Reason;
            dic.Location         = sap.Location;
            dic.Contact          = sap.Contact;
            dic.Date             = new PdfDate(sap.SignDate);
            sap.CryptoDictionary = dic;

            var exc = new Dictionary <PdfName, int>();

            exc[PdfName.Contents] = contentEstimated * 2 + 2;
            sap.PreClose(new Hashtable(exc));

            var sgn           = new PdfPkcs7(cert.Akp, cert.Chain, null, "SHA1", false);
            var data          = sap.RangeStream;
            var messageDigest = DigestUtilities.GetDigest("SHA1");

            byte[] buf = new byte[8192];
            int    n;

            while ((n = data.Read(buf, 0, buf.Length)) > 0)
            {
                messageDigest.BlockUpdate(buf, 0, n);
            }
            byte[] tsImprint = new byte[messageDigest.GetDigestSize()];
            messageDigest.DoFinal(tsImprint, 0);
            var cal = DateTime.UtcNow;

            byte[] tsToken = tsa.GetTimeStampToken(null, tsImprint);

            byte[] ocsp = null;
            if (cert.Chain.Length >= 2)
            {
                String url = PdfPkcs7.GetOcspurl(cert.Chain[0]);
                if (url != null && url.Length > 0)
                {
                    ocsp = new OcspClientBouncyCastle(cert.Chain[0], cert.Chain[1], url).GetEncoded();
                }
            }
            byte[] sh = sgn.GetAuthenticatedAttributeBytes(tsImprint, cal, ocsp);
            sgn.Update(sh, 0, sh.Length);

            byte[] encodedSig = sgn.GetEncodedPkcs7(tsImprint, cal, tsa, ocsp);
            if (contentEstimated + 2 < encodedSig.Length)
            {
                throw new Exception("Not enough space");
            }

            byte[] paddedSig = new byte[contentEstimated];
            Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length);


            var dic2 = new PdfDictionary();

            dic2.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true));

            sap.Close(dic2);

            finalOutput.Close();
            finalOutput.Dispose();
        }
 /// <summary>
 /// Get RFC 3161 timeStampToken.
 /// Method may return null indicating that timestamp should be skipped.
 /// @throws Exception - TSA request failed
 /// @see com.lowagie.text.pdf.TSAClient#getTimeStampToken(com.lowagie.text.pdf.PdfPKCS7, byte[])
 /// </summary>
 /// <param name="caller">PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it)</param>
 /// <param name="imprint">byte[] - data imprint to be time-stamped</param>
 /// <returns>byte[] - encoded, TSA signed data of the timeStampToken</returns>
 public byte[] GetTimeStampToken(PdfPkcs7 caller, byte[] imprint)
 {
     return(GetTimeStampToken(imprint));
 }