Example #1
0
def _insert_or_get_field_at(writer: BasePdfFileWriter, fields, path,
                            parent_ref=None, modified=False, field_obj=None):

    current_partial, tail = path[0], path[1:]

    for field_ref in fields:
        assert isinstance(field_ref, generic.IndirectObject)
        field = field_ref.get_object()
        if field.get('/T', None) == current_partial:
            break
    else:
        # have to insert a new element into the fields array
        if field_obj is not None and not tail:
            field = field_obj
        else:
            # create a generic field
            field = generic.DictionaryObject()
        field['/T'] = pdf_string(current_partial)
        if parent_ref is not None:
            field['/Parent'] = parent_ref
        field_ref = writer.add_object(field)
        fields.append(field_ref)
        writer.update_container(fields)
        modified = True

    if not tail:
        return modified, field_ref
    # check for /Kids, and create it if necessary
    try:
        kids = field['/Kids']
    except KeyError:
        kids = field['/Kids'] = generic.ArrayObject()
        writer.update_container(field)
        modified = True

    # recurse in to /Kids array
    return _insert_or_get_field_at(
        writer, kids, tail, parent_ref=field_ref,
        modified=modified, field_obj=field_obj
    )
Example #2
0
    def __init__(self, stream_xrefs=True):
        # root object
        root = generic.DictionaryObject({
            pdf_name("/Type"): pdf_name("/Catalog"),
        })

        id1 = generic.ByteStringObject(os.urandom(16))
        id2 = generic.ByteStringObject(os.urandom(16))
        id_obj = generic.ArrayObject([id1, id2])

        # info object
        info = generic.DictionaryObject({
            pdf_name('/Producer'): pdf_string(VENDOR)
        })

        super().__init__(root, info, id_obj, stream_xrefs=stream_xrefs)

        pages = generic.DictionaryObject({
            pdf_name("/Type"): pdf_name("/Pages"),
            pdf_name("/Count"): generic.NumberObject(0),
            pdf_name("/Kids"): generic.ArrayObject(),
        })

        root[pdf_name('/Pages')] = self.add_object(pages)
Example #3
0
def test_sv_deserialisation():
    sv_input = generic.DictionaryObject({
        pdf_name('/SubFilter'):
        generic.ArrayObject(
            map(pdf_name, ['/foo', '/adbe.pkcs7.detached', '/bleh'])),
        pdf_name('/LegalAttestation'):
        generic.ArrayObject(['xyz', 'abc', 'def']),
        pdf_name('/AppearanceFilter'):
        generic.pdf_string('blah'),
        pdf_name('/LockDocument'):
        generic.pdf_name('/true')
    })
    sv = fields.SigSeedValueSpec.from_pdf_object(sv_input)
    assert len(sv.subfilters) == 1
    assert len(sv.legal_attestations) == 3
    assert sv.lock_document == fields.SeedLockDocument.LOCK
    sv_output = sv.as_pdf_object()
    assert sv_output['/AppearanceFilter'] == sv_input['/AppearanceFilter']
    assert sv_output['/LockDocument'] == sv_input['/LockDocument']
    assert sv_output['/LegalAttestation'] == sv_input['/LegalAttestation']

    with pytest.raises(SigningError):
        fields.SigSeedValueSpec.from_pdf_object(
            generic.DictionaryObject(
                {pdf_name('/LockDocument'): generic.pdf_name('/nonsense')}))
        fields.SigSeedValueSpec.from_pdf_object(
            generic.DictionaryObject(
                {pdf_name('/LockDocument'): generic.BooleanObject(True)}))
    bad_filter = generic.DictionaryObject(
        {pdf_name('/Filter'): pdf_name('/unsupported')})
    # this should run
    fields.SigSeedValueSpec.from_pdf_object(bad_filter)
    with pytest.raises(SigningError):
        bad_filter[pdf_name('/Ff')] = \
            generic.NumberObject(fields.SigSeedValFlags.FILTER.value)
        fields.SigSeedValueSpec.from_pdf_object(bad_filter)
