def makepdf(self, pdfdata1, udct, zeros, sig_attributes):
        parser = PDFParser(BytesIO(pdfdata1))
        document = PDFDocument(parser, fallback=False)
        log.info('get datas from pdf')
        prev = document.find_xref(parser)
        info = document.xrefs[0].trailer['Info'].objid
        root = document.xrefs[0].trailer['Root'].objid
        size = document.xrefs[0].trailer['Size']
        page_objid = document.catalog['Pages'].objid
        page = None

        log.info('check sig attributes...')
        position = MyConfigLoader().get_pdf_config()['position']
        if not sig_attributes:
            visibility = MyConfigLoader().get_pdf_config()['visibility']
        else:
            visibility = sig_attributes['visibility']
            log.info(f'the sign is {visibility}')
            if visibility == 'visible':
                position = sig_attributes['position']
                log.info(f'position: {position}')

        page_pos = position['page']
        if page_pos == 'n':
            try:
                pages_count = document.getobj(page_objid)['Count']
                page = document.getobj(page_objid)['Kids'][pages_count - 1].objid
            except Exception:
                page = int(1)
        else:
            try:
                page = document.getobj(page_objid)['Kids'][int(page_pos) - 1].objid
            except Exception:
                log.error('page not found...take the first')
                page = document.getobj(page_objid)['Kids'][0].objid

        infodata = self.getdata(pdfdata1, info, prev, document).strip()
        rootdata = self.getdata(pdfdata1, root, prev, document).strip()
        pagedata = self.getdata(pdfdata1, page, prev, document).strip()

        no = size
        multiple_signs = False
        signatures = self.get_signature_names(document)
        if len(signatures) > 0:
            multiple_signs = True

        if visibility == 'visible':
            rect_array = self.get_rect_array(pagedata, position)
            stream_name = compress(STREAM_WITH_NAME % udct[b'name'])
            if multiple_signs:
                objs = self.make_multi_visible_sig_objs(document, udct, no, page, pagedata, infodata, rootdata, stream_name, rect_array, zeros)
                xref = self.make_multi_visible_xref()
                new_size = 11
            else:
                objs = self.make_visible_sig_objs(udct, no, page, pagedata, infodata, rootdata, stream_name, rect_array, zeros)
                xref = self.make_visible_xref()
                new_size = 13
        else:
            if multiple_signs:
                objs = self.make_multi_inv_sig_objs(document, udct, no, page, pagedata, infodata, rootdata, zeros, len(signatures) + 1)
                xref = self.make_multi_inv_xref()
                new_size = 5
            else:
                objs = self.make_invisible_sig_objs(udct, no, page, pagedata, infodata, rootdata, zeros)
                xref = self.make_multi_inv_xref()
                new_size = 5

        pdfdata2 = b''.join(objs)
        startxref = len(pdfdata1)
        dct = {
            b'page': page,
            b'no': no,
            b'startxref': startxref + len(pdfdata2),
            b'prev': prev,
            b'info': no + 0,
            b'root': no + 1,
            b'size': no + new_size,
            b'p0': startxref + pdfdata2.find(b'\n%d 0 obj\n' % page) + 1,
            b'h1': hashlib.md5(pdfdata1).hexdigest().upper().encode('ascii'),
            b'h2': hashlib.md5(pdfdata2).hexdigest().upper().encode('ascii'),
        }
        for i in range(new_size):
            dct.update(({b'n%d' % i: startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + i)) + 1, }))

        trailer = b'''\
trailer
<</ID [<%(h1)s><%(h2)s>]/Info %(info)d 0 R/Prev %(prev)d/Root %(root)d 0 R/Size %(size)d>>\n\
startxref\n\
%(startxref)d\n\
%%%%EOF\n\
'''

        xref = xref % dct
        trailer = trailer % dct

        pdfdata2 = pdfdata2 + xref + trailer

        return pdfdata2
