Beispiel #1
0
def test_pss_exclusive():
    cfg = CertomancerConfig.from_file('tests/data/with-external-config.yml',
                                      'tests/data')
    arch = cfg.get_pki_arch(ArchLabel('testing-ca-pss-exclusive'))
    certs = ['root', 'interm', 'signer1', 'signer2']
    for c in certs:
        assert arch.get_cert(CertLabel(c)).signature_algo == 'rsassa_pss'
        assert arch.get_cert(CertLabel(c)).public_key.algorithm == 'rsassa_pss'
Beispiel #2
0
def test_serial_order_indep(order):
    arch = CONFIG.get_pki_arch(ArchLabel('testing-ca'))
    for lbl in order:
        arch.get_cert(CertLabel(lbl))

    assert arch.get_cert(CertLabel('root')).serial_number == 4096
    assert arch.get_cert(CertLabel('interm')).serial_number == 4097
    assert arch.get_cert(CertLabel('signer1')).serial_number == 4097
Beispiel #3
0
def test_issue_intermediate():
    cfg = '''
      root-ca:
        subject: root
        subject-key: root
        issuer: root
        authority-key: root
        validity:
          valid-from: "2000-01-01T00:00:00+0000"
          valid-to: "2500-01-01T00:00:00+0000"
        extensions:
          - id: basic_constraints
            critical: true
            value:
              ca: true
          - id: key_usage
            critical: true
            smart-value:
              schema: key-usage
              params: [digital_signature, key_cert_sign, crl_sign]
      intermediate-ca:
        subject: interm
        issuer: root
        validity:
          valid-from: "2000-01-01T00:00:00+0000"
          valid-to: "2100-01-01T00:00:00+0000"
        extensions:
          - id: basic_constraints
            critical: true
            value:
              ca: true
              path-len-constraint: 0
          - id: key_usage
            critical: true
            smart-value:
              schema: key-usage
              params: [digital_signature, key_cert_sign, crl_sign]
    '''

    arch = PKIArchitecture(
        arch_label=ArchLabel('test'),
        key_set=RSA_KEYS,
        entities=ENTITIES,
        cert_spec_config=yaml.safe_load(cfg),
        service_config={},
        external_url_prefix='http://test.test',
    )
    root_cert = arch.get_cert(CertLabel('root-ca'))
    assert root_cert.subject == ENTITIES[EntityLabel('root')]
    assert root_cert.issuer == ENTITIES[EntityLabel('root')]
    assert root_cert.not_valid_before == datetime(2000, 1, 1, tzinfo=pytz.utc)
    interm_cert = arch.get_cert(CertLabel('intermediate-ca'))
    assert interm_cert.subject == ENTITIES[EntityLabel('interm')]
    assert root_cert.issuer == ENTITIES[EntityLabel('root')]
    assert root_cert.not_valid_before == datetime(2000, 1, 1, tzinfo=pytz.utc)
Beispiel #4
0
def test_subject_alt_names():
    # test whether SAN extensions are reassigned properly when using
    # cert specs as templates for other cert specs
    arch = CONFIG.get_pki_arch(ArchLabel('testing-ca'))
    signer1 = arch.get_cert(CertLabel('signer1'))
    signer2 = arch.get_cert(CertLabel('signer2'))
    signer1_long = arch.get_cert(CertLabel('signer1-long'))

    assert signer1.subject_alt_name_value[
        0].chosen.native == '*****@*****.**'
    assert signer2.subject_alt_name_value[0].chosen.native \
           == '*****@*****.**'
    assert signer1_long.subject_alt_name_value is None
Beispiel #5
0
def test_pkcs12(pw):
    arch = CONFIG.get_pki_arch(ArchLabel('testing-ca'))
    package = arch.package_pkcs12(CertLabel('signer1'), password=pw)
    if pw:
        # there's something about passwordless PKCS#12 files that doesn't quite
        # jive between oscrypto and pyca/cryptography
        key, cert, chain = oskeys.parse_pkcs12(package, password=pw)
        assert cert.dump() == arch.get_cert(CertLabel('signer1')).dump()
        assert len(chain) == 2
        assert key is not None

    from cryptography.hazmat.primitives.serialization import pkcs12
    key, cert, chain = pkcs12.load_key_and_certificates(package, password=pw)
    assert key is not None
    assert len(chain) == 2
