Beispiel #1
0
def test_write_embedded_string():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    with open(NOTO_SERIF_JP, 'rb') as ffile:
        ga = GlyphAccumulator(w, ffile, font_size=10)
    # shape the string, just to register the glyphs as used
    ga.shape('テスト')
    # ... but we're not going to use the result

    # hardcoded CIDs
    cid_hx = '0637062a0639'
    stream = generic.StreamObject(
        stream_data=f'BT /FEmb 18 Tf 0 100 Td <{cid_hx}> Tj ET'.encode('ascii')
    )
    stream_ref = w.add_object(stream)
    w.add_stream_to_page(
        0, stream_ref, resources=generic.DictionaryObject({
            pdf_name('/Font'): generic.DictionaryObject({
                pdf_name('/FEmb'): ga.as_resource()
            })
        })
    )
    out = BytesIO()
    w.write(out)
    out.seek(0)
    r = PdfFileReader(out)
    page_obj = r.root['/Pages']['/Kids'][0].get_object()
    conts = page_obj['/Contents']
    assert len(conts) == 2
    assert stream_ref.idnum in (c.idnum for c in conts)
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
Beispiel #3
0
def test_write_embedded_string_objstream():
    ffile = ttLib.TTFont(NOTO_SERIF_JP)
    ga = GlyphAccumulator(ffile)
    cid_hx, _ = ga.feed_string('テスト')
    assert cid_hx == '0637062a0639'
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL_XREF))
    obj_stream = w.prepare_object_stream()
    font_ref = ga.embed_subset(w, obj_stream=obj_stream)
    stream = generic.StreamObject(
        stream_data=f'BT /FEmb 18 Tf 0 100 Td <{cid_hx}> Tj ET'.encode(
            'ascii'))
    stream_ref = w.add_object(stream)
    w.add_stream_to_page(0,
                         stream_ref,
                         resources=generic.DictionaryObject({
                             pdf_name('/Font'):
                             generic.DictionaryObject(
                                 {pdf_name('/FEmb'): font_ref})
                         }))
    out = BytesIO()
    w.write(out)
    out.seek(0)
    r = PdfFileReader(out)
    page_obj = r.root['/Pages']['/Kids'][0].get_object()
    conts = page_obj['/Contents']
    assert len(conts) == 2
    assert stream_ref.idnum in (c.idnum for c in conts)
    assert font_ref.idnum in r.xrefs.in_obj_stream
    out.seek(0)

    # attempt to grab the font from the object stream
    font_ref.pdf = r
    font = font_ref.get_object()
    assert font['/Type'] == pdf_name('/Font')
Beispiel #4
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)
Beispiel #5
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)
Beispiel #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)
Beispiel #7
0
def test_pages_kids_tamper(bogus_kids, indirectify):
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))

    # sign, then fill
    meta = signers.PdfSignatureMetadata(field_name='Sig1')
    out = signers.sign_pdf(w, meta, signer=FROM_CA)
    w = IncrementalPdfFileWriter(out)

    # add an empty sig field to trigger the annotation parsing logic
    # in the difference analysis tool
    fields.append_signature_field(
        w, sig_field_spec=fields.SigFieldSpec(sig_field_name="Extra"))
    page_root = w.root['/Pages']
    if indirectify:
        bogus_kids = generic.ArrayObject(map(w.add_object, bogus_kids))
    if bogus_kids is not None:
        page_root['/Kids'] = bogus_kids
    else:
        del page_root['/Kids']
    w.update_container(page_root)
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted_but_modified(s)
Beispiel #8
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
Beispiel #9
0
def test_add_stream_to_direct_arr():
    w = writer.PdfFileWriter()
    w.insert_page(simple_page(w, 'Test Test', extra_stream=True))
    out = BytesIO()
    w.write(out)
    out.seek(0)
    w = IncrementalPdfFileWriter(out)

    new_stream = 'BT /F1 18 Tf 0 50 Td (Test2 Test2) Tj ET'.encode('ascii')
    stream = generic.StreamObject(stream_data=new_stream)
    stream_ref = w.add_object(stream)
    w.add_stream_to_page(0, stream_ref)

    out = BytesIO()
    w.write(out)
    out.seek(0)
    r = PdfFileReader(out)
    # check if the content stream was added
    page_obj_ref = r.root['/Pages']['/Kids'].raw_get(0)
    assert isinstance(page_obj_ref, generic.IndirectObject)
    page_obj = page_obj_ref.get_object()
    conts = page_obj['/Contents']
    assert len(conts) == 3
    assert stream_ref.idnum in (c.idnum for c in conts)
    # check if resource dictionary is still OK
    assert '/F1' in page_obj['/Resources']['/Font']
Beispiel #10
0
def test_sv_subfilter_unsupported_partial():
    sv_spec = fields.SigSeedValueSpec(
        flags=fields.SigSeedValFlags.SUBFILTER,
        subfilters=[fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED, PADES])
    w = IncrementalPdfFileWriter(prepare_sv_field(sv_spec))
    field_name, _, sig_field = next(fields.enumerate_sig_fields(w))
    sig_field = sig_field.get_object()
    sv_ref = sig_field.raw_get('/SV')
    w.mark_update(sv_ref)
    sv_ref.get_object()['/SubFilter'][0] = pdf_name('/this.doesnt.exist')
    out = BytesIO()
    w.write(out)
    out.seek(0)
    frozen = out.getvalue()

    signers.sign_pdf(IncrementalPdfFileWriter(BytesIO(frozen)),
                     signers.PdfSignatureMetadata(field_name='Sig'),
                     signer=FROM_CA,
                     timestamper=DUMMY_TS)
    with pytest.raises(SigningError):
        signers.sign_pdf(
            IncrementalPdfFileWriter(BytesIO(frozen)),
            signers.PdfSignatureMetadata(
                field_name='Sig',
                subfilter=fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED),
            signer=FROM_CA,
            timestamper=DUMMY_TS)
Beispiel #11
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)
Beispiel #12
0
def test_trailer_update():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL_ONE_FIELD))
    dt = generic.pdf_date(datetime.datetime(2020, 10, 10, tzinfo=pytz.utc))

    info = generic.DictionaryObject({pdf_name('/CreationDate'): dt})
    w.trailer['/Info'] = w.add_object(info)
    out = BytesIO()
    w.write(out)
    r = PdfFileReader(out)
    assert r.trailer['/Info']['/CreationDate'] == dt
Beispiel #13
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()
Beispiel #14
0
def test_historical_nonexistent_xref_access_nonstrict():
    out = BytesIO()
    with open(NONEXISTENT_XREF_PATH, 'rb') as inf:
        w = IncrementalPdfFileWriter(inf)
        pg_dict = w.root['/Pages']['/Kids'][0]
        del pg_dict['/Bleh']
        w.update_container(pg_dict)
        w.write(out)
    r = PdfFileReader(out, strict=False)
    hist_root = r.get_historical_root(0)
    bad_ref = hist_root['/Pages']['/Kids'][0].raw_get('/Bleh')
    assert isinstance(bad_ref.get_object(), generic.NullObject)
Beispiel #15
0
def test_form_field_in_group_postsign_fill(variant):
    w = IncrementalPdfFileWriter(BytesIO(GROUP_VARIANTS[variant]))

    # sign, then fill
    meta = signers.PdfSignatureMetadata(field_name='Sig1')
    out = signers.sign_pdf(w, meta, signer=FROM_CA)
    w = IncrementalPdfFileWriter(out)
    set_text_field_in_group(w, 0, "Some text")
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted(s, extd=True)
Beispiel #16
0
def test_form_field_postsign_fill():
    w = IncrementalPdfFileWriter(BytesIO(SIMPLE_FORM))

    # sign, then fill
    meta = signers.PdfSignatureMetadata(field_name='Sig1')
    out = signers.sign_pdf(w, meta, signer=FROM_CA)
    w = IncrementalPdfFileWriter(out)
    set_text_field(w, "Some text")
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted(s, extd=True)
Beispiel #17
0
def test_append_visible_sig_field():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))

    sp = fields.SigFieldSpec('VisibleSig', box=(10, 0, 50, 8))
    fields.append_signature_field(w, sp)
    assert len(w.root['/AcroForm']['/Fields']) == 1
    out = BytesIO()
    w.write(out)
    out.seek(0)
    w = IncrementalPdfFileWriter(out)
    with pytest.raises(PdfWriteError):
        fields.append_signature_field(w, sp)

    w = IncrementalPdfFileWriter(BytesIO(MINIMAL_TWO_FIELDS))
    fields.append_signature_field(w, sp)
    assert len(w.root['/AcroForm']['/Fields']) == 3
Beispiel #18
0
def test_historical_nonexistent_xref_access():
    out = BytesIO()
    with open(NONEXISTENT_XREF_PATH, 'rb') as inf:
        w = IncrementalPdfFileWriter(inf)
        pg_dict = w.root['/Pages']['/Kids'][0]
        del pg_dict['/Bleh']
        w.update_container(pg_dict)
        w.write(out)
    r = PdfFileReader(out)
    current_state = r.root['/Pages']['/Kids'][0]
    assert '/Bleh' not in current_state
    hist_root = r.get_historical_root(0)
    bad_ref = hist_root['/Pages']['/Kids'][0].raw_get('/Bleh')
    with pytest.raises(misc.PdfReadError,
                       match='not found.*error in strict mode'):
        bad_ref.get_object()
