origami 2.0.4 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +6 -5
- data/bin/pdf2pdfa +1 -1
- data/bin/pdfcop +5 -5
- data/bin/pdfsh +1 -1
- data/bin/shell/{.irbrc → irbrc} +0 -0
- data/lib/origami/array.rb +12 -3
- data/lib/origami/dictionary.rb +0 -2
- data/lib/origami/encryption.rb +77 -77
- data/lib/origami/filters.rb +0 -2
- data/lib/origami/filters/ccitt.rb +41 -33
- data/lib/origami/filters/lzw.rb +12 -13
- data/lib/origami/graphics/patterns.rb +3 -1
- data/lib/origami/graphics/render.rb +1 -0
- data/lib/origami/graphics/xobject.rb +2 -2
- data/lib/origami/signature.rb +68 -118
- data/lib/origami/stream.rb +0 -2
- data/lib/origami/version.rb +1 -1
- data/test/test_streams.rb +7 -5
- metadata +4 -21
- data/bin/gui/COPYING +0 -674
- data/bin/gui/about.rb +0 -36
- data/bin/gui/config.rb +0 -120
- data/bin/gui/file.rb +0 -314
- data/bin/gui/gtkhex.rb +0 -1326
- data/bin/gui/hexview.rb +0 -84
- data/bin/gui/imgview.rb +0 -69
- data/bin/gui/menu.rb +0 -382
- data/bin/gui/properties.rb +0 -126
- data/bin/gui/signing.rb +0 -558
- data/bin/gui/textview.rb +0 -88
- data/bin/gui/treeview.rb +0 -416
- data/bin/gui/walker.rb +0 -308
- data/bin/gui/xrefs.rb +0 -75
- data/bin/pdfwalker +0 -6
data/lib/origami/filters/lzw.rb
CHANGED
@@ -52,16 +52,13 @@ module Origami
|
|
52
52
|
input.each_byte do |byte|
|
53
53
|
char = byte.chr
|
54
54
|
|
55
|
-
|
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,
|
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
|
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
|
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
|
-
|
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
|
166
|
-
[table, 9
|
164
|
+
# Codeword table, codeword size
|
165
|
+
[table, 9]
|
167
166
|
end
|
168
167
|
end
|
169
168
|
|
data/lib/origami/signature.rb
CHANGED
@@ -49,17 +49,7 @@ module Origami
|
|
49
49
|
signature = digsig[:Contents]
|
50
50
|
subfilter = digsig.SubFilter.value
|
51
51
|
|
52
|
-
|
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:
|
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
|
150
|
-
digsig.Contents = HexaString.new("\x00" *
|
151
|
-
digsig.Filter = :"Adobe.PPKLite"
|
152
|
-
digsig.SubFilter = Name.new(method)
|
153
|
-
digsig.ByteRange = [0, 0, 0, 0]
|
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
|
-
|
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
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
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
|
-
|
252
|
-
|
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
|
276
|
-
digsig.Contents = HexaString.new("\x00" *
|
277
|
-
digsig.Filter = :"Adobe.PPKLite"
|
278
|
-
digsig.Name = "ARE Acrobat Product v8.0 P23 0002337"
|
279
|
-
digsig.SubFilter =
|
280
|
-
digsig.ByteRange = [0, 0, 0, 0]
|
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
|
283
|
-
sigref.Type = :SigRef
|
284
|
-
sigref.TransformMethod = :UR3
|
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
|
289
|
-
sigref.TransformParams.Type = :TransformParams
|
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 =
|
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
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
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
|
-
|
408
|
-
|
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
|
-
#
|
412
|
-
|
413
|
-
|
414
|
-
|
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
|
data/lib/origami/stream.rb
CHANGED
data/lib/origami/version.rb
CHANGED
data/test/test_streams.rb
CHANGED
@@ -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
|
+
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-
|
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:
|