hexapdf 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -0
  3. data/data/hexapdf/cert/demo_cert.rb +22 -0
  4. data/data/hexapdf/cert/root-ca.crt +119 -0
  5. data/data/hexapdf/cert/signing.crt +125 -0
  6. data/data/hexapdf/cert/signing.key +52 -0
  7. data/data/hexapdf/cert/sub-ca.crt +125 -0
  8. data/lib/hexapdf/cli/info.rb +21 -1
  9. data/lib/hexapdf/configuration.rb +26 -0
  10. data/lib/hexapdf/content/graphics_state.rb +24 -5
  11. data/lib/hexapdf/content/processor.rb +1 -1
  12. data/lib/hexapdf/document/signatures.rb +327 -0
  13. data/lib/hexapdf/document.rb +26 -0
  14. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -2
  15. data/lib/hexapdf/importer.rb +1 -1
  16. data/lib/hexapdf/layout/style.rb +2 -1
  17. data/lib/hexapdf/object.rb +5 -3
  18. data/lib/hexapdf/parser.rb +21 -9
  19. data/lib/hexapdf/rectangle.rb +0 -6
  20. data/lib/hexapdf/revision.rb +13 -6
  21. data/lib/hexapdf/type/acro_form/appearance_generator.rb +2 -4
  22. data/lib/hexapdf/type/acro_form/field.rb +2 -0
  23. data/lib/hexapdf/type/acro_form/form.rb +9 -1
  24. data/lib/hexapdf/type/annotation.rb +36 -3
  25. data/lib/hexapdf/type/font.rb +5 -0
  26. data/lib/hexapdf/type/font_simple.rb +1 -1
  27. data/lib/hexapdf/type/font_type3.rb +20 -0
  28. data/lib/hexapdf/type/object_stream.rb +3 -1
  29. data/lib/hexapdf/type/signature/adbe_pkcs7_detached.rb +125 -0
  30. data/lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb +99 -0
  31. data/lib/hexapdf/type/signature/handler.rb +112 -0
  32. data/lib/hexapdf/type/signature/verification_result.rb +92 -0
  33. data/lib/hexapdf/type/signature.rb +236 -0
  34. data/lib/hexapdf/type.rb +1 -0
  35. data/lib/hexapdf/version.rb +1 -1
  36. data/lib/hexapdf/writer.rb +24 -10
  37. data/test/hexapdf/content/test_graphics_state.rb +9 -1
  38. data/test/hexapdf/content/test_operator.rb +8 -3
  39. data/test/hexapdf/content/test_processor.rb +1 -1
  40. data/test/hexapdf/document/test_signatures.rb +225 -0
  41. data/test/hexapdf/encryption/test_standard_security_handler.rb +8 -6
  42. data/test/hexapdf/layout/test_style.rb +11 -0
  43. data/test/hexapdf/test_document.rb +28 -0
  44. data/test/hexapdf/test_object.rb +7 -2
  45. data/test/hexapdf/test_parser.rb +14 -0
  46. data/test/hexapdf/test_rectangle.rb +0 -7
  47. data/test/hexapdf/test_revision.rb +44 -14
  48. data/test/hexapdf/test_writer.rb +44 -14
  49. data/test/hexapdf/type/acro_form/test_field.rb +11 -1
  50. data/test/hexapdf/type/acro_form/test_form.rb +5 -0
  51. data/test/hexapdf/type/signature/common.rb +71 -0
  52. data/test/hexapdf/type/signature/test_adbe_pkcs7_detached.rb +99 -0
  53. data/test/hexapdf/type/signature/test_adbe_x509_rsa_sha1.rb +66 -0
  54. data/test/hexapdf/type/signature/test_handler.rb +76 -0
  55. data/test/hexapdf/type/signature/test_verification_result.rb +47 -0
  56. data/test/hexapdf/type/test_annotation.rb +40 -2
  57. data/test/hexapdf/type/test_font.rb +4 -0
  58. data/test/hexapdf/type/test_font_simple.rb +5 -5
  59. data/test/hexapdf/type/test_font_type3.rb +16 -1
  60. data/test/hexapdf/type/test_object_stream.rb +9 -0
  61. data/test/hexapdf/type/test_signature.rb +131 -0
  62. metadata +21 -33
  63. data/test/data/cert/create.sh +0 -171
  64. data/test/data/cert/root-ca/certs/84E66B6F4C359E741C0AFA014790DF39.pem +0 -119
  65. data/test/data/cert/root-ca/certs/84E66B6F4C359E741C0AFA014790DF3A.pem +0 -125
  66. data/test/data/cert/root-ca/db/crlnumber +0 -1
  67. data/test/data/cert/root-ca/db/index +0 -2
  68. data/test/data/cert/root-ca/db/index.attr +0 -1
  69. data/test/data/cert/root-ca/db/index.attr.old +0 -1
  70. data/test/data/cert/root-ca/db/index.old +0 -1
  71. data/test/data/cert/root-ca/db/serial +0 -1
  72. data/test/data/cert/root-ca/db/serial.old +0 -1
  73. data/test/data/cert/root-ca/private/root-ca.key +0 -52
  74. data/test/data/cert/root-ca/root-ca.conf +0 -65
  75. data/test/data/cert/root-ca/root-ca.crt +0 -119
  76. data/test/data/cert/root-ca/root-ca.csr +0 -28
  77. data/test/data/cert/signature-1-pkcs7-detached.pdf +0 -182
  78. data/test/data/cert/sub-ca/certs/453FF080E3EDCD6A388D5368DFC320D9.pem +0 -125
  79. data/test/data/cert/sub-ca/db/crlnumber +0 -1
  80. data/test/data/cert/sub-ca/db/index +0 -1
  81. data/test/data/cert/sub-ca/db/index.attr +0 -1
  82. data/test/data/cert/sub-ca/db/index.old +0 -0
  83. data/test/data/cert/sub-ca/db/serial +0 -1
  84. data/test/data/cert/sub-ca/db/serial.old +0 -1
  85. data/test/data/cert/sub-ca/private/signing.key +0 -52
  86. data/test/data/cert/sub-ca/private/sub-ca.key +0 -52
  87. data/test/data/cert/sub-ca/signing.crt +0 -125
  88. data/test/data/cert/sub-ca/signing.csr +0 -28
  89. data/test/data/cert/sub-ca/signing.p12 +0 -0
  90. data/test/data/cert/sub-ca/sub-ca.conf +0 -65
  91. data/test/data/cert/sub-ca/sub-ca.crt +0 -125
  92. data/test/data/cert/sub-ca/sub-ca.csr +0 -28
@@ -0,0 +1,76 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/type/signature'
5
+ require 'time'
6
+ require 'ostruct'
7
+
8
+ describe HexaPDF::Type::Signature::Handler do
9
+ before do
10
+ @time = Time.parse("2021-11-14 7:00")
11
+ @dict = {Name: "handler", M: @time}
12
+ @handler = HexaPDF::Type::Signature::Handler.new(@dict)
13
+ end
14
+
15
+ it "returns the signer name" do
16
+ assert_equal("handler", @handler.signer_name)
17
+ end
18
+
19
+ it "returns the signing time" do
20
+ assert_equal(@time, @handler.signing_time)
21
+ end
22
+
23
+ it "needs an implementation of certificate_chain" do
24
+ assert_raises(RuntimeError) { @handler.certificate_chain }
25
+ end
26
+
27
+ it "needs an implementation of signer_certificate" do
28
+ assert_raises(RuntimeError) { @handler.signer_certificate }
29
+ end
30
+
31
+ describe "store_verification_callback" do
32
+ before do
33
+ @result = HexaPDF::Type::Signature::VerificationResult.new
34
+ @context = OpenStruct.new
35
+ end
36
+
37
+ it "can allow self-signed certificates" do
38
+ [OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
39
+ OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN].each do |error|
40
+ [true, false].each do |allow_self_signed|
41
+ @result.messages.clear
42
+ @context.error = error
43
+ @handler.store_verification_callback(@result, allow_self_signed: allow_self_signed).
44
+ call(false, @context)
45
+ assert_equal(1, @result.messages.size)
46
+ assert_match(/self-signed certificate/i, @result.messages[0].content)
47
+ assert_equal(allow_self_signed ? :info : :error, @result.messages[0].type)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ it "verifies the signing time" do
54
+ result = HexaPDF::Type::Signature::VerificationResult.new
55
+ [
56
+ [true, '6:00', '8:00'],
57
+ [false, '7:30', '8:00'],
58
+ [false, '5:00', '6:00'],
59
+ ].each do |success, not_before, not_after|
60
+ result.messages.clear
61
+ @handler.define_singleton_method(:signer_certificate) do
62
+ OpenStruct.new.tap do |struct|
63
+ struct.not_before = Time.parse("2021-11-14 #{not_before}")
64
+ struct.not_after = Time.parse("2021-11-14 #{not_after}")
65
+ end
66
+ end
67
+ @handler.send(:verify_signing_time, result)
68
+ if success
69
+ assert(result.messages.empty?)
70
+ else
71
+ assert_equal(1, result.messages.size)
72
+ end
73
+ @handler.singleton_class.remove_method(:signer_certificate)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,47 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/type/signature'
5
+
6
+ describe HexaPDF::Type::Signature::VerificationResult do
7
+ describe "Message" do
8
+ it "accepts a type and a content argument on creation" do
9
+ m = HexaPDF::Type::Signature::VerificationResult::Message.new(:type, 'content')
10
+ assert_equal(:type, m.type)
11
+ assert_equal('content', m.content)
12
+ end
13
+
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')
18
+ assert_equal([error, warning, info], [info, error, warning].sort)
19
+ end
20
+ end
21
+
22
+ before do
23
+ @result = HexaPDF::Type::Signature::VerificationResult.new
24
+ end
25
+
26
+ it "can add new messages" do
27
+ @result.log(:error, "content")
28
+ assert_equal(1, @result.messages.size)
29
+ assert_equal(:error, @result.messages[0].type)
30
+ assert_equal('content', @result.messages[0].content)
31
+ end
32
+
33
+ it "reports success if no error messages have been logged" do
34
+ assert(@result.success?)
35
+ @result.log(:info, 'content')
36
+ assert(@result.success?)
37
+ @result.log(:error, 'failure')
38
+ refute(@result.success?)
39
+ end
40
+
41
+ it "reports failure if there is at least one error message" do
42
+ @result.log(:info, 'content')
43
+ refute(@result.failure?)
44
+ @result.log(:error, 'failure')
45
+ assert(@result.failure?)
46
+ end
47
+ end
@@ -25,12 +25,33 @@ describe HexaPDF::Type::Annotation::AppearanceDictionary do
25
25
  @ap.delete(:D)
