Giter Site home page Giter Site logo

m32 / endesive Goto Github PK

View Code? Open in Web Editor NEW
238.0 238.0 93.0 14.94 MB

en-crypt, de-crypt, si-gn, ve-rify - smime, pdf, xades and plain files in pure python

License: MIT License

Python 99.93% Shell 0.07%
asn1 cryptography decrypt encrypt pdf pkcs11 python signin smime xades

endesive's People

Contributors

arbitrage0 avatar barroff avatar bebuk avatar bnznamco avatar chibiegg avatar gungoren avatar hamarituc avatar m32 avatar oh-mycode avatar philipgian avatar schorschii avatar thomasbinsfeld avatar tmudunuri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

endesive's Issues

OCSP, crls response and timestamp

Is there a plan to include OCSP, crls response to CMS envelope along with time stamp. Currently field in CMS for OCSP response is blank.

Please suggest workarounds if possible for timestamp using timestamp service.

Using different schemas for XAdES

I would like to know if it is possible to use a different .xsd eschema for the XAdES signature. I tried changing the http links in lines 12, 14, 38 (which point to schema files) in bes.py to no avail.

Second signature

1)After the update, a new problem came out. When I sign a document with user 1, then its signature is put as a certificate, and not as a signature. And when I sign this document by user 2, his signature is not put. It doesn’t cause any errors, but only the certificate of user 1 is in the file, and there is no way to sign the document by user 2.
221_Политология_Великова Нина Сергеевна.pdf
2)when i use 'signaturebox' and 'signature' :
Internal Server Error: /api/teachers/pdf/orders/sign/7569/
Traceback (most recent call last):
File "D:\test_projects\mrs25\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "D:\test_projects\mrs25\venv\lib\site-packages\rest_framework\views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "D:\test_projects\mrs25\venv\lib\site-packages\rest_framework\views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "D:\test_projects\mrs25\venv\lib\site-packages\rest_framework\views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "D:\test_projects\mrs25\scores\views\teachers.py", line 48, in post
f = self.get_sign_method()
File "D:\test_projects\mrs25\scores\views\teachers.py", line 39, in get_sign_method
return pdfworker.sign()
File "D:\test_projects\mrs25\scores\helpers.py", line 391, in sign
'sha256'
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\cms.py", line 501, in sign
return cls.sign(datau, udct, key, cert, othercerts, algomd, hsm, timestampurl)
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\cms.py", line 399, in sign
self.makepdf(prev, udct, algomd, zeros)
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\cms.py", line 268, in makepdf
pdfa = annotation.as_pdf_object(identity(), page=page0ref)
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\PyPDF2_annotate\annotations\base.py", line 65, in as_pdf_object
transform,
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\PyPDF2_annotate\annotations\base.py", line 170, in _make_appearance_stream_dict
stream = self.make_appearance_stream()
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\PyPDF2_annotate\annotations\text.py", line 265, in make_appearance_stream
line_spacing=A.line_spacing,
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\PyPDF2_annotate\annotations\text.py", line 294, in get_text_commands
path=HELVETICA_PATH, font_name=DEFAULT_BASE_FONT, font_size=font_size
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\PyPDF2_annotate\util\true_type_font.py", line 30, in get_true_type_font
font = TrueTypeFont(path, font_name, font_size)
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\PyPDF2_annotate\util\true_type_font.py", line 43, in init
self._ttfFont = TTFont(self.ttfPath)
File "D:\test_projects\mrs25\venv\lib\site-packages\fontTools\ttLib\ttFont.py", line 122, in init
file = open(file, "rb")
FileNotFoundError: [Errno 2] No such file or directory: 'D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\PyPDF2_annotate\annotations\..\fonts\Helvetica.ttf'
3)Where and how can I read about dictionary parameter keys

Acrobat Reader shows first page blank after signing

I have signed a few documents and while signatures are ok and the documents are visible in all kinds of pdf viewers, some have a blank first page in Acrobat Reader (2019.010.20099)

I have uploaded a simple file made with Libre Office export that acts this way. Before sign the page content is visible. after sign content is invisible, Acrobat shows signature present and valid.

test.pdf
test-signed-cms.pdf

'PDFXRefStream' object has no attribute 'offsets'

Hi,

Thanks for sharing, quite useful!

I encountered this error below when trying the example "pdf-sign-cms.py" on my own pdf.
any idea how to solve this?
`---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in ()
15 p12.get_certificate().to_cryptography(),
16 [],
---> 17 'sha256'
18 )
19 with open('pdf-signed-cms.pdf', 'wb') as fp:

/home/ubuntu/anaconda3/lib/python3.6/site-packages/endesive/pdf/cms.py in sign(datau, udct, key, cert, othercerts, algomd)
147 def sign(datau, udct, key, cert, othercerts, algomd):
148 cls = SignedData()
--> 149 return cls.sign(datau, udct, key, cert, othercerts, algomd)

/home/ubuntu/anaconda3/lib/python3.6/site-packages/endesive/pdf/cms.py in sign(self, datau, dct, key, cert, othercerts, algomd)
120 zeros = self.aligned(b'\0')
121
--> 122 pdfdata2 = self.makepdf(datau, dct, zeros)
123
124 startxref = len(datau)

/home/ubuntu/anaconda3/lib/python3.6/site-packages/endesive/pdf/cms.py in makepdf(self, pdfdata1, udct, zeros)
51 page = document.getobj(document.catalog['Pages'].objid)['Kids'][0].objid
52
---> 53 infodata = self.getdata(pdfdata1, info, prev, document).strip()
54 rootdata = self.getdata(pdfdata1, root, prev, document).strip()
55 pagedata = self.getdata(pdfdata1, page, prev, document).strip()

/home/ubuntu/anaconda3/lib/python3.6/site-packages/endesive/pdf/cms.py in getdata(self, pdfdata1, objid, startxref, document)
29 i1 = startxref
30 for xref in document.xrefs:
---> 31 for (_, offset, _) in xref.offsets.values():
32 if offset > i0:
33 i1 = min(i1, offset)

AttributeError: 'PDFXRefStream' object has no attribute 'offsets'`

