def test_demo_plugin(requests_mock):

    with_plugin_cfg = CertomancerConfig.from_file('tests/data/with-plugin.yml',
                                                  'tests/data')

    arch = with_plugin_cfg.get_pki_arch(ArchLabel('testing-ca'))

    illusionist.Illusionist(pki_arch=arch).register(requests_mock)

    importlib.import_module('example_plugin.encrypt_echo')

    # make the endpoint encrypt something
    endpoint = 'http://test.test/testing-ca/plugin/encrypt-echo/test-endpoint'
    payload = b'test test test'
    response = requests.post(endpoint, data=payload)

    # decrypt it
    env_data = cms.ContentInfo.load(response.content)['content']
    key = arch.key_set.get_private_key(KeyLabel('signer1'))
    ktri = env_data['recipient_infos'][0].chosen
    encrypted_key = ktri['encrypted_key'].native

    decrypted_key = asymmetric.rsa_pkcs1v15_decrypt(
        asymmetric.load_private_key(key.dump()), encrypted_key)

    eci = env_data['encrypted_content_info']
    cea = eci['content_encryption_algorithm']
    assert cea['algorithm'].native == 'aes256_cbc'
    iv = cea['parameters'].native
    encrypted_content_bytes = eci['encrypted_content'].native
    decrypted_payload = symmetric.aes_cbc_pkcs7_decrypt(
        decrypted_key, encrypted_content_bytes, iv)
    assert decrypted_payload == payload
示例#2
0
def test_demo_plugin():

    with_plugin_cfg = CertomancerConfig.from_file('tests/data/with-plugin.yml',
                                                  'tests/data')

    with_plugin_app = Animator(AnimatorArchStore(with_plugin_cfg.pki_archs),
                               with_web_ui=False)
    client = Client(with_plugin_app, Response)

    # make the endpoint encrypt something
    endpoint = '/testing-ca/plugin/encrypt-echo/test-endpoint'
    payload = b'test test test'
    response = client.post(endpoint, data=payload)

    # decrypt it
    env_data = cms.ContentInfo.load(response.data)['content']
    arch = with_plugin_cfg.get_pki_arch(ArchLabel('testing-ca'))
    key = arch.key_set.get_private_key(KeyLabel('signer1'))
    ktri = env_data['recipient_infos'][0].chosen
    encrypted_key = ktri['encrypted_key'].native

    decrypted_key = asymmetric.rsa_pkcs1v15_decrypt(
        asymmetric.load_private_key(key.dump()), encrypted_key)

    eci = env_data['encrypted_content_info']
    cea = eci['content_encryption_algorithm']
    assert cea['algorithm'].native == 'aes256_cbc'
    iv = cea['parameters'].native
    encrypted_content_bytes = eci['encrypted_content'].native
    decrypted_payload = symmetric.aes_cbc_pkcs7_decrypt(
        decrypted_key, encrypted_content_bytes, iv)
    assert decrypted_payload == payload