26
26
  assert_equal(:n, @ap.down_appearance)
27
27
  end
28
+
29
+ describe "set_appearance" do
30
+ it "sets the appearance for the given type" do
31
+ @ap.set_appearance(1, type: :normal)
32
+ @ap.set_appearance(2, type: :rollover)
33
+ @ap.set_appearance(3, type: :down)
34
+
35
+ assert_equal(1, @ap.normal_appearance)
36
+ assert_equal(2, @ap.rollover_appearance)
37
+ assert_equal(3, @ap.down_appearance)
38
+ end
39
+
40
+ it "respects the provided state name" do
41
+ @ap.set_appearance(1, state_name: :X)
42
+ assert_equal(1, @ap.normal_appearance[:X])
43
+ end
44
+
45
+ it "fails if an invalid appearance type is specified" do
46
+ assert_raises(ArgumentError) { @ap.set_appearance(5, type: :other) }
47
+ end
48
+ end
28
49
  end
29
50
 
30
51
  describe HexaPDF::Type::Annotation do
31
52
  before do
32
53
  @doc = HexaPDF::Document.new
33
- @annot = @doc.add({Type: :Annot, F: 0b100011})
54
+ @annot = @doc.add({Type: :Annot, F: 0b100011, Rect: [10, 10, 110, 60]})
34
55
  end
35
56
 
36
57
  it "must always be indirect" do
@@ -66,7 +87,24 @@ describe HexaPDF::Type::Annotation do
66
87
  assert_same(stream.data, @annot.appearance.data)
67
88
 
68
89
  @annot[:AP][:D] = {X: stream}
69
- assert_same(stream.data, @annot.appearance(:down).data)
90
+ assert_same(stream.data, @annot.appearance(type: :down).data)
91
+ assert_same(stream.data, @annot.appearance(type: :down, state_name: :X).data)
92
+ end
93
+
94
+ describe "create_appearance" do
95
+ it "creates the appearance stream directly underneath /AP" do
96
+ stream = @annot.create_appearance
97
+ assert_same(stream, @annot.appearance_dict.normal_appearance)
98
+ end
99
+
100
+ it "respects the state name when creating the appearance" do
101
+ stream = @annot.create_appearance(type: :down, state_name: :X)
102
+ assert_same(stream, @annot.appearance_dict.down_appearance[:X])
103
+
104
+ @annot[:AS] = :X
105
+ stream = @annot.create_appearance(type: :down)
106
+ assert_same(stream, @annot.appearance_dict.down_appearance[:X])
107
+ end
70
108
  end
