Ë
    3¶Íjl  ã                   óx   — d Z ddlZddlZddlZddlZddlZddlZd
d„Zd„ Zd„ Z	d„ Z
d„ Zd„ Zed	k(  r e«        yy)u{  
PDF æ•¸ä½�ç°½ç«  / å¢žé‡�è“‹ç«  â€” ä½¿ç”¨ pyHankoï¼Œä»¥å¢žé‡�æ›´æ–°æ–¹å¼�è™•ç�†ï¼Œä¿�ç•™æ—¢æœ‰ç°½ç« ã€‚

ç”¨æ³•ï¼š
  pdftool_sign.py --ops ops.json --in in.pdf --out out.pdf --cert cert.pem --key key.pem
      ops.json = [ {"op":"stamp","page":1,"box":[x1,y1,x2,y2],"image":"a.png"},
                   {"op":"sign","field":"Sig1","reason":"...","location":"...","contact":"...",
                    "page":1,"box":[x1,y1,x2,y2],"image":"sig.png","text":""} ]
      ï¼ˆbox ç‚º PDF ä½¿ç”¨è€…åº§æ¨™ï¼Œå·¦ä¸‹åŽŸé»žï¼›çœ�ç•¥ page/box çš„ sign ç‚ºä¸�å�¯è¦‹ç°½ç« ï¼‰
  pdftool_sign.py --verify in.pdf   -> JSON åˆ—å‡ºç°½ç« èˆ‡é©—è­‰çµ�æžœ
é    Nc                 óØ   — ddl m} ddlm} ddlm}m}m} |j                  |xs d|j                  | «      dd ||j                  |j                  |j                  d«      ¬«      ¬«      S )	Nr   ©Ústamp)Úimages)ÚSimpleBoxLayoutRuleÚAxisAlignmentÚMarginsÚ g      ð?)Úx_alignÚy_alignÚmargins)Ú
stamp_textÚ
backgroundÚbackground_opacityÚborder_widthÚbackground_layout)Úpyhankor   Úpyhanko.pdf_utilsr   Úpyhanko.pdf_utils.layoutr   r   r	   ÚTextStampStyleÚPdfImageÚ	ALIGN_MIDÚuniform)ÚimageÚtextr   r   r   r   r	   s          úbin/pdftool_sign.pyÚ_image_styler      se   € ÝÝ(ßTÑTà×ÑØ’:˜2Ø—?‘? 5Ó)ØØÙ-Ø!×+Ñ+Ø!×+Ñ+Ø—O‘O AÓ&ô
ð  ó 
ð 
ó    c                 ó  — ddl m} ddlm} ddlm} t        | d«      5 } ||«      }|D ]‹  }|d   D �	cg c]  }	t        |	«      ‘Œ c}	\  }
}}}t        |d   |j                  dd	«      «      } ||| |||
z
  ||z
  ¬
«      ¬«      }|j                  t        |j                  dd«      «      dz
  |
|¬«       Œ� t        |d«      5 }|j                  |«       d d d «       d d d «       y c c}	w # 1 sw Y   ŒxY w# 1 sw Y   y xY w)Nr   ©ÚIncrementalPdfFileWriter)ÚBoxConstraints)Ú	TextStampÚrbÚboxr   r   r
   )ÚwidthÚheight)ÚwriterÚstyler%   Úpageé   )Ú	dest_pageÚxÚyÚwb)Ú$pyhanko.pdf_utils.incremental_writerr!   r   r"   Úpyhanko.stampr#   ÚopenÚfloatr   ÚgetÚapplyÚintÚwrite)ÚsrcÚdstÚstampsr!   r"   r#   ÚinfÚwÚsÚvÚx1Úy1Úx2Úy2r)   ÚstÚoutfs                    r   Úapply_stampsrE   '   s   € ÝMÝ7Ý'ä	ˆc�4‹ð ˜CÙ$ SÓ)ˆØò 	FˆAØ01°%±Ö9¨1œe A�hÒ9‰NˆB��B˜Ü   7¡¨Q¯U©U°6¸2Ó->Ó?ˆEÙ !¨5±nÈ2ÐPRÉ7Ð[]Ð`bÑ[bÔ6cÔdˆBØ�H‰Hœs 1§5¡5¨°Ó#3Ó4°qÑ8¸BÀ"ˆHÕEð		Fô
 �#�t‹_ð 	 Ø�G‰G�DŒM÷	÷ð ùò :÷	ð 	ú÷ð ús5   ŸC8´C'ÁA>C8ÃC,ÃC8Ã'C8Ã,C5	Ã1C8Ã8Dc                 ó�  — ddl m}m} ddlm} ddlm} ddlm} t        | d«      5 }	 ||	«      }
|j                  |j                  d«      xs d|j                  d	«      xs d |j                  d
«      xs d |j                  d«      xs d d¬«      }d }|j                  d«      rÁ|j                  d«      r°|d   D �cg c]  }t        |«      ‘Œ c}\  }}}}|j                  |
 ||j                  t        |d   «      dz
  ||||f¬«      «       |j                  d«      r t!        |d   |j                  dd«      «      }n&|j#                  |j                  d«      xs dd¬«      }|j%                  |||¬«      }t        |d«      5 }|j'                  |
|¬«       d d d «       d d d «       y c c}w # 1 sw Y   ŒxY w# 1 sw Y   y xY w)Nr   )ÚsignersÚfields)ÚSigFieldSpecr    r   r$   ÚfieldÚ
Signature1ÚreasonÚlocationÚcontactÚsha256)Ú
field_namerL   rM   Úcontact_infoÚmd_algorithmr*   r%   r+   )Úsig_field_nameÚon_pager%   r   r   r
   z%(signer)s
%(ts)s)r   r   )ÚsignerÚstamp_styler/   )Úoutput)Úpyhanko.signrG   rH   Úpyhanko.sign.fieldsrI   r0   r!   r   r   r2   ÚPdfSignatureMetadatar4   r3   Úappend_signature_fieldrP   r6   r   r   Ú	PdfSignerÚsign_pdf)r8   r9   ÚoprU   rG   rH   rI   r!   r   r;   r<   ÚmetarV   r>   r?   r@   rA   rB   Ú
pdf_signerrD   s                       r   Ú
apply_signra   7   sª  € ß,Ý0ÝMÝä	ˆc�4‹ð 0˜CÙ$ SÓ)ˆØ×+Ñ+Ø—v‘v˜g“Ò6¨,Ø—6‘6˜(Ó#Ò+ tØ—V‘V˜JÓ'Ò/¨4ØŸ™ 	Ó*Ò2¨dØ!ð ,ó 
ˆð ˆØ�6‰6�&Œ>˜bŸf™f UœmØ02°5±	Ö:¨1œe A�hÒ:‰NˆB��B˜Ø×)Ñ)Ø‘<¨t¯©ÌÈBÈvÉJËÐZ[ÑH[ÐbdÐfhÐjlÐnpÐaqÔrôð �v‰v�gŒÜ*¨2¨g©;¸¿¹¸vÀrÓ8JÓK‘à#×2Ñ2¸b¿f¹fÀV»nÒ>dÐPdÐstÐ2Óu�Ø×&Ñ& t°FÈÐ&ÓTˆ
Ü�#�t‹_ð 	0 Ø×Ñ ¨$ÐÔ/÷	0÷)0ð 0ùò ;÷	0ð 	0ú÷)0ð 0ús7   §BF<Â=F+ÃB7F<ÆF0ÆF<Æ+F<Æ0F9	Æ5F<Æ<Gc                 ó‚  ‡	‡
‡‡— ddl m} t        | j                  dd¬«      5 }t	        j
                  |«      }d d d «       t        t        «      r|st        d«      ‚d }t        d„ |D «       «      r?|j                  j                  | j                  | j                  d ¬«      }|€t        d	«      ‚t        j                  d
¬«      Š	 t        j                   j#                  ‰d«      Š	t%        j&                  | j(                  ‰	«       dŠg Š
g }ˆ	ˆ
ˆˆfd„}|D ]�  }|j+                  d«      dk(  r‰
j-                  |«       Œ)|j+                  d«      dk(  sŒ> |«        ‰dz  Št        j                   j#                  ‰d‰› d�«      }t/        ‰	|||«       |Š	|j-                  |j+                  d«      «       ŒŸ  |«        t%        j&                  ‰	| j0                  «       t%        j2                  ‰d¬«       t5        t	        j6                  d|dœ«      «       y # 1 sw Y   �ŒáxY w# t%        j2                  ‰d¬«       w xY w)Nr   )rG   Úrzutf-8)Úencodingu
   ops ç‚ºç©ºc              3   óD   K  — | ]  }|j                  d «      dk(  –— Œ y­w)r^   ÚsignN)r4   )Ú.0Úos     r   ú	<genexpr>zdo_ops.<locals>.<genexpr>^   s   è ø€ Ò
. Qˆ1�5‰5�‹;˜&Õ Ñ
.ùs   ‚ )Úkey_passphraseu!   ç„¡æ³•è¼‰å…¥ç°½ç« æ†‘è­‰æˆ–ç§�é‘°Úpdfsign_)Úprefixz	step0.pdfc                  óœ   •— ‰sy ‰dz  Št         j                  j                  ‰d‰› d�«      } t        ‰| ‰«       | Š‰j	                  «        y )Nr+   Ústepú.pdf)ÚosÚpathÚjoinrE   Úclear)ÚnxtÚcurÚpending_stampsrn   Útmpdirs    €€€€r   Úflush_stampszdo_ops.<locals>.flush_stampsk   sL   ø€ á!ØØ�A‰IˆDÜ—'‘'—,‘,˜v¨¨d¨V°4Ð'8Ó9ˆCÜ˜˜c >Ô2ØˆCØ× Ñ Õ"r   r^   r   rf   r+   rn   ro   rJ   T)Úignore_errors)ÚokÚsigned_fields)rX   rG   r2   ÚopsÚjsonÚloadÚ
isinstanceÚlistÚ
SystemExitÚanyÚSimpleSignerÚkeyÚcertÚtempfileÚmkdtemprp   rq   rr   ÚshutilÚcopyfileÚinpr4   Úappendra   ÚoutÚrmtreeÚprintÚdumps)ÚargsrG   Úfr|   rU   Údonerx   rh   rt   ru   rv   rn   rw   s            @@@@r   Údo_opsr“   U   sÍ  û€ Ý$ä	ˆd�h‰h˜ gÔ	.ð °!Ü�i‰i˜‹lˆ÷ä�cœ4Ô ©Ü˜Ó&Ð&à€FÜ
Ñ
.¨#Ô
.Ô.Ø×%Ñ%×*Ñ*¨4¯8©8°T·Y±YÈtÐ*ÓTˆØˆ>ÜÐ@ÓAÐAä×Ñ ZÔ0€Fð2Ü�g‰g�l‰l˜6 ;Ó/ˆÜ�‰˜Ÿ™ #Ô&ØˆØˆØˆ÷	#ð ò 
	,ˆAØ�u‰u�T‹{˜gÒ%Ø×%Ñ% aÔ(ØØ�u‰u�T‹{˜fÓ$Ù”Ø˜‘	�Ü—g‘g—l‘l 6¨T°$°°tÐ+<Ó=�Ü˜3  Q¨Ô/Ø�Ø—‘˜AŸE™E '›NÕ+ð
	,ñ 	ŒÜ�‰˜˜TŸX™XÔ&ä�‰�f¨DÕ1Ü	Œ$�*‰*˜D°4Ñ8Ó
9Õ:÷Yñ ûôV 	�‰�f¨DÖ1ús   £HÃBH% ÅB	H% ÈH"È%H>c                 óH  — ddl m} ddlm} ddlm} g }t        | d«      5 } ||«      }|j                  D �]g  }|j                  d d d d d d d d dœ	}	 |j                  }	|	�|	j                  j                  nd |d<   	 |j                  }
|
j                  d«      rt        |
j                  d«      «      nd |d	<   |
j                  d
«      rt        |
j                  d
«      «      nd |d<   	  |d¬«      } |||«      }t!        |j"                  «      |d<   t!        |j$                  «      |d<   t!        |j&                  «      |d<   |j(                  �'t        |j(                  «      j+                  d«      d   nd |d<   |j-                  «       |d<   |j/                  |«       �Œj 	 d d d «       t1        t3        j4                  d|dœd¬«      «       y # t        $ r Y �Œ`w xY w# t        $ r Y �Œw xY w# t        $ r}dt        |«      d d z   |d<   Y d }~Œƒd }~ww xY w# 1 sw Y   ŒwxY w)Nr   )ÚPdfFileReader)Úvalidate_pdf_signature)ÚValidationContextr$   )	rJ   rU   Ú	signed_atrL   ÚintactÚvalidÚtrustedÚcoverageÚsummaryrU   z/ReasonrL   z/Mr˜   F)Úallow_fetchingr™   rš   r›   ú.éÿÿÿÿrœ   r�   zUNVERIFIED: éÈ   T)rz   Ú
signatures©Úensure_ascii)Úpyhanko.pdf_utils.readerr•   Úpyhanko.sign.validationr–   Úpyhanko_certvalidatorr—   r2   Úembedded_signaturesrP   Úsigner_certÚsubjectÚhuman_friendlyÚ	ExceptionÚ
sig_objectr4   ÚstrÚboolr™   rš   r›   rœ   Úsplitr�   r‹   rŽ   r}   r�   )rq   r•   r–   r—   Úresultr‘   rc   ÚsigÚitemr…   ÚobjÚvcÚstatusÚes                 r   Ú	do_verifyr¸   ‡   sý  € Ý6Ý>Ý7à€FÜ	ˆd�DÓ	ð  ˜QÙ˜!ÓˆØ×(Ñ(ó 	 ˆCØ Ÿ^™^°tÈ$ÐZ^Ø"¨T¸dÐPTÐaeñgˆDðØ—‘�Ø@DÐ@P §¡×!<Ò!<ÐVZ��X‘ðØ—n‘n�Ø<?¿G¹GÀIÔ<N¤ S§W¡W¨YÓ%7Ô!8ÐTX��X‘Ø:=¿'¹'À$¼-¤C¨¯©°«Ô$6ÈT��[Ñ!ð	@Ù&°eÔ<�Ù/°°RÓ8�Ü!% f§m¡mÓ!4��X‘Ü $ V§\¡\Ó 2��W‘Ü"& v§~¡~Ó"6��Y‘ØJPÏ/É/ÐJe¤3 v§¡Ó#7×#=Ñ#=¸cÓ#BÀ2Ò#FÐko��ZÑ Ø"(§.¡.Ó"2��Y‘ð �M‰M˜$Öñ1	 ÷ ô6 
Œ$�*‰*˜D°Ñ7ÀeÔ
LÕMøô' ò Úðûô ò Úðûô ò @Ø"0´3°q³6¸$¸3°<Ñ"?��Y–ûð@ú÷1 ð  úss   ¡/HÁ)GÁ;A,GÃ(B%G.ÆHÇ	GÇHÇGÇHÇ	G+Ç'HÇ*G+Ç+HÇ.	HÇ7HÈHÈHÈHÈH!c            	      óž  — t        j                  «       } | j                  dd¬«       | j                  dd¬«       | j                  dd¬«       | j                  d	«       | j                  d
«       | j                  d«       | j                  «       }	 |j                  rt        |j                  «       y |j                  r|j                  r|j                  st        d«      ‚t        |«       y # t        $ r ‚ t        $ rK}t        t        j                  dt        |«      dœd¬«      «       t!        j"                  d«       Y d }~y d }~ww xY w)Nz--verifyu   å�ªé©—è­‰æ­¤ PDF çš„ç°½ç« )Úhelpz--opsu   æ“�ä½œæ¸…å–® JSON æª”z--inrŠ   )Údestz--outz--certz--keyu   ç¼ºå°‘å¿…è¦�å�ƒæ•¸F)rz   Úerrorr£   é   )ÚargparseÚArgumentParserÚadd_argumentÚ
parse_argsÚverifyr¸   r|   rŠ   rŒ   r�   r“   r¬   rŽ   r}   r�   r®   ÚsysÚexit)Úapr�   r·   s      r   ÚmainrÆ   «   só   € Ü	×	 Ñ	 Ó	"€BØ‡O�O�JÐ%A€OÔBØ‡O�O�GÐ"9€OÔ:Ø‡O�O�F €OÔ'Ø‡O�O�GÔØ‡O�O�HÔØ‡O�O�GÔØ�=‰=‹?€DðØ�;Š;Ü�d—k‘kÕ"à—H’H §¢¨d¯hªhÜ Ð!5Ó6Ð6Ü�4�LøÜò ØÜò ÜŒd�j‰j ´°A³Ñ7ÀeÔLÔMÜ�‰��‰ûðús   Â!C/ Â4:C/ Ã/EÄAEÅEÚ__main__)r
   )Ú__doc__r¾   r}   rp   rˆ   rÃ   r†   r   rE   ra   r“   r¸   rÆ   Ú__name__© r   r   ú<module>rË      sS   ðñ
ó Û Û 	Û Û 
Û óò$ò 0ò</;òd!NòHð. ˆzÒÙ…Fð r   