How to sign with multiple signatures?

I've tried to sign with both signatures in different ways, but never got how to do it. The cms.sign function supports a list of certificates, but there is no list of keys/passwords to pair with it. Tried add to the list a certificate without password, it didn't worked also. Could you provide an example where both p12 files are used to sign cumulatively the PDF file?

Problem signing pdf

Hi, referencing to the examples, I've got following problem, when trying to sign a pdf:

In [47]: main()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-47-263240bbee7e> in <module>
----> 1 main()

<ipython-input-46-40e4111ea6e4> in main()
     17         )
     18         datau = open(pdf_orig, 'rb').read()
---> 19         datas = pdf.cms.sign(datau, dct, p12[0], p12[1], [], 'sha256')
     20         with open(pdf_signed, 'wb') as fp:
     21                 fp.write(datau)

C:\Anaconda3\lib\site-packages\endesive\pdf\cms.py in sign(datau, udct, key, cert, othercerts, algomd, hsm)
    318 def sign(datau, udct, key, cert, othercerts, algomd, hsm=None):
    319     cls = SignedData()
--> 320     return cls.sign(datau, udct, key, cert, othercerts, algomd, hsm)

C:\Anaconda3\lib\site-packages\endesive\pdf\cms.py in sign(self, datau, dct, key, cert, othercerts, algomd, hsm)
    309         md = md.digest()
    310
--> 311         contents = signer.sign(None, key, cert, othercerts, algomd, True, md, hsm)
    312         contents = self.aligned(contents)
    313         pdfdata2 = pdfdata2.replace(zeros, contents, 1)

C:\Anaconda3\lib\site-packages\endesive\signer.py in sign(datau, key, cert, othercerts, hashalgo, attrs, signed_value, hsm)
     30         othercerts = []
     31     else:
---> 32         cert = cert2asn(cert)
     33
     34     certificates = []

C:\Anaconda3\lib\site-packages\endesive\signer.py in cert2asn(cert, cert_bytes)
     13 def cert2asn(cert, cert_bytes=True):
     14     if cert_bytes:
---> 15         cert_bytes = cert.public_bytes(serialization.Encoding.PEM)
     16     else:
     17         cert_bytes = cert

AttributeError: 'Certificate' object has no attribute 'public_bytes'

Here is my code, I used:

#!/usr/bin/env python3
# *-* coding: utf-8 *-*
from oscrypto import asymmetric
from endesive import pdf
from datetime import datetime
from time import gmtime, strftime

pwd = "password"
p12_fn=r'cert.p12'
pdf_orig = r"original.pdf"
pdf_signed = pdf_orig.replace(".pdf", "_sign.pdf")

def main():
	dt="".join(map(str, [*datetime.now().timetuple()][:6]))
	tz = strftime("%z", gmtime())
	tzf = f"{tz[:3]}'{tz[3:]}'"
	dt += tzf
	
	dct = {
		b'sigflags': 3,
		b'contact': b'[email protected]',
		b'location': b'Location',
		b'signingdate': dt.encode(),    # b'20180731082642+02\'00\'',  
		b'reason': 'any reason'.encode(),
		b'signature_value': b'My Name',
		b'signaturebox': (0, 0, 100, 100)
	}
	p12 = asymmetric.load_pkcs12(
		open(p12_fn, 'rb').read(),
		pwd
	)
	datau = open(pdf_orig, 'rb').read()
	datas = pdf.cms.sign(datau, dct, p12[0], p12[1], [], 'sha256')
	with open(pdf_signed, 'wb') as fp:
		fp.write(datau)
		fp.write(datas)

main()

My dependencies are:

(base) C:\Anaconda3>pip freeze | grep oscrypto
oscrypto==1.0.0

(base) C:\Anaconda3>pip freeze | grep endesive
endesive==1.2.0

(base) C:\Anaconda3>python -V
Python 3.7.3

Cloud based HSM signing

Hi,

Can endesive sign pdfs using some form of cloud based signature (Smartcard, USB or HSM)?

Thx!

Sign xml attached mode

The signer in xadesbes format only sign in embebed mode, is possible the attached mode?

When i try to sign pdf

