I have specifically checked the chain. It shows there are 3 completely separate certificates in it. With the information you have given me though, I was able to track down where the problem is.
The chain in the setCrypto method isn't getting used in the Certificate Dictionary because I'm setting the dictionary manually and we aren't passing in any kind of ICipherParameters into the SetCrypto method. (It's this way in your online examples) To get it to work correctly I changed the cmsSigner.IncludeOption to ExcludeRoot instead of EndCertificateOnly and the problem was solved, all of the intermediate certs were sent. If you want the root to be sent as well, you can use WholeChain. I also had to change csize variable. I did a more dynamic approach then just saying 4000. I did 4000 plus the sum of the length of the raw data of all the certs in the chain. As I find it annoying when people find an answer, but don't share, here's my entire code. using System; using System.Configuration; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.Pkcs; using System.Security.Cryptography.X509Certificates; using iTextSharp.text; using iTextSharp.text.pdf; using System.Linq; namespace PDFStuff { class PDFPlayground { public static X509Store GetStore() { X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.MaxAllowed); return store; } public static X509Certificate2 GetCertificateByThumbprint(string thumbprint, bool requirePrivate) { if (string.IsNullOrEmpty(thumbprint)) { return null; } X509Store store = GetStore(); X509Certificate2 result = null; try { foreach (X509Certificate2 c in store.Certificates) { if (c.Thumbprint == thumbprint && (c.HasPrivateKey || !requirePrivate)) result = c; } } catch { } finally { store.Close(); } return result; } public static byte[] SignDocument(byte[] pdfDocument) { //get the certificate X509Certificate2 cert = GetCertificateByThumbprint(ConfigurationManager.AppSettings["PDFCertificateThumbprint"], true); if (cert == null) { //no cert, dont do anything return pdfDocument; } using (MemoryStream stream = new MemoryStream()) { //set initial variables X509Chain chain = X509Chain.Create(); PdfReader reader = new PdfReader(pdfDocument); PdfStamper stamper = PdfStamper.CreateSignature(reader, stream, '\0', null, false); PdfSignatureAppearance sap = stamper.SignatureAppearance; PdfSignature signatureDictionary = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1); Dictionary<PdfName, int> reservedSpace = new Dictionary<PdfName, int>(); HashAlgorithm sha = new SHA1CryptoServiceProvider(); int read = 0; byte[] buff = new byte[8192]; int csize = 0; byte[] outc = null; Stream sapStream = null; byte[] pk = null; PdfDictionary certificateDictionary = new PdfDictionary(); //build my certificate chain chain.Build(cert); //guess the size of the certificates and signature. //we don't know for sure how big it really is going to be until after we hash it, so, we give it 4k for the signature //and add the size of all the raw data of the certificates. csize = 4096 + //4K for the signature (from c in chain.ChainElements.OfType<X509ChainElement>() select c.Certificate.RawData.Length).Sum(); //add up the size of each of the certificates and add it up //certificate buffer outc = new byte[csize]; //protect certain features of the document stamper.SetEncryption(null, Guid.NewGuid().ToByteArray(), //random password PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY | PdfWriter.ALLOW_SCREENREADERS, PdfWriter.ENCRYPTION_AES_256); //////sign the document sap.SetVisibleSignature(new Rectangle(1, 1, 1, 1), 1, "Signature field"); //we use a rectangle of 1,1,1,1 to hide it. sap.SignDate = DateTime.Parse(cert.GetEffectiveDateString()); sap.Reason = "reason, i am"; //reason for being signed sap.Location = "location, i am not"; //location it was signed //set to use the wincer_signed, its a windows cert, not sure if this is needed. sap.SetCrypto(null, null, null, PdfSignatureAppearance.WINCER_SIGNED); //set some stuff in the signature dictionary. we dont need to set the appearance stuff because the signature is hidden. signatureDictionary.Reason = sap.Reason; signatureDictionary.Location = sap.Location; signatureDictionary.Date = new PdfDate(sap.SignDate); signatureDictionary.Name = cert.Subject; //certificate name //set the appearance only stuff. sap.Acro6Layers = true; //set to true to make adobe 6.x and higher happier with the layers. sap.Render = PdfSignatureAppearance.SignatureRender.NameAndDescription; //what to show in the signature display. since its hidden, we dont care // but if we do allow an image, then we have to put in an image. //set the crypto dictionary sap.CryptoDictionary = signatureDictionary; //reserve some space for certs and signatures reservedSpace[PdfName.CONTENTS] = csize * 2 + 2; //*2 because binary data is stored as hex strings (i think). +2 for end of field sap.PreClose(reservedSpace); //actually reserve it //build the signature sapStream = sap.RangeStream; while ((read = sapStream.Read(buff, 0, 8192)) > 0) { sha.TransformBlock(buff, 0, read, buff, 0); } sha.TransformFinalBlock(buff, 0, 0); pk = SignMsg(sha.Hash, chain, false); //put the certs and signature into the reserved buffer Array.Copy(pk, 0, outc, 0, pk.Length); //put the reserved buffer into the reserved space certificateDictionary.Put(PdfName.CONTENTS, new PdfString(outc).SetHexWriting(true)); //write the signature sap.Close(certificateDictionary); //close the stamper and save it stamper.Close(); //close the reader reader.Close(); //return the saved pdf return stream.GetBuffer(); } } public static byte[] SignMsg(Byte[] msg, X509Chain chain, bool detached) { // Place message in a ContentInfo object. // This is required to build a SignedCms object. ContentInfo contentInfo = new ContentInfo(msg); // Instantiate SignedCms object with the ContentInfo above. // Has default SubjectIdentifierType IssuerAndSerialNumber. SignedCms signedCms = new SignedCms(contentInfo, detached); // Formulate a CmsSigner object for the signer. CmsSigner cmsSigner = new CmsSigner(chain.ChainElements[0].Certificate); //first cert in the chain is the signer cert // Do the whole certificate chain. This way intermediate certificates get sent across as well. cmsSigner.IncludeOption = X509IncludeOption.ExcludeRoot; // Sign the CMS/PKCS #7 message. The second argument is // needed to ask for the pin. signedCms.ComputeSignature(cmsSigner, false); // Encode the CMS/PKCS #7 message. return signedCms.Encode(); } } } Edward Cooke Programmer II, Information Systems +1 801-325-6143 tel +1 801-898-5940 cell eco...@macu.com http://www.macu.com https://images.mtnam.org/marketing/image.aspx/1 https://images.mtnam.org/marketing/image.aspx/3/fb https://images.mtnam.org/marketing/image.aspx/3/tw -------------------------------------------------------------------------- From: mkl [mailto:m...@wir-sind-cool.org] Sent: Wednesday, August 24, 2011 5:55 AM To: itext-questions@lists.sourceforge.net Subject: Re: [iText-questions] iTextSharp and certificate chains using windows certificate store Edward, Edward Cooke wrote: > Here's my signed document. Your impression is right that there only is one certificate, the user certificate, included in the signature. On the other hand I also looked at the code (more exactly: the Java code, but as nothing magical happens there, I assume that the C# code is equivalent); it simply takes the certificates given to it in PdfSignatureAppearance.setCrypto and stores them locally; it forwards them to other objects; later it uses these certificates and adds them to the PKCS#7 signature container. So every certificate you use in setCrypto should be included in the signature container. BTW, it also implicitly expects the first certificate to be the user certificate. You initially wrote: > I've tried adding the entire chain into the array of certificates, in > both root cert first, signing one last and signing one first the root > last. But adobe is showing that only the signing cert is being put in. Thus, if changing the order of the certificates in the list has no effect, most likely the list does not contain more than one element. So, have you actually checked the size of the OrgX509.X509Certificate[] chain in your code? Either it is 1 or iTextSharp is significantly different from iText in this respect. Regards, Michael. -- View this message in context: http://itext-general.2136553.n4.nabble.com/iTextSharp-and-certificate-chains-using-windows-certificate-store-tp3761613p3765101.html Sent from the iText - General mailing list archive at Nabble.com. ------------------------------------------------------------------------------ EMC VNX: the world's simplest storage, starting under $10K The only unified storage solution that offers unified management Up to 160% more powerful than alternatives and 25% more efficient. Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev _______________________________________________ iText-questions mailing list iText-questions@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/itext-questions iText(R) is a registered trademark of 1T3XT BVBA. Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/ Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php ***Confidentiality and Security Notice: This message and any attachments are intended only for the use of the individual or entity to which it is addressed and may contain confidential and/or privileged information. If you are not the intended recipient you are hereby notified that any dissemination, copying, or distribution of this message, or attachments, is strictly prohibited. If you have received this message in error, please notify the sender immediately by e-mail and delete it from your computer. Do not send sensitive data via unencrypted email as it may be intercepted in transit*** ------------------------------------------------------------------------------ EMC VNX: the world's simplest storage, starting under $10K The only unified storage solution that offers unified management Up to 160% more powerful than alternatives and 25% more efficient. Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev _______________________________________________ iText-questions mailing list iText-questions@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/itext-questions iText(R) is a registered trademark of 1T3XT BVBA. Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/ Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php