Beispiel #19
0
def test_form_field_ft_tamper():
    w = IncrementalPdfFileWriter(BytesIO(SIMPLE_FORM))

    # sign, then fill
    meta = signers.PdfSignatureMetadata(field_name='Sig1')
    out = signers.sign_pdf(w, meta, signer=FROM_CA)
    w = IncrementalPdfFileWriter(out)
    tf = w.root['/AcroForm']['/Fields'][1].get_object()
    tf['/FT'] = pdf_name('/Sig')
    w.update_container(tf)
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted_but_modified(s)
Beispiel #20
0
def prepare_sv_field(sv_spec, add_field_lock=False):
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))

    if add_field_lock:
        sp = fields.SigFieldSpec(
            'Sig',
            seed_value_dict=sv_spec,
            field_mdp_spec=fields.FieldMDPSpec(fields.FieldMDPAction.INCLUDE,
                                               fields=['blah']),
            doc_mdp_update_value=fields.MDPPerm.NO_CHANGES)
    else:
        sp = fields.SigFieldSpec('Sig', seed_value_dict=sv_spec)
    fields.append_signature_field(w, sp)
    out = BytesIO()
    w.write(out)
    out.seek(0)
    return out
Beispiel #21
0
def test_add_stream():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))

    def stream_data(y):
        return f'BT /F1 18 Tf 0 {y} Td (Test Test) Tj ET'.encode('ascii')

    stream = generic.StreamObject(stream_data=stream_data(50))

    stream_ref = w.add_object(stream)
    w.add_stream_to_page(0, stream_ref)

    out = BytesIO()
    w.write(out)
    out.seek(0)
    r = PdfFileReader(out)
    # check if the content stream was added
    page_obj_ref = r.root['/Pages']['/Kids'].raw_get(0)
    assert isinstance(page_obj_ref, generic.IndirectObject)
    page_obj = page_obj_ref.get_object()
    conts = page_obj['/Contents']
    assert len(conts) == 2
    assert stream_ref.idnum in (c.idnum for c in conts)
    # check if resource dictionary is still OK
    assert '/F1' in page_obj['/Resources']['/Font']

    # let's try adding a third
    out.seek(0)
    w = IncrementalPdfFileWriter(out)

    stream = generic.StreamObject(stream_data=stream_data(100))
    new_stream_ref = w.add_object(stream)
    w.add_stream_to_page(0, new_stream_ref)

    out = BytesIO()
    w.write(out)
    out.seek(0)
    r = PdfFileReader(out)
    # check if the content stream was added
    page_obj_ref = r.root['/Pages']['/Kids'].raw_get(0)
    assert isinstance(page_obj_ref, generic.IndirectObject)
    page_obj = page_obj_ref.get_object()
    conts = page_obj['/Contents']
    assert len(conts) == 3
    ids = [c.idnum for c in conts]
    assert stream_ref.idnum in ids and new_stream_ref.idnum in ids