raceback (most recent call last):
File "pdfSigner.py", line 35, in
main()
File "pdfSigner.py", line 28, in main
'sha512'
File "/Users/nikhil.p/.local/share/virtualenvs/pdfSigner-bDNO_miT/lib/python3.7/site-packages/endesive/pdf/cms.py", line 320, in sign
return cls.sign(datau, udct, key, cert, othercerts, algomd, hsm)
File "/Users/nikhil.p/.local/share/virtualenvs/pdfSigner-bDNO_miT/lib/python3.7/site-packages/endesive/pdf/cms.py", line 311, in sign
contents = signer.sign(None, key, cert, othercerts, algomd, True, md, hsm)
File "/Users/nikhil.p/.local/share/virtualenvs/pdfSigner-bDNO_miT/lib/python3.7/site-packages/endesive/signer.py", line 66, in sign
'values': (cms.Time({'utc_time': core.UTCTime(signed_time)}),)
File "/Users/nikhil.p/.local/share/virtualenvs/pdfSigner-bDNO_miT/lib/python3.7/site-packages/asn1crypto/core.py", line 1677, in init
raise e
File "/Users/nikhil.p/.local/share/virtualenvs/pdfSigner-bDNO_miT/lib/python3.7/site-packages/asn1crypto/core.py", line 1669, in init
self.set(value)
File "/Users/nikhil.p/.local/share/virtualenvs/pdfSigner-bDNO_miT/lib/python3.7/site-packages/asn1crypto/core.py", line 4986, in set
raise ValueError('Must be timezone aware')
ValueError: Must be timezone aware
while constructing asn1crypto.core.UTCTime

AttributeError: 'Certificate' object has no attribute 'public_bytes'

Traceback (most recent call last):
File "s4.py", line 36, in
main()
File "s4.py", line 31, in main
datas = pdf.cms.sign(datau, dct, p12[0], p12[1], [], 'sha256')
File "/home/viraj/anaconda3/lib/python3.6/site-packages/endesive-1.4.4-py3.6.egg/endesive/pdf/cms.py", line 384, in sign
return cls.sign(datau, udct, key, cert, othercerts, algomd, hsm, timestampurl)
File "/home/viraj/anaconda3/lib/python3.6/site-packages/endesive-1.4.4-py3.6.egg/endesive/pdf/cms.py", line 375, in sign
contents = signer.sign(None, key, cert, othercerts, algomd, True, md, hsm, False, timestampurl)
File "/home/viraj/anaconda3/lib/python3.6/site-packages/endesive-1.4.4-py3.6.egg/endesive/signer.py", line 38, in sign
cert = cert2asn(cert)
File "/home/viraj/anaconda3/lib/python3.6/site-packages/endesive-1.4.4-py3.6.egg/endesive/signer.py", line 22, in cert2asn
cert_bytes = cert.public_bytes(serialization.Encoding.PEM)
AttributeError: 'Certificate' object has no attribute 'public_bytes'

Timestamp server authentication

Hi,

First of all thank you for your work. This library is great!

We need to sign our PDFs with a timestamp provided by a timestamp server that requires basic access authentication. I don't think this is possible now but we'd like to help implementing it.

I was thinking on adding a new optional parameter to the function:

def sign(
    datau, udct, key, cert, othercerts, algomd="sha1", hsm=None, timestampurl=None
):

Would be this ok with you?

Unable to sign a PDF twice

Description

When I tried to sign a document that has already been signed, the new signature does no appear.

Pre

  • Python3.8 or Python3.7
  • Endesive version: 1.5.10

Reproduce Steps

  1. We create two certificates using the example script cert-make.py (demo2_user1.p12 & demo2_user2.p12)
  2. We sign the pdf with the certificate "demo2_user1.p12".
  3. We open the new pdf with a viewer and we see the signature (USER 1).
  4. We sign the new pdf with the certificate "demo2_user2.p12".
  5. We open the new pdf with a viewer and we only see a signature (USER 1), user2's signature has not been applied.

Code

import datetime
import sys

from cryptography.hazmat import backends
from cryptography.hazmat.primitives.serialization import pkcs12
from endesive.pdf import cms


def sign_pdf(pdf_path, certificate_path, certificate_password, contact, location, reason, output_path):
    """Sign a pdf using a certificate."""
    date = datetime.datetime.utcnow().strftime("D:%Y%m%d%H%M%S+00'00'")
    dct = {
        'signingdate': date,
        'contact': contact,
        'location': location,
        'reason': reason,
    }
    with open(certificate_path, 'rb') as certificate_binary:
        p12 = pkcs12.load_key_and_certificates(
            certificate_binary.read(),
            bytearray(certificate_password, 'utf-8'),
            backends.default_backend()
        )

        file_binary = open(pdf_path, 'rb').read()
        datas = cms.sign(file_binary, dct, p12[0], p12[1], p12[2], 'sha256')
        with open(output_path, 'wb') as output_binary:
            output_binary.write(file_binary)
            output_binary.write(datas)


sign_pdf(pdf_path=sys.argv[1],
         certificate_path=sys.argv[2],
         certificate_password=sys.argv[3],
         contact=sys.argv[4],
         location=sys.argv[5],
         reason=sys.argv[6],
         output_path=sys.argv[7])

Use

python3.8 sign_pdf.py "example.pdf" "demo2_user1" "1234" "[email protected]" "Europe/Berlin" "test" "example_user1.pdf"