示例#3
0
async def test_embed_ac_revinfo_adobe_style(requests_mock):
    signer = get_ac_aware_signer()
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    pki_arch = CERTOMANCER.get_pki_arch(ArchLabel('testing-ca-with-aa'))
    dummy_ts = timestamps.DummyTimeStamper(
        tsa_cert=pki_arch.get_cert(CertLabel('tsa')),
        tsa_key=pki_arch.key_set.get_private_key(KeyLabel('tsa')),
        certs_to_embed=SimpleCertificateStore.from_certs(
            [pki_arch.get_cert('root')]
        )
    )
    from certomancer.integrations.illusionist import Illusionist
    from pyhanko_certvalidator.fetchers.requests_fetchers import (
        RequestsFetcherBackend,
    )
    fetchers = RequestsFetcherBackend().get_fetchers()
    main_vc = ValidationContext(
        trust_roots=[pki_arch.get_cert('root')], allow_fetching=True,
        other_certs=signer.cert_registry, fetchers=fetchers,
        revocation_mode='require'
    )
    ac_vc = ValidationContext(
        trust_roots=[pki_arch.get_cert('root-aa')], allow_fetching=True,
        other_certs=signer.cert_registry, fetchers=fetchers,
        revocation_mode='require'
    )
    Illusionist(pki_arch).register(requests_mock)
    out = await signers.async_sign_pdf(
        w, signers.PdfSignatureMetadata(
            field_name='Sig1',
            embed_validation_info=True,
            validation_context=main_vc,
            ac_validation_context=ac_vc
        ),
        timestamper=dummy_ts,
        signer=signer
    )

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    # 4 CA certs, 1 AA certs, 1 AC, 1 signer cert -> 7 certs
    assert len(s.other_embedded_certs) == 5  # signer cert is excluded
    assert len(s.embedded_attr_certs) == 1
    from pyhanko.sign.validation import RevocationInfoValidationType
    status = await async_validate_pdf_ltv_signature(
        s, RevocationInfoValidationType.ADOBE_STYLE,
        validation_context_kwargs={
            'trust_roots': [pki_arch.get_cert('root')]
        },
        ac_validation_context_kwargs={
            'trust_roots': [pki_arch.get_cert('root-aa')]
        }
    )
    assert status.bottom_line
    roles = list(status.ac_attrs['role'].attr_values)
    role = roles[0]
    assert isinstance(role, cms.RoleSyntax)
    assert role['role_name'].native == '*****@*****.**'
示例#4
0
async def test_sign_weak_sig_digest():
    # We have to jump through some hoops to put together a signature
    # where the signing method's digest is not the same as the "external"
    # digest. This is intentional, since it's bad practice.

    input_buf = BytesIO(MINIMAL)
    w = IncrementalPdfFileWriter(input_buf)

    cms_writer = cms_embedder.PdfCMSEmbedder().write_cms(
        field_name='Signature', writer=w
    )
    next(cms_writer)

    timestamp = datetime.now(tz=tzlocal.get_localzone())
    sig_obj = signers.SignatureObject(timestamp=timestamp, bytes_reserved=8192)

    external_md_algorithm = 'sha256'
    cms_writer.send(cms_embedder.SigObjSetup(sig_placeholder=sig_obj))

    prep_digest, output = cms_writer.send(
        cms_embedder.SigIOSetup(md_algorithm=external_md_algorithm, in_place=True)
    )
    signer = signers.SimpleSigner(
        signing_cert=TESTING_CA.get_cert(CertLabel('signer1')),
        signing_key=TESTING_CA.key_set.get_private_key(KeyLabel('signer1')),
        cert_registry=SimpleCertificateStore.from_certs([ROOT_CERT,
                                                         INTERM_CERT])
    )
    cms_obj = await signer.async_sign(
        data_digest=prep_digest.document_digest,
        digest_algorithm=external_md_algorithm,
        signed_attr_settings=PdfCMSSignedAttributes(signing_time=timestamp)
    )
    si_obj: cms.SignerInfo = cms_obj['content']['signer_infos'][0]
    bad_algo = SignedDigestAlgorithm({'algorithm': 'md5_rsa'})
    si_obj['signature_algorithm'] = signer.signature_mechanism = bad_algo
    attrs = si_obj['signed_attrs']
    cms_prot = find_cms_attribute(attrs, 'cms_algorithm_protection')[0]
    cms_prot['signature_algorithm'] = bad_algo
    # recompute the signature
    si_obj['signature'] = signer.sign_raw(attrs.untag().dump(), 'md5')
    sig_contents = cms_writer.send(cms_obj)

    # we requested in-place output
    assert output is input_buf

    r = PdfFileReader(input_buf)
    emb = r.embedded_signatures[0]
    with pytest.raises(WeakHashAlgorithmError):
        await async_val_trusted(emb)

    lenient_vc = ValidationContext(
        trust_roots=[ROOT_CERT], weak_hash_algos=set()
    )
    await async_val_trusted(emb, vc=lenient_vc)
