origami 2.0.4 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -52,16 +52,13 @@ module Origami
52
52
  input.each_byte do |byte|
53
53
  char = byte.chr
54
54
 
55
- case table.size
56
- when 512 then codesize = 10
57
- when 1024 then codesize = 11
58
- when 2048 then codesize = 12
59
- when 4096
55
+ if table.size == 4096
60
56
  result.write(CLEARTABLE, codesize)
61
- table, codesize = reset_state
62
- redo
57
+ table, _ = reset_state
63
58
  end
64
59
 
60
+ codesize = table.size.bit_length
61
+
65
62
  it = s + char
66
63
  if table.has_key?(it)
67
64
  s = it
@@ -72,7 +69,7 @@ module Origami
72
69
  end
73
70
  end
74
71
 
75
- result.write(table[s], codesize)
72
+ result.write(table[s], codesize) unless s.empty?
76
73
  result.write(EOD, codesize)
77
74
 
78
75
  result.final.to_s
@@ -85,14 +82,16 @@ module Origami
85
82
  def decode(string)
86
83
  result = "".b
87
84
  bstring = Utils::BitReader.new(string)
88
- table, codesize, prevbyte = reset_state
85
+ table, codesize = reset_state
86
+ prevbyte = nil
89
87
 
90
88
  until bstring.eod? do
91
89
  byte = bstring.read(codesize)
92
90
  break if byte == EOD
93
91
 
94
92
  if byte == CLEARTABLE
95
- table, codesize, prevbyte = reset_state
93
+ table, codesize = reset_state
94
+ prevbyte = nil
96
95
  redo
97
96
  end
98
97
 
@@ -120,7 +119,7 @@ module Origami
120
119
  when 510...1022 then 10
121
120
  when 1022...2046 then 11
122
121
  when 2046...4095 then 12
123
- when 4095
122
+ else
124
123
  raise InvalidLZWDataError, "LZW table is full and no clear flag was set"
125
124
  end
126
125
  end
@@ -162,8 +161,8 @@ module Origami
162
161
  table[CLEARTABLE] = CLEARTABLE
163
162
  table[EOD] = EOD
164
163
 
165
- # Codeword table, codeword size, previous_byte
166
- [table, 9, nil]
164
+ # Codeword table, codeword size
165
+ [table, 9]
167
166
  end
168
167
  end
169
168
 
@@ -166,7 +166,9 @@ module Origami
166
166
  end
167
167
 
168
168
  class PDF::Instruction
169
- insn 'sh', Name
169
+ insn 'sh', Name do |canvas, shading|
170
+ canvas.paint_shading(shading)
171
+ end
170
172
  end
171
173
 
172
174
  end
@@ -36,6 +36,7 @@ module Origami
36
36
  def write_text(s); end
37
37
  def stroke_path; end
38
38
  def fill_path; end
39
+ def paint_shading(sh); end
39
40
  end
40
41
 
41
42
  class DummyCanvas
@@ -486,8 +486,8 @@ module Origami
486
486
  end
487
487
 
488
488
  # TODO :nodoc:
489
- def paint_shading(_shade)
490
- raise NotImplementedError
489
+ def paint_shading(shade)
490
+ last_content_stream.paint_shading(shade)
491
491
  end
492
492
 
493
493
  # TODO :nodoc:
@@ -49,17 +49,7 @@ module Origami
49
49
  signature = digsig[:Contents]
50
50
  subfilter = digsig.SubFilter.value
51
51
 
52
- case subfilter
53
- when Signature::DigitalSignature::PKCS7_DETACHED
54
- Signature.verify_pkcs7_detached_signature(data, signature, store, flags)
55
-
56
-
57
- when Signature::DigitalSignature::PKCS7_SHA1
58
- Signature.verify_pkcs7_sha1_signature(data, signature, store, flags)
59
-
60
- else
61
- raise NotImplementedError, "Unsupported method #{digsig.SubFilter}"
62
- end
52
+ Signature.verify(subfilter.to_s, data, signature, store, flags)
63
53
  end
64
54
 
65
55
  #
@@ -75,7 +65,7 @@ module Origami
75
65
  # _reason_:: Signing reason.
76
66
  #
77
67
  def sign(certificate, key,
78
- method: "adbe.pkcs7.detached",
68
+ method: Signature::PKCS7_DETACHED,
79
69
  ca: [],
80
70
  annotation: nil,
81
71
  issuer: nil,
@@ -99,41 +89,6 @@ module Origami
99
89
  raise TypeError, "Expected a Annotation::Widget::Signature object."
100
90
  end
101
91
 
102
- case method
103
- when 'adbe.pkcs7.detached'
104
- signfield_size = -> (crt, pkey, certs) do
105
- OpenSSL::PKCS7.sign(
106
- crt,
107
- pkey,
108
- "",
109
- certs,
110
- OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY
111
- ).to_der.size
112
- end
113
-
114
- when 'adbe.pkcs7.sha1'
115
- signfield_size = -> (crt, pkey, certs) do
116
- OpenSSL::PKCS7.sign(
117
- crt,
118
- pkey,
119
- Digest::SHA1.digest(''),
120
- certs,
121
- OpenSSL::PKCS7::BINARY
122
- ).to_der.size
123
- end
124
-
125
- when 'adbe.x509.rsa_sha1'
126
- signfield_size = -> (_crt, pkey, _certs) do
127
- pkey.private_encrypt(
128
- Digest::SHA1.digest('')
129
- ).size
130
- end
131
- raise NotImplementedError, "Unsupported method #{method.inspect}"
132
-
133
- else
134
- raise NotImplementedError, "Unsupported method #{method.inspect}"
135
- end
136
-
137
92
  digsig = Signature::DigitalSignature.new.set_indirect(true)
138
93
 
139
94
  if annotation.nil?
@@ -146,18 +101,19 @@ module Origami
146
101
  self.Catalog.AcroForm.SigFlags =
147
102
  InteractiveForm::SigFlags::SIGNATURES_EXIST | InteractiveForm::SigFlags::APPEND_ONLY
148
103
 
149
- digsig.Type = :Sig #:nodoc:
150
- digsig.Contents = HexaString.new("\x00" * signfield_size[certificate, key, ca]) #:nodoc:
151
- digsig.Filter = :"Adobe.PPKLite" #:nodoc:
152
- digsig.SubFilter = Name.new(method) #:nodoc:
153
- digsig.ByteRange = [0, 0, 0, 0] #:nodoc:
104
+ digsig.Type = :Sig
105
+ digsig.Contents = HexaString.new("\x00" * Signature::required_size(method, certificate, key, ca))
106
+ digsig.Filter = :"Adobe.PPKLite"
107
+ digsig.SubFilter = Name.new(method)
108
+ digsig.ByteRange = [0, 0, 0, 0]
154
109
  digsig.Name = issuer
155
110
 
156
111
  digsig.Location = HexaString.new(location) if location
157
112
  digsig.ContactInfo = HexaString.new(contact) if contact
158
113
  digsig.Reason = HexaString.new(reason) if reason
159
114
 
160
- if method == 'adbe.x509.rsa_sha1'
115
+ # PKCS1 signatures require a Cert entry.
116
+ if method == Signature::PKCS1_RSA_SHA1
161
117
  digsig.Cert =
162
118
  if ca.empty?
163
119
  HexaString.new(certificate.to_der)
@@ -197,30 +153,10 @@ module Origami
197
153
  signable_data = file_data[digsig.ByteRange[0],digsig.ByteRange[1]] +
198
154
  file_data[digsig.ByteRange[2],digsig.ByteRange[3]]
199
155
 
200
- signature =
201
- case method
202
- when 'adbe.pkcs7.detached'
203
- OpenSSL::PKCS7.sign(
204
- certificate,
205
- key,
206
- signable_data,
207
- ca,
208
- OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY
209
- ).to_der
210
-
211
- when 'adbe.pkcs7.sha1'
212
- OpenSSL::PKCS7.sign(
213
- certificate,
214
- key,
215
- Digest::SHA1.digest(signable_data),
216
- ca,
217
- OpenSSL::PKCS7::BINARY
218
- ).to_der
219
-
220
- when 'adbe.x509.rsa_sha1'
221
- key.private_encrypt(Digest::SHA1.digest(signable_data))
222
- end
223
-
156
+ #
157
+ # Computes and inserts the signature.
158
+ #
159
+ signature = Signature.compute(method, signable_data, certificate, key, ca)
224
160
  digsig.Contents[0, signature.size] = signature
225
161
 
226
162
  #
@@ -248,15 +184,8 @@ module Origami
248
184
  #
249
185
  def enable_usage_rights(cert, pkey, *rights)
250
186
 
251
- signfield_size = -> (crt, key, ca) do
252
- OpenSSL::PKCS7.sign(
253
- crt,
254
- key,
255
- '',
256
- ca,
257
- OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY
258
- ).to_der.size
259
- end
187
+ # Always uses a detached PKCS7 signature for UR.
188
+ method = Signature::PKCS7_DETACHED
260
189
 
261
190
  #
262
191
  # Load key pair
@@ -272,21 +201,21 @@ module Origami
272
201
  self.Catalog.AcroForm ||= InteractiveForm.new
273
202
  #self.Catalog.AcroForm.SigFlags = InteractiveForm::SigFlags::APPEND_ONLY
274
203
 
275
- digsig.Type = :Sig #:nodoc:
276
- digsig.Contents = HexaString.new("\x00" * signfield_size[certificate, key, []]) #:nodoc:
277
- digsig.Filter = :"Adobe.PPKLite" #:nodoc:
278
- digsig.Name = "ARE Acrobat Product v8.0 P23 0002337" #:nodoc:
279
- digsig.SubFilter = :"adbe.pkcs7.detached" #:nodoc:
280
- digsig.ByteRange = [0, 0, 0, 0] #:nodoc:
204
+ digsig.Type = :Sig
205
+ digsig.Contents = HexaString.new("\x00" * Signature.required_size(method, certificate, key, []))
206
+ digsig.Filter = :"Adobe.PPKLite"
207
+ digsig.Name = "ARE Acrobat Product v8.0 P23 0002337"
208
+ digsig.SubFilter = Name.new(method )
209
+ digsig.ByteRange = [0, 0, 0, 0]
281
210
 
282
- sigref = Signature::Reference.new #:nodoc:
283
- sigref.Type = :SigRef #:nodoc:
284
- sigref.TransformMethod = :UR3 #:nodoc:
211
+ sigref = Signature::Reference.new
212
+ sigref.Type = :SigRef
213
+ sigref.TransformMethod = :UR3
285
214
  sigref.Data = self.Catalog
286
215
 
287
216
  sigref.TransformParams = UsageRights::TransformParams.new
288
- sigref.TransformParams.P = true #:nodoc:
289
- sigref.TransformParams.Type = :TransformParams #:nodoc:
217
+ sigref.TransformParams.P = true
218
+ sigref.TransformParams.Type = :TransformParams
290
219
  sigref.TransformParams.V = UsageRights::TransformParams::VERSION
291
220
 
292
221
  rights.each do |right|
@@ -330,13 +259,7 @@ module Origami
330
259
  signable_data = file_data[digsig.ByteRange[0],digsig.ByteRange[1]] +
331
260
  file_data[digsig.ByteRange[2],digsig.ByteRange[3]]
332
261
 
333
- signature = OpenSSL::PKCS7.sign(
334
- certificate,
335
- key,
336
- signable_data,
337
- [],
338
- OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY
339
- ).to_der
262
+ signature = Signature.compute(method, signable_data, certificate, key, [])
340
263
  digsig.Contents[0, signature.size] = signature
341
264
 
342
265
  #
@@ -399,19 +322,50 @@ module Origami
399
322
 
400
323
  module Signature
401
324
 
402
- # Verifies a PKCS7 detached signature.
403
- def self.verify_pkcs7_detached_signature(data, signature, store, flags)
404
- pkcs7 = OpenSSL::PKCS7.new(signature)
405
- raise SignatureError, "Not a PKCS7 detached signature" unless pkcs7.detached?
325
+ PKCS1_RSA_SHA1 = "adbe.x509.rsa_sha1"
326
+ PKCS7_SHA1 = "adbe.pkcs7.sha1"
327
+ PKCS7_DETACHED = "adbe.pkcs7.detached"
328
+
329
+ def self.verify(method, data, signature, store, flags)
330
+ case method
331
+ when PKCS7_DETACHED
332
+ pkcs7 = OpenSSL::PKCS7.new(signature)
333
+ raise SignatureError, "Not a PKCS7 detached signature" unless pkcs7.detached?
334
+ flags |= OpenSSL::PKCS7::DETACHED
335
+ pkcs7.verify([], store, data, flags)
406
336
 
407
- flags |= OpenSSL::PKCS7::DETACHED
408
- pkcs7.verify([], store, data, flags)
337
+ when PKCS7_SHA1
338
+ pkcs7 = OpenSSL::PKCS7.new(signature)
339
+ pkcs7.verify([], store, nil, flags) and pkcs7.data == Digest::SHA1.digest(data)
340
+
341
+ else
342
+ raise NotImplementedError, "Unsupported signature method #{method.inspect}"
343
+ end
344
+ end
345
+
346
+ #
347
+ # Computes the required size in bytes for storing the signature.
348
+ #
349
+ def self.required_size(method, certificate, key, ca)
350
+ self.compute(method, "", certificate, key, ca).size
409
351
  end
410
352
 
411
- # Verifies a PKCS7-SHA1 signature.
412
- def self.verify_pkcs7_sha1_signature(data, signature, store, flags)
413
- pkcs7 = OpenSSL::PKCS7.new(signature)
414
- pkcs7.verify([], store, nil, flags) and pkcs7.data == Digest::SHA1.digest(data)
353
+ #
354
+ # Computes the signature using the specified subfilter method.
355
+ #
356
+ def self.compute(method, data, certificate, key, ca)
357
+ case method
358
+ when PKCS7_DETACHED
359
+ OpenSSL::PKCS7.sign(certificate, key, data, ca, OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::BINARY).to_der
360
+
361
+ when PKCS7_SHA1
362
+ OpenSSL::PKCS7.sign(certificate, key, Digest::SHA1.digest(data), ca, OpenSSL::PKCS7::BINARY).to_der
363
+
364
+ when PKCS1_RSA_SHA1
365
+ key.sign(OpenSSL::Digest::SHA1.new, data)
366
+ else
367
+ raise NotImplementedError, "Unsupported signature method #{method.inspect}"
368
+ end
415
369
  end
416
370
 
417
371
  #
@@ -506,10 +460,6 @@ module Origami
506
460
  class DigitalSignature < Dictionary
507
461
  include StandardObject
508
462
 
509
- PKCS1_RSA_SHA1 = :"adbe.x509.rsa_sha1"
510
- PKCS7_SHA1 = :"adbe.pkcs7.sha1"
511
- PKCS7_DETACHED = :"adbe.pkcs7.detached"
512
-
513
463
  field :Type, :Type => Name, :Default => :Sig
514
464
  field :Filter, :Type => Name, :Default => :"Adobe.PPKLite", :Required => true
515
465
  field :SubFilter, :Type => Name
@@ -99,8 +99,6 @@ module Origami
99
99
  def dictionary=(dict)
100
100
  @dictionary = dict
101
101
  @dictionary.parent = self
102
-
103
- @dictionary
104
102
  end
105
103
 
106
104
  def pre_build
@@ -19,5 +19,5 @@
19
19
  =end
20
20
 
21
21
  module Origami
22
- VERSION = "2.0.4"
22
+ VERSION = "2.1.0"
23
23
  end
@@ -57,6 +57,8 @@ class TestStreams < Minitest::Test
57
57
  stm.encoded_data = raw
58
58
 
59
59
  assert_equal stm.data, @data
60
+
61
+ assert_equal Filter::Flate.decode(Filter::Flate.encode("")), ""
60
62
  end
61
63
 
62
64
  def test_filter_asciihex
@@ -71,7 +73,7 @@ class TestStreams < Minitest::Test
71
73
  Filter::ASCIIHex.decode("123456789ABCDEFGHIJKL")
72
74
  end
73
75
 
74
- assert_equal Filter::ASCIIHex.decode(""), ""
76
+ assert_equal Filter::ASCIIHex.decode(Filter::ASCIIHex.encode("")), ""
75
77
  end
76
78
 
77
79
  def test_filter_ascii85
@@ -86,7 +88,7 @@ class TestStreams < Minitest::Test
86
88
  Filter::ASCII85.decode("ABCD\x01")
87
89
  end
88
90
 
89
- assert_equal Filter::ASCII85.decode(""), ""
91
+ assert_equal Filter::ASCII85.decode(Filter::ASCII85.encode("")), ""
90
92
  end
91
93
 
92
94
  def test_filter_rle
@@ -101,7 +103,7 @@ class TestStreams < Minitest::Test
101
103
  Filter::RunLength.decode("\x7f")
102
104
  end
103
105
 
104
- assert_equal Filter::RunLength.decode(""), ""
106
+ assert_equal Filter::RunLength.decode(Filter::RunLength.encode("")), ""
105
107
  end
106
108
 
107
109
  def test_filter_lzw
@@ -116,7 +118,7 @@ class TestStreams < Minitest::Test
116
118
  Filter::LZW.decode("abcd")
117
119
  end
118
120
 
119
- assert_equal Filter::LZW.decode(""), ""
121
+ assert_equal Filter::LZW.decode(Filter::LZW.encode("")), ""
120
122
  end
121
123
 
122
124
  def test_filter_ccittfax
@@ -132,7 +134,7 @@ class TestStreams < Minitest::Test
132
134
  Filter::CCITTFax.decode("abcd")
133
135
  end
134
136
 
135
- assert_equal Filter::CCITTFax.decode(""), ""
137
+ assert_equal Filter::CCITTFax.decode(Filter::CCITTFax.encode("")), ""
136
138
  end
137
139
 
138
140
  def test_stream
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origami
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guillaume Delugré
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-02 00:00:00.000000000 Z
11
+ date: 2017-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -42,7 +42,6 @@ description: Origami is a pure Ruby library to parse, modify and generate PDF do
42
42
  email: origami@subvert.technology
43
43
  executables:
44
44
  - pdfsh
45
- - pdfwalker
46
45
  - pdf2pdfa
47
46
  - pdf2ruby
48
47
  - pdfcop
@@ -59,20 +58,6 @@ files:
59
58
  - COPYING.LESSER
60
59
  - README.md
61
60
  - bin/config/pdfcop.conf.yml
62
- - bin/gui/COPYING
63
- - bin/gui/about.rb
64
- - bin/gui/config.rb
65
- - bin/gui/file.rb
66
- - bin/gui/gtkhex.rb
67
- - bin/gui/hexview.rb
68
- - bin/gui/imgview.rb
69
- - bin/gui/menu.rb
70
- - bin/gui/properties.rb
71
- - bin/gui/signing.rb
72
- - bin/gui/textview.rb
73
- - bin/gui/treeview.rb
74
- - bin/gui/walker.rb
75
- - bin/gui/xrefs.rb
76
61
  - bin/pdf2pdfa
77
62
  - bin/pdf2ruby
78
63
  - bin/pdfcop
@@ -83,10 +68,9 @@ files:
83
68
  - bin/pdfextract
84
69
  - bin/pdfmetadata
85
70
  - bin/pdfsh
86
- - bin/pdfwalker
87
- - bin/shell/.irbrc
88
71
  - bin/shell/console.rb
89
72
  - bin/shell/hexdump.rb
73
+ - bin/shell/irbrc
90
74
  - examples/README.md
91
75
  - examples/attachments/attachment.rb
92
76
  - examples/attachments/nested_document.rb
@@ -223,8 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
207
  - - ">="
224
208
  - !ruby/object:Gem::Version
225
209
  version: '0'
226
- requirements:
227
- - gtk2 to run the graphical interface
210
+ requirements: []
228
211
  rubyforge_project:
229
212
  rubygems_version: 2.6.13
230
213
  signing_key: