How to access broken digital signatures

Hi Team,
Our inputs are signed PDF files and part of them have broken signatures.
They are not visible in FieldIterator, but we still have to recognize them and extract some required info.
For example I have a file containing the following objects:

6 0 obj
<</AP<</N 7 0 R >>/DR<</XObject<</FRM 8 0 R >>>>/F 132/FT/Sig/P 4 0 R
/Rect[ 80 410 130 440]/Subtype/Widget/T(Signature1)/Type/Annot/V 15 0 R >>
endobj

15 0 obj
<</ByteRange[ 0 623109 623631 7815]/Cert[(0‚aÏ……=dËìm)]
/Contents<04820100……D14C7F24>
/Filter/Adobe.PPKLite/M(D:20220203065054Z)
/Name(DS_XXXX_DEP)/R 65541/SubFilter/adbe.x509.rsa_sha1/Type/Sig>>
endobj

But FieldIterator and SignatureIterator are empty.
The only way I can access the object is SDF::GetObj()
This way I get SDF::Obj only.
Is there any way to “cast/map/import” it, i.e. to get it as DigitalSignatureField and reuse PDFTron parsing capabilities?
As I understand DigitalSignatureFieldIterator ignores invalid or broken signature Fields.
Is it possible not to ignore them somehow?
Thanks
Vadim

Thank you for contacting us about this. If you are looking to extract information from the actual digital signature fields, you can do that by traversing through the page annotations. Please see the sample code here on how to do that.

Just to get more information about your use case, what sort of information are you looking to extract from these broken signatures?

Hi Shakhti,
Thanks for the fast reply.
I think I’ve already tried these standard ways :frowning:
Specifically, page.GetNumAnnots() == 0 for the given document.
May be I wasn’t clear enough when described the issue.
I need the certificate details contained in /Cert Value (decode/parse)
I hope this functionality can be accessed via SDF::Obj interface.
Thanks
Vadim

Hello,

Thank you for the clarification. If you know the object number, you can pass the SDF::Obj to the constructor API.

However, note that since the signature appears to be broken on your PDF, some methods may throw exceptions

Please let me know if this works for you.

Hello Shakthi,
Thank you, it works. I can call Verify() and get response.
BUT…
Unfortunately, the response is:
“No installed SignatureHandler was able to recognize the signature’s encoding.” :frowning:
I’ve tried OpenSSL Handler, according to instructions inside the DigSig Test project, but got errors on deprecated functions (ssl 3.0). It seems not a big deal, but before that, could you please advise, what is a right way to move in your opinion?
What standard signature handlers exist and how can we access them?
Unfortunately, I can’t send the document, but here is a digest object. Can it help?
Thanks for your help

15 0 obj
<</ByteRange[ 0 623109 623631 7815]/Cert[(0‚aÏ0‚· S”±å0\r *†H†÷\r 0ü10 UIN1A0?U\n8Gujarat Narmada Valley Fertilizers and Chemicals Limited10eUCertifying Authority10\rU38005410UaGujarat1&0$U Bodakdev, S G Road, Ahmedabad10U3301, GNFC Infotower1"0 U(n)Code Solutions CA 20140\r190315084441Z\r210228173436Z0é10 UIN110/U\n(UNIQUE IDENTIFICATION AUTHORITY OF INDIA10\rU11000110UDelhi1’0%U BEHIND KALI MANDIR GOLE MARKET1$0"U3e6th FLOOR BANGLA SAHIB ROAD1705U.DS UNIQUE IDENTIFICATION AUTHORITY OF INDIA 040‚"0\r †H†÷\r ‚ 0‚\n‚ ›v£ÍÎBä?Ý‚žfp0Tm\na»§¹†\u·léë+=¤åeÍTËuV|‹E´ž=îù{ezÝ PÚ¿Í­{ Dü£…\M9râDpæíU0ƒ×·åzxì ͲŽ‡ÌxFÔR}Ì¥XÃû{\neýºu3†X0Dý¶p­ó‘™˜åñ’³v»4ƒïjq}é°‹¿p)e|+Sb(dý:øw\n¸ž{ÑøºgÅ»z–Ëüãß÷gŠS,·õm4)—¸qF¢|!,!âÞÚ3$«¥Wúç ZñÓ¶6õò•drW¸ú­ƒD…A”Ž›‰ÈüL–ß29ß6Y £‚h0‚d0UÿÀ0U%#0!+a\n+‚7\n *†H†÷/0‚U ú0÷0†‚dd0|0z+a0nlClass 2 certificates are used for form signing, form authentication and signing other low risk transactions.0l‚dd\n0b0+a0TRThis certificate provides higher level of assurance for document signing function.0Uÿ0 0$U0eajai.chandra@uidai.net.in0‚nU‚e0‚a0‚ ‚ ‚¤‚0‚10 UIN1A0?U\n8Gujarat Narmada Valley Fertilizers and Chemicals Limited10eUCertifying Authority10\rU38005410UaGujarat1&0$U Bodakdev, S G Road, Ahmedabad10U3301, GNFC Infotower1"0 U\(n\)Code Solutions CA 201410UaCRL55080= ; 9†7https://www.ncodesolutions.com/repository/ncodeca14.crl0+U$0"€20190315084441Z20210228173436Z0U#0\n€Ma¾ñžû½0U=S/é ‘ŽÃ\r^‚hO+=/vt00 *†H†ö}aA 0\neV8.1\(0\r *†H†÷\r ‚ ûðu™àwUÄȨ\rckZ¹Ö‹oCLèDiÁL»ŠT Å?Œ’l6ú}w$}zÌÙéÆ®©‘†@eï÷{á¯Õ†º:™ÿj2ñ38üXBNJ¨IGß½»» ]Q»ÅÝsì—ãZ4_…­az©\r\)&”L$~.Ðt÷4W>‘ŽÔ"ØÂDÆæuò}\n’¿Ð~¼MÊ}L‰½8à÷ï!r3OŽìµ%ÂNqæ6ÕÜÆÉz;Óˆž‡w“Ê…£S%@§ ^ŽU¼qþžµéû—mbÑMò~)&ã]îœaïR„àŽ+>sK50[ç™#8Þ ômýŠh)(0‚0‚w ’®0\r *†H†÷\r 0:10 UIN10U\n India PKI10UCCA India 20140\r140305104008Z\r240305063000Z0ü10 UIN1A0?U\n8Gujarat Narmada Valley Fertilizers and Chemicals Limited10eUCertifying Authority10\rU38005410UaGujarat1&0$U Bodakdev, S G Road, Ahmedabad10U3301, GNFC Infotower1"0 U(n)Code Solutions CA 20140‚"0\r †H†÷\r ‚ 0‚\n‚ ¥ð&©lhÔ7]z¢Sø×H›ÁäV£›¾Ž‹rú?ûýN†¾Ý¿kT‹Ü£V(îðú­+éQÙ÷4HSNè’—™-棴¶çb3GÎR™ŠÇ§rÜWŒÇ!t SΨ'¾Ê$yÒí›üHѵ±ñÕeÐ_D»Qï…ÛË’9é=%ÜFϬxúž›ÕtÚcn²¾b´k;ù3 [eæOÿÜÒx‘ñà}KŽú¹ùè¿+#ØœQyc2;\r‹Ç#ü@L–'Šlô=i 6\r‡(Üæ脤mDßy殁ŒÆ°¦©Ž0L[¹ó¸4öîÝ!ÌЮÃÛ £Û0Ø0Uÿ0ÿ 0U\nMa¾ñžû½0U 0 0a`‚dd0U#0\n€B¸ÅÏm³Wá0.+a"0 0+a0†http://ocvs.gov.in0Uÿ0FU?0=0; 9 7†5http://cca.gov.in/rw/resources/CCAIndia2014Latest.crl0\r †H†÷\r ‚ ô·woEuÉp°Z~¯¦OC¯<™%NQ›;µ»'˜D3Ü3$’܃Dºfý—z•­ÚREŒo·¡p³Ò6¿ž×•G÷ô72·ûüG ¶ÂÙZ{ËÆá O÷Gþ£…\r´HJÏh/€^f=µ|Æ°¢QIãó/’öcr·¬UR•,¾Ì<þoèqûµFÑ’œFW>÷ñJ@9Q‘Øžñµ Y¡ÅûŒú)eL7Z‘èY±ÇB§&ÇtB·*nªô\rmxµòë¯æîôÍc“šâ`—l5‰¡=²phYyͱ2>9_6u[uW# £åxÜõˆ©]{0ñÆ´q\r)(0‚#0‚ ’­0\r *†H†÷\r 0:10 UIN10U\n India PKI10UCCA India 20140\r140305101049Z\r240305101049Z0:10 UIN10U\n India PKI10UCCA India 20140‚"0\r †H†÷\r ‚ 0‚\n‚ ÞÈP½Šÿ"\r®¬‚YÚô) Ôkl–¾Ì¥°!w¾­@/do»xû³î€ Äš¾FP2qUSa2§ÿÚ–ž¬Å %MGP"0»î)šâƒ„Yû·Ý9Øl°B>0zLzä-^[Õb-^áŽA!)÷Þº‡7a æ’CÒ˜\r¦Ï¤\nmE˜Rî©Ñ\n¹"}"‘Ú‘õ옅l®#±¦þ—4jÖ’§[+»zí,&‹KD“üßÄ,1Q°ƒ%‚Š„Ó!I KÔ,ÚÀ¤ôñ+¦z‚íRþ±´² §‰ö~zÛPÎLÓ‡2¸ E–oh¹V…hÕ‘d@]Ù)ø‰Û•Gçï £3010Uÿ0ÿ0U\nB¸ÅÏm³Wá0U0\r †H†÷\r ‚ HïÒlŠÊßYâ!še®Y,9bë%˃€a>3‰Bñ°b¸&=, ‘‚Ò^_ƒÕ%S‘ú¿=\rkÅü ÝÜV#í:w½ÄHDÄXµ`ûA—¹úHiõ¥zˆ†,ðP0¾…\rIÍoB`0…€`¶ù¬3µuWˆ[÷5¹kSލǥðÓ ›ß›™Ù1ÝÅ·]áËwÍ¥3°éÁ´ÆòehRðª#Ø¡_IA—øÏÃKTÆÙ›£À¢—\nâªïî»›E…ë:! r[ª9&)}øÎK…ž…Ú]Ê=6C¢Ño,(ªGiJ2Ìì½n7¾ÏAhçë<=dËìm)]/Contents<04820100240396EE3F6EBD4C5BD617438ADD2884723486485BB686BD7902587BF1AC4ECA150BDCB24352535290D67A9E2CF700641AF984AAE39B4AC1C5D929D8D5D44B158D413A14B9C0B7495043F6B95F0EDE9B68EAE3360EC7D8FB76C494AC15B2A9691CCA1ED5955DA1FBA96B444CEC8B7F06A9447625180A3D684DC7A79133E3BC85DBEAD1ABF1FA951B9CCBD041CC74B54AFF41DF1727D2D9368AC9BD7FBF3B886058BEC992A8EE24A6BD0648E1C32681CDF0A616C3D01846EAC7AAE5B7B116202A6E5DABF900FE26E0B696D907B4237500A2D27C4F289EB6AEB224ECF94D10FB2AD9F304A5A77C9C6AD0B290254041A276C9A74BD5CE54719B9EF4C2C9D14C7F24>/Filter/Adobe.PPKLite/M(D:20220203065054Z)/Name(DS UNIQUE IDENTIFICATION AUTHORITY OF INDIA 04)/R 65541/SubFilter/adbe.x509.rsa_sha1/Type/Sig>>
endobj

It appears that the subfilter for this signature the following:

At this time, we do not support this subfilter for verification. However, you also mentioned previously that these signatures were broken. Unfortunately, it is still unclear what you are looking to do. Just to get more information on this issue, what is your end goal?

Thank you in advance for the additional information.

Yes. These 2 are just separate problems.
This document (Type) is one of our input types [unfortunately - unsupported].
The same document (instance) has broken signature.

Ok. This input is mandatory for us.
Could you please advise how can we solve this issue? Does it require a serious development?
Is there any sample and/or guidelines?
As I see, Adobe can parse this information
BTW. I’ve detected that Verification Result received through SDF::Obj doesn’t contain Certificate path info, while the same one got from iterator works fine. Where is my fault?
Thank you for your efforts

just FYI:
SDFDoc& cos_doc = _doc->GetSDFDoc();
SDF::Obj trai = cos_doc.GetTrailer();
int num_objs = cos_doc.XRefSize();
for (int i = 1; i < num_objs; ++i) {
Obj obj = cos_doc.GetObj(i);
Field fld(obj);
bool ok = fld.IsAnnot() && fld.IsValid();
if (ok && kvalFoundDic(obj, “Type”, “Annot”) && kvalFoundDic(obj, “Subtype”, “Widget”)) {
DigitalSignatureField dsFld(fld);
UString dsnam = dsFld.GetSignatureName(); ss = dsnam.ConvertToUtf8();
VerificationOptions opts(VerificationOptions::e_compatibility_and_archiving);
VerificationResult res = dsFld.Verify(opts);
UString sdig = res.GetDigestStatusAsString();
const TrustVerificationResult trustRes = res.GetTrustVerificationResult();
}
}