71
109
 
72
110
  describe "flags" do
@@ -64,4 +64,8 @@ describe HexaPDF::Type::Font do
64
64
  assert_equal(5, @font.font_file)
65
65
  end
66
66
  end
67
+
68
+ it "returns the glyph scaling factor" do
69
+ assert_equal(0.001, @font.glyph_scaling_factor)
70
+ end
67
71
  end
@@ -25,7 +25,7 @@ describe HexaPDF::Type::FontSimple do
25
25
  describe "encoding" do
26
26
  it "fails if /Encoding is absent because encoding_from_font is not implemented" do
27
27
  @font.delete(:Encoding)
28
- assert_raises(NotImplementedError) { @font.encoding }
28
+ assert_raises(RuntimeError) { @font.encoding }
29
29
  end
30
30
 
31
31
  describe "/Encoding is a name" do
@@ -35,7 +35,7 @@ describe HexaPDF::Type::FontSimple do
35
35
 
36
36
  it "fails if /Encoding is an invalid name because encoding_from_font is not implemented" do
37
37
  @font[:Encoding] = :SomethingUnknown
38
- assert_raises(NotImplementedError) { @font.encoding }
38
+ assert_raises(RuntimeError) { @font.encoding }
39
39
  end
40
40
  end
41
41
 
@@ -47,12 +47,12 @@ describe HexaPDF::Type::FontSimple do
47
47
  describe "no /BaseEncoding is specified" do
48
48
  it "fails if the font is embedded because encoding_from_font is not implemented" do
49
49
  @font[:FontDescriptor][:FontFile] = 5
50
- assert_raises(NotImplementedError) { @font.encoding }
50
+ assert_raises(RuntimeError) { @font.encoding }
51
51
  end
52
52
 
53
53
  it "fails for a symbolic non-embedded font because encoding_from_font is not implemented" do
54
54
  @font[:FontDescriptor].flag(:symbolic, clear_existing: true)
55
- assert_raises(NotImplementedError) { @font.encoding }
55
+ assert_raises(RuntimeError) { @font.encoding }
56
56
  end
57
57
 
58
58
  it "returns the StandardEncoding for a non-symbolic non-embedded font" do
@@ -68,7 +68,7 @@ describe HexaPDF::Type::FontSimple do
68
68
 
69
69
  it "fails if /BaseEncoding is invalid because encoding_from_font is not implemented" do
70
70
  @font[:Encoding] = {BaseEncoding: :SomethingUnknown}
71
- assert_raises(NotImplementedError) { @font.encoding }
71
+ assert_raises(RuntimeError) { @font.encoding }
72
72
  end
73
73
 
74
74
  it "returns a difference encoding if /Differences is specified" do
@@ -9,10 +9,25 @@ describe HexaPDF::Type::FontType3 do
9
9
  @doc = HexaPDF::Document.new
10
10
  @font = @doc.add({Type: :Font, Subtype: :Type3, Encoding: :WinAnsiEncoding,
11
11
  FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
12
- FontBBox: [0, 0, 100, 100], FontMatrix: [1, 0, 0, 1, 0, 0],
12
+ FontBBox: [0, 100, 100, 0], FontMatrix: [0.002, 0, 0, 0.002, 0, 0],
13
13
  CharProcs: {}})
14
14
  end
15
15
 
16
+ describe "bounding_box" do
17
+ it "returns the font's bounding box" do
18
+ assert_equal([0, 0, 100, 100], @font.bounding_box)
19
+ end
20
+
21
+ it "inverts the y-values if necessary based on /FontMatrix" do
22
+ @font[:FontMatrix][3] *= -1
23
+ assert_equal([0, -100, 100, 0], @font.bounding_box)
24
+ end
25
+ end
26
+
27
+ it "returns the glyph scaling factor" do
28
+ assert_equal(0.002, @font.glyph_scaling_factor)
29
+ end
30
+
16
31
  describe "validation" do
