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.
- 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:
|