Ejemplo n.º 1
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
Ejemplo n.º 2
0
def test_embed_with_af(incremental):
    if incremental:
        w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    else:
        r = PdfFileReader(BytesIO(MINIMAL))
        w = writer.copy_into_new_writer(r)

    modified = datetime.now(tz=tzlocal.get_localzone())
    created = modified - timedelta(days=1)
    ef_obj = embed.EmbeddedFileObject.from_file_data(
        w,
        data=VECTOR_IMAGE_PDF,
        params=embed.EmbeddedFileParams(creation_date=created,
                                        modification_date=modified))

    spec = embed.FileSpec(file_spec_string='vector-test.pdf',
                          embedded_data=ef_obj,
                          description='Embedding test /w assoc file',
                          af_relationship=generic.pdf_name('/Unspecified'))
    embed.embed_file(w, spec)
    out = BytesIO()
    w.write(out)
    r = PdfFileReader(out)
    assert r.input_version == (2, 0)
    emb_lst = r.root['/Names']['/EmbeddedFiles']['/Names']
    assert len(emb_lst) == 2
    assert emb_lst[0] == 'vector-test.pdf'
    spec_obj = emb_lst[1]
    assert '/UF' not in spec_obj
    assert spec_obj['/AFRelationship'] == '/Unspecified'
    stream = spec_obj['/EF']['/F']
    assert stream.data == VECTOR_IMAGE_PDF
    assert '/UF' not in spec_obj['/EF']

    assert r.root['/AF'].raw_get(0).reference == spec_obj.container_ref
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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
        )
Ejemplo n.º 6
0
def test_pades_dss_object_clobber(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,
    )
    dummy_ref = w.add_object(generic.pdf_string("Hi there")).reference

    out = signers.sign_pdf(w, meta1, signer=FROM_CA, timestamper=DUMMY_TS)
    w = IncrementalPdfFileWriter(out)
    # We're going to reassign the DSS object to another object ID, namely
    #  one that clobbers the dummy_ref object. This should be ample cause
    #  for suspicion.
    dss = w.root['/DSS']
    w.objects[(dummy_ref.generation, dummy_ref.idnum)] = dss
    w.root['/DSS'] = generic.IndirectObject(idnum=dummy_ref.idnum,
                                            generation=dummy_ref.generation,
                                            pdf=w)
    w.update_root()
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted_but_modified(s)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
def test_update_hybrid_twice(fname):
    with open(os.path.join(PDF_DATA_DIR, fname), 'rb') as inf:
        w = IncrementalPdfFileWriter(inf)
        t_obj = w.trailer['/Info'].raw_get('/Title')
        assert isinstance(t_obj, generic.IndirectObject)
        w.objects[(t_obj.generation, t_obj.idnum)] \
            = generic.pdf_string('Updated')
        out = BytesIO()
        w.write(out)

    r = PdfFileReader(out)
    assert r.trailer['/Info']['/Title'] == 'Updated'
    container_info = r.xrefs.get_xref_container_info(1)
    assert container_info.xref_section_type == XRefSectionType.HYBRID_MAIN
    container_info = r.xrefs.get_xref_container_info(2)
    assert container_info.xref_section_type == XRefSectionType.STANDARD

    w = IncrementalPdfFileWriter(out)
    w.add_object(generic.pdf_string('This is an object'))
    w.write_in_place()

    r = PdfFileReader(out)
    assert '/XRefStm' not in r.trailer
    assert '/XRefStm' not in r.trailer_view
    assert r.trailer['/Info']['/Title'] == 'Updated'
    container_info = r.xrefs.get_xref_container_info(1)
    assert container_info.xref_section_type == XRefSectionType.HYBRID_MAIN
    container_info = r.xrefs.get_xref_container_info(2)
    assert container_info.xref_section_type == XRefSectionType.STANDARD
    container_info = r.xrefs.get_xref_container_info(3)
    assert container_info.xref_section_type == XRefSectionType.STANDARD
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
def test_xref_null_update():
    buf = BytesIO(MINIMAL)
    w = IncrementalPdfFileWriter(buf)
    w.write_in_place()
    r = PdfFileReader(buf)
    assert r.xrefs.total_revisions == 2
    assert r.xrefs.explicit_refs_in_revision(1) == set()
Ejemplo n.º 15
0
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)
Ejemplo n.º 16
0
def test_append_sig_field_acro_update():
    # test different configurations of the AcroForm
    w = PdfFileWriter()
    w.root['/AcroForm'] = generic.DictionaryObject(
        {pdf_name('/Fields'): generic.ArrayObject()})
    w.insert_page(simple_page(w, 'Hello world'))
    out = BytesIO()
    w.write(out)
    out.seek(0)

    sp = fields.SigFieldSpec('InvisibleSig')
    w = IncrementalPdfFileWriter(out)
    fields.append_signature_field(w, sp)
    assert len(w.root['/AcroForm']['/Fields']) == 1

    w = PdfFileWriter()
    # Technically, this is not standards-compliant, but our routine
    # shouldn't care
    w.root['/AcroForm'] = generic.DictionaryObject()
    w.insert_page(simple_page(w, 'Hello world'))
    out = BytesIO()
    w.write(out)
    out.seek(0)

    sp = fields.SigFieldSpec('InvisibleSig')
    w = IncrementalPdfFileWriter(out)
    with pytest.raises(ValueError):
        fields.append_signature_field(w, sp)
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
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)
Ejemplo n.º 19
0
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
        )
Ejemplo n.º 20
0
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
        )