17
32
  it "works for valid objects" do
18
33
  assert(@font.validate)
@@ -104,6 +104,15 @@ describe HexaPDF::Type::ObjectStream do
104
104
  assert_equal(0, @obj.value[:First])
105
105
  assert_equal("", @obj.stream)
106
106
  end
107
+
108
+ it "doesn't allow signature dictionaries to be compressed" do
109
+ @obj.add_object(HexaPDF::Dictionary.new({Type: :Sig}, oid: 1))
110
+ @obj.add_object(HexaPDF::Dictionary.new({Type: :DocTimeStamp}, oid: 2))
111
+ @obj.add_object(HexaPDF::Dictionary.new({ByteRange: [], Contents: ''}, oid: 3))
112
+ @obj.write_objects(@revision)
113
+ assert_equal(0, @obj.value[:N])
114
+ assert_equal("", @obj.stream)
115
+ end
107
116
  end
108
117
 
109
118
  it "fails validation if gen != 0" do
@@ -0,0 +1,131 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/signature'
6
+ require_relative 'signature/common'
7
+ require 'stringio'
8
+
9
+ describe HexaPDF::Type::Signature::TransformParams do
10
+ before do
11
+ @doc = HexaPDF::Document.new
12
+ @params = @doc.add({Type: :TransformParams})
13
+ end
14
+
15
+ describe "validation" do
16
+ it "checks the /Annots field for valid values" do
17
+ @params[:Annots] = [:Create, :Other, :Delete, :Other, :New]
18
+ refute(@params.validate(auto_correct: false))
19
+ @params.validate
20
+ assert_equal([:Create, :Delete], @params[:Annots].value)
21
+ end
22
+
23
+ it "checks the /Form field for valid values" do
24
+ @params[:Form] = [:Add, :Other, :Delete, :Other, :New]
25
+ refute(@params.validate(auto_correct: false))
26
+ @params.validate
27
+ assert_equal([:Add, :Delete], @params[:Form].value)
28
+ end
29
+
30
+ it "checks the /EF field for valid values" do
31
+ @params[:EF] = [:Create, :Other, :Delete, :Other, :New]
32
+ refute(@params.validate(auto_correct: false))
33
+ @params.validate
34
+ assert_equal([:Create, :Delete], @params[:EF].value)
35
+ end
36
+ end
37
+ end
38
+
39
+ describe HexaPDF::Type::Signature::SignatureReference do
40
+ before do
41
+ @doc = HexaPDF::Document.new
42
+ @sigref = @doc.add({Type: :SigRef})
43
+ end
44
+
45
+ describe "validation" do
46
+ it "checks the existence of the /Data field for FieldMDP transforms" do
47
+ @sigref[:TransformMethod] = :FieldMDP
48
+ refute(@sigref.validate)
49
+ @sigref[:Data] = HexaPDF::Object.new('data', oid: 1)
50
+ assert(@sigref.validate)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe HexaPDF::Type::Signature do
56
+ before do
57
+ @doc = HexaPDF::Document.new
58
+ @sig = @doc.add({Type: :Sig, Filter: :'Adobe.PPKLite', SubFilter: :'ETSI.CAdES.detached'})
59
+
60
+ @pdf_data = 'Some data'
61
+ @pkcs7 = OpenSSL::PKCS7.sign(CERTIFICATES.signer_certificate, CERTIFICATES.signer_key,
62
+ @pdf_data, [CERTIFICATES.ca_certificate],
63
+ OpenSSL::PKCS7::DETACHED)
64
+ @sig[:Contents] = @pkcs7.to_der
65
+ end
66
+
67
+ it "returns the signer name" do
68
+ assert_equal('signer', @sig.signer_name)
69
+ end
70
+
71
+ it "returns the signing time" do
72
+ assert_equal(@sig.signature_handler.signing_time, @sig.signing_time)
73
+ end
74
+
75
+ it "returns the signing reason" do
76
+ @sig[:Reason] = 'reason'
77
+ assert_equal('reason', @sig.signing_reason)
78
+ end
79
+
80
+ it "returns the signing location" do
81
+ @sig[:Location] = 'location'
82
+ assert_equal('location', @sig.signing_location)
83
+ end
84
+
85
+ it "returns the signature type" do
86
+ assert_equal('ETSI.CAdES.detached', @sig.signature_type)
87
+ end
88
+
89
+ describe "signature_handler" do
90
+ it "returns the signature handler" do
91
+ assert_kind_of(HexaPDF::Type::Signature::Handler, @sig.signature_handler)
92
+ end
93
+
94
+ it "fails if the required handler is not available" do
95
+ @sig[:SubFilter] = :Unknown
96
+ assert_raises(HexaPDF::Error) { @sig.signature_handler }
97
+ end
98
+ end
99
+
100
+ it "returns the signature contents" do
101
+ @sig[:Contents] = 'hallo'
102
+ assert_equal('hallo', @sig.contents)
103
+ end
104
+
105
+ describe "signed_data" do
106
+ it "reads the specified portions of the document" do
107
+ io = StringIO.new(MINIMAL_PDF)
108
+ doc = HexaPDF::Document.new(io: io)
109
+ @sig.document = doc
110
+ @sig[:ByteRange] = [0, 400, 500, 333]
111
+ assert_equal((MINIMAL_PDF[0, 400] << MINIMAL_PDF[500, 333]).b, @sig.signed_data)
112
+ end
113
+
114
+ it "fails if the document isn't associated with an existing PDF file" do
115
+ assert_raises(HexaPDF::Error) { @sig.signed_data }
116
+ end
117
+ end
118
+
119
+ it "invokes the signature handler for verification" do
120
+ handler = Object.new
121
+ store, kwargs = nil
122
+ handler.define_singleton_method(:verify) do |in_store, in_kwargs|
123
+ store, kwargs = in_store, in_kwargs
124
+ :result
125
+ end
126
+ @sig.define_singleton_method(:signature_handler) { handler }
127
+ assert_equal(:result, @sig.verify(allow_self_signed: true))
128
+ assert_kind_of(OpenSSL::X509::Store, store)
129
+ assert(kwargs[:allow_self_signed])
130
+ end
131
+ 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.19.0
4
+ version: 0.20.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: 2021-11-24 00:00:00.000000000 Z
11
+ date: 2021-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse
@@ -124,6 +124,11 @@ files:
124
124
  - data/hexapdf/afm/Times-Italic.afm