示例#5
0
def get_ac_aware_signer(actual_signer='signer1'):
    pki_arch = CERTOMANCER.get_pki_arch(ArchLabel('testing-ca-with-aa'))
    signer = signers.SimpleSigner(
        signing_cert=pki_arch.get_cert(CertLabel(actual_signer)),
        signing_key=pki_arch.key_set.get_private_key(KeyLabel(actual_signer)),
        cert_registry=SimpleCertificateStore.from_certs(
            [
                pki_arch.get_cert('root'), pki_arch.get_cert('interm'),
                pki_arch.get_cert('root-aa'), pki_arch.get_cert('interm-aa'),
                pki_arch.get_cert('leaf-aa')
            ]
        ),
        attribute_certs=[
            pki_arch.get_attr_cert(CertLabel('alice-role-with-rev'))
        ]
    )
    return signer
示例#6
0
def test_sign_with_explicit_dsa_implied_hash():
    signer = signers.SimpleSigner(
        signing_cert=TESTING_CA_DSA.get_cert(CertLabel('signer1')),
        signing_key=TESTING_CA_DSA.key_set.get_private_key(
            KeyLabel('signer1')),
        cert_registry=SimpleCertificateStore.from_certs(
            [DSA_ROOT_CERT, DSA_INTERM_CERT]),
        # this is not allowed, but the validator should accept it anyway
        signature_mechanism=SignedDigestAlgorithm({'algorithm': 'dsa'}))
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    out = signers.sign_pdf(w,
                           signers.PdfSignatureMetadata(field_name='Sig1'),
                           signer=signer)
    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    si = s.signer_info
    assert si['signature_algorithm']['algorithm'].native == 'dsa'
    assert s.field_name == 'Sig1'
    val_trusted(s, vc=SIMPLE_DSA_V_CONTEXT())
示例#7
0
SELF_SIGN = signers.SimpleSigner.load(CRYPTO_DATA_DIR + '/selfsigned.key.pem',
                                      CRYPTO_DATA_DIR + '/selfsigned.cert.pem',
                                      key_passphrase=b'secret')
ROOT_CERT = TESTING_CA.get_cert(CertLabel('root'))
ECC_ROOT_CERT = TESTING_CA_ECDSA.get_cert(CertLabel('root'))
DSA_ROOT_CERT = TESTING_CA_DSA.get_cert(CertLabel('root'))
INTERM_CERT = TESTING_CA.get_cert(CertLabel('interm'))
ECC_INTERM_CERT = TESTING_CA_ECDSA.get_cert(CertLabel('interm'))
DSA_INTERM_CERT = TESTING_CA_DSA.get_cert(CertLabel('interm'))
OCSP_CERT = TESTING_CA.get_cert(CertLabel('interm-ocsp'))
REVOKED_CERT = TESTING_CA.get_cert(CertLabel('signer2'))
TSA_CERT = TESTING_CA.get_cert(CertLabel('tsa'))
TSA2_CERT = TESTING_CA.get_cert(CertLabel('tsa2'))
FROM_CA = signers.SimpleSigner(
    signing_cert=TESTING_CA.get_cert(CertLabel('signer1')),
    signing_key=TESTING_CA.key_set.get_private_key(KeyLabel('signer1')),
    cert_registry=SimpleCertificateStore.from_certs([ROOT_CERT, INTERM_CERT]))
FROM_ECC_CA = signers.SimpleSigner(
    signing_cert=TESTING_CA_ECDSA.get_cert(CertLabel('signer1')),
    signing_key=TESTING_CA_ECDSA.key_set.get_private_key(KeyLabel('signer1')),
    cert_registry=SimpleCertificateStore.from_certs(
        [ECC_ROOT_CERT, ECC_INTERM_CERT]))
FROM_DSA_CA = signers.SimpleSigner(
    signing_cert=TESTING_CA_DSA.get_cert(CertLabel('signer1')),
    signing_key=TESTING_CA_DSA.key_set.get_private_key(KeyLabel('signer1')),
    cert_registry=SimpleCertificateStore.from_certs(
        [DSA_ROOT_CERT, DSA_INTERM_CERT]))
REVOKED_SIGNER = signers.SimpleSigner(
    signing_cert=TESTING_CA.get_cert(CertLabel('signer2')),
    signing_key=TESTING_CA.key_set.get_private_key(KeyLabel('signer2')),
    cert_registry=SimpleCertificateStore.from_certs([ROOT_CERT, INTERM_CERT]))