Exemple #1
0
        public void Sign(PDFSignatureAP sigAP, bool encrypt, PDFEncryption enc)
        {
            byte[] ownerPassword = null;
            if (!string.IsNullOrEmpty(enc.OwnerPwd))
            {
                ownerPassword = DocWriter.GetISOBytes(enc.OwnerPwd);
            }

            PdfReader reader = new PdfReader(this.inputPDF, ownerPassword);

            FileStream fs = new FileStream(this.outputPDF, FileMode.Create, FileAccess.Write);

            PdfStamper st;

            if (this.myCert == null)             //No signature just write meta-data and quit
            {
                st = new PdfStamper(reader, fs);
            }
            else
            {
                st = PdfStamper.CreateSignature(reader, fs, '\0', null, sigAP.Multi);
            }

            if (encrypt && enc != null)
            {
                enc.Encrypt(st);
            }
            //st.SetEncryption(PdfWriter.STRENGTH128BITS, "user", "owner", PdfWriter.ALLOW_COPY);

            st.MoreInfo    = this.metadata.getMetaData();
            st.XmpMetadata = this.metadata.getStreamedMetaData();

            if (this.myCert == null)             //No signature just write meta-data and quit
            {
                st.Close();
                return;
            }

            PdfSignatureAppearance sap = st.SignatureAppearance;

            //sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.WINCER_SIGNED);

            sap.SetCrypto(null, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED);

            sap.Reason   = sigAP.SigReason;
            sap.Contact  = sigAP.SigContact;
            sap.Location = sigAP.SigLocation;
            if (sigAP.Visible)
            {
                iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page);
                sap.Image      = sigAP.RawData == null ? null : iTextSharp.text.Image.GetInstance(sigAP.RawData);
                sap.Layer2Text = sigAP.CustomText;

                sap.SetVisibleSignature(new iTextSharp.text.Rectangle(sigAP.SigX, sigAP.SigY, sigAP.SigX + sigAP.SigW, sigAP.SigY + sigAP.SigH), sigAP.Page, null);
            }

            // Remove yellow question mark (green check mark is still used though)
            //sap.GetLayer(1);

            // The first signature is a certification
            //if (!sigAP.Multi)
            //{
            //    //sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
            //    sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING;
            //}

            PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));

            dic.Reason           = sap.Reason;
            dic.Location         = sap.Location;
            dic.Contact          = sap.Contact;
            dic.Date             = new PdfDate(sap.SignDate);
            sap.CryptoDictionary = dic;

            int contentEstimated = 15000;
            // Preallocate excluded byte-range for the signature content (hex encoded)
            Dictionary <PdfName, int> exc = new Dictionary <PdfName, int>();

            exc[PdfName.CONTENTS] = contentEstimated * 2 + 2;
            sap.PreClose(exc);

            PdfPKCS7 sgn           = new PdfPKCS7(this.myCert.Akp, this.myCert.Chain, null, "SHA-256", false);
            IDigest  messageDigest = DigestUtilities.GetDigest("SHA-256");
            // change for itextsharp-all-5.2.1
            Stream data = sap.GetRangeStream();

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

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

            byte[] ocsp = null;
            if (this.myCert.Chain.Length >= 2)
            {
                String url = PdfPKCS7.GetOCSPURL(this.myCert.Chain[0]);
                if (url != null && url.Length > 0)
                {
                    //ocsp =  new  OcspClientBouncyCastle(this.myCert.Chain[0], this.myCert.Chain[1], url).GetEncoded();
                    // change for itextsharp-all-5.2.1
                    ocsp = new OcspClientBouncyCastle().GetEncoded(this.myCert.Chain[0], this.myCert.Chain[1], url);
                }
            }
            byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp);
            sgn.Update(sh, 0, sh.Length);

            byte[] paddedSig = new byte[contentEstimated];

            if (this.myCert.Tsc != null)
            {
                byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, this.myCert.Tsc, ocsp);
                System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length);
                if (contentEstimated + 2 < encodedSigTsa.Length)
                {
                    throw new Exception("Not enough space for signature");
                }
            }
            else
            {
                byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal);
                System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length);
                if (contentEstimated + 2 < encodedSig.Length)
                {
                    throw new Exception("Not enough space for signature");
                }
            }

            PdfDictionary dic2 = new PdfDictionary();

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

            //// Lock all fields after signing (backport from iText 5.4.4) - wrong - doesn't work
            //PdfDictionary lockDic = new PdfDictionary(new PdfName("SigFieldLock"));
            //lockDic.Put(PdfName.ACTION, new PdfName("All"));
            //lockDic.Put(PdfName.P, new PdfNumber(1));
            //dic2.Put(PdfName.LOCK, lockDic);

            sap.Close(dic2);

            //st.Close();
        }
        public void Sign(PDFSignatureAP sigAP, bool encrypt, PDFEncryption enc)
        {
            byte[] ownerPassword = null;
            if (!string.IsNullOrEmpty(enc.OwnerPwd))
            {
                ownerPassword = DocWriter.GetISOBytes(enc.OwnerPwd);
            }

            PdfReader reader = new PdfReader(this.inputPDF, ownerPassword);

            FileStream fs = new FileStream(this.outputPDF, FileMode.Create, FileAccess.Write);

            PdfStamper st;
            if (this.myCert == null) //No signature just write meta-data and quit
            {
                st = new PdfStamper(reader, fs);
            }
            else
            {
                st = PdfStamper.CreateSignature(reader, fs, '\0', null, sigAP.Multi);
            }

            if (encrypt && enc != null) enc.Encrypt(st);
            //st.SetEncryption(PdfWriter.STRENGTH128BITS, "user", "owner", PdfWriter.ALLOW_COPY);

            st.MoreInfo = this.metadata.getMetaData();
            st.XmpMetadata = this.metadata.getStreamedMetaData();

            if (this.myCert == null) //No signature just write meta-data and quit
            {
                st.Close();
                return;
            }

            PdfSignatureAppearance sap = st.SignatureAppearance;

            //sap.SetCrypto(this.myCert.Akp, this.myCert.Chain, null, PdfSignatureAppearance.WINCER_SIGNED);

            sap.SetCrypto(null, this.myCert.Chain, null, PdfSignatureAppearance.SELF_SIGNED);

            sap.Reason = sigAP.SigReason;
            sap.Contact = sigAP.SigContact;
            sap.Location = sigAP.SigLocation;
            if (sigAP.Visible)
            {
                iTextSharp.text.Rectangle rect = st.Reader.GetPageSize(sigAP.Page);
                sap.Image = sigAP.RawData == null ? null : iTextSharp.text.Image.GetInstance(sigAP.RawData);
                sap.Layer2Text = sigAP.CustomText;

                sap.SetVisibleSignature(new iTextSharp.text.Rectangle(sigAP.SigX, sigAP.SigY, sigAP.SigX + sigAP.SigW, sigAP.SigY + sigAP.SigH), sigAP.Page, null);
            }

            // Remove yellow question mark (green check mark is still used though)
            //sap.GetLayer(1);

            // The first signature is a certification
            //if (!sigAP.Multi)
            //{
            //    //sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
            //    sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_FORM_FILLING;
            //}

            PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
            dic.Reason = sap.Reason;
            dic.Location = sap.Location;
            dic.Contact = sap.Contact;
            dic.Date = new PdfDate(sap.SignDate);
            sap.CryptoDictionary = dic;

            int contentEstimated = 15000;
            // Preallocate excluded byte-range for the signature content (hex encoded)
            Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>();
            exc[PdfName.CONTENTS] = contentEstimated * 2 + 2;
            sap.PreClose(exc);

            PdfPKCS7 sgn = new PdfPKCS7(this.myCert.Akp, this.myCert.Chain, null, "SHA-256", false);
            IDigest messageDigest = DigestUtilities.GetDigest("SHA-256");
            // change for itextsharp-all-5.2.1
            Stream data = sap.GetRangeStream();
            byte[] buf = new byte[8192];
            int n;
            while ((n = data.Read(buf, 0, buf.Length)) > 0)
            {
                messageDigest.BlockUpdate(buf, 0, n);
            }
            byte[] hash = new byte[messageDigest.GetDigestSize()];
            messageDigest.DoFinal(hash, 0);
            DateTime cal = DateTime.Now;
            byte[] ocsp = null;
            if (this.myCert.Chain.Length >= 2)
            {
                String url = PdfPKCS7.GetOCSPURL(this.myCert.Chain[0]);
                if (url != null && url.Length > 0)
                {
                    //ocsp =  new  OcspClientBouncyCastle(this.myCert.Chain[0], this.myCert.Chain[1], url).GetEncoded();
                    // change for itextsharp-all-5.2.1
                    ocsp = new OcspClientBouncyCastle().GetEncoded(this.myCert.Chain[0], this.myCert.Chain[1], url);
                }
            }
            byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp);
            sgn.Update(sh, 0, sh.Length);

            byte[] paddedSig = new byte[contentEstimated];

            if (this.myCert.Tsc != null)
            {
                byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal, this.myCert.Tsc, ocsp);
                System.Array.Copy(encodedSigTsa, 0, paddedSig, 0, encodedSigTsa.Length);
                if (contentEstimated + 2 < encodedSigTsa.Length)
                    throw new Exception("Not enough space for signature");
            }
            else
            {
                byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal);
                System.Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length);
                if (contentEstimated + 2 < encodedSig.Length)
                    throw new Exception("Not enough space for signature");
            }

            PdfDictionary dic2 = new PdfDictionary();
            dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true));

            //// Lock all fields after signing (backport from iText 5.4.4) - wrong - doesn't work
            //PdfDictionary lockDic = new PdfDictionary(new PdfName("SigFieldLock"));
            //lockDic.Put(PdfName.ACTION, new PdfName("All"));
            //lockDic.Put(PdfName.P, new PdfNumber(1));
            //dic2.Put(PdfName.LOCK, lockDic);

            sap.Close(dic2);

            //st.Close();
        }
        private void signWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Cert myCert = null;
            string certName = null;
            string tsaUrl = "http://timestamp.globalsign.com/scripts/timestamp.dll";   // null if unused
            X509Certificate2 certificateData = certificates[certificateComboSelectedIndex] as X509Certificate2;
            if (certificateData != null)
            {
                certName = ExtractDNField(certificateData.Subject, "CN");
                if (certName == null)
                {
                    certName = certificateData.Subject;   // Use fallback
                }
                byte[] bytes = certificateData.Export(X509ContentType.Pfx, "");
                myCert = new Cert(bytes, "", tsaUrl, "" /* TSA login */, "" /* TSA password */);
            }
            else
            {
                return;
                //myCert = new Cert(certificateTextBox.Text, certificatePwdBox.Text, tsaUrl, tsaLogin.Text, tsaPwd.Text);
            }

            if (reasonComboText == null)
            {
                reasonComboText = "";
            }

            // Copy original to backup file, then sign that back to original file name
            string outputFile;
            bool outputFileIsTemporary = false;
            outputFile = Path.GetFileNameWithoutExtension(inputFileTextText) +
                ".unsigned" +
                Path.GetExtension(inputFileTextText);
            outputFile = Path.Combine(Path.GetDirectoryName(inputFileTextText),
                outputFile);
            string inputFile = outputFile;

            // Create a copy if it does not exist yet (keep original unsigned forever)
            if (!File.Exists(outputFile))
            {
                File.Copy(inputFileTextText, outputFile);
                outputFile = inputFileTextText;
            }
            else
            {
                // We need a different temporary file
                inputFile = inputFileTextText;
                outputFile = Path.GetTempFileName();
                outputFileIsTemporary = true;
            }

            // NOTES:
            // * Encryption can only be applied before any signatures exist, otherwise existing signatures are broken.
            // * Encryption requires a non-empty password set, or we'll get problems when opening next time.
            // * Permissions can only be set together with the encryption status.
            // => Permissions cannot be changed once a signature exists.
            // http://stackoverflow.com/q/20008256/143684
            // TODO

            PDFEncryption pdfEnc = new PDFEncryption();
            pdfEnc.UserPwd = "";
            //pdfEnc.OwnerPwd = "1234";
            pdfEnc.OwnerPwd = "";
            pdfEnc.Encryption = true;   // Use 128 bit instead of 40 bit, but still RC4
            // Permissions explanation: http://www.pdflib.com/knowledge-base/pdf-security/permissions/
            pdfEnc.Permissions.Add(permissionType.Copy);
            pdfEnc.Permissions.Add(permissionType.DegradedPrinting);
            pdfEnc.Permissions.Add(permissionType.Printing);
            pdfEnc.Permissions.Add(permissionType.ScreenReaders);

            //pdfEnc.Permissions.Add(permissionType.Assembly);
            pdfEnc.Permissions.Add(permissionType.FillIn);   // Includes signing
            //pdfEnc.Permissions.Add(permissionType.ModifyAnnotation);
            //pdfEnc.Permissions.Add(permissionType.ModifyContent);

            // Sign document
            PDFSigner pdfs = new PDFSigner(inputFile, outputFile, myCert, metaData);
            PDFSignatureAP sigAp = new PDFSignatureAP();
            sigAp.SigReason = reasonComboText;
            sigAp.SigContact = "";
            sigAp.SigLocation = "";
            sigAp.Visible = visibleSignatureCheckChecked;
            sigAp.Multi = existingSignatures;
            sigAp.Page = pageNumValue;

            sigAp.CustomText = "";
            if (visibleSignatureCheckChecked)
            {
                if (showName)
                {
                    if (showLabels)
                    {
                        sigAp.CustomText += "Digital signiert von ";
                    }
                    sigAp.CustomText += certName + "\n";
                }
                if (showLocation)
                {
                    string country = ExtractDNField(certificateData.Subject, "C");
                    string locality = ExtractDNField(certificateData.Subject, "L");
                    if (!string.IsNullOrEmpty(country) || !string.IsNullOrEmpty(locality))
                    {
                        if (showLabels)
                        {
                            sigAp.CustomText += "Ort: ";
                        }
                        sigAp.CustomText += locality +
                            (!string.IsNullOrEmpty(locality) && !string.IsNullOrEmpty(country) ? ", " : "") +
                            country + "\n";
                    }
                }
                if (showReason)
                {
                    if (showLabels)
                    {
                        sigAp.CustomText += "Grund: ";
                    }
                    sigAp.CustomText += reasonComboText + "\n";
                }
                if (showDate)
                {
                    if (showLabels)
                    {
                        sigAp.CustomText += "Datum: ";
                    }
                    sigAp.CustomText += DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss K") + "\n";
                }
                sigAp.CustomText = sigAp.CustomText.TrimEnd();

                if (showImage && signaturePictureImage != null)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        signaturePictureImage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
                        sigAp.RawData = ms.ToArray();
                    }
                }

                sigAp.SigX = mm2pt(leftNumValue);
                sigAp.SigY = mm2pt(bottomNumValue);
                sigAp.SigW = mm2pt(widthNumValue);
                sigAp.SigH = mm2pt(heightNumValue);
            }

            // Encrypt only if no signatures exist. Later it won't work anymore because it'll
            // break the existing signatures.
            pdfs.Sign(sigAp, false /*!existingSignatures*/, pdfEnc);

            if (outputFileIsTemporary)
            {
                // Delete input file and replace with temp output
                File.Delete(inputFile);
                File.Move(outputFile, inputFile);
            }
        }
Exemple #4
0
        private void signWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            Cert             myCert          = null;
            string           certName        = null;
            string           tsaUrl          = "http://timestamp.globalsign.com/scripts/timestamp.dll"; // null if unused
            X509Certificate2 certificateData = certificates[certificateComboSelectedIndex] as X509Certificate2;

            if (certificateData != null)
            {
                certName = ExtractDNField(certificateData.Subject, "CN");
                if (certName == null)
                {
                    certName = certificateData.Subject;                       // Use fallback
                }
                byte[] bytes = certificateData.Export(X509ContentType.Pfx, "");
                myCert = new Cert(bytes, "", tsaUrl, "" /* TSA login */, "" /* TSA password */);
            }
            else
            {
                return;
                //myCert = new Cert(certificateTextBox.Text, certificatePwdBox.Text, tsaUrl, tsaLogin.Text, tsaPwd.Text);
            }

            if (reasonComboText == null)
            {
                reasonComboText = "";
            }

            // Copy original to backup file, then sign that back to original file name
            string outputFile;
            bool   outputFileIsTemporary = false;

            outputFile = Path.GetFileNameWithoutExtension(inputFileTextText) +
                         ".unsigned" +
                         Path.GetExtension(inputFileTextText);
            outputFile = Path.Combine(Path.GetDirectoryName(inputFileTextText),
                                      outputFile);
            string inputFile = outputFile;

            // Create a copy if it does not exist yet (keep original unsigned forever)
            if (!File.Exists(outputFile))
            {
                File.Copy(inputFileTextText, outputFile);
                outputFile = inputFileTextText;
            }
            else
            {
                // We need a different temporary file
                inputFile             = inputFileTextText;
                outputFile            = Path.GetTempFileName();
                outputFileIsTemporary = true;
            }

            // NOTES:
            // * Encryption can only be applied before any signatures exist, otherwise existing signatures are broken.
            // * Encryption requires a non-empty password set, or we'll get problems when opening next time.
            // * Permissions can only be set together with the encryption status.
            // => Permissions cannot be changed once a signature exists.
            // http://stackoverflow.com/q/20008256/143684
            // TODO

            PDFEncryption pdfEnc = new PDFEncryption();

            pdfEnc.UserPwd = "";
            //pdfEnc.OwnerPwd = "1234";
            pdfEnc.OwnerPwd   = "";
            pdfEnc.Encryption = true;               // Use 128 bit instead of 40 bit, but still RC4
            // Permissions explanation: http://www.pdflib.com/knowledge-base/pdf-security/permissions/
            pdfEnc.Permissions.Add(permissionType.Copy);
            pdfEnc.Permissions.Add(permissionType.DegradedPrinting);
            pdfEnc.Permissions.Add(permissionType.Printing);
            pdfEnc.Permissions.Add(permissionType.ScreenReaders);

            //pdfEnc.Permissions.Add(permissionType.Assembly);
            pdfEnc.Permissions.Add(permissionType.FillIn);               // Includes signing
            //pdfEnc.Permissions.Add(permissionType.ModifyAnnotation);
            //pdfEnc.Permissions.Add(permissionType.ModifyContent);

            // Sign document
            PDFSigner      pdfs  = new PDFSigner(inputFile, outputFile, myCert, metaData);
            PDFSignatureAP sigAp = new PDFSignatureAP();

            sigAp.SigReason   = reasonComboText;
            sigAp.SigContact  = "";
            sigAp.SigLocation = "";
            sigAp.Visible     = visibleSignatureCheckChecked;
            sigAp.Multi       = existingSignatures;
            sigAp.Page        = pageNumValue;

            sigAp.CustomText = "";
            if (visibleSignatureCheckChecked)
            {
                if (showName)
                {
                    if (showLabels)
                    {
                        sigAp.CustomText += "Digital signiert von ";
                    }
                    sigAp.CustomText += certName + "\n";
                }
                if (showLocation)
                {
                    string country  = ExtractDNField(certificateData.Subject, "C");
                    string locality = ExtractDNField(certificateData.Subject, "L");
                    if (!string.IsNullOrEmpty(country) || !string.IsNullOrEmpty(locality))
                    {
                        if (showLabels)
                        {
                            sigAp.CustomText += "Ort: ";
                        }
                        sigAp.CustomText += locality +
                                            (!string.IsNullOrEmpty(locality) && !string.IsNullOrEmpty(country) ? ", " : "") +
                                            country + "\n";
                    }
                }
                if (showReason)
                {
                    if (showLabels)
                    {
                        sigAp.CustomText += "Grund: ";
                    }
                    sigAp.CustomText += reasonComboText + "\n";
                }
                if (showDate)
                {
                    if (showLabels)
                    {
                        sigAp.CustomText += "Datum: ";
                    }
                    sigAp.CustomText += DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss K") + "\n";
                }
                sigAp.CustomText = sigAp.CustomText.TrimEnd();

                if (showImage && signaturePictureImage != null)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        signaturePictureImage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
                        sigAp.RawData = ms.ToArray();
                    }
                }

                sigAp.SigX = mm2pt(leftNumValue);
                sigAp.SigY = mm2pt(bottomNumValue);
                sigAp.SigW = mm2pt(widthNumValue);
                sigAp.SigH = mm2pt(heightNumValue);
            }

            // Encrypt only if no signatures exist. Later it won't work anymore because it'll
            // break the existing signatures.
            pdfs.Sign(sigAp, false /*!existingSignatures*/, pdfEnc);

            if (outputFileIsTemporary)
            {
                // Delete input file and replace with temp output
                File.Delete(inputFile);
                File.Move(outputFile, inputFile);
            }
        }