125
125
  - data/hexapdf/afm/Times-Roman.afm
126
126
  - data/hexapdf/afm/ZapfDingbats.afm
127
+ - data/hexapdf/cert/demo_cert.rb
128
+ - data/hexapdf/cert/root-ca.crt
129
+ - data/hexapdf/cert/signing.crt
130
+ - data/hexapdf/cert/signing.key
131
+ - data/hexapdf/cert/sub-ca.crt
127
132
  - data/hexapdf/cmap/83pv-RKSJ-H
128
133
  - data/hexapdf/cmap/90ms-RKSJ-H
129
134
  - data/hexapdf/cmap/90ms-RKSJ-V
@@ -254,6 +259,7 @@ files:
254
259
  - lib/hexapdf/document/fonts.rb
255
260
  - lib/hexapdf/document/images.rb
256
261
  - lib/hexapdf/document/pages.rb
262
+ - lib/hexapdf/document/signatures.rb
257
263
  - lib/hexapdf/encryption.rb
258
264
  - lib/hexapdf/encryption/aes.rb
259
265
  - lib/hexapdf/encryption/arc4.rb
@@ -396,6 +402,11 @@ files:
396
402
  - lib/hexapdf/type/page.rb
397
403
  - lib/hexapdf/type/page_tree_node.rb
398
404
  - lib/hexapdf/type/resources.rb
405
+ - lib/hexapdf/type/signature.rb
406
+ - lib/hexapdf/type/signature/adbe_pkcs7_detached.rb
407
+ - lib/hexapdf/type/signature/adbe_x509_rsa_sha1.rb
408
+ - lib/hexapdf/type/signature/handler.rb
409
+ - lib/hexapdf/type/signature/verification_result.rb
399
410
  - lib/hexapdf/type/trailer.rb
400
411
  - lib/hexapdf/type/viewer_preferences.rb
401
412
  - lib/hexapdf/type/xref_stream.rb
@@ -434,36 +445,6 @@ files:
434
445
  - test/data/aes-test-vectors/CBCVarTxt-192-encrypt.data.gz
435
446
  - test/data/aes-test-vectors/CBCVarTxt-256-decrypt.data.gz
