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 )
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)
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)
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
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({