Beispiel #22
0
def test_form_field_kids_tamper(bogus_kids, indirectify):
    w = IncrementalPdfFileWriter(BytesIO(SIMPLE_FORM))

    # sign, then fill
    meta = signers.PdfSignatureMetadata(field_name='Sig1')
    out = signers.sign_pdf(w, meta, signer=FROM_CA)
    w = IncrementalPdfFileWriter(out)
    tf = w.root['/AcroForm']['/Fields'][1].get_object()
    if indirectify:
        bogus_kids = generic.ArrayObject(map(w.add_object, bogus_kids))
    tf['/Kids'] = bogus_kids
    w.update_container(tf)
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted_but_modified(s)
Beispiel #23
0
def test_form_field_structure_modification():
    w = IncrementalPdfFileWriter(BytesIO(SIMPLE_FORM))
    meta = signers.PdfSignatureMetadata(field_name='Sig1')

    out = signers.sign_pdf(w, meta, signer=FROM_CA, timestamper=DUMMY_TS)
    w = IncrementalPdfFileWriter(out)
    field_arr = w.root['/AcroForm']['/Fields']
    # shallow copy the text field
    tf = generic.DictionaryObject(field_arr[1].get_object())
    tf['/T'] = generic.pdf_string('OtherField')
    field_arr.append(w.add_object(tf))
    w.update_container(field_arr)
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted_but_modified(s)
Beispiel #24
0
def test_append_sig_field_with_simple_sv():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))

    sv = fields.SigSeedValueSpec(
        reasons=['a', 'b', 'c'],
        cert=fields.SigCertConstraints(
            subject_dn=FROM_CA.signing_cert.subject,
            issuers=[INTERM_CERT],
            subjects=[FROM_CA.signing_cert],
            key_usage=[
                fields.SigCertKeyUsage.from_sets(
                    {'digital_signature', 'non_repudiation'},
                    {'key_agreement'})
            ]),
        digest_methods=['ssh256'],
        add_rev_info=True,
        subfilters=[fields.SigSeedSubFilter.ADOBE_PKCS7_DETACHED],
        timestamp_server_url='https://tsa.example.com',
    )
    sp = fields.SigFieldSpec('InvisibleSig', seed_value_dict=sv)
    fields.append_signature_field(w, sp)
    out = BytesIO()
    w.write(out)
    out.seek(0)
    r = PdfFileReader(out)
    _, _, sig_field_ref = next(fields.enumerate_sig_fields(r))
    sv_dict = sig_field_ref.get_object()['/SV']
    assert sv_dict['/V'] == generic.NumberObject(2)
    del sv_dict['/V']
    recovered_sv = fields.SigSeedValueSpec.from_pdf_object(sv_dict)
    # x509.Certificate doesn't have an __eq__ implementation apparently,
    # so for the purposes of the test, we replace them by byte dumps
    issuers1 = recovered_sv.cert.issuers
    issuers2 = sv.cert.issuers
    issuers1[0] = issuers1[0].dump()
    issuers2[0] = issuers2[0].dump()

    subjects1 = recovered_sv.cert.subjects
    subjects2 = sv.cert.subjects
    subjects1[0] = subjects1[0].dump()
    subjects2[0] = subjects2[0].dump()
    assert recovered_sv == sv
Beispiel #25
0
def test_embed_twice(incremental):
    r = PdfFileReader(BytesIO(MINIMAL))
    w = writer.copy_into_new_writer(r)

    modified = datetime.now(tz=tzlocal.get_localzone())
    created = modified - timedelta(days=1)
    _embed_test(w,
                fname='vector-test.pdf',
                ufname='テスト.pdf',
                data=VECTOR_IMAGE_PDF,
                created=created,
                modified=modified)

    if incremental:
        out = BytesIO()
        w.write(out)
        w = IncrementalPdfFileWriter(out)

    _embed_test(w,
                fname='some-other-file.pdf',
                ufname='テスト2.pdf',
                data=MINIMAL_AES256,
                created=created,
                modified=modified)

    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    emb_lst = r.root['/Names']['/EmbeddedFiles']['/Names']
    assert len(emb_lst) == 4
    assert emb_lst[0] == 'vector-test.pdf'
    spec_obj = emb_lst[1]
    assert spec_obj['/UF'] == 'テスト.pdf'
    stream = spec_obj['/EF']['/F']
    assert stream.data == VECTOR_IMAGE_PDF

    assert emb_lst[2] == 'some-other-file.pdf'
    spec_obj = emb_lst[3]
    assert spec_obj['/UF'] == 'テスト2.pdf'
    stream = spec_obj['/EF']['/F']
    assert stream.data == MINIMAL_AES256
Beispiel #26
0
def test_form_field_postsign_fill_pades_lt(requests_mock):
    w = IncrementalPdfFileWriter(BytesIO(SIMPLE_FORM))
    vc = live_testing_vc(requests_mock)
    meta = signers.PdfSignatureMetadata(
        field_name='Sig1',
        validation_context=vc,
        subfilter=PADES,
        embed_validation_info=True,
    )

    # sign, then fill
    out = signers.sign_pdf(w, meta, signer=FROM_CA, timestamper=DUMMY_TS)
    w = IncrementalPdfFileWriter(out)
    set_text_field(w, "Some text")
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    s = r.embedded_signatures[0]
    assert s.field_name == 'Sig1'
    val_trusted(s, extd=True)