Beispiel #6
0
async def test_prefetched_sad_not_twice(aiohttp_client):
    client, auth_man, csc_dummy = await _set_up_dummy_client(
        aiohttp_client, require_hash_pinning=False)

    # prefetch SAD that is not bound to any hashes
    async with client.post('/csc/v1/credentials/authorize',
                           json=auth_man.format_csc_auth_request(),
                           raise_for_status=True) as resp:
        sad = (await resp.json())['SAD']
    auth_man = csc_signer.PrefetchedSADAuthorizationManager(
        csc_session_info=auth_man.csc_session_info,
        credential_info=auth_man.credential_info,
        csc_auth_info=csc_signer.CSCAuthorizationInfo(sad=sad))

    signer = csc_signer.CSCSigner(
        session=client,
        auth_manager=auth_man,
        batch_autocommit=True,
        batch_size=1,
    )

    result = await signer.async_sign_raw(b'foobar', digest_algorithm='sha256')
    signer_cert = TESTING_CA.get_cert(CertLabel('signer1'))
    _validate_raw(result,
                  b'foobar',
                  signer_cert,
                  signature_algorithm=algos.SignedDigestAlgorithm(
                      {'algorithm': 'sha256_rsa'}),
                  md_algorithm='sha256')

    # but a second attempt should fail
    with pytest.raises(SigningError, match='No signing results'):
        await signer.async_sign_raw(b'foobar', digest_algorithm='sha256')
Beispiel #7
0
async def test_sign_unreadable_sig(aiohttp_client, response_obj):
    csc_session_info = csc_signer.CSCServiceSessionInfo('', 'foobar')
    auth_man = csc_signer.PrefetchedSADAuthorizationManager(
        csc_session_info=csc_session_info,
        credential_info=csc_signer.CSCCredentialInfo(
            signing_cert=TESTING_CA.get_cert(CertLabel('signer1')),
            chain=[],
            supported_mechanisms=frozenset({'sha256_rsa'}),
            max_batch_size=1,
            hash_pinning_required=False,
            response_data={}),
        csc_auth_info=csc_signer.CSCAuthorizationInfo(sad=''))

    async def fake_return(_request):
        return web.json_response(response_obj)

    app = web.Application()
    app.router.add_post('/csc/v1/signatures/signHash', fake_return)
    client = await aiohttp_client(app)
    signer = csc_signer.CSCSigner(
        client,
        auth_manager=auth_man,
        batch_size=1,
        batch_autocommit=False,
        client_data='Some client data, because why not')
    result = asyncio.create_task(signer.async_sign_raw(b'foobarbaz', 'sha256'))
    with pytest.raises(SigningError, match='Expected response with b64'):
        await asyncio.sleep(1)
        await signer.commit()

    try:
        result.cancel()
        await result
    except asyncio.CancelledError:
        pass
Beispiel #8
0
async def test_sign_mechanism_not_supported():
    csc_session_info = csc_signer.CSCServiceSessionInfo(
        'https://example.com', 'foobar')
    auth_man = csc_signer.PrefetchedSADAuthorizationManager(
        csc_session_info=csc_session_info,
        credential_info=csc_signer.CSCCredentialInfo(
            signing_cert=TESTING_CA.get_cert(CertLabel('signer1')),
            chain=[],
            supported_mechanisms=frozenset({'is_nonsense'}),
            max_batch_size=10,
            hash_pinning_required=False,
            response_data={}),
        csc_auth_info=csc_signer.CSCAuthorizationInfo(sad=''))
    # check expected failure for a signing attempt
    with pytest.raises(SigningError, match='No signing results available'):
        async with aiohttp.ClientSession() as session:
            signer = csc_signer.CSCSigner(session, auth_manager=auth_man)
            await signer.async_sign_raw(b'foobarbazquux', 'sha256')

    # check expected failure when fetching the signature mechanism directly
    with pytest.raises(SigningError, match='must be one of'):
        # noinspection PyTypeChecker
        signer = csc_signer.CSCSigner(None, auth_manager=auth_man)
        signer.get_signature_mechanism(digest_algorithm='sha256')

    # ...but overrides should still work
    # noinspection PyTypeChecker
    signer = csc_signer.CSCSigner(None, auth_manager=auth_man)
    signer.signature_mechanism = mech \
        = algos.SignedDigestAlgorithm({'algorithm': 'sha256_rsa'})
    assert signer.get_signature_mechanism(digest_algorithm='sha256') == mech
Beispiel #9
0
def test_old_style_signing_cert_attr_mismatch(with_issser):

    if with_issser:
        # this file has an old-style signing cert attr with issuerSerial
        fname = 'pades-with-old-style-signing-cert-attr-issser.pdf'
    else:
        fname = 'pades-with-old-style-signing-cert-attr.pdf'
    with open(os.path.join(PDF_DATA_DIR, fname), 'rb') as f:
        r = PdfFileReader(f)
        s = r.embedded_signatures[0]
        signer_info = s.signer_info
        digest = s.compute_digest()
    # signer1-long has the same key as signer1
    alt_cert = TESTING_CA.get_cert(CertLabel('signer1-long'))
    signer_info['sid'] = {
        'issuer_and_serial_number': cms.IssuerAndSerialNumber({
            'issuer': alt_cert.issuer,
            'serial_number': alt_cert.serial_number
        })
    }
    with pytest.raises(
            SignatureValidationError,
            match="Signing certificate attribute does not match ") as exc_info:
        validate_sig_integrity(
            signer_info, alt_cert, expected_content_type='data',
            actual_digest=digest
        )

    assert exc_info.value.ades_status == AdESStatus.INDETERMINATE
    assert exc_info.value.ades_subindication \
           == AdESIndeterminate.NO_SIGNING_CERTIFICATE_FOUND
Beispiel #10
0
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)
Beispiel #11
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
def test_validate(requests_mock, setup):
    setup.illusionist.register(requests_mock)
    signer_cert = setup.arch.get_cert(CertLabel('signer1'))
    root = setup.arch.get_cert(CertLabel('root'))
    interm = setup.arch.get_cert(CertLabel('interm'))
    vc = ValidationContext(trust_roots=[root],
                           allow_fetching=True,
                           revocation_mode='hard-fail',
                           other_certs=[interm])

    validator = CertificateValidator(signer_cert,
                                     intermediate_certs=[],
                                     validation_context=vc)
    validator.validate_usage({'digital_signature'})

    assert len(vc.ocsps)
    assert len(vc.crls)
Beispiel #13
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 == '*****@*****.**'
Beispiel #14
0
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,
            )
Beispiel #15
0
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 serve_any_cert(self, _request: Request, *,
                       arch: str, label: str, use_pem):
        mime = 'application/x-pem-file' if use_pem else 'application/pkix-cert'
        pki_arch = self.architectures[ArchLabel(arch)]
        cert = pki_arch.get_cert(CertLabel(label))

        data = cert.dump()
        if use_pem:
            data = pem.armor('certificate', data)
        return Response(data, mimetype=mime)
Beispiel #17
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)
def test_aia_ca_issuers(setup):
    signer1 = setup.arch.get_cert(CertLabel('signer1'))
    ca_issuer_urls = {
        aia_entry['access_location']
        for aia_entry in signer1.authority_information_access_value.native
        if aia_entry['access_method'] == 'ca_issuers'
    }
    assert ca_issuer_urls == {
        'http://test.test/testing-ca/certs/interm/ca.crt',
        'http://test.test/testing-ca/certs/root/issued/interm.crt'
    }
Beispiel #19
0
def live_testing_vc(requests_mock, with_extra_tsa=False, **kwargs):
    if with_extra_tsa:
        trust_roots = TRUST_ROOTS + [UNRELATED_TSA.get_cert(CertLabel('root'))]
    else:
        trust_roots = TRUST_ROOTS
    vc = ValidationContext(trust_roots=trust_roots,
                           allow_fetching=True,
                           other_certs=[],
                           **kwargs)
    Illusionist(TESTING_CA).register(requests_mock)
    if with_extra_tsa:
        Illusionist(UNRELATED_TSA).register(requests_mock)
    return vc
Beispiel #20
0
def live_ac_vcs(requests_mock, with_authorities=False):
    pki_arch = CERTOMANCER.get_pki_arch(ArchLabel('testing-ca-with-aa'))
    if with_authorities:
        other_certs = [
            pki_arch.get_cert('interm'),
            pki_arch.get_cert('interm-aa'),
            pki_arch.get_cert('leaf-aa')
        ]
    else:
        other_certs = []
    main_vc = ValidationContext(
        trust_roots=[pki_arch.get_cert(CertLabel('root'))],
        allow_fetching=True,
        other_certs=other_certs,
    )
    ac_vc = ValidationContext(
        trust_roots=[pki_arch.get_cert(CertLabel('root-aa'))],
        allow_fetching=True,
        other_certs=other_certs,
    )
    Illusionist(pki_arch).register(requests_mock)
    return main_vc, ac_vc
Beispiel #21
0
def test_provided_certs():

    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,
            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'
    assert emb.signer_cert.dump() == signer_cert.dump()
    # this will fail if the intermediate cert is not present
    val_trusted(emb)
    def _parse_credential_id(self, cred_id):
        splits = cred_id.split(sep='/', maxsplit=1)
        arch_label = ArchLabel(splits[0])
        try:
            cert_label = CertLabel(splits[1])
        except IndexError:
            raise web.HTTPNotFound()

        config = self.certomancer_config
        try:
            pki_arch = config.get_pki_arch(arch_label)
            cert_spec = pki_arch.get_cert_spec(cert_label)
        except CertomancerObjectNotFoundError:
            raise web.HTTPNotFound()
        return pki_arch, cert_spec
Beispiel #23
0
def test_sign_public_only():
    cfg = '''
      root-ca:
        subject: root
        subject-key: root
        issuer: root
        authority-key: root
        validity:
          valid-from: "2000-01-01T00:00:00+0000"
          valid-to: "2500-01-01T00:00:00+0000"
        extensions:
          - id: basic_constraints
            critical: true
            value:
              ca: true
          - id: key_usage
            critical: true
            smart-value:
              schema: key-usage
              params: [digital_signature, key_cert_sign, crl_sign]
      leaf:
          subject: pub-only
          subject-key: split-key-pub
          issuer: root
          authority-key: root
          validity:
            valid-from: "2020-01-01T00:00:00+0000"
            valid-to: "2050-01-01T00:00:00+0000"
          extensions:
            - id: key_usage
              critical: true
              smart-value:
                schema: key-usage
                params: [digital_signature]
    '''

    arch = PKIArchitecture(
        arch_label=ArchLabel('test'),
        key_set=RSA_KEYS,
        entities=ENTITIES,
        cert_spec_config=yaml.safe_load(cfg),
        service_config={},
        external_url_prefix='http://test.test',
    )
    pubkey = arch.get_cert(CertLabel('leaf')).public_key
    with open('tests/data/keys-rsa/split-key-pub.key.pem', 'rb') as inf:
        pubkey_actual = oskeys.parse_public(inf.read())
    assert pubkey.native == pubkey_actual.native
Beispiel #24
0
def test_signing_cert_attr_malformed_issuer():
    from asn1crypto import x509
    cert = TESTING_CA.get_cert(CertLabel('signer1'))
    bogus_attr = as_signing_certificate_v2(cert)
    bogus_attr['certs'][0]['issuer_serial']['issuer'][0] = x509.GeneralName(
        {'dns_name': 'www.example.com'})
    output = _tamper_with_signed_attrs('signing_certificate_v2',
                                       resign=True,
                                       replace_with=bogus_attr)
    r = PdfFileReader(output)
    emb = r.embedded_signatures[0]
    digest = emb.compute_digest()
    with pytest.raises(SignatureValidationError,
                       match="Signing certificate attribute does not match "):
        validate_sig_integrity(emb.signer_info, emb.signer_cert, 'data',
                               digest)
    def serve_cert(self, _request: Request, *, label: str, arch: str,
                   cert_label: Optional[str], use_pem):
        mime = 'application/x-pem-file' if use_pem else 'application/pkix-cert'
        pki_arch = self.architectures[ArchLabel(arch)]
        cert_label = CertLabel(cert_label) if cert_label is not None else None

        cert = pki_arch.service_registry.get_cert_from_repo(
            ServiceLabel(label), cert_label
        )
        if cert is None:
            raise NotFound()

        data = cert.dump()
        if use_pem:
            data = pem.armor('certificate', data)
        return Response(data, mimetype=mime)
Beispiel #26
0
async def test_csc_placeholder_sig_size():

    csc_session_info = csc_signer.CSCServiceSessionInfo(
        'https://example.com', 'foobar')
    auth_man = csc_signer.PrefetchedSADAuthorizationManager(
        csc_session_info=csc_session_info,
        credential_info=csc_signer.CSCCredentialInfo(
            signing_cert=TESTING_CA.get_cert(CertLabel('signer1')),
            chain=[],
            supported_mechanisms=frozenset({'is_nonsense'}),
            max_batch_size=10,
            hash_pinning_required=False,
            response_data={}),
        csc_auth_info=csc_signer.CSCAuthorizationInfo(sad=''))
    # noinspection PyTypeChecker
    signer = csc_signer.CSCSigner(None, auth_manager=auth_man)
    await signer.async_sign_raw(b'foobarbazquux', 'sha256', dry_run=True)
    def serve_pfx(self, request: Request, *, arch):
        pki_arch = self.architectures[ArchLabel(arch)]
        try:
            cert = request.form['cert']
        except KeyError:
            raise BadRequest()

        cert = CertLabel(cert)
        if not (pyca_cryptography_present() and
                pki_arch.is_subject_key_available(cert)):
            raise NotFound()

        pass_bytes = request.form.get('passphrase', '').encode('utf8')
        data = pki_arch.package_pkcs12(cert, password=pass_bytes or None)
        cd_header = f'attachment; filename="{cert}.pfx"'
        return Response(data, mimetype='application/x-pkcs12',
                        headers={'Content-Disposition': cd_header})
Beispiel #28
0
async def test_submit_job_during_commit(aiohttp_client):

    client, auth_man, csc_dummy = await _set_up_dummy_client(aiohttp_client)

    class SlowCommitter(csc_signer.CSCSigner):
        _committed_once = False

        async def _do_commit(self, batch):
            # waste time
            if not self._committed_once:
                await asyncio.sleep(5)
            self._committed_once = True
            await super()._do_commit(batch)

    signer = SlowCommitter(session=client,
                           auth_manager=auth_man,
                           batch_autocommit=True,
                           batch_size=2)

    async def make_first_sig():
        # submit an incomplete batch
        result = asyncio.create_task(
            signer.async_sign_raw(b'foobar1', 'sha256'), )
        await asyncio.sleep(1)
        await signer.commit()
        return await result

    async def make_other_sigs():
        await asyncio.sleep(2)
        return await asyncio.gather(
            signer.async_sign_raw(b'foobar2', 'sha256'),
            signer.async_sign_raw(b'foobar3', 'sha256'),
        )

    sig1, others = await asyncio.gather(make_first_sig(), make_other_sigs())

    signer_cert = TESTING_CA.get_cert(CertLabel('signer1'))
    for ix, sig in enumerate([sig1, *others]):
        _validate_raw(sig,
                      b'foobar%d' % (ix + 1),
                      signer_cert,
                      signature_algorithm=algos.SignedDigestAlgorithm(
                          {'algorithm': 'sha256_rsa'}),
                      md_algorithm='sha256')
    assert auth_man.authorizations_requested == 2
Beispiel #29
0
async def test_sign_network_fail():
    csc_session_info = csc_signer.CSCServiceSessionInfo(
        'https://example.invalid', 'foobar')
    auth_man = csc_signer.PrefetchedSADAuthorizationManager(
        csc_session_info=csc_session_info,
        credential_info=csc_signer.CSCCredentialInfo(
            signing_cert=TESTING_CA.get_cert(CertLabel('signer1')),
            chain=[],
            supported_mechanisms=frozenset({'sha256_rsa'}),
            max_batch_size=10,
            hash_pinning_required=False,
            response_data={}),
        csc_auth_info=csc_signer.CSCAuthorizationInfo(sad=''))

    with pytest.raises(SigningError, match='No signing results available'):
        async with aiohttp.ClientSession() as session:
            signer = csc_signer.CSCSigner(session, auth_manager=auth_man)
            await signer.async_sign_raw(b'foobarbazquux', 'sha256')
Beispiel #30
0
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)