Example #4
0
    def as_pdf_object(self):
        """
        Render this :class:`.SigSeedValueSpec` object to a PDF dictionary.

        :return:
            A :class:`~.generic.DictionaryObject`.
        """
        min_version = SeedValueDictVersion.PDF_1_5
        result = generic.DictionaryObject({
            pdf_name('/Type'):
            pdf_name('/SV'),
            pdf_name('/Ff'):
            generic.NumberObject(self.flags.value),
        })

        if self.subfilters is not None:
            result[pdf_name('/SubFilter')] = generic.ArrayObject(
                sf.value for sf in self.subfilters)
        if self.add_rev_info is not None:
            min_version = SeedValueDictVersion.PDF_1_7
            result[pdf_name('/AddRevInfo')] = generic.BooleanObject(
                self.add_rev_info)
        if self.digest_methods is not None:
            min_version = SeedValueDictVersion.PDF_1_7
            result[pdf_name('/DigestMethod')] = generic.ArrayObject(
                map(pdf_string, self.digest_methods))
        if self.reasons is not None:
            result[pdf_name('/Reasons')] = generic.ArrayObject(
                pdf_string(reason) for reason in self.reasons)
        if self.timestamp_server_url is not None:
            min_version = SeedValueDictVersion.PDF_1_7
            result[pdf_name('/TimeStamp')] = generic.DictionaryObject({
                pdf_name('/URL'):
                pdf_string(self.timestamp_server_url),
                pdf_name('/Ff'):
                generic.NumberObject(1 if self.timestamp_required else 0)
            })
        if self.cert is not None:
            result[pdf_name('/Cert')] = self.cert.as_pdf_object()
        if self.seed_signature_type is not None:
            mdp_perm = self.seed_signature_type.mdp_perm
            result[pdf_name('/MDP')] = generic.DictionaryObject({
                pdf_name('/P'):
                generic.NumberObject(
                    mdp_perm.value if mdp_perm is not None else 0)
            })
        if self.legal_attestations is not None:
            result[pdf_name('/LegalAttestation')] = generic.ArrayObject(
                pdf_string(att) for att in self.legal_attestations)
        if self.lock_document is not None:
            min_version = SeedValueDictVersion.PDF_2_0
            result[pdf_name('/LockDocument')] = self.lock_document.value
        if self.appearance is not None:
            result[pdf_name('/AppearanceFilter')] = pdf_string(self.appearance)

        specified_version = self.sv_dict_version
        if specified_version is not None:
            result[pdf_name('/V')] = generic.NumberObject(
                specified_version.
                value if isinstance(specified_version, SeedValueDictVersion
                                    ) else specified_version)
        else:
            result[pdf_name('/V')] = generic.NumberObject(min_version.value)
        return result
Example #5
0
    w.objects[(dummy_ref.generation, dummy_ref.idnum)] = dss
    w.root['/DSS'] = generic.IndirectObject(idnum=dummy_ref.idnum,
                                            generation=dummy_ref.generation,
                                            pdf=w)
    w.update_root()
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted_but_modified(s)


BOGUS_DSS_VALUES = [
    generic.pdf_string("Hi there"),
    generic.DictionaryObject({pdf_name('/Blah'): generic.NullObject()}),
    generic.DictionaryObject({pdf_name('/Certs'): generic.NullObject()}),
    generic.DictionaryObject({pdf_name('/VRI'): generic.NullObject()}),
    generic.DictionaryObject({
        pdf_name('/VRI'):
        generic.DictionaryObject({pdf_name('/Bleh'): generic.NullObject()})
    }),
    generic.DictionaryObject({
        pdf_name('/VRI'):
        generic.DictionaryObject(
            {pdf_name('/' + 'A' * 40): generic.NullObject()})
    }),
    generic.DictionaryObject({
        pdf_name('/VRI'):
        generic.DictionaryObject({