Exemplo n.º 1
0
def _tamper_with_sig_obj(tamper_fun):
    input_buf = BytesIO(MINIMAL)
    w = IncrementalPdfFileWriter(input_buf)
    md_algorithm = 'sha256'

    cms_writer = cms_embedder.PdfCMSEmbedder().write_cms(
        field_name='Signature', writer=w
    )
    next(cms_writer)
    sig_obj = signers.SignatureObject(bytes_reserved=8192)

    cms_writer.send(cms_embedder.SigObjSetup(sig_placeholder=sig_obj))

    tamper_fun(w, sig_obj)

    prep_document_hash, output = cms_writer.send(
        cms_embedder.SigIOSetup(md_algorithm=md_algorithm, in_place=True)
    )

    signer: signers.SimpleSigner = signers.SimpleSigner(
        signing_cert=FROM_CA.signing_cert, signing_key=FROM_CA.signing_key,
        cert_registry=FROM_CA.cert_registry,
        signature_mechanism=SignedDigestAlgorithm({
            'algorithm': 'rsassa_pkcs1v15'
        })
    )
    with pytest.deprecated_call():
        # noinspection PyDeprecation
        cms_obj = signer.sign(
            data_digest=prep_document_hash.document_digest,
            digest_algorithm=md_algorithm,
        )
    cms_writer.send(cms_obj)
    return output
Exemplo n.º 2
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)
Exemplo n.º 3
0
def _tamper_with_signed_attrs(attr_name, *, duplicate=False, delete=False,
                              replace_with=None, resign=False):
    input_buf = BytesIO(MINIMAL)
    w = IncrementalPdfFileWriter(input_buf)
    md_algorithm = 'sha256'

    cms_writer = cms_embedder.PdfCMSEmbedder().write_cms(
        field_name='Signature', writer=w
    )
    next(cms_writer)
    sig_obj = signers.SignatureObject(bytes_reserved=8192)

    cms_writer.send(cms_embedder.SigObjSetup(sig_placeholder=sig_obj))

    prep_digest, output = cms_writer.send(
        cms_embedder.SigIOSetup(md_algorithm=md_algorithm, in_place=True)
    )

    signer: signers.SimpleSigner = signers.SimpleSigner(
        signing_cert=FROM_CA.signing_cert, signing_key=FROM_CA.signing_key,
        cert_registry=FROM_CA.cert_registry,
        signature_mechanism=SignedDigestAlgorithm({
            'algorithm': 'rsassa_pkcs1v15'
        })
    )
    with pytest.deprecated_call():
        # noinspection PyDeprecation
        cms_obj = signer.sign(
            data_digest=prep_digest.document_digest,
            digest_algorithm=md_algorithm,
        )
    sd = cms_obj['content']
    si, = sd['signer_infos']
    signed_attrs = si['signed_attrs']
    ix = next(
        ix for ix, attr in enumerate(signed_attrs)
        if attr['type'].native == attr_name
    )

    # mess with the attribute in the requested way
    if delete:
        del signed_attrs[ix]
    elif duplicate:
        vals = signed_attrs[ix]['values']
        vals.append(vals[0])
    else:
        vals = signed_attrs[ix]['values']
        vals[0] = replace_with

    # ... and replace the signature if requested
    if resign:
        si['signature'] = \
            signer.sign_raw(si['signed_attrs'].untag().dump(), md_algorithm)
    cms_writer.send(cms_obj)
    return output
Exemplo n.º 4
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
Exemplo n.º 5
0
async def test_no_embed_root():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    cr = SimpleCertificateStore()
    cr.register_multiple(FROM_CA.cert_registry)
    no_embed_root_signer = signers.SimpleSigner(
        signing_cert=FROM_CA.signing_cert, signing_key=FROM_CA.signing_key,
        cert_registry=cr, embed_roots=False
    )
    out = await signers.async_sign_pdf(
        w, signers.PdfSignatureMetadata(field_name='Sig1'),
        signer=no_embed_root_signer
    )
    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    assert '/AP' not in s.sig_field
    assert len(s.signed_data['certificates']) == 2
    await async_val_trusted(s)
Exemplo n.º 6
0
async def test_no_certificates(delete):
    input_buf = BytesIO(MINIMAL)
    w = IncrementalPdfFileWriter(input_buf)
    md_algorithm = 'sha256'

    cms_writer = cms_embedder.PdfCMSEmbedder().write_cms(
        field_name='Signature', writer=w
    )
    next(cms_writer)
    sig_obj = signers.SignatureObject(bytes_reserved=8192)

    cms_writer.send(cms_embedder.SigObjSetup(sig_placeholder=sig_obj))

    prep_digest, output = cms_writer.send(
        cms_embedder.SigIOSetup(md_algorithm=md_algorithm, in_place=True)
    )

    signer: signers.SimpleSigner = signers.SimpleSigner(
        signing_cert=FROM_CA.signing_cert, signing_key=FROM_CA.signing_key,
        cert_registry=FROM_CA.cert_registry,
        signature_mechanism=SignedDigestAlgorithm({
            'algorithm': 'rsassa_pkcs1v15'
        })
    )
    cms_obj = await signer.async_sign(
        data_digest=prep_digest.document_digest,
        digest_algorithm=md_algorithm,
    )
    sd = cms_obj['content']
    if delete:
        del sd['certificates']
    else:
        sd['certificates'] = cms.CertificateSet([])
    cms_writer.send(cms_obj)

    r = PdfFileReader(output)
    with pytest.raises(CMSExtractionError, match='signer cert.*includ'):
        emb = r.embedded_signatures[0]
        await collect_validation_info(
            embedded_sig=emb, validation_context=ValidationContext()
        )
    with pytest.raises(SignatureValidationError,
                       match='signer cert.*includ'):
        r.embedded_signatures[0].signer_cert.dump()
Exemplo n.º 7
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())
Exemplo n.º 8
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]))