Ejemplo n.º 21
0
def test_deep_modify():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    obj3 = generic.Reference(3, 0, w)
    deep_obj = w.get_object(obj3)['/Resources']['/Font']['/F1']['/Subtype']
    assert deep_obj.container_ref.idnum == obj3.idnum

    w.update_container(deep_obj)
    assert (0, 3) in w.objects
Ejemplo n.º 22
0
def test_xref_stream_null_update():
    buf = BytesIO(MINIMAL_XREF)
    w = IncrementalPdfFileWriter(buf)
    w.write_in_place()
    r = PdfFileReader(buf)
    assert r.xrefs.total_revisions == 2
    # The xref stream itself got added
    assert len(r.xrefs.explicit_refs_in_revision(1)) == 1
Ejemplo n.º 23
0
def _stamp_file(input_name: str, output_name: str, style: TextStampStyle,
                stamp_class, dest_page: int, x: int, y: int, **stamp_kwargs):

    with open(input_name, 'rb') as fin:
        pdf_out = IncrementalPdfFileWriter(fin)
        stamp = stamp_class(writer=pdf_out, style=style, **stamp_kwargs)
        stamp.apply(dest_page, x, y)

        with open(output_name, 'wb') as out:
            pdf_out.write(out)
Ejemplo n.º 24
0
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])
Ejemplo n.º 25
0
    def add_dss(cls, output_stream, sig_contents, *, certs=None,
                ocsps=None, crls=None, paths=None, validation_context=None,
                force_write: bool = False, embed_roots: bool = True):
        """
        Wrapper around :meth:`supply_dss_in_writer`.

        The result is applied to the output stream as an incremental update.

        :param output_stream:
            Output stream to write to.
        :param sig_contents:
            Contents of the new signature (used to compute the VRI hash), as
            as a hexadecimal string, including any padding.
            If ``None``, the information will not be added to any VRI
            dictionary.
        :param certs:
            Certificates to include in the VRI entry.
        :param ocsps:
            OCSP responses to include in the VRI entry.
        :param crls:
            CRLs to include in the VRI entry.
        :param paths:
            Validation paths that have been established, and need to be added
            to the DSS.
        :param force_write:
            Force a write even if the DSS doesn't have any new content.
        :param validation_context:
            Validation context from which to draw OCSP responses and CRLs.
        :param embed_roots:
            .. versionadded:: 0.9.0

            Option that controls whether the root certificate of each validation
            path should be embedded into the DSS. The default is ``True``.

            .. note::
                Trust roots are configured by the validator, so embedding them
                typically does nothing in a typical validation process.
                Therefore they can be safely omitted in most cases.
                Nonetheless, embedding the roots can be useful for documentation
                purposes.

            .. warning::
                This only applies to paths, not the ``certs`` parameter.

        """
        pdf_out = IncrementalPdfFileWriter(output_stream)
        dss = cls.supply_dss_in_writer(
            pdf_out, sig_contents, certs=certs, ocsps=ocsps,
            crls=crls, paths=paths, validation_context=validation_context,
            embed_roots=embed_roots
        )
        if force_write or dss.modified:
            pdf_out.write_in_place()
Ejemplo n.º 26
0
def add_sig_field(infile, outfile, field):
    with pyhanko_exception_manager():
        writer = IncrementalPdfFileWriter(infile)

        for s in field:
            name, spec = parse_field_location_spec(s)
            assert spec is not None
            fields.append_signature_field(writer, spec)

        writer.write(outfile)
        infile.close()
        outfile.close()
def test_sign_crypt_aes256(password):
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD_AES256))
    w.encrypt(password)
    out = signers.sign_pdf(w,
                           signers.PdfSignatureMetadata(),
                           signer=FROM_CA,
                           existing_fields_only=True)

    r = PdfFileReader(out)
    r.decrypt(password)
    s = r.embedded_signatures[0]
    val_trusted(s)
Ejemplo n.º 28
0
def test_trailer_refs():
    # This is a corner case in the reference handler that shouldn't really
    # come up in real life. That said, it's easy to test for using a (somewhat
    # contrived) example, so let's do that.
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    # Note: the container of the catalog is the thing root_ref points to,
    # but root_ref, when viewed as a PDF object by itself (i.e. the indirect
    # object embedded in the trailer) should have a TrailerReference as its
    # container.
    root_ref = w.trailer.raw_get('/Root')
    assert isinstance(root_ref.container_ref, generic.TrailerReference)
    w.update_container(root_ref)
def test_sign_crypt_pubkey_rc4():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL_PUBKEY_ONE_FIELD_RC4))
    w.encrypt_pubkey(PUBKEY_SELFSIGNED_DECRYPTER)
    out = signers.sign_pdf(w,
                           signers.PdfSignatureMetadata(),
                           signer=FROM_CA,
                           existing_fields_only=True)

    r = PdfFileReader(out)
    r.decrypt_pubkey(PUBKEY_SELFSIGNED_DECRYPTER)
    s = r.embedded_signatures[0]
    val_trusted(s)
Ejemplo n.º 30
0
def test_sign_with_empty_kids():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    fields.append_signature_field(
        w, fields.SigFieldSpec(
            sig_field_name='Sig1', combine_annotation=False,
            box=(20, 20, 80, 40)
        )
    )
    w.root['/AcroForm']['/Fields'][0]['/Kids'] = generic.ArrayObject()
    meta = signers.PdfSignatureMetadata(field_name='Sig1')

    with pytest.raises(SigningError, match="Failed to access.*annot.*"):
        signers.sign_pdf(w, meta, signer=FROM_CA)