hexapdf 0.28.0 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -10
  3. data/examples/024-digital-signatures.rb +23 -0
  4. data/lib/hexapdf/configuration.rb +12 -12
  5. data/lib/hexapdf/dictionary_fields.rb +13 -4
  6. data/lib/hexapdf/digital_signature/cms_handler.rb +137 -0
  7. data/lib/hexapdf/digital_signature/handler.rb +138 -0
  8. data/lib/hexapdf/digital_signature/pkcs1_handler.rb +96 -0
  9. data/lib/hexapdf/{type → digital_signature}/signature.rb +3 -8
  10. data/lib/hexapdf/digital_signature/signatures.rb +210 -0
  11. data/lib/hexapdf/digital_signature/signing/default_handler.rb +317 -0
  12. data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +308 -0
  13. data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +148 -0
  14. data/lib/hexapdf/digital_signature/signing.rb +101 -0
  15. data/lib/hexapdf/{type/signature → digital_signature}/verification_result.rb +37 -41
  16. data/lib/hexapdf/digital_signature.rb +56 -0
  17. data/lib/hexapdf/document/pages.rb +35 -18
  18. data/lib/hexapdf/document.rb +21 -14
  19. data/lib/hexapdf/encryption/standard_security_handler.rb +4 -3
  20. data/lib/hexapdf/type/font_simple.rb +14 -2
  21. data/lib/hexapdf/type.rb +0 -1
  22. data/lib/hexapdf/version.rb +1 -1
  23. data/test/hexapdf/{type/signature → digital_signature}/common.rb +31 -3
  24. data/test/hexapdf/digital_signature/signing/test_default_handler.rb +162 -0
  25. data/test/hexapdf/digital_signature/signing/test_signed_data_creator.rb +225 -0
  26. data/test/hexapdf/digital_signature/signing/test_timestamp_handler.rb +88 -0
  27. data/test/hexapdf/{type/signature/test_adbe_pkcs7_detached.rb → digital_signature/test_cms_handler.rb} +7 -7
  28. data/test/hexapdf/{type/signature → digital_signature}/test_handler.rb +4 -4
  29. data/test/hexapdf/{type/signature/test_adbe_x509_rsa_sha1.rb → digital_signature/test_pkcs1_handler.rb} +3 -3
  30. data/test/hexapdf/{type → digital_signature}/test_signature.rb +7 -7
  31. data/test/hexapdf/digital_signature/test_signatures.rb +137 -0
  32. data/test/hexapdf/digital_signature/test_signing.rb +53 -0
  33. data/test/hexapdf/{type/signature → digital_signature}/test_verification_result.rb +7 -7
  34. data/test/hexapdf/document/test_pages.rb +25 -0
  35. data/test/hexapdf/encryption/test_standard_security_handler.rb +2 -2
  36. data/test/hexapdf/test_dictionary_fields.rb +9 -3
  37. data/test/hexapdf/test_document.rb +1 -1
  38. data/test/hexapdf/test_writer.rb +6 -6
  39. data/test/hexapdf/type/test_font_simple.rb +18 -6
  40. metadata +25 -15
  41. data/lib/hexapdf/document/signatures.rb +0 -546
  42. data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +0 -135
  43. data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +0 -95
  44. data/lib/hexapdf/type/signature/handler.rb +0 -140
  45. data/test/hexapdf/document/test_signatures.rb +0 -352
@@ -1,26 +1,26 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  require 'test_helper'
4
- require 'hexapdf/type/signature'
4
+ require 'hexapdf/digital_signature'
5
5
 
6
- describe HexaPDF::Type::Signature::VerificationResult do
6
+ describe HexaPDF::DigitalSignature::VerificationResult do
7
7
  describe "Message" do
8
8
  it "accepts a type and a content argument on creation" do
9
- m = HexaPDF::Type::Signature::VerificationResult::Message.new(:type, 'content')
9
+ m = HexaPDF::DigitalSignature::VerificationResult::Message.new(:type, 'content')
10
10
  assert_equal(:type, m.type)
11
11
  assert_equal('content', m.content)
