def test_approval_sig(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) out = signers.sign_pdf( w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, ), signer=FROM_CA ) out.seek(0) w = IncrementalPdfFileWriter(out) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='Sig2'), signer=FROM_CA ) out.seek(0) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' val_trusted(s, extd=True) info = read_certification_data(r) assert info.author_sig == s.sig_object.get_object() assert info.permission == pyhanko.sign.fields.MDPPerm.FILL_FORMS s = r.embedded_signatures[1] assert s.field_name == 'Sig2' val_trusted(s)
def test_sv_sign_md_req(): sv = fields.SigSeedValueSpec( flags=fields.SigSeedValFlags.DIGEST_METHOD, digest_methods=['sha256', 'sha512'], ) with pytest.raises(SigningError): sign_with_sv( sv, signers.PdfSignatureMetadata( md_algorithm='sha1', field_name='Sig' ) ) sign_with_sv( sv, signers.PdfSignatureMetadata(md_algorithm='sha1', field_name='Sig'), test_violation=True ) emb_sig = sign_with_sv( sv, signers.PdfSignatureMetadata(field_name='Sig') ) assert emb_sig.md_algorithm == 'sha256' emb_sig = sign_with_sv( sv, signers.PdfSignatureMetadata( md_algorithm='sha512', field_name='Sig' ) ) assert emb_sig.md_algorithm == 'sha512'
def test_sign_with_revoked(requests_mock): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='Sig1'), signer=REVOKED_SIGNER ) r = PdfFileReader(out) s = r.embedded_signatures[0] vc = live_testing_vc(requests_mock) val_status = validate_pdf_signature(s, vc) assert val_status.intact assert val_status.valid assert val_status.revoked assert not val_status.trusted assert 'revoked' in val_status.pretty_print_details() summ = val_status.summary() assert 'INTACT' in summ assert 'REVOKED' in summ assert val_status.coverage == SignatureCoverageLevel.ENTIRE_FILE assert val_status.modification_level == ModificationLevel.NONE assert not val_status.bottom_line # should refuse to sign with a known revoked cert w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) with pytest.raises(SigningError): signers.sign_pdf( w, signers.PdfSignatureMetadata( field_name='Sig1', validation_context=vc ), signer=REVOKED_SIGNER )
def test_double_sign_lock_second(): # test if the difference analysis correctly processes /Reference # on a newly added signature object w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) fields.append_signature_field(w, field_with_lock_sp(True)) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='SigFirst'), signer=FROM_CA, ) w = IncrementalPdfFileWriter(out) # now sign the locked field out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='SigNew'), signer=FROM_CA, ) r = PdfFileReader(out) s = r.embedded_signatures[0] val_trusted(s, extd=True) s = r.embedded_signatures[1] assert len(s.sig_object.get_object()['/Reference']) == 1 val_trusted(s)
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_double_sig_add_field(file_ix): w = IncrementalPdfFileWriter(BytesIO(DOUBLE_SIG_TESTDATA_FILES[file_ix])) out = signers.sign_pdf( w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS), signer=FROM_CA, ) # create a new signature field after signing w = IncrementalPdfFileWriter(out) # throw in an /Info update for good measure dt = generic.pdf_date(datetime(2020, 10, 10, tzinfo=pytz.utc)) info = generic.DictionaryObject({pdf_name('/CreationDate'): dt}) w.set_info(info) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='SigNew'), signer=FROM_CA, ) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' status = val_trusted(s, extd=True) assert status.modification_level == ModificationLevel.FORM_FILLING assert status.docmdp_ok s = r.embedded_signatures[1] assert s.field_name == 'SigNew' val_trusted(s)
def test_pades_double_sign(requests_mock, certify_first): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_TWO_FIELDS)) meta1 = signers.PdfSignatureMetadata( field_name='Sig1', validation_context=live_testing_vc(requests_mock), subfilter=PADES, embed_validation_info=True, certify=certify_first) meta2 = signers.PdfSignatureMetadata( field_name='Sig2', validation_context=live_testing_vc(requests_mock), subfilter=PADES, embed_validation_info=True, ) out = signers.sign_pdf(w, meta1, signer=FROM_CA, timestamper=DUMMY_TS) w = IncrementalPdfFileWriter(out) out = signers.sign_pdf(w, meta2, signer=FROM_CA, timestamper=DUMMY_TS) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' if certify_first: assert len(s.sig_object['/Reference']) == 1 val_trusted(s, extd=True) s = r.embedded_signatures[1] assert s.field_name == 'Sig2' val_trusted(s, extd=True)
def test_pades_double_sign_delete_dss(requests_mock): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_TWO_FIELDS)) meta1 = signers.PdfSignatureMetadata( field_name='Sig1', validation_context=live_testing_vc(requests_mock), subfilter=PADES, embed_validation_info=True, ) meta2 = signers.PdfSignatureMetadata( field_name='Sig2', validation_context=live_testing_vc(requests_mock), subfilter=PADES, embed_validation_info=True, ) out = signers.sign_pdf(w, meta1, signer=FROM_CA, timestamper=DUMMY_TS) w = IncrementalPdfFileWriter(out) out = signers.sign_pdf(w, meta2, signer=FROM_CA, timestamper=DUMMY_TS) w = IncrementalPdfFileWriter(out) # DSS is now covered by the second signature, so this is illegal del w.root['/DSS'] w.update_root() out = BytesIO() w.write(out) r = PdfFileReader(out) assert '/DSS' not in r.root s = r.embedded_signatures[0] assert s.field_name == 'Sig1' val_trusted(s, extd=True) # however, the second signature is violated by the deletion of the /DSS key s = r.embedded_signatures[1] assert s.field_name == 'Sig2' val_trusted_but_modified(s)
def test_double_sig_add_field_annots_indirect(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) out = signers.sign_pdf( w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS), signer=FROM_CA, ) # create a new signature field after signing w = IncrementalPdfFileWriter(out) # ... but first make the /Annots entry of the first page an indirect one first_page = w.root['/Pages']['/Kids'][0] annots_copy = generic.ArrayObject(first_page['/Annots']) first_page['/Annots'] = annots_ref = w.add_object(annots_copy) annots_copy.container_ref = annots_ref w.update_container(first_page) out = signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name='SigNew'), signer=FROM_CA, new_field_spec=fields.SigFieldSpec( sig_field_name='SigNew', box=(10, 10, 10, 10))) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' status = val_trusted(s, extd=True) assert status.modification_level == ModificationLevel.FORM_FILLING assert status.docmdp_ok s = r.embedded_signatures[1] assert s.field_name == 'SigNew' val_trusted(s)
def test_double_sig_add_visible_field(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) out = signers.sign_pdf(w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS), signer=FROM_CA) # create a new signature field after signing w = IncrementalPdfFileWriter(out) sp = fields.SigFieldSpec('SigNew', box=(10, 74, 140, 134)) fields.append_signature_field(w, sp) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='SigNew'), signer=FROM_CA, ) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' status = val_trusted(s, extd=True) assert status.modification_level == ModificationLevel.FORM_FILLING assert status.docmdp_ok s = r.embedded_signatures[1] assert s.field_name == 'SigNew' val_trusted(s)
def test_not_all_paths_cleared(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) # make /Fields indirect fields_arr = w.root['/AcroForm'].raw_get('/Fields') # just in case we ever end up declaring /Fields as indirect in the example assert isinstance(fields_arr, generic.ArrayObject) w.root['/AcroForm']['/Fields'] = w.root['/Blah'] = w.add_object(fields_arr) w.update_root() w.update_container(w.root['/AcroForm']) out = signers.sign_pdf( w, signature_meta=signers.PdfSignatureMetadata(field_name='Sig1'), signer=FROM_CA) # create a new signature field after signing w = IncrementalPdfFileWriter(out) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='SigNew'), signer=FROM_CA, ) r = PdfFileReader(out) val_trusted_but_modified(embedded_sig=r.embedded_signatures[0])
def test_no_field_type(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) out = signers.sign_pdf(w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS), signer=FROM_CA, in_place=True) w = IncrementalPdfFileWriter(out) fields._insert_or_get_field_at( w, w.root['/AcroForm']['/Fields'], ('Blah', ), ) meta = signers.PdfSignatureMetadata(field_name='NewSig') out = signers.sign_pdf(w, meta, signer=FROM_CA) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' status = validate_pdf_signature( s, signer_validation_context=SIMPLE_V_CONTEXT()) assert status.modification_level == ModificationLevel.OTHER
def test_double_sig_fill_deep_field_post_sign(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) # create part of the structure already fields._insert_or_get_field_at( w, w.root['/AcroForm']['/Fields'], ('NewSigs', 'NewSig1'), field_obj=fields.SignatureFormField( 'NewSig1', include_on_page=w.root['/Pages']['/Kids'].raw_get(0))) out = signers.sign_pdf(w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS), signer=FROM_CA, in_place=True) w = IncrementalPdfFileWriter(out) fqn = 'NewSigs.NewSig1' meta = signers.PdfSignatureMetadata(field_name=fqn) out = signers.sign_pdf(w, meta, signer=FROM_CA) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' val_trusted(s, extd=True) s = r.embedded_signatures[1] val_trusted(s)
def test_double_sig_create_deep_field_post_sign(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) # create part of the structure already fields._insert_or_get_field_at( w, w.root['/AcroForm']['/Fields'], ('NewSigs', 'NewSig1'), field_obj=generic.DictionaryObject({pdf_name('/FT'): pdf_name('/Sig')})) out = signers.sign_pdf(w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS), signer=FROM_CA, in_place=True) w = IncrementalPdfFileWriter(out) fqn = 'NewSigs.NewSig2' meta = signers.PdfSignatureMetadata(field_name=fqn) out = signers.sign_pdf(w, meta, signer=FROM_CA) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' status = validate_pdf_signature( s, signer_validation_context=SIMPLE_V_CONTEXT()) # the /Kids array of NewSigs was modified, which we don't allow (right now) assert status.modification_level == ModificationLevel.OTHER
def test_certify(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) out = signers.sign_pdf( w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=pyhanko.sign.fields.MDPPerm.NO_CHANGES ), signer=FROM_CA ) r = PdfFileReader(out) s = r.embedded_signatures[0] refs = s.sig_object.get_object()['/Reference'] assert len(refs) == 1 assert s.field_name == 'Sig1' val_trusted(s) info = read_certification_data(r) assert info.author_sig == s.sig_object.get_object() assert info.permission == pyhanko.sign.fields.MDPPerm.NO_CHANGES # with NO_CHANGES, we shouldn't be able to append an approval signature out.seek(0) w = IncrementalPdfFileWriter(out) with pytest.raises(SigningError): signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='Sig2'), signer=FROM_CA )
def test_http_timestamp(requests_mock): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) # bad content-type requests_mock.post(DUMMY_HTTP_TS.url, content=ts_response_callback) from pyhanko.sign.timestamps import TimestampRequestError with pytest.raises(TimestampRequestError): signers.sign_pdf( w, signers.PdfSignatureMetadata(), signer=FROM_CA, timestamper=DUMMY_HTTP_TS, existing_fields_only=True, ) requests_mock.post(DUMMY_HTTP_TS.url, content=ts_response_callback, headers={'Content-Type': 'application/timestamp-reply'}) w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD)) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(), signer=FROM_CA, timestamper=DUMMY_HTTP_TS, existing_fields_only=True, ) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' validity = val_trusted(s) assert validity.timestamp_validity is not None assert validity.timestamp_validity.trusted
def test_sign_with_new_field_spec(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) spec = fields.SigFieldSpec(sig_field_name='Sig1', box=(20, 20, 80, 40)) out = signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name='Sig1'), signer=FROM_CA, new_field_spec=spec) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' assert '/AP' in s.sig_field w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) spec = fields.SigFieldSpec(sig_field_name='Sig1', box=(20, 20, 80, 40)) with pytest.raises(SigningError): signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name='Sig2'), signer=FROM_CA, new_field_spec=spec) with pytest.raises(SigningError): signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name='Sig1'), signer=FROM_CA, new_field_spec=spec, existing_fields_only=True)
def test_double_signature_tagged_file(): w = IncrementalPdfFileWriter(BytesIO(MINIMAL_TWO_FIELDS_TAGGED)) out = signers.sign_pdf(w, signers.PdfSignatureMetadata( field_name='Sig1', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS), signer=FROM_CA) # create a new signature field after signing w = IncrementalPdfFileWriter(out) out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='Sig2'), signer=FROM_CA, ) r = PdfFileReader(out) s = r.embedded_signatures[0] assert s.field_name == 'Sig1' status = val_trusted(s, extd=True) assert status.modification_level == ModificationLevel.FORM_FILLING assert status.docmdp_ok s = r.embedded_signatures[1] assert s.field_name == 'Sig2' val_trusted(s)
def test_sv_no_lock_certify(): sv = fields.SigSeedValueSpec( flags=fields.SigSeedValFlags.LOCK_DOCUMENT, lock_document=fields.SeedLockDocument.DO_NOT_LOCK) meta = signers.PdfSignatureMetadata( field_name='Sig', certify=True, docmdp_permissions=fields.MDPPerm.FILL_FORMS) sign_with_sv(sv, meta) meta = signers.PdfSignatureMetadata( field_name='Sig', certify=True, docmdp_permissions=fields.MDPPerm.ANNOTATE) sign_with_sv(sv, meta) meta = signers.PdfSignatureMetadata( field_name='Sig', certify=True, ) sign_with_sv(sv, meta) meta = signers.PdfSignatureMetadata(field_name='Sig') sign_with_sv(sv, meta) meta = signers.PdfSignatureMetadata( field_name='Sig', certify=True, docmdp_permissions=fields.MDPPerm.NO_CHANGES) sign_with_sv(sv, meta, test_violation=True)
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_overspecify_cms_digest_algo(): # TODO this behaviour is not ideal, but at least this test documents it signer = signers.SimpleSigner.load( CRYPTO_DATA_DIR + '/selfsigned.key.pem', CRYPTO_DATA_DIR + '/selfsigned.cert.pem', ca_chain_files=(CRYPTO_DATA_DIR + '/selfsigned.cert.pem',), key_passphrase=b'secret', # specify an algorithm object that also mandates a specific # message digest signature_mechanism=SignedDigestAlgorithm( {'algorithm': 'sha256_rsa'} ) ) w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) # digest methods agree, so that should be OK out = signers.sign_pdf( w, signers.PdfSignatureMetadata(field_name='Sig1', md_algorithm='sha256'), signer=signer ) r = PdfFileReader(out) s = r.embedded_signatures[0] val_untrusted(s) w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) with pytest.raises(SigningError): signers.sign_pdf( w, signers.PdfSignatureMetadata( field_name='Sig1', md_algorithm='sha512' ), signer=signer )
def test_sv_sign_addrevinfo_subfilter_conflict(): sv = fields.SigSeedValueSpec(flags=fields.SigSeedValFlags.ADD_REV_INFO, subfilters=[PADES], add_rev_info=True) with pytest.raises(SigningError): meta = signers.PdfSignatureMetadata(field_name='Sig', validation_context=dummy_ocsp_vc(), embed_validation_info=True) sign_with_sv(sv, meta) revinfo_and_subfilter = (fields.SigSeedValFlags.ADD_REV_INFO | fields.SigSeedValFlags.SUBFILTER) sv = fields.SigSeedValueSpec(flags=revinfo_and_subfilter, subfilters=[PADES], add_rev_info=True) meta = signers.PdfSignatureMetadata(field_name='Sig', validation_context=dummy_ocsp_vc(), embed_validation_info=True) with pytest.raises(SigningError): sign_with_sv(sv, meta) sign_with_sv(sv, meta, test_violation=True) sv = fields.SigSeedValueSpec(flags=revinfo_and_subfilter, subfilters=[PADES], add_rev_info=False) meta = signers.PdfSignatureMetadata( field_name='Sig', validation_context=dummy_ocsp_vc(), ) sign_with_sv(sv, meta)
def test_sv_sign_addrevinfo_req(requests_mock): sv = fields.SigSeedValueSpec(flags=fields.SigSeedValFlags.ADD_REV_INFO, add_rev_info=True) vc = live_testing_vc(requests_mock) meta = signers.PdfSignatureMetadata( field_name='Sig', validation_context=vc, subfilter=fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED, embed_validation_info=True) emb_sig = sign_with_sv(sv, meta) status = validate_pdf_ltv_signature( emb_sig, RevocationInfoValidationType.ADOBE_STYLE, {'trust_roots': TRUST_ROOTS}) assert status.valid and status.trusted assert emb_sig.sig_object['/SubFilter'] == '/adbe.pkcs7.detached' meta = signers.PdfSignatureMetadata( field_name='Sig', validation_context=vc, subfilter=fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED, embed_validation_info=False) with pytest.raises(SigningError): sign_with_sv(sv, meta) sign_with_sv(sv, meta, test_violation=True) meta = signers.PdfSignatureMetadata( field_name='Sig', validation_context=vc, subfilter=fields.SigSeedSubFilter.PADES, embed_validation_info=True) # this shouldn't work with PAdES with pytest.raises(SigningError): sign_with_sv(sv, meta) sign_with_sv(sv, meta, test_violation=True)
def test_sv_sign_subfilter_hint(): sv = fields.SigSeedValueSpec(subfilters=[PADES]) emb_sig = sign_with_sv( sv, signers.PdfSignatureMetadata( md_algorithm='sha1', field_name='Sig', subfilter=fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED)) assert emb_sig.sig_object['/SubFilter'] == '/adbe.pkcs7.detached' emb_sig = sign_with_sv(sv, signers.PdfSignatureMetadata(field_name='Sig')) assert emb_sig.sig_object['/SubFilter'] == PADES.value
def test_field_lock_compat(): sv = fields.SigSeedValueSpec(flags=fields.SigSeedValFlags.LOCK_DOCUMENT, lock_document=fields.SeedLockDocument.LOCK) meta = signers.PdfSignatureMetadata(field_name='Sig') sign_with_sv(sv, meta, add_field_lock=True) sv = fields.SigSeedValueSpec( flags=fields.SigSeedValFlags.LOCK_DOCUMENT, lock_document=fields.SeedLockDocument.DO_NOT_LOCK) meta = signers.PdfSignatureMetadata(field_name='Sig') with pytest.raises(SigningError): sign_with_sv(sv, meta, add_field_lock=True)
def test_sv_sign_md_hint(): sv = fields.SigSeedValueSpec(digest_methods=['sha256', 'sha512']) emb_sig = sign_with_sv( sv, signers.PdfSignatureMetadata(md_algorithm='sha1', field_name='Sig')) assert emb_sig.md_algorithm == 'sha1' emb_sig = sign_with_sv(sv, signers.PdfSignatureMetadata(field_name='Sig')) assert emb_sig.md_algorithm == 'sha256' emb_sig = sign_with_sv( sv, signers.PdfSignatureMetadata(md_algorithm='sha512', field_name='Sig')) assert emb_sig.md_algorithm == 'sha512'
def test_sv_mdp_no_certify(): sv = fields.SigSeedValueSpec( seed_signature_type=fields.SeedSignatureType(), ) meta = signers.PdfSignatureMetadata(field_name='Sig') sign_with_sv(sv, meta) meta = signers.PdfSignatureMetadata(field_name='Sig', certify=True) with pytest.raises(SigningError): sign_with_sv(sv, meta) meta = signers.PdfSignatureMetadata(field_name='Sig', certify=True) sign_with_sv(sv, meta, test_violation=True)
def test_sv_sign_reason_prohibited(reasons_param): sv = fields.SigSeedValueSpec(flags=fields.SigSeedValFlags.REASONS, reasons=reasons_param) aw_yiss = signers.PdfSignatureMetadata(reason='Aw yiss', field_name='Sig') with pytest.raises(SigningError): sign_with_sv(sv, aw_yiss) sign_with_sv(sv, aw_yiss, test_violation=True) dot = signers.PdfSignatureMetadata(reason='.', field_name='Sig') with pytest.raises(SigningError): sign_with_sv(sv, dot) sign_with_sv(sv, dot, test_violation=True) emb_sig = sign_with_sv(sv, signers.PdfSignatureMetadata(field_name='Sig')) assert pdf_name('/Reason') not in emb_sig.sig_object
def test_sign_pss_md_discrepancy(): # Acrobat refuses to validate PSS signatures where the internal # hash functions disagree, but mathematically speaking, that shouldn't # be an issue. signer = signers.SimpleSigner.load( CRYPTO_DATA_DIR + '/selfsigned.key.pem', CRYPTO_DATA_DIR + '/selfsigned.cert.pem', ca_chain_files=(CRYPTO_DATA_DIR + '/selfsigned.cert.pem',), key_passphrase=b'secret', signature_mechanism=SignedDigestAlgorithm({ 'algorithm': 'rsassa_pss', 'parameters': RSASSAPSSParams({ 'mask_gen_algorithm': MaskGenAlgorithm({ 'algorithm': 'mgf1', 'parameters': DigestAlgorithm({'algorithm': 'sha512'}) }), 'hash_algorithm': DigestAlgorithm({'algorithm': 'sha256'}), 'salt_length': 478 }) }) ) w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') out = signers.sign_pdf(w, meta, signer=signer) r = PdfFileReader(out) emb = r.embedded_signatures[0] assert emb.field_name == 'Sig1' sda: SignedDigestAlgorithm = emb.signer_info['signature_algorithm'] assert sda.signature_algo == 'rsassa_pss' val_untrusted(emb)
def test_sign_new_existingonly(file): w = IncrementalPdfFileWriter(BytesIO(sign_test_files[file])) with pytest.raises(SigningError): signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name='SigNew'), signer=FROM_CA, existing_fields_only=True)