Example #2
0
    def makepdf(self, pdfdata1, udct, zeros):
        parser = PDFParser(BytesIO(pdfdata1))
        document = PDFDocument(parser, fallback=False)

        prev = document.find_xref(parser)
        info = document.xrefs[0].trailer['Info'].objid
        root = document.xrefs[0].trailer['Root'].objid
        size = 1
        # calculate last object id, size is only xref size but not count of object in xref
        for ref in document.xrefs:
            if isinstance(ref, PDFXRefStream):
                no = max(ref.ranges, key=operator.itemgetter(1))[1]
            else:
                if len(ref.offsets) == 0:
                    no = 0
                else:
                    no = max(ref.offsets.keys())
            size = max(size, no)
        page = document.getobj(
            document.catalog['Pages'].objid)['Kids'][0].objid

        nsig, fields = self.getfields(root, document)
        annots = self.getannots(page, document)

        infodata = self.getdata(pdfdata1, info, prev, document)
        rootdata = self.getdata(pdfdata1, root, prev, document, ('AcroForm', ))
        pagedata = self.getdata(pdfdata1, page, prev, document, ('Annots', ))

        annotation = udct.get(b'signature', b'').decode('utf8')
        x1, y1, x2, y2 = udct.get(b'signaturebox', (0, 0, 0, 0))
        annotation = FreeText(
            Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0),
            Appearance(
                fill=[0, 0, 0],
                stroke_width=1,
                wrap_text=True,
                font_size=12,
                content=annotation,
            ),
        )
        pdfa = annotation.as_pdf_object(identity(), page=None)
        pdfar = b'[%d %d %d %d]' % tuple(pdfa.Rect)
        pdfas = pdfa.AP.N.stream.encode('latin1')

        no = size + 1
        objs = [
            self.makeobj(page,
                         (b'/Annots[%s%d 0 R]' % (annots, no + 3) + pagedata)),
            self.makeobj(no + 0, infodata),
            self.makeobj(no + 1, (b'/AcroForm %d 0 R' % (no + 2)) + rootdata),
            self.makeobj(
                no + 2, b'/Fields[%s%d 0 R]/SigFlags %d' %
                (fields, no + 3, udct[b'sigflags'])),
            self.makeobj(
                no + 3, b'''
/Type
/Annot
/Subtype
/FreeText
/AP <</N %d 0 R>>
/BS <</S /S /Type /Border /W 0>>
/C []
/Contents (%s)
/DA (0 0 0 rg /%s 12 Tf)
/Rect %s
/F 704
/P %d 0 R
/FT
/Sig
/T(Signature%d)
/V %d 0 R
''' % (no + 4, pdfa.Contents.encode('latin1'),
        pdfa.AP.N.Resources.Font.keys()[0].encode('latin1'), pdfar, page, nsig,
        no + 5)),
            self.makeobj(
                no + 4, b'''
/BBox %s
/FormType 1
/Length %d
/Matrix [1 0 0 1 0 0]
/Resources <</Font <<%s <</BaseFont /Helvetica /Encoding /WinAnsiEncoding /Subtype /Type1 /Type /Font>>>> /ProcSet /PDF>>
/Subtype
/Form
/Type
/XObject
''' % (
                    pdfar,
                    len(pdfas),
                    pdfa.AP.N.Resources.Font.keys()[0].encode('latin1'),
                ), b'stream\n' + pdfas + b'\nendstream\n'),
            self.makeobj(no + 5, (
                b'/ByteRange [0000000000 0000000000 0000000000 0000000000]/ContactInfo(%s)\
/Filter/Adobe.PPKLite/Location(%s)/M(D:%s)/Prop_Build<</App<</Name/>>>>/Reason(%s)/SubFilter/adbe.pkcs7.detached/Type/Sig\
/Contents <' % (udct[b'contact'], udct[b'location'], udct[b'signingdate'],
                udct[b'reason'])) + zeros + b'>'),
        ]

        pdfdata2 = b''.join(objs)
        xref = b'''\
xref\n\
%(page)d 1\n\
%(p0)010d 00000 n \n\
%(no)d 6\n\
%(n0)010d 00000 n \n\
%(n1)010d 00000 n \n\
%(n2)010d 00000 n \n\
%(n3)010d 00000 n \n\
%(n4)010d 00000 n \n\
%(n5)010d 00000 n \n\
'''
        startxref = len(pdfdata1)
        dct = {
            b'page': page,
            b'no': no,
            b'startxref': startxref + len(pdfdata2),
            b'prev': prev,
            b'info': no + 0,
            b'root': no + 1,
            b'size': 6,
            b'p0': startxref + pdfdata2.find(b'\n%d 0 obj\n' % page) + 1,
            b'n0': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 0)) + 1,
            b'n1': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 1)) + 1,
            b'n2': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 2)) + 1,
            b'n3': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 3)) + 1,
            b'n4': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 4)) + 1,
            b'n5': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 5)) + 1,
            b'h1': hashlib.md5(pdfdata1).hexdigest().upper().encode('ascii'),
            b'h2': hashlib.md5(pdfdata2).hexdigest().upper().encode('ascii'),
        }

        trailer = b'''\
trailer
<</ID [<%(h1)s><%(h2)s>]/Info %(info)d 0 R/Prev %(prev)d/Root %(root)d 0 R/Size %(size)d>>\n\
startxref\n\
%(startxref)d\n\
%%%%EOF\n\
'''

        xref = xref % dct
        trailer = trailer % dct

        pdfdata2 = pdfdata2 + xref + trailer

        return pdfdata2
