/// <summary>Split PDF string into array of single character PDF strings.</summary> /// <param name="string">PDF string to be split.</param> /// <returns>split PDF string.</returns> private PdfString[] SplitString(PdfString @string) { CheckGraphicsState(); PdfFont font = gs.GetFont(); if (font is PdfType0Font) { // Number of bytes forming one glyph can be arbitrary from [1; 4] range IList <PdfString> strings = new List <PdfString>(); GlyphLine glyphLine = gs.GetFont().DecodeIntoGlyphLine(@string); for (int i = glyphLine.start; i < glyphLine.end; i++) { strings.Add(new PdfString(gs.GetFont().ConvertToBytes(glyphLine.Get(i)))); } return(strings.ToArray(new PdfString[strings.Count])); } else { // One byte corresponds to one character PdfString[] strings = new PdfString[@string.GetValue().Length]; for (int i = 0; i < @string.GetValue().Length; i++) { strings[i] = new PdfString(@string.GetValue().JSubstring(i, i + 1), @string.GetEncoding()); } return(strings); } }
/// <summary> /// Prepares an /// <see cref="PdfPKCS7"/> /// instance for the given signature. /// This method handles signature parsing and might throw an exception if /// signature is malformed. /// <p> /// The returned /// <see cref="PdfPKCS7"/> /// can be used to fetch additional info about the signature /// and also to perform integrity check of data signed by the given signature field. /// </p> /// Prepared /// <see cref="PdfPKCS7"/> /// instance calculates digest based on signature's /ByteRange entry. /// In order to check that /ByteRange is properly defined and given signature indeed covers the current PDF document /// revision please use /// <see cref="SignatureCoversWholeDocument(System.String)"/> /// method. /// </summary> /// <param name="signatureFieldName">the signature field name</param> /// <param name="securityProvider">the security provider or null for the default provider</param> /// <returns> /// a /// <see cref="PdfPKCS7"/> /// instance which can be used to fetch additional info about the signature /// and also to perform integrity check of data signed by the given signature field. /// </returns> public virtual PdfPKCS7 ReadSignatureData(String signatureFieldName) { PdfSignature signature = GetSignature(signatureFieldName); if (signature == null) { return(null); } try { PdfName sub = signature.GetSubFilter(); PdfString contents = signature.GetContents(); PdfPKCS7 pk = null; if (sub.Equals(PdfName.Adbe_x509_rsa_sha1)) { PdfString cert = signature.GetPdfObject().GetAsString(PdfName.Cert); if (cert == null) { cert = signature.GetPdfObject().GetAsArray(PdfName.Cert).GetAsString(0); } pk = new PdfPKCS7(PdfEncodings.ConvertToBytes(contents.GetValue(), null), cert.GetValueBytes()); } else { pk = new PdfPKCS7(PdfEncodings.ConvertToBytes(contents.GetValue(), null), sub); } UpdateByteRange(pk, signature); PdfString date = signature.GetDate(); if (date != null) { pk.SetSignDate(PdfDate.Decode(date.ToString())); } String signName = signature.GetName(); pk.SetSignName(signName); String reason = signature.GetReason(); if (reason != null) { pk.SetReason(reason); } String location = signature.GetLocation(); if (location != null) { pk.SetLocation(location); } return(pk); } catch (Exception e) { throw new PdfException(e); } }
/// <exception cref="System.IO.IOException"/> /// <exception cref="System.Exception"/> /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/> public virtual void CheckEncryptedWithCertificateDocumentAppending(String filename, X509Certificate certificate ) { String srcFileName = destinationFolder + filename; String outFileName = destinationFolder + "appended_" + filename; PdfReader reader = new PdfReader(srcFileName, new ReaderProperties().SetPublicKeySecurityParams(certificate , GetPrivateKey())); PdfDocument document = new PdfDocument(reader, new PdfWriter(outFileName), new StampingProperties().UseAppendMode ()); PdfPage newPage = document.AddNewPage(); String helloWorldStringValue = "Hello world string"; newPage.Put(PdfName.Default, new PdfString(helloWorldStringValue)); WriteTextBytesOnPageContent(newPage, "Hello world page_2!"); document.Close(); PdfReader appendedDocReader = new PdfReader(outFileName, new ReaderProperties().SetPublicKeySecurityParams (certificate, GetPrivateKey())); PdfDocument appendedDoc = new PdfDocument(appendedDocReader); PdfPage secondPage = appendedDoc.GetPage(2); PdfString helloWorldPdfString = secondPage.GetPdfObject().GetAsString(PdfName.Default); String actualHelloWorldStringValue = helloWorldPdfString != null ? helloWorldPdfString.GetValue() : null; NUnit.Framework.Assert.AreEqual(actualHelloWorldStringValue, helloWorldStringValue); appendedDoc.Close(); CompareTool compareTool = new CompareTool().EnableEncryptionCompare(); compareTool.GetOutReaderProperties().SetPublicKeySecurityParams(certificate, GetPrivateKey()); compareTool.GetCmpReaderProperties().SetPublicKeySecurityParams(certificate, GetPrivateKey()); String compareResult = compareTool.CompareByContent(outFileName, sourceFolder + "cmp_appended_" + filename , destinationFolder, "diff_"); if (compareResult != null) { NUnit.Framework.Assert.Fail(compareResult); } }
/// <summary>Calculates width and word spacing of a single character PDF string.</summary> /// <remarks> /// Calculates width and word spacing of a single character PDF string. /// IMPORTANT: Shall ONLY be used for a single character pdf strings. /// </remarks> /// <param name="string">a character to calculate width.</param> /// <returns>array of 2 items: first item is a character width, second item is a calculated word spacing.</returns> private float[] GetWidthAndWordSpacing(PdfString @string) { float[] result = new float[2]; result[0] = (float)((gs.GetFont().GetContentWidth(@string) * fontMatrix[0])); result[1] = " ".Equals(@string.GetValue()) ? gs.GetWordSpacing() : 0; return(result); }
public override String Decode(PdfString content) { String cids = content.GetValue(); if (cids.Length == 1) { return(""); } StringBuilder builder = new StringBuilder(cids.Length / 2); //number of cids must be even. With i < cids.length() - 1 we garantee, that we will not process the last odd index. for (int i = 0; i < cids.Length - 1; i += 2) { int code = (cids[i] << 8) + cids[i + 1]; Glyph glyph = fontProgram.GetGlyphByCode(cmapEncoding.GetCidCode(code)); if (glyph != null && glyph.GetChars() != null) { builder.Append(glyph.GetChars()); } else { builder.Append('?'); } } return(builder.ToString()); }
public override void Draw(DrawContext drawContext) { LayoutTaggingHelper taggingHelper = GetProperty <LayoutTaggingHelper>(Property.TAGGING_HELPER); // We want to reach the actual tag from logical structure tree, in order to set custom properties, for // which iText doesn't provide convenient API at the moment. Specifically we are aiming at setting /ID // entry in structure element dictionary corresponding to the table header cell. Here we are creating tag // for the current element in logical structure tree right at the beginning of #draw method. // If this particular instance of header cell is paging artifact it would be marked so by layouting // engine and it would not allow to create a tag (return value of the method would be 'false'). // If this particular instance of header cell is the header which is to be tagged, a tag will be created. // It's safe to create a tag at this moment, it will be picked up and placed at correct position in the // logical structure tree later by layout engine. TagTreePointer p = new TagTreePointer(pdfDocument); if (taggingHelper.CreateTag(this, p)) { // After the tag is created, we can fetch low level entity PdfStructElem // in order to work with it directly. These changes would be directly reflected // in the PDF file inner structure. PdfStructElem structElem = tagContext.GetPointerStructElem(p); PdfDictionary structElemDict = structElem.GetPdfObject(); structElemDict.Put(PdfName.ID, headerId); idTree.AddEntry(headerId.GetValue(), structElemDict); } base.Draw(drawContext); }
/// <summary><inheritDoc/></summary> public override GlyphLine DecodeIntoGlyphLine(PdfString content) { //A sequence of one or more bytes shall be extracted from the string and matched against the codespace //ranges in the CMap. That is, the first byte shall be matched against 1-byte codespace ranges; if no match is //found, a second byte shall be extracted, and the 2-byte code shall be matched against 2-byte codespace //ranges. This process continues for successively longer codes until a match is found or all codespace ranges //have been tested. There will be at most one match because codespace ranges shall not overlap. String cids = content.GetValue(); IList <Glyph> glyphs = new List <Glyph>(); for (int i = 0; i < cids.Length; i++) { //The code length shall not be greater than 4. int code = 0; Glyph glyph = null; int codeSpaceMatchedLength = 1; for (int codeLength = 1; codeLength <= 4 && i + codeLength <= cids.Length; codeLength++) { code = (code << 8) + cids[i + codeLength - 1]; if (!cmapEncoding.ContainsCodeInCodeSpaceRange(code, codeLength)) { continue; } else { codeSpaceMatchedLength = codeLength; } int glyphCode = cmapEncoding.GetCidCode(code); glyph = fontProgram.GetGlyphByCode(glyphCode); if (glyph != null) { i += codeLength - 1; break; } } if (glyph == null) { StringBuilder failedCodes = new StringBuilder(); for (int codeLength = 1; codeLength <= 4 && i + codeLength <= cids.Length; codeLength++) { failedCodes.Append((int)cids[i + codeLength - 1]).Append(" "); } ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Font.PdfType0Font)); logger.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.COULD_NOT_FIND_GLYPH_WITH_CODE, failedCodes .ToString())); i += codeSpaceMatchedLength - 1; } if (glyph != null && glyph.GetChars() != null) { glyphs.Add(glyph); } else { glyphs.Add(new Glyph(0, fontProgram.GetGlyphByCode(0).GetWidth(), -1)); } } return(new GlyphLine(glyphs)); }
/// <exception cref="Org.BouncyCastle.Security.SecurityUtilityException"/> /// <exception cref="System.IO.IOException"/> private PdfName GetSignatureHashKey(String signatureName) { PdfSignature sig = sgnUtil.GetSignature(signatureName); PdfString contents = sig.GetContents(); byte[] bc = PdfEncodings.ConvertToBytes(contents.GetValue(), null); byte[] bt = null; if (PdfName.ETSI_RFC3161.Equals(sig.GetSubFilter())) { Asn1InputStream din = new Asn1InputStream(new MemoryStream(bc)); Asn1Object pkcs = din.ReadObject(); bc = pkcs.GetEncoded(); } bt = HashBytesSha1(bc); return(new PdfName(ConvertToHex(bt))); }
/// <summary>Split PDF string into array of single character PDF strings.</summary> /// <param name="string">PDF string to be splitted.</param> /// <returns>splitted PDF string.</returns> private PdfString[] SplitString(PdfString @string) { IList <PdfString> strings = new List <PdfString>(); String stringValue = @string.GetValue(); for (int i = 0; i < stringValue.Length; i++) { PdfString newString = new PdfString(stringValue.JSubstring(i, i + 1), @string.GetEncoding()); String text = gs.GetFont().Decode(newString); if (text.Length == 0 && i < stringValue.Length - 1) { newString = new PdfString(stringValue.JSubstring(i, i + 2), @string.GetEncoding()); i++; } strings.Add(newString); } return(strings.ToArray(new PdfString[strings.Count])); }
protected internal virtual void InspectKid(IStructureNode kid) { try { if (kid is PdfStructElem) { PdfStructElem structElemKid = (PdfStructElem)kid; PdfName s = structElemKid.GetRole(); String tagN = s.GetValue(); String tag = FixTagName(tagN); @out.Write("<"); @out.Write(tag); InspectAttributes(structElemKid); @out.Write(">" + Environment.NewLine); PdfString alt = (structElemKid).GetAlt(); if (alt != null) { @out.Write("<alt><![CDATA["); @out.Write(iText.IO.Util.StringUtil.ReplaceAll(alt.GetValue(), "[\\000]*", "")); @out.Write("]]></alt>" + Environment.NewLine); } InspectKids(structElemKid.GetKids()); @out.Write("</"); @out.Write(tag); @out.Write(">" + Environment.NewLine); } else { if (kid is PdfMcr) { ParseTag((PdfMcr)kid); } else { @out.Write(" <flushedKid/> "); } } } catch (System.IO.IOException e) { throw new iText.IO.IOException(iText.IO.IOException.UnknownIOException, e); } }
public override float GetContentWidth(PdfString content) { String cids = content.GetValue(); Glyph notdef = fontProgram.GetGlyphByCode(0); float width = 0; for (int i = 0; i < cids.Length; i++) { int code = cids[i++]; if (i < cids.Length) { code <<= 8; code |= cids[i]; } Glyph glyph = fontProgram.GetGlyphByCode(cmapEncoding.GetCidCode(code)); if (glyph == null) { System.Console.Error.WriteLine(code); } width += glyph != null?glyph.GetWidth() : notdef.GetWidth(); } return(width); }
private void FillFontDescriptor(PdfDictionary fontDesc) { if (fontDesc == null) { return; } PdfNumber v = fontDesc.GetAsNumber(PdfName.ItalicAngle); if (v != null) { SetItalicAngle(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.FontWeight); if (v != null) { SetFontWeight(v.IntValue()); } PdfName fontStretch = fontDesc.GetAsName(PdfName.FontStretch); if (fontStretch != null) { SetFontStretch(fontStretch.GetValue()); } PdfName fontName = fontDesc.GetAsName(PdfName.FontName); if (fontName != null) { SetFontName(fontName.GetValue()); } PdfString fontFamily = fontDesc.GetAsString(PdfName.FontFamily); if (fontFamily != null) { SetFontFamily(fontFamily.GetValue()); } }
/// <summary> /// Finds and sets the page numbers of links mapped to HTML headings in the specified PDF file. /// </summary> /// <param name="htmlToPdfFile">The HTML to PDF file.</param> internal static void SetHeadingPageNumbers(HtmlToPdfFile htmlToPdfFile) { using (PdfReader pdfReader = new PdfReader(htmlToPdfFile.PdfFilePath)) { using (iText.Kernel.Pdf.PdfDocument pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader)) { int pageCount = pdfDocument.GetNumberOfPages(); for (int i = 1; i <= pageCount; i++) { // get page PdfPage pdfPage = pdfDocument.GetPage(i); // get link annotations IEnumerable <PdfLinkAnnotation> linkAnnotations = pdfPage.GetAnnotations().OfType <PdfLinkAnnotation>(); foreach (PdfLinkAnnotation linkAnnotation in linkAnnotations) { // get action PdfDictionary action = linkAnnotation.GetAction(); if (action == null) { continue; } PdfName s = action.GetAsName(PdfName.S); if (s != PdfName.URI) { continue; } PdfString uriPdfString = action.GetAsString(PdfName.URI); if (!Uri.TryCreate(uriPdfString.GetValue(), UriKind.RelativeOrAbsolute, out Uri uri)) { continue; } if (!uri.IsFile) { continue; } // get query string NameValueCollection queryString = HttpUtility.ParseQueryString(uri.Query); // ex. ?headingLevel={level}&headingText string headingLevel = queryString["headingLevel"]; if (headingLevel == null) { continue; } if (!int.TryParse(headingLevel, out int level)) { continue; } string headingText = queryString["headingText"]; if (headingText == null) { continue; } HtmlHeading htmlHeading = htmlToPdfFile.TitleAndHeadings.SingleOrDefault(x => (x.Level == level) && (x.Text == headingText)); if (htmlHeading == null) { continue; } htmlHeading.Page = i; } } } } }
internal static void FillFontDescriptor(iText.Kernel.Font.DocTrueTypeFont font, PdfDictionary fontDesc) { if (fontDesc == null) { ILog logger = LogManager.GetLogger(typeof(FontUtil)); logger.Warn(iText.IO.LogMessageConstant.FONT_DICTIONARY_WITH_NO_FONT_DESCRIPTOR); return; } PdfNumber v = fontDesc.GetAsNumber(PdfName.Ascent); if (v != null) { font.SetTypoAscender(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.Descent); if (v != null) { font.SetTypoDescender(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.CapHeight); if (v != null) { font.SetCapHeight(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.XHeight); if (v != null) { font.SetXHeight(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.ItalicAngle); if (v != null) { font.SetItalicAngle(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.StemV); if (v != null) { font.SetStemV(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.StemH); if (v != null) { font.SetStemH(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.FontWeight); if (v != null) { font.SetFontWeight(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.MissingWidth); if (v != null) { font.missingWidth = v.IntValue(); } PdfName fontStretch = fontDesc.GetAsName(PdfName.FontStretch); if (fontStretch != null) { font.SetFontStretch(fontStretch.GetValue()); } PdfArray bboxValue = fontDesc.GetAsArray(PdfName.FontBBox); if (bboxValue != null) { int[] bbox = new int[4]; bbox[0] = bboxValue.GetAsNumber(0).IntValue(); //llx bbox[1] = bboxValue.GetAsNumber(1).IntValue(); //lly bbox[2] = bboxValue.GetAsNumber(2).IntValue(); //urx bbox[3] = bboxValue.GetAsNumber(3).IntValue(); //ury if (bbox[0] > bbox[2]) { int t = bbox[0]; bbox[0] = bbox[2]; bbox[2] = t; } if (bbox[1] > bbox[3]) { int t = bbox[1]; bbox[1] = bbox[3]; bbox[3] = t; } font.SetBbox(bbox); // If ascender or descender in font descriptor are zero, we still want to get more or less correct valuee for // text extraction, stamping etc. Thus we rely on font bbox in this case if (font.GetFontMetrics().GetTypoAscender() == 0 && font.GetFontMetrics().GetTypoDescender() == 0) { float maxAscent = Math.Max(bbox[3], font.GetFontMetrics().GetTypoAscender()); float minDescent = Math.Min(bbox[1], font.GetFontMetrics().GetTypoDescender()); font.SetTypoAscender((int)(maxAscent * 1000 / (maxAscent - minDescent))); font.SetTypoDescender((int)(minDescent * 1000 / (maxAscent - minDescent))); } } PdfString fontFamily = fontDesc.GetAsString(PdfName.FontFamily); if (fontFamily != null) { font.SetFontFamily(fontFamily.GetValue()); } PdfNumber flagsValue = fontDesc.GetAsNumber(PdfName.Flags); if (flagsValue != null) { int flags = flagsValue.IntValue(); if ((flags & 1) != 0) { font.SetFixedPitch(true); } if ((flags & 262144) != 0) { font.SetBold(true); } } PdfName[] fontFileNames = new PdfName[] { PdfName.FontFile, PdfName.FontFile2, PdfName.FontFile3 }; foreach (PdfName fontFile in fontFileNames) { if (fontDesc.ContainsKey(fontFile)) { font.fontFileName = fontFile; font.fontFile = fontDesc.GetAsStream(fontFile); break; } } }
/// <summary>Gets bytes of String-value without considering encoding.</summary> /// <param name="string"/> /// <returns>byte array</returns> protected internal virtual byte[] GetIsoBytes(PdfString @string) { return(ByteUtils.GetIsoBytes(@string.GetValue())); }
/// <summary> /// Updates the links. /// </summary> /// <param name="pdfFilePath">The PDF file path.</param> /// <param name="htmlToPdfFiles">The HTML to PDF files.</param> /// <param name="logger">The logger.</param> internal static void UpdateLinks( string pdfFilePath, IReadOnlyCollection <HtmlToPdfFile> htmlToPdfFiles, ILogger logger) { string tempFilePath = Path.GetTempFileName(); using (PdfReader pdfReader = new PdfReader(pdfFilePath)) { using (PdfWriter pdfWriter = new PdfWriter(tempFilePath)) { using (iText.Kernel.Pdf.PdfDocument pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader, pdfWriter)) { int pageCount = pdfDocument.GetNumberOfPages(); for (int i = 1; i <= pageCount; i++) { // get page PdfPage pdfPage = pdfDocument.GetPage(i); // get link annotations IEnumerable <PdfLinkAnnotation> linkAnnotations = pdfPage.GetAnnotations().OfType <PdfLinkAnnotation>(); foreach (PdfLinkAnnotation linkAnnotation in linkAnnotations) { // get action PdfDictionary action = linkAnnotation.GetAction(); if (action == null) { continue; } PdfName s = action.GetAsName(PdfName.S); if (s != PdfName.URI) { continue; } PdfString uriPdfString = action.GetAsString(PdfName.URI); if (!Uri.TryCreate(uriPdfString.GetValue(), UriKind.RelativeOrAbsolute, out Uri uri)) { continue; } if (!uri.IsFile) { continue; } string htmlFilePath = uri.LocalPath.ToLower(); if (!htmlToPdfFiles.Any(x => string.Compare(x.Input, htmlFilePath, StringComparison.OrdinalIgnoreCase) == 0)) { // ex. when printing PDF from TOC.html by itself logger.LogDebug($"Could not find '{htmlFilePath}'. Referenced in '{pdfFilePath}' on page {i}."); continue; } HtmlToPdfFile linkedHtmlToPdfFile = htmlToPdfFiles.Single(x => x.Input == htmlFilePath); int linkedPageNumber = linkedHtmlToPdfFile.OutputPdfFilePageNumber; PdfPage linkedPage; try { // http://api.itextpdf.com/itext/com/itextpdf/text/pdf/PdfDestination.html linkedPage = pdfDocument.GetPage(linkedPageNumber); } catch (Exception ex) { throw new PdfPageNotFoundException(linkedPageNumber, linkedHtmlToPdfFile.Input, ex); } float top = linkedPage.GetPageSize().GetTop(); PdfExplicitDestination destination = PdfExplicitDestination.CreateFitH(linkedPage, top); PdfAction newAction = PdfAction.CreateGoTo(destination); linkAnnotation.SetAction(newAction); } } } } } File.Delete(pdfFilePath); File.Move(tempFilePath, pdfFilePath); }
/// <summary>Provides detail useful if a listener needs access to the position of each individual glyph in the text render operation /// </summary> /// <returns> /// A list of /// <see cref="TextRenderInfo"/> /// objects that represent each glyph used in the draw operation. The next effect is if there was a separate Tj opertion for each character in the rendered string /// </returns> public virtual IList <iText.Kernel.Pdf.Canvas.Parser.Data.TextRenderInfo> GetCharacterRenderInfos() { CheckGraphicsState(); IList <iText.Kernel.Pdf.Canvas.Parser.Data.TextRenderInfo> rslt = new List <iText.Kernel.Pdf.Canvas.Parser.Data.TextRenderInfo >(@string.GetValue().Length); PdfString[] strings = SplitString(@string); float totalWidth = 0; foreach (PdfString str in strings) { float[] widthAndWordSpacing = GetWidthAndWordSpacing(str); iText.Kernel.Pdf.Canvas.Parser.Data.TextRenderInfo subInfo = new iText.Kernel.Pdf.Canvas.Parser.Data.TextRenderInfo (this, str, totalWidth); rslt.Add(subInfo); totalWidth += (widthAndWordSpacing[0] * gs.GetFontSize() + gs.GetCharSpacing() + widthAndWordSpacing[1]) * (gs.GetHorizontalScaling() / 100f); } foreach (iText.Kernel.Pdf.Canvas.Parser.Data.TextRenderInfo tri in rslt) { tri.GetUnscaledWidth(); } return(rslt); }
/// <summary>Verifies a signature.</summary> /// <remarks> /// Verifies a signature. Further verification can be done on the returned /// <see cref="PdfPKCS7"/> /// object. /// </remarks> /// <param name="name">the signature field name</param> /// <param name="provider">the provider or null for the default provider</param> /// <returns>PdfPKCS7 object to continue the verification</returns> public virtual PdfPKCS7 VerifySignature(String name) { PdfDictionary v = GetSignatureDictionary(name); if (v == null) { return(null); } try { PdfName sub = v.GetAsName(PdfName.SubFilter); PdfString contents = v.GetAsString(PdfName.Contents); PdfPKCS7 pk = null; if (sub.Equals(PdfName.Adbe_x509_rsa_sha1)) { PdfString cert = v.GetAsString(PdfName.Cert); if (cert == null) { cert = v.GetAsArray(PdfName.Cert).GetAsString(0); } pk = new PdfPKCS7(PdfEncodings.ConvertToBytes(contents.GetValue(), null), cert.GetValueBytes()); } else { pk = new PdfPKCS7(PdfEncodings.ConvertToBytes(contents.GetValue(), null), sub); } UpdateByteRange(pk, v); PdfString str = v.GetAsString(PdfName.M); if (str != null) { pk.SetSignDate(PdfDate.Decode(str.ToString())); } PdfObject obj = v.Get(PdfName.Name); if (obj != null) { if (obj.IsString()) { pk.SetSignName(((PdfString)obj).ToUnicodeString()); } else { if (obj.IsName()) { pk.SetSignName(((PdfName)obj).GetValue()); } } } str = v.GetAsString(PdfName.Reason); if (str != null) { pk.SetReason(str.ToUnicodeString()); } str = v.GetAsString(PdfName.Location); if (str != null) { pk.SetLocation(str.ToUnicodeString()); } return(pk); } catch (Exception e) { throw new PdfException(e); } }