12
12
  end
13
13
 
14
14
  it "allows sorting by type" do
15
- info = HexaPDF::Type::Signature::VerificationResult::Message.new(:info, 'c')
16
- warning = HexaPDF::Type::Signature::VerificationResult::Message.new(:warning, 'c')
17
- error = HexaPDF::Type::Signature::VerificationResult::Message.new(:error, 'c')
15
+ info = HexaPDF::DigitalSignature::VerificationResult::Message.new(:info, 'c')
16
+ warning = HexaPDF::DigitalSignature::VerificationResult::Message.new(:warning, 'c')
17
+ error = HexaPDF::DigitalSignature::VerificationResult::Message.new(:error, 'c')
18
18
  assert_equal([error, warning, info], [info, error, warning].sort)
19
19
  end
20
20
  end
21
21
 
22
22
  before do
23
- @result = HexaPDF::Type::Signature::VerificationResult.new
23
+ @result = HexaPDF::DigitalSignature::VerificationResult.new
24
24
  end
25
25
 
26
26
  it "can add new messages" do
@@ -14,6 +14,31 @@ describe HexaPDF::Document::Pages do
14
14
  end
15
15
  end
16
16
 
17
+ describe "create" do
18
+ it "uses the defaults from the configuration for missing arguments" do
19
+ page = @doc.pages.create
20
+ assert_equal([0, 0, 595, 842], page.box(:media).value)
21
+ end
22
+
23
+ it "allows specifying a reference to a predefined page size" do
24
+ page = @doc.pages.create(media_box: :A3)
25
+ assert_equal([0, 0, 842, 1191], page.box(:media).value)
26
+ end
27
+
28
+ it "allows specifying the orientation for a predefined page size" do
29
+ page = @doc.pages.create(media_box: :A4, orientation: :landscape)
30
+ assert_equal([0, 0, 842, 595], page.box(:media).value)
31
+
32
+ page = @doc.pages.create(orientation: :landscape)
33
+ assert_equal([0, 0, 842, 595], page.box(:media).value)
34
+ end
35
+
36
+ it "allows using a media box array" do
37
+ page = @doc.pages.create(media_box: [0, 0, 12, 24], orientation: :landscape)
38
+ assert_equal([0, 0, 12, 24], page.box(:media).value)
39
+ end
40
+ end
41
+
17
42
  describe "add" do
18
43
  it "adds a new empty page when no page is given" do
19
44
  page = @doc.pages.add
@@ -213,14 +213,14 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
213
213
  exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
214
214
  @handler.set_up_decryption({Filter: :NonStandard, V: 2})
215
215
  end
216
- assert_match(/Invalid \/Filter/i, exp.message)
216
+ assert_match(/Invalid \/Filter value NonStandard/i, exp.message)
217
217
  end
218
218
 
219
219
  it "fails if the /R value is incorrect" do
220
220
  exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
221
221
  @handler.set_up_decryption({Filter: :Standard, V: 2, R: 5})
222
222
  end
223
- assert_match(/Invalid \/R/i, exp.message)
223
+ assert_match(/Invalid \/R value 5/i, exp.message)
224
224
  end
225
225
 
226
226
  it "fails if the supplied password is invalid" do
@@ -175,7 +175,6 @@ describe HexaPDF::DictionaryFields do
175
175
 
176
176
  it "allows conversion to a Time object from a binary string" do
177
177
  refute(@field.convert('test'.b, self))
178
- refute(@field.convert('D:01211016165909+00\'64'.b, self))
179
178
 
