def test_sv_subfilter_unsupported_partial(): sv_spec = fields.SigSeedValueSpec( flags=fields.SigSeedValFlags.SUBFILTER, subfilters=[fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED, PADES]) w = IncrementalPdfFileWriter(prepare_sv_field(sv_spec)) field_name, _, sig_field = next(fields.enumerate_sig_fields(w)) sig_field = sig_field.get_object() sv_ref = sig_field.raw_get('/SV') w.mark_update(sv_ref) sv_ref.get_object()['/SubFilter'][0] = pdf_name('/this.doesnt.exist') out = BytesIO() w.write(out) out.seek(0) frozen = out.getvalue() signers.sign_pdf(IncrementalPdfFileWriter(BytesIO(frozen)), signers.PdfSignatureMetadata(field_name='Sig'), signer=FROM_CA, timestamper=DUMMY_TS) with pytest.raises(SigningError): signers.sign_pdf( IncrementalPdfFileWriter(BytesIO(frozen)), signers.PdfSignatureMetadata( field_name='Sig', subfilter=fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED), signer=FROM_CA, timestamper=DUMMY_TS)
def test_delete_signature(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_TWO_FIELDS)) # first, we simply sign the two fields out = signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name='Sig1'), signer=FROM_CA, existing_fields_only=True) w = IncrementalPdfFileWriter(out) out = signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name='Sig2'), signer=FROM_CA, existing_fields_only=True) # after that, we add an incremental update that deletes the first signature # This should invalidate the remaining one. w = IncrementalPdfFileWriter(out) sig_fields = fields.enumerate_sig_fields(w) field_name, sig_obj, sig_field = next(sig_fields) assert field_name == 'Sig1' del sig_field.get_object()['/V'] w.mark_update(sig_field) out = BytesIO() w.write(out) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig2' val_trusted_but_modified(s)
def test_rogue_backreferences(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) # intentionally refer back to the contents of the first page w.root['/DSS'] = w.root['/Pages']['/Kids'][0].get_object().raw_get( '/Contents') w.update_root() meta = signers.PdfSignatureMetadata(field_name='Sig1', ) out = signers.sign_pdf(w, meta, signer=FROM_CA) # pretend to add a new form field, but actually secretly do a page # tree modification. sp = fields.SigFieldSpec('SigNew', box=(10, 74, 140, 134), doc_mdp_update_value=fields.MDPPerm.FILL_FORMS) w = IncrementalPdfFileWriter(out) fields.append_signature_field(w, sp) w.write_in_place() w = IncrementalPdfFileWriter(out) contents_ref = w.root['/Pages']['/Kids'][0].get_object().raw_get( '/Contents') content_stream: generic.StreamObject = contents_ref.get_object() content_stream._data = content_stream.data + b"q Q" content_stream._encoded_data = None w.mark_update(contents_ref) w.write_in_place() r = PdfFileReader(out) emb = r.embedded_signatures[0] emb.compute_integrity_info() assert isinstance(emb.diff_result, SuspiciousModification)
def test_no_clobbering_xref_streams(): # Test witnessing the limitation on our reader implementation # that disallows references to the xref stream of a previous revision # from being overridden. # (this behaviour may change in the future, but for now, the test is in # place to deal with it) buf = BytesIO(MINIMAL_XREF) w = IncrementalPdfFileWriter(buf) # update the xref stream in the previous revision stream_ref = w.prev.xrefs.get_xref_container_info(0).stream_ref w.mark_update(stream_ref) w.write_in_place() with pytest.raises(misc.PdfReadError, match="XRef.*must not be clobbered"): PdfFileReader(buf)
def test_bogus_metadata_manipulation(): # test using a double signature created using Adobe Reader # (uses object streams, XMP metadata updates and all the fun stuff) infile = BytesIO( read_all(PDF_DATA_DIR + '/minimal-two-fields-signed-twice.pdf')) bogus = b'This is bogus data, yay!' def do_check(): r = PdfFileReader(out) print(r.get_object(generic.Reference(2, 0, r), revision=3).data) s = r.embedded_signatures[0] status = validate_pdf_signature(s) assert status.modification_level == ModificationLevel.OTHER w = IncrementalPdfFileWriter(infile) w.root['/Metadata'] = w.add_object(generic.StreamObject(stream_data=bogus)) w.update_root() out = BytesIO() w.write(out) do_check() w = IncrementalPdfFileWriter(infile) metadata_ref = w.root.raw_get('/Metadata') metadata_stream: generic.StreamObject = metadata_ref.get_object() metadata_stream.strip_filters() metadata_stream._data = bogus metadata_stream._encoded_data = None w.mark_update(metadata_ref) out = BytesIO() w.write(out) do_check() w = IncrementalPdfFileWriter(infile) w.root['/Metadata'] = generic.NullObject() w.update_root() out = BytesIO() w.write(out) do_check() w = IncrementalPdfFileWriter(infile) w.root['/Metadata'] = w.add_object(generic.NullObject()) w.update_root() out = BytesIO() w.write(out) do_check()