Example #3
0
    def makepdf(self, pdfdata1, udct, zeros):
        parser = PDFParser(BytesIO(pdfdata1))
        document = PDFDocument(parser, fallback=False)

        prev = document.find_xref(parser)
        info = document.xrefs[0].trailer['Info'].objid
        root = document.xrefs[0].trailer['Root'].objid
        size = 1
        # calculate last object id, size is only xref size but not count of object in xref
        for ref in document.xrefs:
            if isinstance(ref, PDFXRefStream):
                no = max(ref.ranges, key=operator.itemgetter(1))[1]
            else:
                if len(ref.offsets) == 0:
                    no = 0
                else:
                    no = max(ref.offsets.keys())
            size = max(size, no)
        page = document.getobj(
            document.catalog['Pages'].objid)['Kids'][0].objid

        nsig, fields = self.getfields(root, document)
        annots = self.getannots(page, document)

        infodata = self.getdata(pdfdata1, info, prev, document)
        rootdata = self.getdata(pdfdata1, root, prev, document, ('AcroForm', ))
        pagedata = self.getdata(pdfdata1, page, prev, document, ('Annots', ))

        rectPos = b'0 0 0 0'

        if b'rectPos' in udct:
            rectPos = udct[b'rectPos']

        no = size + 1
        objs = [
            self.makeobj(page,
                         (b'/Annots[%s%d 0 R]' % (annots, no + 3) + pagedata)),
            self.makeobj(no + 0, infodata),
            self.makeobj(no + 1, (b'/AcroForm %d 0 R' % (no + 2)) + rootdata),
            self.makeobj(
                no + 2, b'/Fields[%s%d 0 R]/SigFlags %d' %
                (fields, no + 3, udct[b'sigflags'])),
            self.makeobj(
                no + 3,
                b'/AP<</N %d 0 R>>/F 132/FT/Sig/P %d 0 R/Rect[%s]/Subtype/Widget/T(Signature%d)/V %d 0 R'
                % (no + 4, page, rectPos, nsig, no + 5)),
            self.makeobj(
                no + 4,
                b'/BBox[0 0 0 0]/Filter/FlateDecode/Length 8/Subtype/Form/Type/XObject',
                b'stream\n\x78\x9C\x03\x00\x00\x00\x00\x01\nendstream\n'),
            self.makeobj(no + 5, (
                b'/ByteRange [0000000000 0000000000 0000000000 0000000000]/ContactInfo(%s)\
/Filter/Adobe.PPKLite/Location(%s)/M(D:%s)/Prop_Build<</App<</Name/>>>>/Reason(%s)/SubFilter/adbe.pkcs7.detached/Type/Sig\
/Contents <' % (udct[b'contact'], udct[b'location'], udct[b'signingdate'],
                udct[b'reason'])) + zeros + b'>'),
        ]

        pdfdata2 = b''.join(objs)
        xref = b'''\
xref\n\
%(page)d 1\n\
%(p0)010d 00000 n \n\
%(no)d 6\n\
%(n0)010d 00000 n \n\
%(n1)010d 00000 n \n\
%(n2)010d 00000 n \n\
%(n3)010d 00000 n \n\
%(n4)010d 00000 n \n\
%(n5)010d 00000 n \n\
'''
        startxref = len(pdfdata1)
        dct = {
            b'page': page,
            b'no': no,
            b'startxref': startxref + len(pdfdata2),
            b'prev': prev,
            b'info': no + 0,
            b'root': no + 1,
            b'size': 6,
            b'p0': startxref + pdfdata2.find(b'\n%d 0 obj\n' % page) + 1,
            b'n0': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 0)) + 1,
            b'n1': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 1)) + 1,
            b'n2': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 2)) + 1,
            b'n3': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 3)) + 1,
            b'n4': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 4)) + 1,
            b'n5': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 5)) + 1,
            b'h1': hashlib.md5(pdfdata1).hexdigest().upper().encode('ascii'),
            b'h2': hashlib.md5(pdfdata2).hexdigest().upper().encode('ascii'),
        }

        trailer = b'''\
trailer
<</ID [<%(h1)s><%(h2)s>]/Info %(info)d 0 R/Prev %(prev)d/Root %(root)d 0 R/Size %(size)d>>\n\
startxref\n\
%(startxref)d\n\
%%%%EOF\n\
'''

        xref = xref % dct
        trailer = trailer % dct

        pdfdata2 = pdfdata2 + xref + trailer

        return pdfdata2
Example #4
0
    def makepdf(self, pdfdata1, udct, zeros):
        parser = PDFParser(BytesIO(pdfdata1))
        document = PDFDocument(parser, fallback=False)

        prev = document.find_xref(parser)
        info = document.xrefs[0].trailer['Info'].objid
        root = document.xrefs[0].trailer['Root'].objid
        size = 1
        # calculate last object id, size is only xref size but not count of object in xref
        for ref in document.xrefs:
            if isinstance(ref, PDFXRefStream):
                no = max(ref.ranges, key=operator.itemgetter(1))[1]
            else:
                if len(ref.offsets) == 0:
                    no = 0
                else:
                    no = max(ref.offsets.keys())
            size = max(size, no)
        pages = len(document.getobj(document.catalog['Pages'].objid)['Kids'])
        page = udct.get(b'sigpage',
                        0) if 0 <= udct.get(b'sigpage', 0) <= pages - 1 else 0
        page = document.getobj(
            document.catalog['Pages'].objid)['Kids'][page].objid

        nsig, fields = self.getfields(root, document)
        annots = self.getannots(page, document)

        infodata = self.getdata(pdfdata1, info, prev, document)
        rootdata = self.getdata(pdfdata1, root, prev, document, ('AcroForm', ))
        pagedata = self.getdata(pdfdata1, page, prev, document, ('Annots', ))

        no = size + 1
        visualization, nav = self.makevisualization(no, udct, nsig, page)
        objs = [
            self.makeobj(page,
                         (b'/Annots[%s%d 0 R]' % (annots, no + 3) + pagedata)),
            self.makeobj(no + 0, infodata),
            self.makeobj(no + 1, (b'/AcroForm %d 0 R' % (no + 2)) + rootdata),
            self.makeobj(
                no + 2, b'/Fields[%s%d 0 R]/SigFlags %d' %
                (fields, no + 3, udct[b'sigflags'])),
            visualization,
            self.makeobj(nav + 1, (
                b'/ByteRange [0000000000 0000000000 0000000000 0000000000]/ContactInfo(%s)\
/Filter/Adobe.PPKLite/Location(%s)/M(D:%s)/Prop_Build<</App<</Name/>>>>/Reason(%s)/SubFilter/adbe.pkcs7.detached/Type/Sig\
/Contents <' % (udct[b'contact'], udct[b'location'], udct[b'signingdate'],
                udct[b'reason'])) + zeros + b'>'),
            #            self.makeobj(nav + 1, (b'/ByteRange [0000000000 0000000000 0000000000 0000000000]/ContactInfo(%s)\
            #/Filter/Adobe.PPKMS/SubFilter/ETSI.CAdES.detached/Location(%s)/M(D:%s)/Prop_Build<</App<</Name/>>>>/Reason(%s)/SubFilter/adbe.pkcs7.detached/Type/Sig\
            #/Contents <' % (udct[b'contact'], udct[b'location'], udct[b'signingdate'], udct[b'reason'])) + zeros + b'>'),
        ]

        size = nav - no + 2
        pdfdata2 = b''.join(objs)
        startxref = len(pdfdata1)
        xref = b'xref\n%d 1\n%010d 00000 n \n%d %d\n' % (
            page, startxref + pdfdata2.find(b'\n%d 0 obj\n' % page) + 1, no,
            size)
        xref += b''.join([
            b'%010d 00000 n \n' % (startxref + pdfdata2.find(b'\n%d 0 obj\n' %
                                                             (no + i)) + 1)
            for i in range(size)
        ])

        trailer = b'''\
trailer
<</ID [<%(h1)s><%(h2)s>]/Info %(info)d 0 R/Prev %(prev)d/Root %(root)d 0 R/Size %(size)d>>\n\
startxref\n\
%(startxref)d\n\
%%%%EOF\n\
'''
        trailer = trailer % {
            b'page': page,
            b'no': no,
            b'startxref': startxref + len(pdfdata2),
            b'prev': prev,
            b'info': no + 0,
            b'root': no + 1,
            b'size': size,
            b'h1': hashlib.md5(pdfdata1).hexdigest().upper().encode('ascii'),
            b'h2': hashlib.md5(pdfdata2).hexdigest().upper().encode('ascii'),
        }

        pdfdata2 = pdfdata2 + xref + trailer

        return pdfdata2
Example #5
0
    def makepdf(self, pdfdata1, udct, zeros):
        parser = PDFParser(BytesIO(pdfdata1))
        document = PDFDocument(parser, fallback=False)

        prev = document.find_xref(parser)
        info = document.xrefs[0].trailer['Info'].objid
        root = document.xrefs[0].trailer['Root'].objid
        size = document.xrefs[0].trailer['Size']
        page = document.getobj(
            document.catalog['Pages'].objid)['Kids'][0].objid

        infodata = self.getdata(pdfdata1, info, prev, document).strip()
        rootdata = self.getdata(pdfdata1, root, prev, document).strip()
        pagedata = self.getdata(pdfdata1, page, prev, document).strip()

        no = size
        objs = [
            self.makeobj(page, (b'/Annots[%d 0 R]' % (no + 3)) + pagedata),
            self.makeobj(no + 0, infodata),
            self.makeobj(no + 1, (b'/AcroForm %d 0 R' % (no + 2)) + rootdata),
            self.makeobj(
                no + 2,
                b'/Fields[%d 0 R]/SigFlags %d' % (no + 3, udct[b'sigflags'])),
            self.makeobj(
                no + 3,
                b'/AP<</N %d 0 R>>/F 132/FT/Sig/P %d 0 R/Rect[0 0 0 0]/Subtype/Widget/T(Signature1)/V %d 0 R'
                % (no + 4, page, no + 5)),
            self.makeobj(
                no + 4,
                b'/BBox[0 0 0 0]/Filter/FlateDecode/Length 8/Subtype/Form/Type/XObject',
                b'stream\n\x78\x9C\x03\x00\x00\x00\x00\x01\nendstream\n'),
            self.makeobj(no + 5, (
                b'/ByteRange [0000000000 0000000000 0000000000 0000000000]/ContactInfo(%s)\
/Filter/Adobe.PPKLite/Location(%s)/M(D:%s)/Prop_Build<</App<</Name/>>>>/Reason(%s)/SubFilter/adbe.pkcs7.detached/Type/Sig\
/Contents <' % (udct[b'contact'], udct[b'location'], udct[b'signingdate'],
                udct[b'reason'])) + zeros + b'>'),
        ]

        pdfdata2 = b''.join(objs)
        xref = b'''\
xref\n\
%(page)d 1\n\
%(p0)010d 00000 n \n\
%(no)d 6\n\
%(n0)010d 00000 n \n\
%(n1)010d 00000 n \n\
%(n2)010d 00000 n \n\
%(n3)010d 00000 n \n\
%(n4)010d 00000 n \n\
%(n5)010d 00000 n \n\
'''
        startxref = len(pdfdata1)
        dct = {
            b'page': page,
            b'no': no,
            b'startxref': startxref + len(pdfdata2),
            b'prev': prev,
            b'info': no + 0,
            b'root': no + 1,
            b'size': 6,
            b'p0': startxref + pdfdata2.find(b'\n%d 0 obj\n' % page) + 1,
            b'n0': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 0)) + 1,
            b'n1': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 1)) + 1,
            b'n2': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 2)) + 1,
            b'n3': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 3)) + 1,
            b'n4': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 4)) + 1,
            b'n5': startxref + pdfdata2.find(b'\n%d 0 obj\n' % (no + 5)) + 1,
            b'h1': hashlib.md5(pdfdata1).hexdigest().upper().encode('ascii'),
            b'h2': hashlib.md5(pdfdata2).hexdigest().upper().encode('ascii'),
        }

        trailer = b'''\
trailer
<</ID [<%(h1)s><%(h2)s>]/Info %(info)d 0 R/Prev %(prev)d/Root %(root)d 0 R/Size %(size)d>>\n\
startxref\n\
%(startxref)d\n\
%%%%EOF\n\
'''

        xref = xref % dct
        trailer = trailer % dct

        pdfdata2 = pdfdata2 + xref + trailer

        return pdfdata2