m32 / endesive

en-crypt, de-crypt, si-gn, ve-rify - smime, pdf, xades and plain files in pure python
MIT License
243 stars 93 forks source link

PDF is not being recognised as a signed pdf by adobe (can you check why ? ) vv urgent #31

Closed Nik31 closed 5 years ago

Nik31 commented 5 years ago

sample-signed.pdf

m32 commented 5 years ago

No idea why. Sign the document without parentheses in the description /Contents (DS ENDURANCE INTERNATIONAL GROUP (INDIA) PRIVATE LIMITED 1 DATE: 2019.11.20)

m32 commented 5 years ago

The file:sample-signed.pdf is not valid, error(s) : 1.0.14 : Syntax error, Object {52:0} has an offset of 0 1.0.14 : Syntax error, Object {54:0} has an offset of 0

Nik31 commented 5 years ago

sample-signed.pdf

changed the sigflags to 3 and it is being recognised now as digitally signed but now this problem persists that

  1. signer 's identity has not yet been verified
  2. here is my code
Nik31 commented 5 years ago

`#!/usr/bin/env python3.6

""" A tool which takes in pdf, pfx file, password as input and gives out a corresponding signed pdf

""" import argparse import pytz import re import sys

from OpenSSL.crypto import load_pkcs12 from endesive import pdf from datetime import datetime

signature_string = lambda organization, date, country : (organization + '\nDATE: '+ date)

def eprint(error): print(error, file=sys.stderr)

def load_pfx(file_path, password): """ Function to load pkcs12 object from the given password protected pfx file."""

return load_pkcs12(open(file_path, 'rb').read(), password.encode())

def create_args(): """Creates CLI arguments for the pdfSigner script."""

parser = argparse.ArgumentParser(description='Script for digitally signing a pdf') parser.add_argument('pfx_certificate', type=str, help='Specify keystore file in .pfx format (Mandatory)') parser.add_argument('password', type=str, help=' Specify password for keystore file (mandatory)') parser.add_argument('src', type=str, help='Specify the source file (.pdf) that needs to be digitally signed. Only 1 file at a time can be signed. (Mandatory) ') parser.add_argument('-d', '--dest', type=str, help='Specify the destination file where digitally signed content will be stored.When not specified, by default it will ' 'digitally sign the source file.(Mandatory) \n' 'E.g. Given source file /var/hp/some.pdf will be digitally signed') parser.add_argument('-c', '--coords', type=str, help='Specify the co-ordinates of where you want the digital signature to be placed on the PDF file page.(Optional)\n' 'Format: Accepts 4 comma-separated float values (without spaces). E.g. 1,2,3,4 ') parser.add_argument('-p', '--page', type=int, help='You can specify the page number of PDF file where digital signature(Optional)')

return parser.parse_args()

def validate_args(args): """Validating commandline arguments raises valueError exception with if any command line arguments are not valid."""

IS_PFX = lambda pfx_certificate: re.match( r'^(.[^,]+)(.pfx|.PFX){1}$', pfx_certificate) if not IS_PFX(args.pfx_certificate): raise ValueError('Not a proper pfx file with .pfx or .PFX extension') if args.coords: for num in args.coords.split(','): if not num.isdigit(): raise ValueError('Coords are not integers')

def run(): args = create_args()

try: validate_args(args) except ValueError as e: eprint(e) sys.exit(1)

try:

Load the PKCS12 object from the pfx file

p12 = load_pfx(args.pfx_certificate, args.password)

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]
if args.coords:
  coords = [int(coord) for coord in args.coords.split(',') if coord]
page = args.page if args.page else 0
dest = args.dest if args.dest else args.src
date = datetime.now(tz=timezone)
date = date.strftime('%Y.%m.%d')
signature = signature_string(subject.CN, date, subject.C)
dct = {
  b'sigflags': 3,
  b'sigpage': page - 1,
  b'contact': b'finacctind@endurance.com',
  b'location': subject.C.encode(),
  b'signingdate': date.encode(),
  b'reason': b'Signed by endurance',
  b'signature': signature.encode(),
  b'signaturebox': tuple(coords[:4]),
}

input_file = args.src
datau = open(input_file, 'rb').read()
datas = pdf.cms.sign(datau,
                     dct,
                     p12.get_privatekey().to_cryptography_key(),
                     p12.get_certificate().to_cryptography(),
                     [],
                     'sha256'
                     )

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: eprint(e) sys.exit()

if name == 'main': run(); `

m32 commented 5 years ago

There is a problem with the time when the document was signed and the time zone. I'm checking different settings

m32 commented 5 years ago

Please confirm my results - it works for me

Nik31 commented 5 years ago

ya works fine for me date was the main issue thanks alot :)