180
179
  [
181
180
  ["D:1998", [1998, 01, 01, 00, 00, 00, "-00:00"]],
@@ -189,8 +188,15 @@ describe HexaPDF::DictionaryFields do
189
188
  ["D:19981223-08'00'", [1998, 12, 23, 00, 00, 00, "-08:00"]],
190
189
  ["D:199812-08'00'", [1998, 12, 01, 00, 00, 00, "-08:00"]],
191
190
  ["D:1998-08'00'", [1998, 01, 01, 00, 00, 00, "-08:00"]],
192
- ["D:19981223195210-08", [1998, 12, 23, 19, 52, 10, "-08:00"]], # non-standard, missing '
193
- ["D:19981223195210-08'00", [1998, 12, 23, 19, 52, 10, "-08:00"]], # non-standard, missing '
191
+ ["D:19981223195210-08", [1998, 12, 23, 19, 52, 10, "-08:00"]], # missing '
192
+ ["D:19981223195210-08'00", [1998, 12, 23, 19, 52, 10, "-08:00"]], # missing '
193
+ ["D:19981223195210-54'00", [1998, 12, 23, 19, 52, 10, "-23:59:59"]], # TZ hour too large
194
+ ["D:19981223195210+10'65", [1998, 12, 23, 19, 52, 10, "+11:05"]], # TZ min too large
195
+ ["D:19982423195210-08'00'", [1998, 12, 23, 19, 52, 10, "-08:00"]], # months too large
196
+ ["D:19981273195210-08'00'", [1998, 12, 31, 19, 52, 10, "-08:00"]], # day too large
197
+ ["D:19981223275210-08'00'", [1998, 12, 23, 23, 52, 10, "-08:00"]], # hour too large
198
+ ["D:19981223197710-08'00'", [1998, 12, 23, 19, 59, 10, "-08:00"]], # minute too large
199
+ ["D:19981223195280-08'00'", [1998, 12, 23, 19, 52, 59, "-08:00"]], # seconds too large
194
200
  ].each do |str, data|
195
201
  obj = @field.convert(str, self)
196
202
  assert_equal(Time.new(*data), obj, "date str used: #{str}")
@@ -504,7 +504,7 @@ describe HexaPDF::Document do
504
504
 
505
505
  it "allows to conveniently sign a document" do
506
506
  mock = Minitest::Mock.new
507
- mock.expect(:handler, :handler, name: :handler, opt: :key)
507
+ mock.expect(:signing_handler, :handler, name: :handler, opt: :key)
508
508
  mock.expect(:add, :added, [:io, :handler], signature: :sig, write_options: :write_options)
509
509
  @doc.instance_variable_set(:@signatures, mock)
510
510
  result = @doc.sign(:io, handler: :handler, write_options: :write_options, signature: :sig, opt: :key)
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.28.0)>>
43
+ <</Producer(HexaPDF version 0.30.0)>>
44
44
  endobj
45
45
  xref
46
46
  3 1
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
72
72
  141
73
73
  %%EOF
74
74
  6 0 obj
75
- <</Producer(HexaPDF version 0.28.0)>>
75
+ <</Producer(HexaPDF version 0.30.0)>>
76
76
  endobj
77
77
  2 0 obj
78
78
  <</Length 10>>stream
@@ -164,9 +164,9 @@ describe HexaPDF::Writer do
164
164
 
165
165
  document = HexaPDF::Document.new(io: io)
166
166
  assert_equal(3, document.revisions.count)
167
- assert_equal(1, document.revisions.all[0].object(2)[:Kids].length)
168
- assert_equal(2, document.revisions.all[1].object(2)[:Kids].length)
169
- assert_equal(3, document.revisions.all[2].object(2)[:Kids].length)
167
+ assert_equal(1, document.revisions.all[0].object(3)[:Kids].length)
168
+ assert_equal(2, document.revisions.all[1].object(3)[:Kids].length)
169
+ assert_equal(3, document.revisions.all[2].object(3)[:Kids].length)
170
170
  end
171
171
 
172
172
  it "creates an xref stream if no xref stream is in a revision but object streams are" do
@@ -214,7 +214,7 @@ describe HexaPDF::Writer do
214
214
  <</Type/Page/MediaBox[0 0 595 842]/Parent 2 0 R/Resources<<>>>>
215
215
  endobj
216
216
  5 0 obj
217
- <</Producer(HexaPDF version 0.28.0)>>
217
+ <</Producer(HexaPDF version 0.30.0)>>
218
218
  endobj
219
219
  4 0 obj
220
220
  <</Root 1 0 R/Info 5 0 R/Size 6/Type/XRef/W[1 1 2]/Index[0 6]/Filter/FlateDecode/DecodeParms<</Columns 4/Predictor 12>>/Length 33>>stream
@@ -15,7 +15,7 @@ describe HexaPDF::Type::FontSimple do
15
15
  EOF
16
16
  font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
17
17
  FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
18
- Descent: -100, CapHeight: 800, StemV: 20})
18
+ MissingWidth: 500, Descent: -100, CapHeight: 800, StemV: 20})
19
19
  @font = @doc.add({Type: :Font, Encoding: :WinAnsiEncoding,
20
20
  BaseFont: :Embedded, FontDescriptor: font_descriptor, ToUnicode: cmap,
21
21
  FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]},
@@ -130,9 +130,7 @@ describe HexaPDF::Type::FontSimple do
130
130
  end
131
131
 
132
132
  it "returns the /MissingWidth of a /FontDescriptor if available and the width was not found" do
133
- assert_equal(0, @font.width(0))
134
- @font[:FontDescriptor][:MissingWidth] = 99
135
- assert_equal(99, @font.width(0))
133
+ assert_equal(500, @font.width(0))
136
134
  end
137
135
 
138
136
  it "returns 0 for a missing code point when FontDescriptor is not available" do
@@ -169,8 +167,22 @@ describe HexaPDF::Type::FontSimple do
169
167
  end
170
168
 
171
169
  it "validates the lengths of the /Widths field" do
172
- @font[:Widths] = [65]
173
- refute(@font.validate)
170
+ @font[:Widths] = [65, 65]
171
+ assert(@font.validate)
172
+ assert_equal([65, 65, 65], @font[:Widths])
173
+
174
+ @font[:Widths] = [65, 70]
175
+ assert(@font.validate)
176
+ assert_equal([65, 70, 500], @font[:Widths])
177
+
178
+ @font[:Widths] = [65, 70]
179
+ @font.delete(:FontDescriptor)
180
+ assert(@font.validate)
181
+ assert_equal([65, 70, 0], @font[:Widths])
182
+
183
+ @font[:Widths] = [65, 65, 70, 90, 100]
184
+ assert(@font.validate)
185
+ assert_equal([65, 65, 70], @font[:Widths])
174
186
  end
175
187
  end
176
188
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.28.0
4
+ version: 0.30.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-30 00:00:00.000000000 Z
11
+ date: 2023-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse
@@ -291,6 +291,7 @@ files:
291
291
  - examples/021-list_box.rb
292
292
  - examples/022-outline.rb
293
293
  - examples/023-images.rb
294
+ - examples/024-digital-signatures.rb
294
295
  - examples/emoji-smile.png
295
296
  - examples/emoji-wink.png
296
297
  - examples/machupicchu.jpg
@@ -328,6 +329,17 @@ files:
328
329
  - lib/hexapdf/data_dir.rb
329
330
  - lib/hexapdf/dictionary.rb
330
331
  - lib/hexapdf/dictionary_fields.rb
332
+ - lib/hexapdf/digital_signature.rb
333
+ - lib/hexapdf/digital_signature/cms_handler.rb
334
+ - lib/hexapdf/digital_signature/handler.rb
335
+ - lib/hexapdf/digital_signature/pkcs1_handler.rb
336
+ - lib/hexapdf/digital_signature/signature.rb
337
+ - lib/hexapdf/digital_signature/signatures.rb
338
+ - lib/hexapdf/digital_signature/signing.rb
339
+ - lib/hexapdf/digital_signature/signing/default_handler.rb
340
+ - lib/hexapdf/digital_signature/signing/signed_data_creator.rb
341
+ - lib/hexapdf/digital_signature/signing/timestamp_handler.rb
342
+ - lib/hexapdf/digital_signature/verification_result.rb
331
343
  - lib/hexapdf/document.rb
332
344
  - lib/hexapdf/document/destinations.rb
333
345
  - lib/hexapdf/document/files.rb
@@ -335,7 +347,6 @@ files:
335
347
  - lib/hexapdf/document/images.rb