Thank you very much! (:

KeyError: 'OpenAction'

Was trying to sign a pdf using the example code, 2/3 pdf samples: I got an error. Here is the trace.
Traceback (most recent call last): File "./pdf-sign-cms.py", line 25, in <module> main() File "./pdf-sign-cms.py", line 19, in main datas = pdf.cms.sign(datau, dct, p12[0], p12[1], [], 'sha256') File "../endesive/pdf/cms.py", line 152, in sign return cls.sign(datau, udct, key, cert, othercerts, algomd) File "../endesive/pdf/cms.py", line 125, in sign pdfdata2 = self.makepdf(datau, dct, zeros) File "../endesive/pdf/cms.py", line 52, in makepdf for i in document.catalog['OpenAction']: KeyError: 'OpenAction'

Signed pdf does not comply with pdf/a standards

I have signed a pdf/a-2b file that already confirms with its standards, however after adding signature, the resulting pdf fails vera/acrobat test flight verification.

dummy_pdfa_2b-signed-cms.pdf
dummy_pdfa_2b.pdf

`
Validation Report
Validation Profile: PDF/A-2B validation profile
PDF/A compliance: Failed
Statistics
Version: 1.12.1
Parser: GreenField
Build Date: 2018-05-08T22:06:00+05:30
Processing time: 00:00:00.312
Total rules in Profile: 121
Passed Checks: 578
Failed Checks: 3
Validation information
Rule Status
Specification: ISO 19005-2:2011, Clause: 6.1.6, Test number: 1
Hexadecimal strings shall contain an even number of non-white-space characters Failed
2 occurrences Hide
CosString
(isHex != true) || hexCount % 2 == 0
root/trailer[0]/values[3]/elements[0]
root/trailer[0]/values[3]/elements[1]

Specification: ISO 19005-2:2011, Clause: 6.3.3, Test number: 2
For all annotation dictionaries containing an AP key, the appearance dictionary that it defines as its value shall contain only the N key. If an annotation dictionary's Subtype key has a value of Widget and its FT key has a value of Btn, the value of the N key shall be an appearance subdictionary, otherwise the value of the N key shall be an appearance stream. Failed
1 occurrences Hide
PDAnnot
AP == null || ( AP == "N" && ( ((Subtype != "Widget" || FT != "Btn") && N_type == "Stream") || (Subtype == "Widget" && FT == "Btn" && N_type == "Dict") ) )
root/document[0]/pages[0](11 0 obj PDPage)/annots[0](21 0 obj PDAnnot)

`

UnicodeEncodeError: 'latin-1' codec can't encode characters in position 61-66: ordinal not in range(256)

def main(request):
    try:
        # Load the PKCS12 object from the pfx file
        p12 = load_pfx(path.join(settings.MEDIA_ROOT, 'cer', '12152.pfx'), '123')

        subject = p12.get_certificate().get_subject()
        timezone = pytz.timezone('Asia/Calcutta')
        # default coords of bottom right corner in a pdf page
        coords = [350, 50, 550, 150]  # Координаты где будет подпись!
        # coords = [int(coord) for coord in args.coords.split(',') if coord]
        page = 1  # страница где будет подпись
        dest = path.join(settings.MEDIA_ROOT, 'pdf','signed.pdf')  # Путь где сохранить подписанный подф
        date = datetime.datetime.utcnow() - datetime.timedelta(hours=12)
        date = date.strftime('%Y%m%d%H%M%S+00\'00\'')
        signature = signature_string(subject.CN, date, subject.C)
        dct = {
            b'sigflags': 3,
            b'sigpage': page - 1,
            b'contact': b'[email protected]',
            # b'location': subject.C.encode(),
            b'location': b'Szczecin',
            b'signingdate': date.encode(),
            b'signingdate': b'20191122082642+02\'00\'',
            b'reason': b'Signed by endurance',
            b'signature': signature.encode(),
            b'signaturebox': tuple(coords[:4]),
        }
        print(settings.BASE_DIR)
        input_file = path.join(settings.BASE_DIR, 'pdf.pdf')  # Путь к самому пдф файлу
        datau = open(input_file, 'rb').read()
        print(sys.getfilesystemencoding())
        print(locale.getpreferredencoding())
        datas = pdf.cms.sign(datau,
                             dct,
                             p12.get_privatekey().to_cryptography_key(),
                             p12.get_certificate().to_cryptography(),
                             [],
                             'utf-8'
                             )

        output_file = input_file.replace(input_file, dest)
        with open(output_file, 'wb') as fp:
            fp.write(datau)
            fp.write(datas)
    except Exception as e:
        import traceback;
        traceback.print_exc()
        eprint(e)
        sys.exit()

Traceback (most recent call last):
File "D:\test_projects\sign_pdf\sign\views.py", line 82, in main
'utf-8'
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 377, in sign
return cls.sign(datau, udct, key, cert, othercerts, algomd, hsm)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 350, in sign
pdfdata2 = self.makepdf(datau, dct, zeros)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 301, in makepdf
visualization, nav = self.makevisualization(no, udct, nsig, page)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 269, in makevisualization
return self.textvisual(no, udct, nsig, page)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 194, in textvisual
visual, nav = self.makeannotation(pdfao, no+4)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 173, in makeannotation
result += b'stream\n%s\nendstream\n' % stream.encode('latin1')
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 61-66: ordinal not in range(256)
'latin-1' codec can't encode characters in position 61-66: ordinal not in range(256)
Traceback (most recent call last):
File "D:\test_projects\sign_pdf\sign\views.py", line 82, in main
'utf-8'
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 377, in sign
return cls.sign(datau, udct, key, cert, othercerts, algomd, hsm)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 350, in sign
pdfdata2 = self.makepdf(datau, dct, zeros)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 301, in makepdf
visualization, nav = self.makevisualization(no, udct, nsig, page)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 269, in makevisualization
return self.textvisual(no, udct, nsig, page)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 194, in textvisual
visual, nav = self.makeannotation(pdfao, no+4)
File "D:\test_projects\sign_pdf\venv\lib\site-packages\endesive\pdf\cms.py", line 173, in makeannotation
result += b'stream\n%s\nendstream\n' % stream.encode('latin1')
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 61-66: ordinal not in range(256)
Constantly getting this error. I tried changing the encoding did not help. I don’t know what to do

xref dict empty causes cms.py to fail

For some PDFs while calculating the last object ID the check
no = max(ref.offsets.keys())
fails. This is line number 159 in cms.py due to the dict being empty. Because of unhandled condition the program fails. Attaching sample document, I think the work around probably is to not do the max if dict is empty.
ABC_PO sample.pdf

Show Certificate Symbol

Thank you for the library.

I am able to sign the document but I am unable to make it as certified symbol on signature panel, it always comes as signed. Is there a parameter to be passed. As shown in the image attached.

Also please suggest if it is possible to add multiple signatures.
Screenshot 2019-04-11 at 9 44 37 PM

regression from >1.4.x (Python3.8)

There was an incompatible change for versions of endesive > 1.4.5 (starting with 1.5.0).

working code for 1.4.5:

now = datetime.datetime.now().isoformat().encode('utf-8')
signature = endesive.pdf.cms.sign(
    pdf_bytes,
    {
        b'sigflags': 3,
        b'sigbutton': True,
        b'contact': b'[email protected]',
        b'location': b'example',
        b'signingdate': now,
        b'reason': b'signed as an example',
      },
     pk.to_cryptography_key(), # loaded with OpenSSL.crypto.load_privatekey
     cert.to_cryptography(), # loaded with OpenSSL.crypto.load_certificate
     [],
     'sha256',
)

starting with 1.5.0, the dict values are expected as strs - no problem, changed that.

After doing those adjustments, however, the resulting PDF signature is significantly smaller than with 1.4.x. They are no longer recognised, e.g. by LibreOffice Impress.

After looking through the inline-documentation + Code, I could not figure out what else I need to adjust. So my assumption is that this is a bug

When I sign a document, adobe reader shows it as certified instead of signed

Hey, first of all, thanks for all the awesome work with this library. The new update looks great except for this one issue I noticed. I updated the package from 1.4.5 to 1.5.7 and noticed an issue where after signing the document, adobe reader shows it as "Certified by" instead of "Signed by" as it used to do earlier.

In 1.4.5 -
Screenshot 2020-06-05 at 12 41 51 PM
In 1.5.7 -
Screenshot 2020-06-05 at 12 42 59 PM

For multiple signatures, the first signature shows up as "Certified by" and the rest show up as "Signed by" -
Screenshot 2020-06-05 at 1 15 17 PM

Is there a way to always sign instead of certify since the semantics for both are different?

PDFXRefStream vs PDFXRef

Thanks for library. I am trying to use it to sign PDF document. It seems the PDF documents are of two types one having PDFXRef and another with PDFXRefStream. The library signs perfectly well when the PDF is of type PDFXRef. But fails when the document is made of PDFXRefStream with attribute 'offset not found' on line 31 in cms.py.

I have attached documents to which I have used to test
test.pdf - made using Google Docs (PDFXRefStream)
test1.pdf - made using Google Slides (PDFXRef)

Just wanted to check ifI can request handling PDFXRefStream type PDF. Or suggest way to approach doing it.

Test.pdf
test1.pdf

signer with hsm ignores othercerts

Hi,

I just wanted to know if null'ing othercerts in the signer is required when using an HSM.

def sign(datau, key, cert, othercerts, hashalgo, attrs=True, signed_value=None, hsm=None, pss=False, timestampurl=None):
if signed_value is None:
signed_value = getattr(hashlib, hashalgo)(datau).digest()
signed_time = datetime.now(tz=util.timezone.utc)
if hsm is not None:
keyid, cert = hsm.certificate()
cert = cert2asn(cert, False)
othercerts = []

Currently is not possible to sign with an HSM and have a valid certificate chain embedded in the signature.
It is possible to retain current behavior by providing empty othercerts when using an HSM.

Therefore I propose to drop the line.

Multiple signatures don't show up in adobe reader

Hey, I just updated the package from 1.4.5 to 1.5.7 and noticed an issue with signing a document multiple times. When I sign a document twice, both the signature images show up in the chrome pdf reader (and preview on mac), but when I open it in Adobe reader, only the image for the first signature shows up. This was working in version 1.4.5.

In preview -
Screenshot 2020-06-05 at 12 39 10 PM
Same document in adobe reader -
Screenshot 2020-06-05 at 12 39 38 PM

You can find this document here - https://drive.google.com/file/d/1TvW1j4t8_V-ee50R2TkEy7InmliDsFBv/view
Original document before signing - https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf

Also, another issue I noticed is that now instead of signing the document, the library certifies the document.
Earlier in adobe reader -
Screenshot 2020-06-05 at 12 41 51 PM
Now in adobe reader -
Screenshot 2020-06-05 at 12 42 59 PM

The expectation while using the library is to sign and not to certify so I'm not sure why that changed. Could this also be the reason why multiple signatures don't show up in adobe reader? Can you help me with this?

Not found library pkcs12

Error at execute example pdf_verify.py
It is the error message:

File "/usr/local/lib/python3.6/dist-packages/endesive/pdf/cms.py", line 12, in
from cryptography.hazmat.primitives.serialization import pkcs12
ImportError: cannot import name 'pkcs12'

I' cant find pkcs12. Any suggestion?
Thanks

Ubuntu 18 - Python 3.6

PDFObjectNotFound

Sorry, I can’t understand what this error is and why it comes out? When I sign it a second time, some files are signed normally, others are not.
def sign(self): self.sign_step = True p12 = load_pkcs12(open(self.cert_path, "rb").read(), bytes(self.password, encoding="utf-8")) formed_file = self.pdf_file self.draw() images = convert_from_path(os.path.join(settings.BASE_DIR, "cer", "sign_pdfs", str(self.user.id) + ".pdf"), 600) images[0].save(os.path.join(settings.BASE_DIR, "cer", "sign_pngs", str(self.user.id) + ".png"), "PNG") pdf_bytes = open(formed_file.name, "rb").read() dct = self.dct

    signature = pdf.cms.sign(pdf_bytes, dct,
                             p12.get_privatekey().to_cryptography_key(),
                             p12.get_certificate().to_cryptography(),
                             [],
                             'sha256'
                             )
    with io.BytesIO() as f:
        f.write(pdf_bytes)
        f.write(signature)
        signed_pdf = f.getvalue()
    copy = open(str(formed_file.name), 'wb')
    copy.write(signed_pdf)
    copy.close()
    self.instance.save_signed(self.step)
    return formed_file 

Traceback (most recent call last):
File "D:\test_projects\mrs25\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "D:\test_projects\mrs25\venv\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "D:\test_projects\mrs25\venv\lib\site-packages\rest_framework\views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "D:\test_projects\mrs25\venv\lib\site-packages\rest_framework\views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "D:\test_projects\mrs25\venv\lib\site-packages\rest_framework\views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "D:\test_projects\mrs25\scores\views\decanats.py", line 66, in post
f = self.get_sign_method()
File "D:\test_projects\mrs25\scores\views\decanats.py", line 59, in get_sign_method
return pdfworker.sign()
File "D:\test_projects\mrs25\scores\helpers.py", line 377, in sign
'sha256'
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\cms.py", line 377, in sign
return cls.sign(datau, udct, key, cert, othercerts, algomd, hsm)
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\cms.py", line 350, in sign
pdfdata2 = self.makepdf(datau, dct, zeros)
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\cms.py", line 296, in makepdf
infodata = self.getdata(pdfdata1, info, prev, document)
File "D:\test_projects\mrs25\venv\lib\site-packages\endesive\pdf\cms.py", line 111, in getdata
obj = document.getobj(objid)
File "D:\test_projects\mrs25\venv\lib\site-packages\pdfminer\pdfdocument.py", line 706, in getobj
raise PDFObjectNotFound(objid)
pdfminer.pdftypes.PDFObjectNotFound: 17

Must be timezone aware

Recently getting this error from signer.py from signed_time variable --- ' ValueError('Must be timezone aware') while constructing asn1crypto.core.UTCTime'

I think the fix to remove this error is to pass the timezone using pytz. Please check.

datetime.now(tz=pytz.utc).

using PIL image instead of image file

Hello,

Right now, in order to use signature_img we must provide a path to an image file (line 266 of cms.py).

It would help a lot if we could also provide a PIL image, which we have created in the program, without having to save it to a file. If I am not mistaken, pdf_annotate's Appearance can also take a PIL image as input instead of a file. Therefore the issue might probably be easy to solve, and it would save us a needless image save (and then deletion).

Best Regards,

Panos.

The Selected certificate has errors: Not valid for usage.

These are the cases i have tested.

  1. pdf.cms.sign works well with .p12 created from example/cert-make.py

  2. pdf.cms.sign + pdf.verify also works with the same .p12 and CA.crt.pem from example/cert-make.py

  3. pdf.cms.sign with my another .p12 not working. At leas one signature is invalid. And shows as "the selected certificate has errors: Not valid for usage" while my p12 is working with other signer

image

Please help me what is the problem?
This is my code

        with open(fixture(keyname+'.p12'), 'rb') as fh:
            p12 = load_pkcs12(fh.read(), keypwd)

        date = datetime.now()
        strdate1 = date.strftime('%Y.%m.%d')
        subject = p12.get_certificate().get_subject()
        location = str(subject.C)
        signature = signature_string(subject.CN, strdate1, subject.C, reason)
        signature_img = self.makeSignature.create_signature_img(subject.CN, strdate1, location, reason)
        strdate2 = date.strftime('%Y%m%d%H%M%S')

        # print(subject)

        dct = {
            b'sigbutton':b'mysignbutton',
            b'signature' : signature.encode(),
            b'signaturebox':(off_x, off_y, off_x+rr_w, off_y+rr_h),
            b'sigpage': 0,
            b'sigflags': 3,
            b'contact': b'[email protected]',
            b'location': location.encode(),
            # b'signingdate': b'20200331082642+02\'00\'',
            b'signingdate': strdate2.encode(),
            b'reason': reason.encode(),
            b'fontsize': 8,
            b'signature_img': signature_img.encode(),
        }
        with open(pdfname, 'rb') as fh:
            datau = fh.read()
        datas = pdf.cms.sign(datau, dct,
            p12.get_privatekey().to_cryptography_key(),
            p12.get_certificate().to_cryptography(),
            [],
            'sha256'
        )
        pdfname = pdfname.replace('.pdf', '-signed.pdf')
        with open(pdfname, 'wb') as fp:
            fp.write(datau)
            fp.write(datas)


        # with open(fixture(verifyname+'.crt.pem'), 'rt') as fh:
        #     trusted_cert_pems = (fh.read(),)
        # print(trusted_cert_pems)
        # with open(pdfname, 'rb') as fh:
        #     data = fh.read()
        
        # (hashok, signatureok, certok) = pdf.verify(data, trusted_cert_pems)
        # assert signatureok and hashok and certok

%x format: a number is required, not str

I trying to sign a pdf using the example code pdf-sign-cms.py, 2/3 pdf samples: I got an error.

%x format: a number is required, not str

at /endesive/pdf/cms.py in aligned, line 15

PDF verification failing

Hi,
I was trying to perform full process of signing pdf and verification, but every time last result of verification (cert_ok) fails. OpenSSL signals 'certificate signature failure'. It seems like retriving user certificate from signature is not working properly (but that's just my guess). Any chance of fixing that issue?

Thanks!

AttributeError: 'PublicKeyInfo' object has no attribute 'issuer'

running these scripts in sequence.

python cert-make.py
python pdf-make.py
python pdf-sign-cms.py

produces

Traceback (most recent call last):
File "pdf-sign-fpdf.py", line 26, in
main()
File "pdf-sign-fpdf.py", line 23, in main
doc.output('pdf-signed-fpdf.pdf', "F")
File "C:\HOMEWARE\Anaconda3-Windows-x86_64\envs\abc\lib\site-packages\endesive\pdf\fpdf\fpdf.py", line 1065, in output
self.close()
File "C:\HOMEWARE\Anaconda3-Windows-x86_64\envs\abc\lib\site-packages\endesive\pdf\fpdf\fpdf.py", line 246, in close
self._enddoc()
File "C:\HOMEWARE\Anaconda3-Windows-x86_64\envs\abc\lib\site-packages\endesive\pdf\fpdf\fpdf.py", line 1673, in _enddoc
self.pkcs11_sign()
File "C:\HOMEWARE\Anaconda3-Windows-x86_64\envs\abc\lib\site-packages\endesive\pdf\pdf.py", line 65, in pkcs11_sign
signed_md)
File "C:\HOMEWARE\Anaconda3-Windows-x86_64\envs\abc\lib\site-packages\endesive\signer.py", line 23, in sign
'issuer': cert.asn1.issuer,
AttributeError: 'PublicKeyInfo' object has no attribute 'issuer'

After a bit of digging, it seems that the information has been lost during the export function in the pkcs12.py

serial_number is also lost during the process which are required in the sign stage later.

Would you be able to take a look? Thanks.

error while installing through pip

i am facing an error while installing endesive through pip. the error follows down below, please help as i am very new to all this.

Installing collected packages: pykcs11, endesive
Running setup.py install for pykcs11 ... error
ERROR: Command errored out with exit status 1:
command: /Users/rishavsharma/PycharmProjects/signpdf/venv/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/fj/1p_6x9n93j541nl1_ny6rkyh0000gp/T/pip-install-jmwleh31/pykcs11/setup.py'"'"'; file='"'"'/private/var/folders/fj/1p_6x9n93j541nl1_ny6rkyh0000gp/T/pip-install-jmwleh31/pykcs11/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /private/var/folders/fj/1p_6x9n93j541nl1_ny6rkyh0000gp/T/pip-record-5gh_4ps5/install-record.txt --single-version-externally-managed --compile --install-headers /Users/rishavsharma/PycharmProjects/signpdf/venv/include/site/python3.8/pykcs11
cwd: /private/var/folders/fj/1p_6x9n93j541nl1_ny6rkyh0000gp/T/pip-install-jmwleh31/pykcs11/
Complete output (8 lines):
running install
running build
running build_ext
building 'PyKCS11._LowLevel' extension
swigging src/pykcs11.i to src/pykcs11_wrap.cpp
swig -python -c++ -o src/pykcs11_wrap.cpp src/pykcs11.i
unable to execute 'swig': No such file or directory
error: command 'swig' failed with exit status 1
----------------------------------------
ERROR: Command errored out with exit status 1: /Users/rishavsharma/PycharmProjects/signpdf/venv/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/fj/1p_6x9n93j541nl1_ny6rkyh0000gp/T/pip-install-jmwleh31/pykcs11/setup.py'"'"'; file='"'"'/private/var/folders/fj/1p_6x9n93j541nl1_ny6rkyh0000gp/T/pip-install-jmwleh31/pykcs11/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /private/var/folders/fj/1p_6x9n93j541nl1_ny6rkyh0000gp/T/pip-record-5gh_4ps5/install-record.txt --single-version-externally-managed --compile --install-headers /Users/rishavsharma/PycharmProjects/signpdf/venv/include/site/python3.8/pykcs11 Check the logs for full command output.

Images in signatures broken >= 1.5.3

Using images to produce signatures seems to be broken as of version 1.5.3.
3 Heights online validator returns some errors with v1.5.3, but not with 1.5.2. I'm using a .png file for a signature, but have also tried .jpg.

Passing the signature file either as an argument or a PIL object seems to make no diference.

Screenshot 2020-05-05 at 14 24 15
Screenshot 2020-05-05 at 14 23 01

signingCertificateV2 obj in the signed attributes

Hi, i'm trying to sign a pdf with pkcs11 using your library.
I have to generate this structure in the 'signed_attrs':

SEQUENCE (2 elem)
  OBJECT IDENTIFIER 1.2.840.113549.1.9.16.2.47 signingCertificateV2 (S/MIME Authenticated Attributes)
  SET (1 elem)
    SEQUENCE (1 elem)
      SEQUENCE (1 elem)
        SEQUENCE (2 elem)
         SEQUENCE (1 elem)
            OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 (NIST Algorithm)
         OCTET STRING (32 byte) 404AA14FCF1F701A7BD44503BCB34714DF129E4CFD4F9E66893404AA14FCF1F7

To insert signingCertificateV2 as CMSAttribute I've already made a change in the asn1crypto lib but I can't figure out how to continue in that tree structure.
Do you have some advice?

add drawing signature to pdf , and many signer ( endesive python )

hello ,
You have used the electronic signature of endesive ,
The signature works wonderfully, that's what I was looking for almost.
But, I want to enter the signature under a drawing signature like this ,
Screen Shot 2019-04-28 at 12 31 12

and also i need method for many signer for one time ,
if u gave me solution for this problem

thnx

Issue when sign on a iText signature pdf

I have a pdf with a digital signature from iText-5.5.5. After that, I signed again by endesive but two signature break (use Adobe to open file pdf)
issue return: the signature byte range is invalid

pdfsig choking

This library has helped me in signing files made by reportlab. I found that the signed bytes should not include the < > markers in the /Content part of the file. Acrobat reader says the signature is corrupted if those bytes are made part of the signature so thanks for all the work.

However, I find that the pdfsig utility from poppler doesn't like the files produced by endesive I see this
`$ pdfsig pdf-signed-fpdf.pdf
Digital Signature Info of: pdf-signed-fpdf.pdf
Signature #1:

  • Signer Certificate Common Name: USER 1
  • Signer full Distinguished Name: CN=USER 1
  • Signing Time: May 17 2019 17:23:02
  • Signing Hash Algorithm: SHA-256
  • Signature Type: adbe.pkcs7.detached
  • Signed Ranges: [0 - 1396], [17782 - 18111]
  • Total document signed
  • Signature Validation: Signature is Valid.
  • Certificate Validation: Certificate issuer is unknown.
    `
    I guess that is expected as we have a self signed certificate.

If I modify pdf-sign-fpdf.py to use my test p12 file which is based on letsencrypt's chain (I have my cert + the letsencrypt intermediate).

`$ pdfsig pdf-signed-fpdf.pdf
Digital Signature Info of: pdf-signed-fpdf.pdf
Signature #1:

  • Signer Certificate Common Name: reportlab.com
  • Signer full Distinguished Name: CN=reportlab.com
  • Signing Time: May 11 2019 22:19:29
  • Signing Hash Algorithm: SHA-256
  • Signature Type: adbe.pkcs7.detached
  • Signed Ranges: [0 - 1381], [17767 - 18096]
  • Total document signed
  • Signature Validation: Signature is Valid.
  • Certificate Validation: Unknown issue with Certificate or corrupted data.
    `
    however, Acrobat Reader finds these files acceptable and provided I accept the root cert I see things ticked green.

Signing PDF unsuccessful with error

I am getting the following error on signing PDF with cms (using example pdf-sign-cms.py)

File "/Users/user/projects/test/.venv/lib/python3.7/site-packages/endesive/pdf/cms.py", line 276, in makepdf
    info = document.xrefs[0].trailer['Info'].objid
KeyError: 'Info

The PDF is generated from Image. view

I am noob to PDF. Is the PDF invalid? (Adobe Acrobat Preflight check does not give any notice)

What can I do to make signing work? or how can I avoid this error or detect this and get meaning message?

Sign pdf with a signed hash

I used the library to sign pdf with pkcs12 key and its working. Now I want to sign a PDF document with a signed Hash that i receive from user. Can you please guide/refer me to implement such requirement.

Can not print pdf after digital signature in Acrobat reader.

After applying digital signature, the printing fails with message 'The document can not be printed' and 'No page selected for printing' showing up in Acrobat Reader.
Please find below the link of documents -

  • [https://drive.google.com/file/d/1Zkv0vs9gdBXNkdPkJlQ8pCJ19PnpfIV3/view?usp=sharing](Signed PDF)( not being printed.)

  • [https://drive.google.com/file/d/1T4nHVmMw-AjoNvWo7nJOYbDFfaCKDm_E/view?usp=sharing](Unsigned PDF)(Prints fine.)

I use Mac OS(v10.14) and Acrobat Reader (v19.12.20040.345140); I used OpenSSL's load_pkcs12 function for signing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.