async def test_embed_signed_attachment():
    dt = datetime.fromisoformat('2020-11-01T05:00:00+00:00')
    signature = await FROM_CA.async_sign_general_data(
        VECTOR_IMAGE_PDF, 'sha256', PdfCMSSignedAttributes(signing_time=dt)
    )

    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    signers.embed_payload_with_cms(
        w, file_spec_string='attachment.pdf',
        payload=embed.EmbeddedFileObject.from_file_data(
            w, data=VECTOR_IMAGE_PDF, mime_type='application/pdf',
            params=embed.EmbeddedFileParams(
                creation_date=dt, modification_date=dt
            )
        ),
        cms_obj=signature,
        file_name='添付ファイル.pdf',
        file_spec_kwargs={'description': "Signed attachment test"}
    )
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    emb_lst = r.root['/Names']['/EmbeddedFiles']['/Names']
    assert len(emb_lst) == 4
    assert emb_lst[0] == 'attachment.pdf'
    spec_obj = emb_lst[1]
    assert spec_obj['/UF'] == '添付ファイル.pdf'
    stream = spec_obj['/EF']['/F']
    assert stream.data == VECTOR_IMAGE_PDF
    assert spec_obj['/RF']['/F'][0] == 'attachment.sig'
    assert spec_obj['/RF']['/UF'][0] == '添付ファイル.sig'
    rel_file_ref = spec_obj['/RF']['/F'].raw_get(1).reference

    assert emb_lst[2] == 'attachment.sig'
    spec_obj = emb_lst[3]
    assert spec_obj['/UF'] == '添付ファイル.sig'
    stream = spec_obj['/EF']['/F']
    assert stream.data == signature.dump()
    assert stream.container_ref == rel_file_ref
Beispiel #28
0
def test_write_embedded_string_objstream():
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL_XREF))
    obj_stream = w.prepare_object_stream()
    with open(NOTO_SERIF_JP, 'rb') as ffile:
        ga = GlyphAccumulator(w, ffile, font_size=10, obj_stream=obj_stream)
    # shape the string, just to register the glyphs as used
    ga.shape('テスト')
    # ... but we're not going to use the result

    # hardcoded CIDs
    cid_hx = '0637062a0639'
    font_ref = ga.as_resource()
    stream = generic.StreamObject(
        stream_data=f'BT /FEmb 18 Tf 0 100 Td <{cid_hx}> Tj ET'.encode(
            'ascii'))
    stream_ref = w.add_object(stream)
    w.add_stream_to_page(0,
                         stream_ref,
                         resources=generic.DictionaryObject({
                             pdf_name('/Font'):
                             generic.DictionaryObject(
                                 {pdf_name('/FEmb'): font_ref})
                         }))
    out = BytesIO()
    w.write(out)
    out.seek(0)
    r = PdfFileReader(out)
    page_obj = r.root['/Pages']['/Kids'][0].get_object()
    conts = page_obj['/Contents']
    assert len(conts) == 2
    assert stream_ref.idnum in (c.idnum for c in conts)
    xref_sections = r.xrefs._xref_sections
    last = xref_sections[len(xref_sections) - 1]
    assert font_ref.idnum in last.xref_data.xrefs_in_objstm
    out.seek(0)

    # attempt to grab the font from the object stream
    font_ref.pdf = r
    font = font_ref.get_object()
    assert font['/Type'] == pdf_name('/Font')
Beispiel #29
0
def test_simple_embed(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)
    _embed_test(w,
                fname='vector-test.pdf',
                ufname='テスト.pdf',
                data=VECTOR_IMAGE_PDF,
                created=created,
                modified=modified)

    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    assert r.input_version == (1, 7)
    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 spec_obj['/Desc'] == 'Embedding test'
    assert spec_obj['/UF'] == 'テスト.pdf'
    stream = spec_obj['/EF']['/F']
    assert stream.data == VECTOR_IMAGE_PDF

    assert stream['/Subtype'] == '/application/pdf'

    assert stream['/Params']['/CheckSum'] \
           == binascii.unhexlify('caaf24354fd2e68c08826d65b309b404')
    assert generic.parse_pdf_date(stream['/Params']['/ModDate']) == modified
    assert generic.parse_pdf_date(
        stream['/Params']['/CreationDate']) == created

    assert '/AF' not in r.root
Beispiel #30
0
def test_tamper_sig_obj(policy, skip_diff):
    w = IncrementalPdfFileWriter(BytesIO(MINIMAL))
    meta = signers.PdfSignatureMetadata(field_name='Sig1')
    out = signers.sign_pdf(w, meta, signer=FROM_CA)

    w = IncrementalPdfFileWriter(out)
    sig_obj = w.prev.embedded_signatures[0].sig_object
    sig_obj['/Bleh'] = generic.BooleanObject(False)
    w.update_container(sig_obj)
    out = BytesIO()
    w.write(out)

    r = PdfFileReader(out)
    emb = r.embedded_signatures[0]
    status = validate_pdf_signature(emb,
                                    diff_policy=policy,
                                    skip_diff=skip_diff)
    if skip_diff:
        assert emb.diff_result is None
        assert status.modification_level is None
    else:
        assert isinstance(emb.diff_result, SuspiciousModification)
        assert status.modification_level == ModificationLevel.OTHER