336
348
  - lib/hexapdf/document/layout.rb
337
349
  - lib/hexapdf/document/pages.rb
338
- - lib/hexapdf/document/signatures.rb
339
350
  - lib/hexapdf/encryption.rb
340
351
  - lib/hexapdf/encryption/aes.rb
341
352
  - lib/hexapdf/encryption/arc4.rb
@@ -486,11 +497,6 @@ files:
486
497
  - lib/hexapdf/type/page_label.rb
487
498
  - lib/hexapdf/type/page_tree_node.rb
488
499
  - lib/hexapdf/type/resources.rb
489
- - lib/hexapdf/type/signature.rb
490
- - lib/hexapdf/type/signature/adbe_pkcs7_detached.rb
491
- - lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb
492
- - lib/hexapdf/type/signature/handler.rb
493
- - lib/hexapdf/type/signature/verification_result.rb
494
500
  - lib/hexapdf/type/trailer.rb
495
501
  - lib/hexapdf/type/viewer_preferences.rb
496
502
  - lib/hexapdf/type/xref_stream.rb
@@ -587,13 +593,23 @@ files:
587
593
  - test/hexapdf/content/test_parser.rb
588
594
  - test/hexapdf/content/test_processor.rb
589
595
  - test/hexapdf/content/test_transformation_matrix.rb
596
+ - test/hexapdf/digital_signature/common.rb
597
+ - test/hexapdf/digital_signature/signing/test_default_handler.rb
598
+ - test/hexapdf/digital_signature/signing/test_signed_data_creator.rb
599
+ - test/hexapdf/digital_signature/signing/test_timestamp_handler.rb
600
+ - test/hexapdf/digital_signature/test_cms_handler.rb
601
+ - test/hexapdf/digital_signature/test_handler.rb
602
+ - test/hexapdf/digital_signature/test_pkcs1_handler.rb
603
+ - test/hexapdf/digital_signature/test_signature.rb
604
+ - test/hexapdf/digital_signature/test_signatures.rb
605
+ - test/hexapdf/digital_signature/test_signing.rb
606
+ - test/hexapdf/digital_signature/test_verification_result.rb
590
607
  - test/hexapdf/document/test_destinations.rb
591
608
  - test/hexapdf/document/test_files.rb
592
609
  - test/hexapdf/document/test_fonts.rb
593
610
  - test/hexapdf/document/test_images.rb
594
611
  - test/hexapdf/document/test_layout.rb
595
612
  - test/hexapdf/document/test_pages.rb
596
- - test/hexapdf/document/test_signatures.rb
597
613
  - test/hexapdf/encryption/common.rb
598
614
  - test/hexapdf/encryption/test_aes.rb
599
615
  - test/hexapdf/encryption/test_arc4.rb
@@ -705,11 +721,6 @@ files:
705
721
  - test/hexapdf/type/annotations/test_markup_annotation.rb
706
722
  - test/hexapdf/type/annotations/test_text.rb
707
723
  - test/hexapdf/type/annotations/test_widget.rb
708
- - test/hexapdf/type/signature/common.rb
709
- - test/hexapdf/type/signature/test_adbe_pkcs7_detached.rb
710
- - test/hexapdf/type/signature/test_adbe_x509_rsa_sha1.rb
711
- - test/hexapdf/type/signature/test_handler.rb
712
- - test/hexapdf/type/signature/test_verification_result.rb
713
724
  - test/hexapdf/type/test_annotation.rb
714
725
  - test/hexapdf/type/test_catalog.rb
715
726
  - test/hexapdf/type/test_cid_font.rb
@@ -732,7 +743,6 @@ files:
732
743
  - test/hexapdf/type/test_page_label.rb
733
744
  - test/hexapdf/type/test_page_tree_node.rb
734
745
  - test/hexapdf/type/test_resources.rb
735
- - test/hexapdf/type/test_signature.rb
736
746
  - test/hexapdf/type/test_trailer.rb
737
747
  - test/hexapdf/type/test_xref_stream.rb
738
748
  - test/hexapdf/utils/test_bit_field.rb