436
447
  - test/data/aes-test-vectors/CBCVarTxt-256-encrypt.data.gz
437
- - test/data/cert/create.sh
438
- - test/data/cert/root-ca/certs/84E66B6F4C359E741C0AFA014790DF39.pem
439
- - test/data/cert/root-ca/certs/84E66B6F4C359E741C0AFA014790DF3A.pem
440
- - test/data/cert/root-ca/db/crlnumber
441
- - test/data/cert/root-ca/db/index
442
- - test/data/cert/root-ca/db/index.attr
443
- - test/data/cert/root-ca/db/index.attr.old
444
- - test/data/cert/root-ca/db/index.old
445
- - test/data/cert/root-ca/db/serial
446
- - test/data/cert/root-ca/db/serial.old
447
- - test/data/cert/root-ca/private/root-ca.key
448
- - test/data/cert/root-ca/root-ca.conf
449
- - test/data/cert/root-ca/root-ca.crt
450
- - test/data/cert/root-ca/root-ca.csr
451
- - test/data/cert/signature-1-pkcs7-detached.pdf
452
- - test/data/cert/sub-ca/certs/453FF080E3EDCD6A388D5368DFC320D9.pem
453
- - test/data/cert/sub-ca/db/crlnumber
454
- - test/data/cert/sub-ca/db/index
455
- - test/data/cert/sub-ca/db/index.attr
456
- - test/data/cert/sub-ca/db/index.old
457
- - test/data/cert/sub-ca/db/serial
458
- - test/data/cert/sub-ca/db/serial.old
459
- - test/data/cert/sub-ca/private/signing.key
460
- - test/data/cert/sub-ca/private/sub-ca.key
461
- - test/data/cert/sub-ca/signing.crt
462
- - test/data/cert/sub-ca/signing.csr
463
- - test/data/cert/sub-ca/signing.p12
464
- - test/data/cert/sub-ca/sub-ca.conf
465
- - test/data/cert/sub-ca/sub-ca.crt
466
- - test/data/cert/sub-ca/sub-ca.csr
467
448
  - test/data/fonts/Ubuntu-Title.ttf
468
449
  - test/data/images/cmyk.jpg
469
450
  - test/data/images/fillbytes.jpg
@@ -527,6 +508,7 @@ files:
527
508
  - test/hexapdf/document/test_fonts.rb
528
509
  - test/hexapdf/document/test_images.rb
529
510
  - test/hexapdf/document/test_pages.rb
511
+ - test/hexapdf/document/test_signatures.rb
530
512
  - test/hexapdf/encryption/common.rb
531
513
  - test/hexapdf/encryption/test_aes.rb
532
514
  - test/hexapdf/encryption/test_arc4.rb
@@ -635,6 +617,11 @@ files:
635
617
  - test/hexapdf/type/annotations/test_markup_annotation.rb
636
618
  - test/hexapdf/type/annotations/test_text.rb
637
619
  - test/hexapdf/type/annotations/test_widget.rb
620
+ - test/hexapdf/type/signature/common.rb
621
+ - test/hexapdf/type/signature/test_adbe_pkcs7_detached.rb
622
+ - test/hexapdf/type/signature/test_adbe_x509_rsa_sha1.rb
623
+ - test/hexapdf/type/signature/test_handler.rb
624
+ - test/hexapdf/type/signature/test_verification_result.rb
638
625
  - test/hexapdf/type/test_annotation.rb
639
626
  - test/hexapdf/type/test_catalog.rb
640
627
  - test/hexapdf/type/test_cid_font.rb
@@ -653,6 +640,7 @@ files:
653
640
  - test/hexapdf/type/test_page.rb
654
641
  - test/hexapdf/type/test_page_tree_node.rb
655
642
  - test/hexapdf/type/test_resources.rb
643
+ - test/hexapdf/type/test_signature.rb
656
644
  - test/hexapdf/type/test_trailer.rb
657
645
  - test/hexapdf/type/test_xref_stream.rb
658
646
  - test/hexapdf/utils/test_bit_field.rb
@@ -683,7 +671,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
683
671
  - !ruby/object:Gem::Version
684
672
  version: '0'
685
673
  requirements: []
686
- rubygems_version: 3.2.3
674
+ rubygems_version: 3.2.32
687
675
  signing_key:
688
676
  specification_version: 4
689
677
  summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby