origami 2.0.4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: