matthiasvalvekens / pyhanko Goto Github PK
View Code? Open in Web Editor NEWpyHanko: sign and stamp PDF files
License: MIT License
pyHanko: sign and stamp PDF files
License: MIT License
Hi:
I am trying to use pyhanko to perform a Pades-LTV signature using the spanish eID card. First I was trying with the CLI:
pyhanko sign addsig pkcs11 --lib /usr/lib64/pkcs11/opensc-pkcs11.so --token-label 'DNI electrónico (PIN1)' --cert-label CertFirmaDigital lorem_field.pdf lorem-f.pdf and get the following error, which I suppose is related to not being able to get the right certificate from the card:
Traceback (most recent call last):
File "/usr/local/lib64/python3.8/site-packages/pyhanko/cli.py", line 63, in pyhanko_exception_manager
yield
File "/usr/local/lib64/python3.8/site-packages/pyhanko/cli.py", line 829, in addsig_pkcs11
generic_sign(
File "/usr/local/lib64/python3.8/site-packages/pyhanko/cli.py", line 689, in generic_sign
result = signers.PdfSigner(
File "/usr/local/lib64/python3.8/site-packages/pyhanko/sign/signers.py", line 2277, in sign_pdf
test_signature_cms = signer.sign(
File "/usr/local/lib64/python3.8/site-packages/pyhanko/sign/signers.py", line 710, in sign
signed_attrs = self.signed_attrs(
File "/usr/local/lib64/python3.8/site-packages/pyhanko/sign/signers.py", line 533, in signed_attrs
general.as_signing_certificate(self.signing_cert)
File "/usr/local/lib64/python3.8/site-packages/pyhanko/sign/pkcs11.py", line 159, in signing_cert
self._load_objects()
File "/usr/local/lib64/python3.8/site-packages/pyhanko/sign/pkcs11.py", line 268, in _load_objects
kh, = list(q)
ValueError: not enough values to unpack (expected 1, got 0)
Error: Generic processing error.
Then, I tried to do it using a python code which it is as follows:
`import os
from io import BytesIO
import pytest
import logging
from freezegun import freeze_time
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.pdf_utils.reader import PdfFileReader
from pyhanko.sign import signers, pkcs11
#from pyhanko_tests.test_signing import val_trusted, SIMPLE_ECC_V_CONTEXT
def read_all(fname):
with open(fname, 'rb') as f:
return f.read()
MINIMAL_PATH = '../lorem-f.pdf'
MINIMAL = read_all(MINIMAL_PATH)
logger = logging.getLogger(__name__)
SKIP_PKCS11 = False
def _simple_sess():
lib = "/usr/lib64/libpkcs11-fnmtdnie.so"
session=pkcs11.open_pkcs11_session(
lib, user_pin='p4rp4rp4arpxp2', token_label='DNI electrónico (PIN1)'
)
return session
default_other_certs = ('CertCAIntermediaDGP',)
def test_simple_sign(bulk_fetch, pss):
w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
meta = signers.PdfSignatureMetadata(field_name='Sigg2')
with _simple_sess() as sess:
signer = pkcs11.PKCS11Signer(
sess, 'CertFirmaDigital', other_certs_to_pull=default_other_certs,
bulk_fetch=bulk_fetch, prefer_pss=pss
)
print(signer)
out = signers.sign_pdf(w, meta, signer,None,None,False,None,False,None)
r = PdfFileReader(out)
emb = r.embedded_signatures[0]
assert emb.field_name == 'Sigg1'
val_trusted(emb)
test_simple_sign(True,False)`
And get the same error in "out=signers.sign_pdf (....)" whic is "Exception has occurred: ValueError
not enough values to unpack (expected 1, got 0)"
But using:
`for cert in session.get_objects({ Attribute.LABEL: "CertFirmaDigital",
Attribute.CLASS: ObjectClass.CERTIFICATE,}):
der_bytes = cert[Attribute.VALUE]
# Load a certificate object from the DER-encoded value
cert = x509.Certificate.load(der_bytes)
print(cert)`
I am getting the signature certificate.
Any help will be appreciated
Thanks in advance
Hey Matthias,
I have been playing arround the subject of our last discussion: signing filled forms, but hit a roadblock. Here it is:
Describe the bug
I get pyhanko.pdf_utils.misc.PdfReadError
when signing a pdf with any filled form I could find. Perhaps the forms are not A-grade and are the root cause of the issue, or the programs I am using to fill them (okular and evince). I can sign any pdf with forms just fine if and only if they are empty.
To Reproduce
python3 sign.py
to sign the filled form and get an error like pyhanko.pdf_utils.misc.PdfReadError: Generation 0 of object 3 was never freed, but reused later.
Expected behavior
No errors and a signed pdf.
Environment (please complete the following information):
Hi, Matthias. I am trying to sign a PDF but encountered the following:
Command:
pyhanko sign addsig --field Sig1 beid --lib /usr/lib/libaetpkss.so ii.pdf o.pdf
Error:
(several lines eliminated...)
raise PKCS11Error(
pkcs11.exceptions.PKCS11Error: Could not find (unique) cert with label 'Root'.
Error: Generic processing error.
Perhaps the issue has to do with beid
, but I don't know what to put in place.
Also, It would be very good if you could point me towards a sample code the allows me to sign a PDF using the API instead of using the CLI.
Thank you.
Fernando Cabral
This bug was originally reported by @fredericoschardong in #31 (thanks!).
The pdf_date
function has been broken in a very particular way since it was first defined (see 543aac7). When passed a datetime with a negative UTC offset, the seconds
field of the resulting timedelta is positive, and the days
field is set to -1
. Our pdf_date
function simply proceeds with the value in the seconds
field, resulting in a PDF date string that's off by one day.
1 uploads/61cd28fb986c7817124531770sample.pdf uploads/1_out_61cd28fb986c7817124531770sample.pdf uploads/1_signed_61cd28fb986c7817124531770sample.pdf
Executing Command : pyhanko sign addfields --field 1/1,1,100,50/signature1 uploads/61cd28fb986c7817124531770sample.pdf uploads/1_out_61cd28fb986c7817124531770sample.pdf
(node:7556) UnhandledPromiseRejectionWarning: Error: Command failed: pyhanko sign addfields --field 1/1,1,100,50/signature1 uploads/61cd28fb986c7817124531770sample.pdf uploads/1_out_61cd28fb986c7817124531770sample.pdf
2021-12-30 10:16:56,111 - pyhanko.cli - ERROR - Failed to read PDF file.
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/pyhanko/cli.py", line 80, in pyhanko_exception_manager
yield
File "/usr/local/lib/python3.9/site-packages/pyhanko/cli.py", line 1205, in add_sig_field
writer = IncrementalPdfFileWriter(infile)
File "/usr/local/lib/python3.9/site-packages/pyhanko/pdf_utils/incremental_writer.py", line 41, in init
prev = PdfFileReader(input_stream)
File "/usr/local/lib/python3.9/site-packages/pyhanko/pdf_utils/reader.py", line 617, in init
self.read()
File "/usr/local/lib/python3.9/site-packages/pyhanko/pdf_utils/reader.py", line 972, in read
self._read_xrefs()
File "/usr/local/lib/python3.9/site-packages/pyhanko/pdf_utils/reader.py", line 940, in _read_xrefs
raise PdfReadError(
pyhanko.pdf_utils.misc.PdfReadError: Xref table contains orphaned higher generation objects: 78 39 obj,80 37 obj,82 35 obj,84 33 obj,86 31 obj,101 1 obj
Hi! Thanks for this project, a good PDF signing library for Python was missing!
I have a mechanism for remote signature creation, i.e., I have an interface where I can provide the hash of a PDF document (already prepared with an empty signature placeholder) from the interface I get back a CMS object representing the signature for this document and the certificate of the signer; potentially I get some revocation information as well.
Compared to the BeID example that you already provide, there are some differences for this remote signature interace. Most importantly, I cannot know the signer's certificate beforehand, as this certificate is short-lived and is created on-demand.
I would be happy to provide code for remote signature devices for your library. It seems that implementing a Signer
class is the way to go, but from what I saw so far it seems that the library assumes that the certificate is known beforehand. It would be great if you could provide me some pointers on the following topics:
Describe the bug
During validation of a pdf file with three signatures, have met with the following warning and the following error:
2021-05-20 09:47:22,762 - pyhanko.sign.diff_analysis - WARNING - Error in diff operation between revision 1 and 2
Traceback (most recent call last):
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\sign\diff_analysis.py", line 2130, in review_file
diff_result = self.apply(
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\sign\diff_analysis.py", line 2030, in apply
for level, fu in form_changes:
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\sign\diff_analysis.py", line 1168, in apply
_compare_dicts(old_acroform, new_acroform, self.ignored_acroform_keys)
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\sign\diff_analysis.py", line 1705, in _compare_dicts
raise SuspiciousModification(
pyhanko.sign.diff_analysis.SuspiciousModification: Dict keys differ: {'/DA', '/SigFlags'} vs. {'/SigFlags'}.
2021-05-20 09:47:23,482 - pyhanko.cli - ERROR - Generic processing error.
Traceback (most recent call last):
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\cli.py", line 69, in pyhanko_exception_manager
yield
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\cli.py", line 437, in validate_signatures
status_str = _signature_status(
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\cli.py", line 327, in _signature_status
status = validation.validate_pdf_signature(
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\sign\validation.py", line 1263, in validate_pdf_signature
status_kwargs = _validate_cms_signature(
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\sign\validation.py", line 178, in _validate_cms_signature
trusted, revoked, path = status_cls.validate_cert_usage(
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\sign\general.py", line 359, in validate_cert_usage
path = validator.validate_usage(key_usage=set())
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\__init__.py", line 211, in validate_usage
self._validate_path()
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\__init__.py", line 139, in _validate_path
validate_path(self._context, candidate_path, self._params)
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\validate.py", line 70, in validate_path
return _validate_path(validation_context, path, parameters=parameters)
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\validate.py", line 592, in _validate_path
_check_revocation(
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\validate.py", line 786, in _check_revocation
verify_crl(
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\validate.py", line 1500, in verify_crl
certificate_lists = validation_context.retrieve_crls(cert)
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\context.py", line 465, in retrieve_crls
certs = crl_client.fetch_certs(
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\pyhanko_certvalidator\crl_client.py", line 125, in fetch_certs
content_type = response.headers['Content-Type'].strip()
File "c:\Users\guilhermec\source\repos\pyHanko\env\lib\site-packages\requests\structures.py", line 54, in __getitem__
return self._store[key.lower()][1]
KeyError: 'content-type'
Error: Generic processing error.
To Reproduce
python -mpyhanko sign validate --pretty-print testdata/teste3.pdf
The used file is attached
Expected behavior
The two first signatures should be valide (if Brazilian CA roots are used), the last one invalid since it used a self-signed certificate.
Environment (please complete the following information):
Hi!
First, congrats for the project! It's fantastic!
I have a quirk about the time stamp and, well, I don't know if it's a feature of the project or some wrong implementation I did.
I'm getting a valid timestamp from a server and embedding it in the code. However, when I sign the PDF, Adobe Reader/Acrobat reports that “signature date/time are from the clock on the signer’s computer”.
Do the output PDF (digital signature + timestamped) have "correct" timestamp validation when opened in Adobe (“The signature includes an embedded timestamp”), or is it anyway - i.e., will this message always appear?
Hi everyone. After updating pyhanko from 0.6.0 to 0.8.0, I am not able to choose the font for a visible signature. Only the "NotoSans-Regular" works. I have downloaded a lot of ttf unicode fonts , but always I get
Could not deduce PostScript name for font; only unicode-compatible encodings in the name table are supported. This is may code line:
tbst=TextBoxStyle(opentype.GlyphAccumulatorFactory('linux-biolinum-capitals-italic.ttf'))
Also I have tried with:
letra=SimpleFontEngine(writer.BasePdfFileWriter.get_subset_collection(self=root, base_postscript_name='ArialMT-Bold'), name='ArialMT-Bold',avg_width=1)
with the result:
'_tkinter.tkapp' object has no attribute '_font_resources'
Don't know what to do.
Any helps will be appreciated
Thanks in advance
Describe the bug
Trying to validate a PDF with pyhanko sign validate
and I got a Traceback with KeyError.
To Reproduce
Execute
pyhanko sign validate --pretty-print signed-lorem-ipsum.pdf
I got:
022-02-03 14:54:47,419 - pyhanko.cli - ERROR - Generic processing error.
Traceback (most recent call last):
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 164, in queue_fetch_task
wait_event: asyncio.Event = running_jobs[tag]
KeyError: 'https://www.sk.ee/upload/files/TEST_of_EE_Certification_Centre_Root_CA.der.crt'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "$VENV/lib/python3.8/site-packages/pyhanko/cli.py", line 78, in pyhanko_exception_manager
yield
File "$VENV/lib/python3.8/site-packages/pyhanko/cli.py", line 529, in validate_signatures
(status_str, signature_ok) = _signature_status_str(
File "$VENV/lib/python3.8/site-packages/pyhanko/cli.py", line 387, in _signature_status_str
status = status_callback()
File "$VENV/lib/python3.8/site-packages/pyhanko/cli.py", line 530, in <lambda>
status_callback=lambda: _signature_status(
File "$VENV/lib/python3.8/site-packages/pyhanko/cli.py", line 349, in _signature_status
status = pyhanko.sign.validation.validate_pdf_signature(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/__init__.py", line 221, in validate_pdf_signature
return asyncio.run(coro)
File "/Users/tlilja/.pyenv/versions/3.8.10/lib/python3.8/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/tlilja/.pyenv/versions/3.8.10/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/pdf_embedded.py", line 845, in async_validate_pdf_signature
ts_status_kwargs = await collect_timing_info(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/generic_cms.py", line 432, in collect_timing_info
tst_validity_kwargs = await validate_tst_signed_data(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/generic_cms.py", line 492, in validate_tst_signed_data
return await cms_basic_validation(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/generic_cms.py", line 270, in cms_basic_validation
trusted, revoked, path = await status_cls.validate_cert_usage(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/status.py", line 154, in validate_cert_usage
path = await validator.async_validate_usage(key_usage=set())
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/__init__.py", line 263, in async_validate_usage
await self._validate_path()
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/__init__.py", line 107, in _validate_path
paths = await self._context.certificate_registry.async_build_paths(
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/registry.py", line 323, in async_build_paths
await self._walk_issuers(path, paths, failed_paths)
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/registry.py", line 375, in _walk_issuers
async for issuer in self.fetcher.fetch_cert_issuers(path.first):
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 268, in complete_certificate_fetch_jobs
certs_fetched = await fetch_job
File "$PYENV/versions/3.8.10/lib/python3.8/asyncio/tasks.py", line 619, in _wait_for_one
return f.result() # May raise f.exception().
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 57, in fetch_certs
return await self._perform_fetch(url, task)
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/util.py", line 37, in _perform_fetch
return await queue_fetch_task(
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 195, in queue_fetch_task
return _return_or_raise(result)
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 200, in _return_or_raise
raise result
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 182, in queue_fetch_task
result = await async_fun()
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 49, in task
results = await self._grab_certs(
File "$VENV/lib/python3.8/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 103, in _grab_certs
content_type = response.headers['Content-Type'].strip()
File "$VENV/lib/python3.8/site-packages/requests/structures.py", line 54, in __getitem__
return self._store[key.lower()][1]
KeyError: 'content-type'
Error: Generic processing error.
Expected behavior
No traceback. Perhaps error message or successful validation?
Environment (please complete the following information):
pyHanko==0.12.0
pyhanko-certvalidator==0.19.2
Additional context
Looks like https://www.sk.ee/upload/files/TEST_of_EE_Certification_Centre_Root_CA.der.crt is serving the file without Content-Type
header and hence the error.
currently the encrypt function is working good, with only one problem.
I'm using it to encrypt and sign PDF certificates and then release to public, alrough the signed documents are protected for altering, however, what I need is also that the PDF are protected against content copy, I managed to sub-class the PdfFileWriter and set the perms=2500 and which works as expected. user can open the pdf via the user_password and view the pdf.
The only problem is that I also need to left user_password empty so that public users can just open the certificate and view the content althrough they are not allowed to copy the conent to DOC etc.
my code as following:
def generate_certificate(self): from pyhanko.sign import signers from pyhanko.pdf_utils.reader import PdfFileReader from mysite.lib.pdf import copy_into_new_writer password = current_app.config['PDF_PASSWORD'] path = self.file_uploaded_path() certificate_url = url_for( 'web.validate_certificate', id=self.id, utn=self.utn, _external=True) if not self.draft: raise NotFound( 'certicate draft for certificat line {} not found.'.format(self.id)) buffer = io.BytesIO() filename = os.path.join(path, self.draft) with open(filename, 'rb') as fp: b_in = io.BytesIO(fp.read()) input = PdfFileReader(b_in) w = copy_into_new_writer(input) w.encrypt(password, '123456') out_filename = os.path.join(path, self.filename) cms_signer = signers.SimpleSigner.load('test.key', 'test.pem', key_passphrase=b'wswa2011') out = signers.PdfSigner(signers.PdfSignatureMetadata(field_name='Signature1'), signer=cms_signer,).sign_pdf(w) with open(out_filename, 'wb+') as fp: fp.write(out.getvalue())
Hi Matthias,
I would like to kindly ask for your guidance once again. I have a similar objective as reported in #6. Let me explain.
I have a PDF whose entire content is signed with pyHanko. Now, I would like to: (i) add a few strings to the signed pdf by x/y coordinates; and (ii) sign only whatever was added after the first signature.
Regarding (i), after looking at the documentation and source code, there doesn't seem to be a readily available class/method for writing strings to the pdf. If that is indeed the case, what would be the straightforward way of doing so? What comes to mind is to mimic what is done in this method.
Regarding (ii) I am not sure where to start :-)
Describe the bug
The difference analysis tool that performs comparisons between revisions of the same PDF file doesn't correctly process references to objects that are undefined or freed.
The standard mandates that such references be treated as nulls. Of course, nothing prevents us from considering such references as suspicious anyway (there's a sound security argument to be made for that), but at least we need to treat them gracefully.
To Reproduce
Take a PDF document containing a reference to a freed object or an undefined one. Sign it twice and attempt to validate the first signature. An ugly stack trace ensues.
Expected behavior
SuspiciousModification
exception, or assume null
.
Additional context
Reported in #54.
Thanks for such a useful little tool! I'm trying to utilize it to sign a PDF using my Estonian ID card. So far by trial and error, I've managed to get to this command:
pyhanko sign addsig pkcs11 \
--lib /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so \
--token-label 'PUSHKOV,ALEKSANDR,3970... (PIN2)' \
--cert-label 'Allkirjastamine' \
test.pdf signed.pdf
But it fails with the pkcs11.exceptions.MechanismInvalid
error.
PKCS#11 user PIN:
2021-09-27 18:33:09,048 - pyhanko.cli - ERROR - Generic processing error.
Traceback (most recent call last):
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/cli.py", line 75, in pyhanko_exception_manager
yield
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/cli.py", line 981, in _sign_pkcs11
generic_sign_pdf(
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/cli.py", line 795, in generic_sign_pdf
result = signers.PdfSigner(
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_signer.py", line 990, in sign_pdf
post_signing_doc = tbs_document.perform_signature(
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_signer.py", line 1687, in perform_signature
signature_cms = self.signer.sign(
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_cms.py", line 465, in sign
return self.sign_prescribed_attributes(
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_cms.py", line 538, in sign_prescribed_attributes
signature = self.sign_raw(
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pyhanko/sign/pkcs11.py", line 266, in sign_raw
signature = kh.sign(data, **kwargs)
File "/home/ale/.local/pipx/venvs/pyHanko/lib/python3.8/site-packages/pkcs11/types.py", line 939, in sign
return self._sign(data, **kwargs)
File "pkcs11/_pkcs11.pyx", line 1072, in pkcs11._pkcs11.SignMixin._sign
File "pkcs11/_pkcs11.pyx", line 1074, in pkcs11._pkcs11.SignMixin._sign
File "pkcs11/_errors.pyx", line 88, in pkcs11._pkcs11.assertRV
pkcs11.exceptions.MechanismInvalid
Error: Generic processing error.
I've added a couple quick print
s to pyhanko.sign.pkcs11.PKCS11Signer.sing_raw
to verify that the mechanism picked is indeed correct and it seems plausible to me:
signature_algo: ecdsa
digest_algorithm: sha256
Here's some info about the certificate and the card itself:
$ pkcs11-tool --slot 1 -OM
Supported mechanisms:
SHA-1, digest
SHA224, digest
SHA256, digest
SHA384, digest
SHA512, digest
MD5, digest
RIPEMD160, digest
GOSTR3411, digest
ECDSA, keySize={384,384}, hw, sign, other flags=0x1800000
ECDH1-COFACTOR-DERIVE, keySize={384,384}, hw, derive, other flags=0x1800000
ECDH1-DERIVE, keySize={384,384}, hw, derive, other flags=0x1800000
Certificate Object; type = X.509 cert
label: Allkirjastamine
subject: DN: C=EE, O=ESTEID, OU=digital signature, CN=PUSHKOV,ALEKSANDR,397xxxxxxxx, SN=PUSHKOV, GN=ALEKSANDR/serialNumber=397xxxxxxxx
ID: 02
Public Key Object; EC EC_POINT 384 bits
EC_POINT: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EC_PARAMS: 06052b81040022
label: Allkirjastamine
ID: 02
Usage: encrypt, verify
Access: local
What are my next steps to solve this mystery? :-)
Note: this grew out of a conversation with @fornwall on PR #33 .
As I mentioned over there, the CLI code used to be much more of a thin wrapper around pyHanko's internals. However, as time went on, it gradually evolved into something more complex. I'd like to refactor the CLI wrapper code into something more modular, but that's not the thing that's at issue here.
The library code has a lot of tests, and almost all of these run in Github Actions as well (the PKCS#11 tests being a notable exception). The CLI code isn't tested anywhere near as rigorously. There's certainly a lot of room for improvement there. I've put some of my own thoughts below.
I think we can approach this problem from two angles:
pytest
tests that call click
's entry pointsbats
) to invoke pyHanko from an actual shellI'm not sure which of these would be better (although nothing stops us from doing both, of course).
Here's what I think:
click
(mainly password prompts), that will require some care.bats
-like testing tools, but you could argue that those would provide a more complete/representative integration test suite. I certainly wouldn't object to that. The main difficulties here will be in deciding what kind of assertions to write (without relying too much on pyHanko internals), and in setting up our trust services mocks properly.Note: Certomancer can still handle the second scenario, but it will require some care to set up correctly (and we might have to tweak the existing test setup a little in order to make it work using the same configuration for both CLI tests and library tests).
Anyway, let's discuss here. I'm happy to consider a PR to address CLI tests, but I'd like to get a sense of direction here first, so we don't waste time and effort arguing over test strategies after the code has been written :).
Obviously, I can also help with the Certomancer setup for testing commands that require OCSP/CRL/TSA access. If getting this right requires tweaking things in Certomancer: we can discuss that as well.
I'm trying to include signing features in pdfarranger using pyhanko, but on my first import of pyhanko modules the application coredumps. This is the very specific line which causes the coredump: https://github.com/plenaerts/pdfarranger/blob/a96db16096ca80e2af01be4f151c5e41fc58b1a6/pdfarranger/signer.py#L104
I tested using the pyhanko API in this script but once I try reusing this code in the gtk application I don't get to import pyhanko modules.
I don't have a clue where to start looking what causes this. Anyone else?
According to documentation, I am trying to add a signature field to a PDF document, so:
This is my code:
`from pyhanko.sign.fields import append_signature_fields,SigFieldSpec
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
with open('output-signed.pdf', 'rb+') as doc:
w = IncrementalPdfFileWriter(doc)
append_signature_fields(w, SigFieldSpec(sig_field_name='Sig'))
w.write_in_place()`
I had to change"append_signature_field" for "append_signature_fields", but no matter the parameters I add to SigFieldSpec, that I have always the same result which is 'SigFieldSpec' object is not iterable.
But my CLI version works perfecly
Any help will be grateful
Thanks in advance
Is your feature request related to a problem? Please describe.
PyHanko supports PDF documents with traditional cross-reference tables and documents with cross-reference streams. Hybrid reference documents aren't currently supported, though. Those make use of a standard cross-reference table with the XrefStm directive to get support for PDF 1.5 features in a document that's still (mostly) understandable to a PDF 1.4 reader. PDF readers without support for PDF 1.5 have all but disappeared, but some PDF producer tools still generate such hybrid-reference files to this day (looking at you, MS Office). Those documents are pretty rare in the grand scheme of things, but still common enough that we should support them properly.
Describe the solution you'd like
Four items:
It's all very straightforward in principle, but there are quite a few sharp edges, esp. with regards to the last point.
Is your feature request related to a problem? Please describe.
I have an not encrypted key RSA key and certificate and like to use that in pemder mode.
It asks for an 'Key passphrase' and returns 'TypeError: Password was given but private key is not encrypted.' if I enter an empty one.
Describe the solution you'd like
Add an parameter like "--unencrypted" to skip requesting the 'Key passphrase'
Hello Matthias,
First of all great work you have done with pyHanko.
Describe the bug
We are planning on using pyHanko on a large scale for signed pdf docs for the Greek public sector. For that we need
the signed documents to be LTV enabled. I have tried to make an initial implementation but when I use the param embed_validation_info
I get an pyhanko.sign.general.SigningError: ("The signer's certificate could not be validated", InvalidCertificateError('The X.509 certificate provided is not valid for the purpose of non repudiation'))
error.
To Reproduce
The code I have written so far looks like this
cms_signer = signers.SimpleSigner.load_pkcs12(
certificate_filename, passphrase=password.encode('utf-8'))
w = IncrementalPdfFileWriter(pdf_buffer)
tst_client = timestamps.HTTPTimeStamper('https://timestamp.aped.gov.gr/qtss')
sv = fields.SigSeedValueSpec(
reasons=[],
digest_methods=[],
flags=3,
)
sp = fields.SigFieldSpec('Signature', seed_value_dict=sv, box=(15, 705, 175, 798))
image = PdfImage(image=settings.STAMP_IMAGE)
style = TextStampStyle(background=image, border_width=0)
vc = ValidationContext(trust_roots=[cms_signer.signing_cert])
out = signers.PdfSigner(signature_meta=signers.PdfSignatureMetadata(
field_name='Signature',
reason='My reason',
location='My location',
use_pades_lta=True,
subfilter=fields.SigSeedSubFilter.PADES,
embed_validation_info=True,
validation_context=vc
),
signer=cms_signer,
timestamper=tst_client,
stamp_style=style,
new_field_spec=sp
).sign_pdf(w)
Where the certificate_filename
is a p12 signing certificate and pdf_buffer
is the document I want to sign in BytesIO
Expected behavior
In the end I expect a signed document that when opened with Adobe Acrobat Reader it is listed as "LTV enabled"
Environment (please complete the following information):
Additional context
The same issue exists in both 0.4.0 as well as 0.5.0-dev1
I have contaced HARICA which is the Hellenic Academic & Research Institutions Certification Authority and they told me that non-repudiaton has nothing to do with LTV and it shouldn't be needed to LTV enable a document.
Hi Matthias! A great Python library you've made there so far!
Describe the bug
I try to use pyHanko to validate PDFs that have LTV enabled signatures. What I do now is execute pyHanko with the following CLI command:
python3 -m pyhanko --config "C:/Users/Leon/Desktop/Verification/pyhanko.yml" sign validate "C:/Users/Leon/Desktop/Verification/signed_pdf.pdf" --ltv-profile adobe --validation-context standart1
at the --ltv-profile
option, I tried all 3 accepted values adobe
, pades
and pades-lta
.
When I use adobe
, pyHanko returns pyhanko.sign.general.SignatureValidationError: LTV signatures require a trusted timestamp
.
When I use pades
, pyHanko returns pyhanko.cli - ERROR - An error occurred while parsing the revocation information for this signature: No DDS found
- same is returned for pades-lta
.
To Reproduce
python3 -m pyhanko --config "C:/Users/Leon/Desktop/Verification/pyhanko.yml" sign validate "C:/Users/Leon/Desktop/Verification/signed_pdf.pdf" --ltv-profile adobe --validation-context standart1
at the --ltv-profile
option I tried all 3 accepted values adobe
, pades
and pades-lta
The configuration used looks like this:
Expected behavior
I expect to return the same output like when not using --ltv-profile
(see below at Additional Context).
Screenshots
As you can see above in the screenshot, it seems like LTV is enabled.
Environment (please complete the following information):
Additional context
The CLI command without the --ltv-profile
works like a charm and returns INTACT:TRUSTED:UNTOUCHED
.
Thanks and best regards,
Leon Dierkes
Hello Matthias,
i got a problem with this command
pyhanko sign addsig --field Sig1 --timestamp-url http://tsa.example.com
--with-validation-info --use-pades pemder
--key key.pem --cert cert.pem input.pdf output.pdf
the result
2021-07-29 13:51:42,948 - pyhanko.cli - ERROR - Error raised while producing signed file.
Traceback (most recent call last):
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_signer.py", line 959, in _perform_presign_signer_validation
signer_cert_validation_path = validator.validate_usage(key_usage)
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko_certvalidator/init.py", line 212, in validate_usage
self._validate_path()
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko_certvalidator/init.py", line 127, in _validate_path
paths = self._context.certificate_registry.build_paths(self._certificate)
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko_certvalidator/registry.py", line 314, in build_paths
raise PathBuildingError(pretty_message(
pyhanko_certvalidator.errors.PathBuildingError: Unable to build a validation path for the certificate "Common Name: Danny Jawa Timur; Country: ID" - no issuer matching "Common Name: iXXX CA G1, Organizational Unit: iXXXX, Organization: XXX, Country: ID" was found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko/cli.py", line 75, in pyhanko_exception_manager
yield
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko/cli.py", line 781, in addsig_simple_signer
generic_sign_pdf(
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko/cli.py", line 791, in generic_sign_pdf
result = signers.PdfSigner(
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_signer.py", line 764, in sign_pdf
validation_info = signing_session.perform_presign_validation(pdf_out)
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_signer.py", line 904, in perform_presign_validation
signer_path = self._perform_presign_signer_validation(
File "/home/dany/.local/lib/python3.8/site-packages/pyhanko/sign/signers/pdf_signer.py", line 961, in _perform_presign_signer_validation
raise SigningError(
pyhanko.sign.general.SigningError: ("The signer's certificate could not be validated", PathBuildingError('Unable to build a validation path for the certificate "Common Name: XXXX; Organization: XXX; Country: ID" - no issuer matching "Common Name: iXXX CA G1, Organizational Unit: iXXXX, Organization: XXX, Country: ID" was found'))
Error: Error raised while producing signed file.
please help me solve this problem
pyHanko-0.9.0 on linux Python 3.7.3
pdf signed on https://autenti.com/
after
./.local/bin/pyhanko sign validate --pretty-print PDF_sign_test.pdf
I got:
2021-11-13 20:09:13,402 - pyhanko.sign.diff_analysis - WARNING - Error in diff operation between revision 1 and 5
Traceback (most recent call last):
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/diff_analysis.py", line 2240, in review_file
field_mdp_spec=field_mdp_spec, doc_mdp=doc_mdp
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/diff_analysis.py", line 2131, in apply
for level, fu in form_changes:
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/diff_analysis.py", line 1304, in apply
yield from rule.apply(context)
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/diff_analysis.py", line 981, in apply
yield from self.check_form_field(fq_name, spec, context)
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/diff_analysis.py", line 1046, in check_form_field
valid_when_locked = self.compare_fields(spec)
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/diff_analysis.py", line 971, in compare_fields
old_field, new_field, self.value_update_keys
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/diff_analysis.py", line 1806, in _compare_dicts
f"Dict keys differ: {new_dict_keys} vs. "
pyhanko.sign.diff_analysis.SuspiciousModification: Dict keys differ: {'/Lock', '/P', '/Rect', '/FT', '/Subtype', '/T'} vs. {'/P', '/Rect', '/FT', '/Subtype', '/T'}.
2021-11-13 20:09:13,412 - pyhanko.sign.general - WARNING - Unable to build a validation path for the certificate "Organization Identifier: VATPL-5170359458, Common Name: Certum QTST 2017, Organization: Asseco Data Systems S.A., Country: PL" - no issuer matching "Organization Identifier: VATPL-5250008198, Common Name: Narodowe Centrum Certyfikacji, Organization: Narodowy Bank Polski, Country: PL" was found
2021-11-13 20:09:13,412 - pyhanko.sign.general - WARNING - Chain of trust validation for Organization Identifier: VATPL-5170359458, Common Name: Certum QTST 2017, Organization: Asseco Data Systems S.A., Country: PL failed.
2021-11-13 20:09:13,436 - pyhanko.cli - ERROR - Generic processing error.
Traceback (most recent call last):
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 139, in queue_fetch_task
wait_event: asyncio.Event = running_jobs[tag]
KeyError: 'http://elektronicznypodpis.pl/certyfikaty/ozk62.der'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/cli.py", line 80, in pyhanko_exception_manager
yield
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/cli.py", line 518, in validate_signatures
pretty_print=pretty_print, executive_summary=executive_summary
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/cli.py", line 386, in _signature_status_str
status = status_callback()
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/cli.py", line 516, in <lambda>
embedded_sig=embedded_sig
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/cli.py", line 352, in _signature_status
signer_validation_context=vc
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/validation.py", line 1569, in validate_pdf_signature
return asyncio.run(coro)
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/validation.py", line 1639, in async_validate_pdf_signature
status_kwargs=status_kwargs, key_usage_settings=key_usage_settings
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/validation.py", line 266, in _validate_cms_signature
validator, key_usage_settings=key_usage_settings
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko/sign/general.py", line 373, in validate_cert_usage
path = await validator.async_validate_usage(key_usage=set())
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/__init__.py", line 283, in async_validate_usage
await self._validate_path()
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/__init__.py", line 128, in _validate_path
self._certificate
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/registry.py", line 426, in async_build_paths
await self._walk_issuers(path, paths, failed_paths)
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/registry.py", line 478, in _walk_issuers
async for issuer in self.fetcher.fetch_cert_issuers(path.first):
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 70, in fetch_cert_issuers
url, url_origin_type='certificate'
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 56, in fetch_certs
return await self._perform_fetch(url, task)
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/util.py", line 38, in _perform_fetch
self.__results, self.__result_events, tag, fetch_fun
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 170, in queue_fetch_task
return _return_or_raise(result)
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 175, in _return_or_raise
raise result
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 157, in queue_fetch_task
result = await async_fun()
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 55, in task
return list(results)
File "/home/eod/.local/lib/python3.7/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 46, in unpack_cert_content
"Expected PEM data when extracting certs from "
ValueError: Expected PEM data when extracting certs from application/x-x509-ca-cert payload. Source URL: http://elektronicznypodpis.pl/certyfikaty/ozk62.der.
Error: Generic processing error.
what I did wrong ?
I have upgraded my system and python has upgraded from 3.8 to 3.9. On version 3.8 everything worked fine, but now I have got this error which I do not know how to solve. Error occurs when I get a p12 file certificate to sign, when is verifying the certificate. This is the error:
File "/root/Descargas/programacion/firma_digital/pades_sign/firma_final.py", line 307, in certificadodig out = signers.PdfSigner(signature_meta=signers.PdfSignatureMetadata( File "/usr/local/lib/python3.9/site-packages/pyhanko/sign/signers.py", line 2198, in sign_pdf signer_cert_validation_path = validator.validate_usage( File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/__init__.py", line 211, in validate_usage self._validate_path() File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/__init__.py", line 139, in _validate_path validate_path(self._context, candidate_path, self._params) File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/validate.py", line 70, in validate_path return _validate_path(validation_context, path, parameters=parameters) File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/validate.py", line 661, in _validate_path qualified_policies = _finish_policy_processing( File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/validate.py", line 741, in _finish_policy_processing qualified_policies = frozenset(_enum_policies()) File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/validate.py", line 732, in _enum_policies user_domain_policy_id=next( File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/validate.py", line 735, in <genexpr> if ancestor.parent.valid_policy == 'any_policy' AttributeError: 'PolicyTreeRoot' object has no attribute 'valid_policy'
My pyhanko version is 0.6.1 and the pyhanko-certvalidator is 0.15.1 (I have als tested 0.15.2 with same result)
The code is :
` def certificadodigper(x1,y1,x2,y2,fname):
try:
root.filename = filedialog.askopenfilename(initialdir = ".",title = "Seleccione archivo",filetypes = (("p12 files","*.p12"),("all files","*.*")))
finame=root.filename
w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
pin=simpledialog.askstring(title = 'Introduzca PIN', prompt='PIN secreto', show ='*')
FROM_CA_PKCS12 = signers.SimpleSigner.load_pkcs12(
finame, passphrase=bytes(pin,'utf-8'))
p12 = crypto.load_pkcs12(open(finame, 'rb').read(), bytes(pin,'utf-8'))
acert=p12.get_certificate() # (signed) certificate object
bkey=p12.get_privatekey() # private key.
cinter=p12.get_ca_certificates() # ca chain.
certs =crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, acert)
certt2=crypto.load_certificate(FILETYPE_PEM,certs)
subject=certt2.get_subject()
print(subject)
nombre = dict(subject.get_components())[b'CN'].decode()
cif = dict(subject.get_components())[b'serialNumber'].decode()
#empresa=dict(subject.get_components())[b'O'].decode()
privkey=crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, bkey)
datos_firma=f'Firma digital por:\n\n{nombre}.\n\nDNI/CIF:{cif}\n'
sv = fields.SigSeedValueSpec(
reasons=[],
flags=3,
)
letra=SimpleFontEngine('Arial-BoldMT',0.4)
sp = fields.SigFieldSpec('Sigg1', seed_value_dict=sv, on_page=pagina_firma-1, box=(x1, y1, x2, y2),)
tbst=TextBoxStyle( letra,)
#image = PdfImage(image=settings.STAMP_IMAGE)
vc = ValidationContext(trust_roots=[FROM_CA_PKCS12.signing_cert])
if (firma.ci==False):
style=TextStampStyle(text_box_style=tbst,stamp_text=datos_firma,border_width=0)
else:
style=TextStampStyle(text_box_style=tbst,stamp_text=datos_firma, background=PdfImage(cargaimagen.imname),border_width=0,background_opacity=0.4)
fname = fname.replace('.pdf', '-f.pdf')
with open(fname, 'wb') as outf:
out = signers.PdfSigner(signature_meta=signers.PdfSignatureMetadata(
field_name='Sigg1',
reason='Firma',
location='',
use_pades_lta=True,
subfilter=fields.SigSeedSubFilter.PADES,
embed_validation_info=True,
validation_context=vc
),
signer=FROM_CA_PKCS12,
timestamper=None,
stamp_style=style,
new_field_spec=sp
).sign_pdf(w, output=outf)
print(nombre,cif)
except TypeError:
salidaerror=messagebox.askokcancel("ERROR!!!!","Ha habido un error en la firma\n Aségurese de que el fichero es el correcto y la clave es la correcta")
if salidaerror==True:
parent.destroy()
else:
salida=messagebox.askokcancel("Fichero firmado","Se ha realizado la firma correctamente\n Se ha guardado el archivo con el mismo nombre + la 'f'")
if salida==True:
parent.destroy() `
I have changed my code according to changes in the new release:
`from certvalidator import ValidationContext`
to
`from pyhanko_certvalidator import ValidationContext`
Thanks in advance
Hey :)
I'm trying to make a script so I can sign my pdfs. As far as I understand from the docs I need a stamp to make it visually obvious that that file is signed.
I assume this is because of %(signer)s
in the default stamp-style?
Did I mess something up creating my identity file?
cheers Leo
To Reproduce
openssl req -x509 -newkey rsa:2048 -keyout mykey.pem -out cert.pem -days 365
openssl pkcs12 -export -out identity.p12 -inkey mykey.pem -in cert.pem
pyhanko sign addsig --field Sig1 pkcs12 test.pdf test-sig.pdf identity.p12
pyhanko --config pyhanko.yaml stamp --style-name default --page 1 test-sig.pdf test-sig-stamp.pdf 50 100
2021-12-11 10:33:30,710 - pyhanko.pdf_utils.font.opentype - WARNING - No ROS metadata. Is this really a CIDFont?
2021-12-11 10:33:30,718 - pyhanko.cli - ERROR - Generic processing error.
Traceback (most recent call last):
File "pyhanko/cli.py", line 80, in pyhanko_exception_manager
yield
File "pyhanko/cli.py", line 1247, in stamp
text_stamp_file(
File "pyhanko/stamp.py", line 810, in text_stamp_file
_stamp_file(
File "pyhanko/stamp.py", line 784, in _stamp_file
stamp.apply(dest_page, x, y)
File "pyhanko/stamp.py", line 493, in apply
stamp_ref = self.register()
File "pyhanko/stamp.py", line 473, in register
form_xobj = self.as_form_xobject()
File "pyhanko/pdf_utils/content.py", line 231, in as_form_xobject
command_stream = self.render()
File "pyhanko/stamp.py", line 439, in render
inner_content = self._render_inner_content()
File "pyhanko/stamp.py", line 600, in _render_inner_content
= self._inner_layout_natural_size()
File "pyhanko/stamp.py", line 587, in _inner_layout_natural_size
text_commands = self._text_layout()
File "pyhanko/stamp.py", line 578, in _text_layout
text = self.style.stamp_text % _text_params
KeyError: 'signer'
Error: Generic processing error.
stamp-styles:
default:
type: text
background: __stamp__
stamp-text: "Signed by %(signer)s\nTimestamp: %(ts)s"
text-box-style:
font: /usr/share/fonts/gnu-free/FreeMono.otf
noto-qr:
type: qr
background: background.png
stamp-text: "Signed by %(signer)s\nTimestamp: %(ts)s\n%(url)s"
text-box-style:
font: NotoSerif-Regular.otf
leading: 13
Environment
linux 5.15.7-arch1-1
pyHanko, version 0.10.0
Python 3.9.9
Problem solved so I deleted my message. Sorry.
Doubt: support TSA using socket connection on port 318?
Describe the bug
There seems to be a regression between 0.3.0 and 0.4.0 -- version 0.4.0 insists on adding empty signature fields on page 1 of the document, while version 0.3.0 honors command line arguments. Didn't see this fixed when looking through commits, however I did not test current version from git.
Where we find the config file for configuring the cert label changes/assignment purpose...
Like:
pkcs11-setups:
test-setup:
module-path: /usr/lib/libsofthsm2.so
token-label: testrsa
cert-label: signer
user-pin: 1234
It is more like a help building code for sign a pdf document using my USB token (self signed certificate).
The signature on output file is corrupted. Im using the test code bellow with your pdf template (minimal-with-field_signed.pdf):
from pyhanko.sign import signers, pkcs11
from pyhanko.sign import timestamps
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
PKCS11LIB='C:\\Windows\\System32\\eTPKCS11.dll'
SERIALTOKEN=b'xxxxxxxx'
LABEL='xxxxxxxxxxx'
PIN='xxxxxxxxxx'
EXTENSION=".pdf"
DOCUMENT='C:\\Users\\vinicius\\Desktop\\minimal-with-field'
DOCUMENT_EXT=DOCUMENT+EXTENSION
SIGNED_FILE = DOCUMENT+"_signed.pdf"
cms_session = pkcs11.open_pkcs11_session(PKCS11LIB,user_pin=PIN,token_label=LABEL)
cms_signer = pkcs11.PKCS11Signer(cms_session,'')
with open(DOCUMENT_EXT, 'rb') as doc:
w = IncrementalPdfFileWriter(doc)
print(w.document_id)
with open(SIGNED_FILE, 'wb+') as file_out:
signers.PdfSigner(signers.PdfSignatureMetadata(field_name='Sig1'),signer=cms_signer).sign_pdf(w,output=file_out)
The code is able to get my certificate data, as the signature (visible text) shows without any trouble, but the signature comes corrupted as shown bellow:
btw, nice job with this library! tks in advance
Describe the bug
After installing pyHanko on my machine, it's impossible to run it without getting this error:
ModuleNotFoundError: No module named 'pyhanko.sign.ades'
To Reproduce
Environment (please complete the following information):
Additional context
I also tried to do apt-get update/upgrade, it didn't help.
I've added the entire log from the installation and the traceback when running pyhanko
log.txt
pyHanko/pyhanko/sign/signers/pdf_signer.py
Line 1240 in 022ac7c
According to my calculations bytes_reserved ~ 3 * len(test_signature_cms.dump())
and this is not the 50% extra placeholder that was expected.
Proposed solution
test_len = len(test_signature_cms.dump())
# External actors such as timestamping servers can't be relied on to
# always return exactly the same response, so we build in a 50%
# error margin (+ ensure that bytes_reserved is even)
bytes_reserved = test_len * 3 // 4 * 2
This problem is in one more place in this file.
--with-validation-info not working and internet was well connected. (Single document sign validation well working in Adobe Reader)
C:\Users\Satanu\Desktop\signfield>pyhanko --verbose sign addsig --field chairman --with-validation-info --style-name backlogo pkcs11 --p11-setup test-setup Degree1.pdf outputtest1.pdf
2021-07-15 17:59:22,964 - root - DEBUG - Running with --verbose
2021-07-15 17:59:22,965 - root - DEBUG - Finished reading configuration from pyhanko.yml.
2021-07-15 17:59:25,833 - urllib3.connectionpool - DEBUG - Starting new HTTP connection (1): ocvs.pantasign.com:80
2021-07-15 17:59:26,435 - urllib3.connectionpool - DEBUG - http://ocvs.pantasign.com:80 "POST / HTTP/1.1" 200 3298
2021-07-15 17:59:26,452 - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): www.pantasign.com:443
2021-07-15 17:59:27,359 - urllib3.connectionpool - DEBUG - https://www.pantasign.com:443 "GET /repository/PantaSignCRL.crl HTTP/1.1" 200 699013
2021-07-15 17:59:28,714 - pyhanko.cli - ERROR - Error raised while producing signed file.
Traceback (most recent call last):
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko-0.7.0.dev1-py3.9.egg\pyhanko\sign\signers.py", line 2320, in sign_pdf
signer_cert_validation_path = validator.validate_usage(
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko_certvalidator\__init__.py", line 211, in validate_usage
self._validate_path()
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko_certvalidator\__init__.py", line 146, in _validate_path
raise exceptions[0]
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko_certvalidator\__init__.py", line 139, in _validate_path
validate_path(self._context, candidate_path, self._params)
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko_certvalidator\validate.py", line 70, in validate_path
return _validate_path(validation_context, path, parameters=parameters)
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko_certvalidator\validate.py", line 592, in _validate_path
_check_revocation(
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko_certvalidator\validate.py", line 817, in _check_revocation
raise PathValidationError(pretty_message(
pyhanko_certvalidator.errors.PathValidationError: The path could not be validated because the end-entity certificate revocation checks failed: OCSP response is from after the validation time; CRL is from after the validation time
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko-0.7.0.dev1-py3.9.egg\pyhanko\cli.py", line 74, in pyhanko_exception_manager
yield
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko-0.7.0.dev1-py3.9.egg\pyhanko\cli.py", line 910, in _sign_pkcs11
generic_sign_pdf(
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko-0.7.0.dev1-py3.9.egg\pyhanko\cli.py", line 787, in generic_sign_pdf
result = signers.PdfSigner(
File "C:\Users\Satanu\AppData\Local\Programs\Python\Python39\lib\site-packages\pyhanko-0.7.0.dev1-py3.9.egg\pyhanko\sign\signers.py", line 2324, in sign_pdf
raise SigningError(
pyhanko.sign.general.SigningError: ("The signer's certificate could not be validated", PathValidationError('The path could not be validated because the end-entity certificate revocation checks failed: OCSP response is from after the validation time; CRL is from after the validation time'))
Error: Error raised while producing signed file.
Need help.. pls!
Maybe I do not understand how setup.py works, but I think this diff should be applied.
diff --git a/setup.py b/setup.py
index 14f1ea5..722d2e5 100644
--- a/setup.py
+++ b/setup.py
@@ -23,7 +23,7 @@ setup(
packages=[
'pyhanko',
'pyhanko.pdf_utils', 'pyhanko.pdf_utils.font',
- 'pyhanko.sign', 'pyhanko.sign.ades',
+ 'pyhanko.sign', 'pyhanko.sign.ades', 'pyhanko.sign.signers',
],
url='https://github.com/MatthiasValvekens/pyHanko',
license='MIT',
The problem is that I failed to install pyhanko master branch using pipenv.
Describe the bug
I get an exception when I am trying to run ltvfix on a signed PDF file.
To Reproduce
wget https://www.sk.ee/upload/files/TEST_of_EE_Certification_Centre_Root_CA.der.crt
pyhanko sign ltvfix --trust TEST_of_EE_Certification_Centre_Root_CA.der.crt --field Signature1 lorem-ipsum-signed.pdf
Expected behavior
Environment (please complete the following information):
pyHanko==0.12.0
pyhanko-certvalidator==0.19.4
Additional context
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/dss.py", line 133, in _cms_objects_to_streams
yield seen[obj_bytes]
KeyError: [...]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "$VENV/bin/pyhanko", line 8, in <module>
sys.exit(launch())
File "$VENV/lib/python3.8/site-packages/pyhanko/__main__.py", line 7, in launch
cli(prog_name='pyhanko')
File "$VENV/lib/python3.8/site-packages/click/core.py", line 1128, in __call__
return self.main(*args, **kwargs)
File "$VENV/lib/python3.8/site-packages/click/core.py", line 1053, in main
rv = self.invoke(ctx)
File "$VENV/lib/python3.8/site-packages/click/core.py", line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "$VENV/lib/python3.8/site-packages/click/core.py", line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "$VENV/lib/python3.8/site-packages/click/core.py", line 1395, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "$VENV/lib/python3.8/site-packages/click/core.py", line 754, in invoke
return __callback(*args, **kwargs)
File "$VENV/lib/python3.8/site-packages/click/decorators.py", line 26, in new_func
return f(get_current_context(), *args, **kwargs)
File "$VENV/lib/python3.8/site-packages/pyhanko/cli.py", line 632, in ltv_fix
output = validation.add_validation_info(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/__init__.py", line 302, in add_validation_info
return asyncio.run(coro)
File "/Users/tlilja/.pyenv/versions/3.8.10/lib/python3.8/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/Users/tlilja/.pyenv/versions/3.8.10/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
return future.result()
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/dss.py", line 645, in async_add_validation_info
resulting_dss = DocumentSecurityStore.supply_dss_in_writer(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/dss.py", line 443, in supply_dss_in_writer
dss.register_vri(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/dss.py", line 215, in register_vri
crl_refs = set(
File "$VENV/lib/python3.8/site-packages/pyhanko/sign/validation/dss.py", line 140, in _cms_objects_to_streams
dest.append(ref)
AttributeError: 'tuple' object has no attribute 'append'
Describe the bug
Cannot modify font-size via yml config file in text stamp style.
To Reproduce
To reproduce, use the following yml config.
stamp-styles:
default:
type: text
background: signature.png
stamp-text: "Signed by %(signer)s\nTimestamp: %(ts)s"
text-box-style:
font-size: 32
Note that in this example background: signature.png
works perfectly fine and changes the background according to the corresponding file.
Expected behavior
Expected output: the font is increased to 32 from the default value of 10.
Environment (please complete the following information):
Is there any demo how to merge 2 or 2+ pages into 1 single page like pyPDF2?
I have looked to the folder pyhanko-tests, however, due to I'm not familiar the low level details how the PDF was assmbled, the atempt to add a qr code imgage and a text with link was never success.
Would you please advise the equivalent of pyPDF2 as bellow for pyhanko?
newPdf = PdfFileReader(buffer)
filename = os.path.join(path, self.draft)
existingPdf = PdfFileReader(open(filename, 'rb'))
page = existingPdf.getPage(0)
page.mergePage(newPdf.getPage(0))
output = PdfFileWriter()
for page in range(existingPdf.getNumPages()):
output.addPage(existingPdf.getPage(page))
output.write(buffer)
Hi! First of all, this is not an issue with the toolkit itself. So far it works great for my uses. I'd love to see more "alpha quality" code like this... ;)
To the point: I'm currently using a headless LibreOffice to convert a template to final PDF file with some replacements along the way. Problem is, I have to manually "target" coordinates for signature fields with trial and error. Do you have an idea how would I go about automating the process in pyHanko? Number of required signatures is dynamic, so I'm thinking some kind of search & replace type solution here.
Steps I Followed -
add Signature Placeholder
pyhanko sign addfields --field PAGE/X1,Y1,X2,Y2/NAME input.pdf output.pdf
Sign PDF
pyhanko sign addsig --field Sig1 pemder \ --key key.pem --cert cert.pem input.pdf output.pdf
This signs the PDF and create a rectangle with the signature.
But is there a way to add signature image like png there ?
Describe the solution you'd like
I would like to get the digest and digest algorithm after signing a PDF.
Describe alternatives you've considered
I have tried to get it somehow out of the sign_pdf method, but it only uses local variables... there is probably a way to get it from the signer PDF, but I don't know how to do it.
This can be done using field locks, but the API to do so isn't exactly transparent. See discussion on #49.
Describe the bug
Currently --use-pades-lta
can be (mis)used without --with-validation-info
, which runs counter to the intended usage of --use-pades-lta
. That's not supposed to be possible.
To Reproduce
See above.
Expected behavior
--use-pades-lta
should act as if --with-validation-info
was also supplied on the command line.
Screenshots
N/A
Additional context
See discussion #79.
Describe the bug
Signing a already signed PAdES pdf file seems to change the /MediaBox coordinates types from NumberObject to FloatObject, leading to a invalid first signature.
To Reproduce
python -m pyhanko sign addsig --use-pades --field 1/0,0,240,40/SignatureSinc pemder --cert testdata/cert/cert.pem --key testdata/cert/key.pem testdata/test-signed_1.pdf testdata/test-signed_2.pdf
python -m pyhanko sign validate --pretty-print testdata/test-signed_2.pdf
021-03-09 14:40:38,205 - pyhanko.sign.diff_analysis - WARNING - Error in diff operation between revision 1 and 2
Traceback (most recent call last):
File "c:\users\guilhermec\source\repos\assinador\validador\env\src\pyhanko\pyhanko\sign\diff_analysis.py", line 2067, in review_file
diff_result = self.apply(
File "c:\users\guilhermec\source\repos\assinador\validador\env\src\pyhanko\pyhanko\sign\diff_analysis.py", line 1967, in apply
for level, fu in form_changes:
File "c:\users\guilhermec\source\repos\assinador\validador\env\src\pyhanko\pyhanko\sign\diff_analysis.py", line 1211, in apply
yield from rule.apply(context)
File "c:\users\guilhermec\source\repos\assinador\validador\env\src\pyhanko\pyhanko\sign\diff_analysis.py", line 826, in apply
yield from qualify(
File "c:\users\guilhermec\source\repos\assinador\validador\env\src\pyhanko\pyhanko\pdf_utils\misc.py", line 218, in map_with_return
yield func(next(gen))
File "c:\users\guilhermec\source\repos\assinador\validador\env\src\pyhanko\pyhanko\sign\diff_analysis.py", line 1644, in _walk_page_tree_annots
_compare_dicts(old_kid, new_kid, {'/Annots'})
File "c:\users\guilhermec\source\repos\assinador\validador\env\src\pyhanko\pyhanko\sign\diff_analysis.py", line 1717, in _compare_dicts
raise SuspiciousModification(
pyhanko.sign.diff_analysis.SuspiciousModification: Values for dict key /MediaBox differ:[0, 0, 841.92, 595.32] changed to [0, 0, 841.92, 595.32]
And complains about integrity:
Integrity
---------
The signature is cryptographically sound.
The signature does not cover the entire file.
Some modifications may be illegitimate, and they appear to be incompatible with the current document modification policy.
The MediaBox comparison, using DeepDiff module, had dectected the following diferences:
{'type_changes': {'root[0]': {'new_type': <class 'pyhanko.pdf_utils.generic.FloatObject'>,
'new_value': 0,
'old_type': <class 'pyhanko.pdf_utils.generic.NumberObject'>,
'old_value': 0},
'root[1]': {'new_type': <class 'pyhanko.pdf_utils.generic.FloatObject'>,
'new_value': 0,
'old_type': <class 'pyhanko.pdf_utils.generic.NumberObject'>,
'old_value': 0}},
'values_changed': {'root[2]': {'new_value': 841.92, 'old_value': 841.92},
'root[3]': {'new_value': 595.32, 'old_value': 595.32}}}
Expected behavior
It should validate the integrity of both signatures:
Screenshots
n/a
Environment (please complete the following information):
Additional context
I am studying adapt pyhanko to validate and sign according with Brazilian standard signed PAdES documents (/SubFilter PBAD-PAdES), that is mostly compatible with ETSI PAdES with minor changes.
Updating - 9h22min
Now I have something to ruminate. I kept running the same command again and again, trying to figure out what was going on.
Sometimes it would hang up for a long, long time (like 5, 10, 15 minutes) and then come back with the same error message.
But, after some tries, out of the blue, it started working again...
I am mystified, but the fact is that it is working again.
I'll let the issue as reported bellow, but for the time being, IT IS WORKING.
After installing pyhanko 0.7 the command line I've been using for a long time stop working with the following message:
[cut]
File "/home/fernando/.local/lib/python3.8/site-packages/pyhanko/cli.py", line 972, in addsig_pkcs11
with pkcs11.PKCS11SigningContext(pkcs11_config) as signer:
File "/home/fernando/.local/lib/python3.8/site-packages/pyhanko/sign/pkcs11.py", line 310, in __enter__
self._session = session = open_pkcs11_session(
File "/home/fernando/.local/lib/python3.8/site-packages/pyhanko/sign/pkcs11.py", line 72, in open_pkcs11_session
raise PKCS11Error(
pkcs11.exceptions.PKCS11Error: No token with label FERNANDO JOSE CASTRO CABRAL:12436666687's AC VALID RFB v5 ID found
(I know this is a long and strange label, but that's what worked with previous versions.)
Command line:
pyhanko sign addsig --field "1/250,200,410,300/Fernando Cabral" --style-name vereador pkcs11 --lib /usr/lib/libaetpkss.so --token-label "FERNANDO JOSE CASTRO CABRAL:12436666687's AC VALID RFB v5 ID" --cert-label "FERNANDO JOSE CASTRO CABRAL:12436666687's AC VALID RFB v5 ID" "OF047-2021.pdf" "OF047-2021_assinado.pdf"
OS: Linux Mint 20.2, cinnamon edition
Describe the bug
I can install pyHanko normally, but when trying to install python-pkcs11, I get an error message. I know this isn't completely related to this project, but I've reported the bug here and still haven't got an answer. Is there any other way to make pyHanko work with a RSA PKCS1 Smart Card?
To Reproduce
Try to install python-pkcs11 on a new env.
Expected behavior
Have pyHanko installed along with the needed dependencies.
Environment (please complete the following information):
Additional context
I need a way to install python-pkcs11 on a new env, or a way to have pyHanko work with a Smart Card.
My use case is that I want to validate on a server that signatures in certain documents (signed with Adobe Reader) fulfill some specific requirements (comply with PAdES LT or LTA).
This is my fiddle code
with open('extCades_Test document.pdf', 'rb') as doc:
r = PdfFileReader(doc)
sig = r.embedded_signatures[0]
print(sig.signer_cert.subject.native.get('common_name'))
status = validate_pdf_ltv_signature(sig,
RevocationInfoValidationType.PADES_LT,
key_usage_settings = KeyUsageConstraints(key_usage=set(['digital_signature', 'non_repudiation'])),
validation_context_kwargs={'trust_roots': [root_cert2, root_cert, ts_root_cert]})
print(status.pretty_print_details())
which causes this exception:
Traceback (most recent call last):
File "c:\Users\ttwellmann\Desktop\byHanko.py", line 55, in <module>
status = validate_pdf_ltv_signature(sig,
File "C:\Users\ttwellmann\AppData\Local\Programs\Python\Python38\lib\site-packages\pyhanko\sign\validation.py", line 1511, in validate_pdf_ltv_signature
dss = DocumentSecurityStore.read_dss(reader)
File "C:\Users\ttwellmann\AppData\Local\Programs\Python\Python38\lib\site-packages\pyhanko\sign\validation.py", line 1924, in read_dss
for cert_ref in dss_dict.get('/Certs', ()):
TypeError: 'IndirectObject' object is not iterable
The signature in the text document is level B-LT, has an external timestamp and was created with Adobe Reader DC.
Expected behavior
I would have expected that the function returns information about any missing information in the signature, but not an exception
.
Environment (please complete the following information):
Window 10, python 3.8.x, pyHanko 0.4.0
Additional context
I
pyhanko sign addsig --field signature1 --with-validation-info --use-pades pkcs12 output.pdf signed.pdf emudhra.pfx --passfile password.txt
this above is the whole command.
which produces the following error.
`2021-12-04 18:54:37,804 - pyhanko.cli - ERROR - Generic processing error.
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 145, in queue_fetch_task
wait_event: asyncio.Event = running_jobs[tag]
KeyError: 'http://www.e-mudhra.com/repository/cacerts/doccl2.crt'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/pyhanko/cli.py", line 80, in pyhanko_exception_manager
yield
File "/usr/local/lib/python3.9/site-packages/pyhanko/cli.py", line 831, in addsig_simple_signer
generic_sign_pdf(
File "/usr/local/lib/python3.9/site-packages/pyhanko/cli.py", line 841, in generic_sign_pdf
result = signers.PdfSigner(
File "/usr/local/lib/python3.9/site-packages/pyhanko/sign/signers/pdf_signer.py", line 1220, in sign_pdf
result = asyncio.run(
File "/usr/local/Cellar/[email protected]/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/local/Cellar/[email protected]/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/usr/local/lib/python3.9/site-packages/pyhanko/sign/signers/pdf_signer.py", line 1272, in async_sign_pdf
await signing_session.perform_presign_validation(pdf_out)
File "/usr/local/lib/python3.9/site-packages/pyhanko/sign/signers/pdf_signer.py", line 1419, in perform_presign_validation
signer_path = await self._perform_presign_signer_validation(
File "/usr/local/lib/python3.9/site-packages/pyhanko/sign/signers/pdf_signer.py", line 1476, in _perform_presign_signer_validation
await validator.async_validate_usage(key_usage)
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/init.py", line 283, in async_validate_usage
await self._validate_path()
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/init.py", line 127, in _validate_path
paths = await self._context.certificate_registry.async_build_paths(
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/registry.py", line 425, in async_build_paths
await self._walk_issuers(path, paths, failed_paths)
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/registry.py", line 477, in _walk_issuers
async for issuer in self.fetcher.fetch_cert_issuers(path.first):
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 69, in fetch_cert_issuers
fetched_certs = await self.fetch_certs(
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 56, in fetch_certs
return await self._perform_fetch(url, task)
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/util.py", line 37, in _perform_fetch
return await queue_fetch_task(
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 176, in queue_fetch_task
return _return_or_raise(result)
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 181, in _return_or_raise
raise result
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 163, in queue_fetch_task
result = await async_fun()
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/requests_fetchers/cert_fetch_client.py", line 55, in task
return list(results)
File "/usr/local/lib/python3.9/site-packages/pyhanko_certvalidator/fetchers/common_utils.py", line 38, in unpack_cert_content
yield x509.Certificate.load(response_data)
File "/usr/local/lib/python3.9/site-packages/asn1crypto/core.py", line 230, in load
value, _ = _parse_build(encoded_data, spec=spec, spec_params=kwargs, strict=strict)
File "/usr/local/lib/python3.9/site-packages/asn1crypto/core.py", line 5672, in _parse_build
return (_build(*info, spec=spec, spec_params=spec_params), new_pointer)
File "/usr/local/lib/python3.9/site-packages/asn1crypto/core.py", line 5568, in _build
raise ValueError(unwrap(
ValueError: Error parsing asn1crypto.x509.Certificate - tag should have been 16, but 13 was found
Error: Generic processing error.`
Describe the bug
Error on file parsing during validation of signed file.
>python -mpyhanko sign validate --pretty-print testdata\assinado_com_web_socket.pdf
2021-05-21 17:00:19,316 - pyhanko.cli - ERROR - Generic processing error.
Traceback (most recent call last):
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\cli.py", line 69, in pyhanko_exception_manager
yield
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\cli.py", line 421, in validate_signatures
r = PdfFileReader(infile)
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\pdf_utils\reader.py", line 605, in __init__
self.read()
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\pdf_utils\reader.py", line 940, in read
self._read_xrefs()
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\pdf_utils\reader.py", line 875, in _read_xrefs
startxref = self._read_xref_stream()
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\pdf_utils\reader.py", line 825, in _read_xref_stream
idnum, generation = read_object_header(stream, strict=self.strict)
File "C:\Users\guilhermec\source\repos\pyHanko\pyhanko\pdf_utils\reader.py", line 447, in read_object_header
return int(idnum), int(generation)
ValueError: invalid literal for int() with base 10: b'f'
Error: Generic processing error.
To Reproduce
python -mpyhanko sign validate --pretty-print testdata\assinado_com_web_socket.pdf
assinado_com_web_socket.pdf
Expected behavior
File should be invalid, unless added the AC file to the trusted file
Environment (please complete the following information):
I have a PDF with a signature (with an external timestamp) and a separate second timestamp (for the purpose of LTA compliance). I want to validate all embedded signatures with validate_pdf_signature(..).
reader.embedded_signatures is in this case a list of two objects.
The validation works fine for the first signature, but when the function is applied to the separate timestamp the following exception is raised:
File "C:\Users\digisig-service\Desktop\SigningCenter\manager\signature.py", line 35, in validateAllSignatures
status = validate_pdf_signature(signature,
File "C:\Program Files\Python38\lib\site-packages\pyhanko-0.6.0.dev1-py3.8.egg\pyhanko\sign\validation.py", line 1201, in validate_pdf_signature
raise SignatureValidationError("Signature object type must be /Sig")
pyhanko.sign.general.SignatureValidationError: Signature object type must be /Sig
It seems that the function should/can only be applied to embedded signatures that are actually true signatures. But how can I check if an EmbeddedPDFSignature object is a true signature or just a simple timestamp that should not be used as input to validate_pdf_signature(..)? Or should validate_pdf_signature(..) actually also work correctly with timestamps?
Best regards
Thorsten
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.