def test_unclear_signer_cert(): with _simple_sess() as sess: with pytest.raises(SigningError, match='Please specify'): pkcs11.PKCS11Signer( sess, other_certs_to_pull=default_other_certs, )
def test_sign_external_certs(bulk_fetch): # Test to see if unnecessary fetches for intermediate certs are skipped w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') with _simple_sess() as sess: signer = pkcs11.PKCS11Signer(sess, 'signer', ca_chain=(TESTING_CA.get_cert( CertLabel('interm')), ), bulk_fetch=bulk_fetch) orig_fetcher = pkcs11._pull_cert try: def _trap_pull(session, *, label=None, cert_id=None): if label != 'signer': raise RuntimeError return orig_fetcher(session, label=label, cert_id=cert_id) pkcs11._pull_cert = _trap_pull assert isinstance(signer.cert_registry, SimpleCertificateStore) assert len(list(signer.cert_registry)) == 1 out = signers.sign_pdf(w, meta, signer=signer) finally: pkcs11._pull_cert = orig_fetcher r = PdfFileReader(out) emb = r.embedded_signatures[0] assert emb.field_name == 'Sig1' val_trusted(emb)
async def test_async_sign_raw_many_concurrent_no_preload_objs(bulk_fetch, pss): concurrent_count = 10 # don't instantiate through PKCS11SigningContext # also, just sign raw strings, we want to exercise the correctness of # the awaiting logic in sign_raw for object loading with _simple_sess() as sess: signer = pkcs11.PKCS11Signer(sess, 'signer', other_certs_to_pull=default_other_certs, bulk_fetch=bulk_fetch) async def _job(_i): payload = f"PKCS#11 concurrency test #{_i}!".encode('utf8') sig_result = await signer.async_sign_raw(payload, 'sha256') await asyncio.sleep(2) return _i, sig_result jobs = asyncio.as_completed(map(_job, range(1, concurrent_count + 1))) for finished_job in jobs: i, sig = await finished_job general._validate_raw( signature=sig, signed_data=f"PKCS#11 concurrency test #{i}!".encode('utf8'), cert=signer.signing_cert, md_algorithm='sha256', signature_algorithm=SignedDigestAlgorithm( {'algorithm': 'sha256_rsa'}))
def test_unclear_key_label(): signer_cert = TESTING_CA.get_cert(CertLabel('signer1')) with _simple_sess() as sess: with pytest.raises(SigningError, match='\'key_label\'.*must be prov'): pkcs11.PKCS11Signer( sess, signing_cert=signer_cert, other_certs_to_pull=default_other_certs, )
def test_wrong_cert(bulk_fetch): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') with _simple_sess() as sess: signer = pkcs11.PKCS11Signer(sess, key_label='signer', other_certs_to_pull=default_other_certs, bulk_fetch=bulk_fetch, cert_id=binascii.unhexlify(b'deadbeef')) with pytest.raises(PKCS11Error, match='Could not find.*with ID'): signers.sign_pdf(w, meta, signer=signer)
def test_wrong_key_label(bulk_fetch): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') with _simple_sess() as sess: signer = pkcs11.PKCS11Signer(sess, 'signer', other_certs_to_pull=default_other_certs, bulk_fetch=bulk_fetch, key_label='NoSuchKeyExists') with pytest.raises(NoSuchKey): signers.sign_pdf(w, meta, signer=signer)
def test_simple_sign_ecdsa(bulk_fetch): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1', md_algorithm='sha1') with _simple_sess(token='testecdsa') as sess: signer = pkcs11.PKCS11Signer(sess, 'signer', other_certs_to_pull=default_other_certs, bulk_fetch=bulk_fetch) out = signers.sign_pdf(w, meta, signer=signer) r = PdfFileReader(out) emb = r.embedded_signatures[0] assert emb.field_name == 'Sig1' val_trusted(emb, vc=SIMPLE_ECC_V_CONTEXT())
def test_simple_sign(bulk_fetch, pss): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') with _simple_sess() as sess: signer = pkcs11.PKCS11Signer(sess, 'signer', other_certs_to_pull=default_other_certs, bulk_fetch=bulk_fetch, prefer_pss=pss) out = signers.sign_pdf(w, meta, signer=signer) r = PdfFileReader(out) emb = r.embedded_signatures[0] assert emb.field_name == 'Sig1' val_trusted(emb)
def test_signer_pulled_others_provided(bulk_fetch): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') signer_cert = TESTING_CA.get_cert(CertLabel('signer1')) with _simple_sess() as sess: signer = pkcs11.PKCS11Signer(sess, key_label='signer', signing_cert=signer_cert, bulk_fetch=bulk_fetch, other_certs_to_pull=default_other_certs) out = signers.sign_pdf(w, meta, signer=signer) r = PdfFileReader(out) emb = r.embedded_signatures[0] assert emb.field_name == 'Sig1' assert emb.signer_cert.dump() == signer_cert.dump() # this will fail if the intermediate cert is not present val_trusted(emb)
def test_signer_provided_others_pulled(bulk_fetch): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') with _simple_sess() as sess: signer = pkcs11.PKCS11Signer( sess, 'signer', ca_chain={ TESTING_CA.get_cert(CertLabel('root')), TESTING_CA.get_cert(CertLabel('interm')), }, ) out = signers.sign_pdf(w, meta, signer=signer) r = PdfFileReader(out) emb = r.embedded_signatures[0] assert emb.field_name == 'Sig1' val_trusted(emb)
def test_sign_multiple_cert_sources(bulk_fetch): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') with _simple_sess() as sess: signer = pkcs11.PKCS11Signer(sess, 'signer', other_certs_to_pull=('root', ), ca_chain=(TESTING_CA.get_cert( CertLabel('interm')), ), bulk_fetch=bulk_fetch) assert isinstance(signer.cert_registry, SimpleCertificateStore) assert len(list(signer.cert_registry)) == 2 out = signers.sign_pdf(w, meta, signer=signer) r = PdfFileReader(out) emb = r.embedded_signatures[0] assert emb.field_name == 'Sig1' val_trusted(emb)
def addsig_pkcs11(ctx, infile, outfile, lib, token_label, cert_label, key_label, slot_no, skip_user_pin): signature_meta = ctx.obj[Ctx.SIG_META] existing_fields_only = ctx.obj[Ctx.EXISTING_ONLY] timestamp_url = ctx.obj[Ctx.TIMESTAMP_URL] if skip_user_pin: user_pin = None else: user_pin = getpass.getpass(prompt='PKCS#11 user PIN: ') session = pkcs11.open_pkcs11_session(lib_location=lib, slot_no=slot_no, token_label=token_label, user_pin=user_pin) if timestamp_url is not None: timestamper = HTTPTimeStamper(timestamp_url) else: timestamper = None signer = pkcs11.PKCS11Signer( session, cert_label=cert_label, key_label=key_label, ) with pyhanko_exception_manager(): generic_sign(writer=IncrementalPdfFileWriter(infile), outfile=outfile, signature_meta=signature_meta, signer=signer, timestamper=timestamper, style=ctx.obj[Ctx.STAMP_STYLE], new_field_spec=ctx.obj[Ctx.NEW_FIELD_SPEC], existing_fields_only=existing_fields_only, text_params=get_text_params(ctx))