origami 1.2.5 → 1.2.6
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 +7 -0
- data/bin/gui/config.rb +0 -4
- data/bin/gui/imgview.rb +2 -2
- data/bin/gui/menu.rb +11 -3
- data/bin/gui/treeview.rb +9 -3
- data/bin/pdfexplode +220 -0
- data/bin/pdfextract +3 -0
- data/lib/origami/acroform.rb +2 -2
- data/lib/origami/actions.rb +62 -35
- data/lib/origami/annotations.rb +3 -2
- data/lib/origami/array.rb +27 -4
- data/lib/origami/boolean.rb +2 -2
- data/lib/origami/catalog.rb +45 -45
- data/lib/origami/dictionary.rb +87 -14
- data/lib/origami/encryption.rb +46 -24
- data/lib/origami/file.rb +1 -2
- data/lib/origami/filters/ccitt.rb +118 -66
- data/lib/origami/filters/flate.rb +5 -1
- data/lib/origami/filters.rb +84 -2
- data/lib/origami/font.rb +71 -71
- data/lib/origami/graphics/patterns.rb +2 -1
- data/lib/origami/graphics/xobject.rb +123 -1
- data/lib/origami/javascript.rb +2 -1
- data/lib/origami/name.rb +2 -2
- data/lib/origami/null.rb +2 -2
- data/lib/origami/numeric.rb +11 -3
- data/lib/origami/object.rb +37 -16
- data/lib/origami/page.rb +135 -71
- data/lib/origami/parser.rb +11 -4
- data/lib/origami/parsers/pdf/linear.rb +1 -0
- data/lib/origami/parsers/pdf.rb +10 -0
- data/lib/origami/pdf.rb +10 -70
- data/lib/origami/reference.rb +4 -5
- data/lib/origami/signature.rb +22 -8
- data/lib/origami/stream.rb +41 -20
- data/lib/origami/string.rb +15 -6
- data/lib/origami/trailer.rb +9 -5
- data/lib/origami.rb +19 -0
- data/samples/actions/loop/loopgoto.rb +1 -1
- data/samples/actions/loop/loopnamed.rb +2 -2
- data/samples/actions/named/named.rb +1 -1
- data/samples/actions/samba/smbrelay.rb +1 -1
- data/samples/actions/triggerevents/trigger.rb +13 -13
- data/samples/actions/webbug/webbug-browser.rb +1 -1
- data/samples/actions/webbug/webbug-js.rb +1 -1
- data/samples/actions/webbug/webbug-reader.rb +1 -1
- data/samples/attachments/attach.rb +2 -2
- data/samples/exploits/cve-2008-2992-utilprintf.rb +1 -1
- data/samples/exploits/cve-2009-0927-geticon.rb +1 -1
- data/samples/exploits/exploit_customdictopen.rb +2 -2
- data/samples/exploits/getannots.rb +1 -1
- data/samples/javascript/js.rb +2 -2
- data/test/ts_pdf.rb +23 -23
- metadata +71 -86
data/lib/origami/catalog.rb
CHANGED
@@ -284,51 +284,6 @@ module Origami
|
|
284
284
|
ATTACHMENTS = :UseAttachments
|
285
285
|
end
|
286
286
|
|
287
|
-
#
|
288
|
-
# Class representing the Catalog Dictionary of a PDF file.
|
289
|
-
#
|
290
|
-
class Catalog < Dictionary
|
291
|
-
|
292
|
-
include StandardObject
|
293
|
-
|
294
|
-
field :Type, :Type => Name, :Default => :Catalog, :Required => true
|
295
|
-
field :Version, :Type => Name, :Version => "1.4"
|
296
|
-
field :Pages, :Type => Dictionary, :Required => true
|
297
|
-
field :PageLabels, :Type => Dictionary, :Version => "1.3"
|
298
|
-
field :Names, :Type => Dictionary, :Version => "1.2"
|
299
|
-
field :Dests, :Type => Dictionary, :Version => "1.1"
|
300
|
-
field :ViewerPreferences, :Type => Dictionary, :Version => "1.2"
|
301
|
-
field :PageLayout, :Type => Name, :Default => PageLayout::SINGLE
|
302
|
-
field :PageMode, :Type => Name, :Default => PageMode::NONE
|
303
|
-
field :Outlines, :Type => Dictionary
|
304
|
-
field :Threads, :Type => Array, :Version => "1.1"
|
305
|
-
field :OpenAction, :Type => [ Array, Dictionary ], :Version => "1.1"
|
306
|
-
field :AA, :Type => Dictionary, :Version => "1.4"
|
307
|
-
field :URI, :Type => Dictionary, :Version => "1.1"
|
308
|
-
field :AcroForm, :Type => Dictionary, :Version => "1.2"
|
309
|
-
field :Metadata, :Type => Stream, :Version => "1.4"
|
310
|
-
field :StructTreeRoot, :Type => Dictionary, :Version => "1.3"
|
311
|
-
field :MarkInfo, :Type => Dictionary, :Version => "1.4"
|
312
|
-
field :Lang, :Type => String, :Version => "1.4"
|
313
|
-
field :SpiderInfo, :Type => Dictionary, :Version => "1.3"
|
314
|
-
field :OutputIntents, :Type => Array, :Version => "1.4"
|
315
|
-
field :PieceInfo, :Type => Dictionary, :Version => "1.4"
|
316
|
-
field :OCProperties, :Type => Dictionary, :Version => "1.5"
|
317
|
-
field :Perms, :Type => Dictionary, :Version => "1.5"
|
318
|
-
field :Legal, :Type => Dictionary, :Version => "1.5"
|
319
|
-
field :Requirements, :Type => Array, :Version => "1.7"
|
320
|
-
field :Collection, :Type => Dictionary, :Version => "1.7"
|
321
|
-
field :NeedsRendering, :Type => Boolean, :Version => "1.7", :Default => false
|
322
|
-
field :Extensions, :Type => Dictionary, :Version => "1.7", :ExtensionLevel => 3
|
323
|
-
|
324
|
-
def initialize(hash = {})
|
325
|
-
set_indirect(true)
|
326
|
-
|
327
|
-
super(hash)
|
328
|
-
end
|
329
|
-
|
330
|
-
end
|
331
|
-
|
332
287
|
#
|
333
288
|
# Class representing additional actions which can be associated with a Catalog.
|
334
289
|
#
|
@@ -482,4 +437,49 @@ module Origami
|
|
482
437
|
|
483
438
|
end
|
484
439
|
|
440
|
+
#
|
441
|
+
# Class representing the Catalog Dictionary of a PDF file.
|
442
|
+
#
|
443
|
+
class Catalog < Dictionary
|
444
|
+
|
445
|
+
include StandardObject
|
446
|
+
|
447
|
+
field :Type, :Type => Name, :Default => :Catalog, :Required => true
|
448
|
+
field :Version, :Type => Name, :Version => "1.4"
|
449
|
+
field :Pages, :Type => Dictionary, :Required => true
|
450
|
+
field :PageLabels, :Type => Dictionary, :Version => "1.3"
|
451
|
+
field :Names, :Type => Dictionary, :Version => "1.2"
|
452
|
+
field :Dests, :Type => Dictionary, :Version => "1.1"
|
453
|
+
field :ViewerPreferences, :Type => ViewerPreferences, :Version => "1.2"
|
454
|
+
field :PageLayout, :Type => Name, :Default => PageLayout::SINGLE
|
455
|
+
field :PageMode, :Type => Name, :Default => PageMode::NONE
|
456
|
+
field :Outlines, :Type => Dictionary
|
457
|
+
field :Threads, :Type => Array, :Version => "1.1"
|
458
|
+
field :OpenAction, :Type => [ Array, Dictionary ], :Version => "1.1"
|
459
|
+
field :AA, :Type => Dictionary, :Version => "1.4"
|
460
|
+
field :URI, :Type => Dictionary, :Version => "1.1"
|
461
|
+
field :AcroForm, :Type => Dictionary, :Version => "1.2"
|
462
|
+
field :Metadata, :Type => Stream, :Version => "1.4"
|
463
|
+
field :StructTreeRoot, :Type => Dictionary, :Version => "1.3"
|
464
|
+
field :MarkInfo, :Type => Dictionary, :Version => "1.4"
|
465
|
+
field :Lang, :Type => String, :Version => "1.4"
|
466
|
+
field :SpiderInfo, :Type => Dictionary, :Version => "1.3"
|
467
|
+
field :OutputIntents, :Type => Array, :Version => "1.4"
|
468
|
+
field :PieceInfo, :Type => Dictionary, :Version => "1.4"
|
469
|
+
field :OCProperties, :Type => Dictionary, :Version => "1.5"
|
470
|
+
field :Perms, :Type => Dictionary, :Version => "1.5"
|
471
|
+
field :Legal, :Type => Dictionary, :Version => "1.5"
|
472
|
+
field :Requirements, :Type => Array, :Version => "1.7"
|
473
|
+
field :Collection, :Type => Dictionary, :Version => "1.7"
|
474
|
+
field :NeedsRendering, :Type => Boolean, :Version => "1.7", :Default => false
|
475
|
+
field :Extensions, :Type => Dictionary, :Version => "1.7", :ExtensionLevel => 3
|
476
|
+
|
477
|
+
def initialize(hash = {})
|
478
|
+
set_indirect(true)
|
479
|
+
|
480
|
+
super(hash)
|
481
|
+
end
|
482
|
+
|
483
|
+
end
|
484
|
+
|
485
485
|
end
|
data/lib/origami/dictionary.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
=begin
|
2
|
-
|
3
2
|
= File
|
4
3
|
dictionary.rb
|
5
4
|
|
@@ -39,6 +38,7 @@ module Origami
|
|
39
38
|
@@regexp_open = Regexp.new(WHITESPACES + Regexp.escape(TOKENS.first) + WHITESPACES)
|
40
39
|
@@regexp_close = Regexp.new(WHITESPACES + Regexp.escape(TOKENS.last) + WHITESPACES)
|
41
40
|
|
41
|
+
@@cast_fingerprints = {}
|
42
42
|
attr_reader :strings_cache, :names_cache, :xref_cache
|
43
43
|
|
44
44
|
#
|
@@ -76,7 +76,7 @@ module Origami
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
def self.parse(stream) #:nodoc:
|
79
|
+
def self.parse(stream, parser = nil) #:nodoc:
|
80
80
|
|
81
81
|
offset = stream.pos
|
82
82
|
|
@@ -86,28 +86,44 @@ module Origami
|
|
86
86
|
|
87
87
|
pairs = {}
|
88
88
|
while stream.skip(@@regexp_close).nil? do
|
89
|
-
key = Name.parse(stream)
|
89
|
+
key = Name.parse(stream, parser)
|
90
90
|
|
91
91
|
type = Object.typeof(stream)
|
92
92
|
if type.nil?
|
93
93
|
raise InvalidDictionaryObjectError, "Invalid object for field #{key.to_s}"
|
94
94
|
end
|
95
|
-
value = type.parse(stream)
|
96
95
|
|
96
|
+
value = type.parse(stream, parser)
|
97
97
|
pairs[key] = value
|
98
98
|
end
|
99
99
|
|
100
100
|
dict =
|
101
101
|
if Origami::OPTIONS[:enable_type_guessing]
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
guessed_type = self.guess_type(pairs)
|
103
|
+
|
104
|
+
if Origami::OPTIONS[:enable_type_propagation]
|
105
|
+
guessed_type.new(
|
106
|
+
Hash[
|
107
|
+
pairs.map {|key, value|
|
108
|
+
hint_type = guessed_type.hint_type(key.value)
|
109
|
+
if hint_type.is_a?(::Array) and not value.is_a?(Reference) # Choose best match
|
110
|
+
hint_type.find {|type| type.native_type == value.native_type}
|
111
|
+
end
|
112
|
+
|
113
|
+
if hint_type.is_a?(Class) and hint_type.native_type == value.native_type
|
114
|
+
[key, value.cast_to(hint_type)]
|
115
|
+
elsif hint_type and value.is_a?(Reference) and parser
|
116
|
+
parser.defer_type_cast(value, hint_type)
|
117
|
+
[key, value]
|
118
|
+
else
|
119
|
+
[key, value]
|
120
|
+
end
|
121
|
+
}])
|
105
122
|
else
|
106
|
-
|
123
|
+
guessed_type.new(pairs)
|
107
124
|
end
|
108
|
-
|
109
125
|
else
|
110
|
-
|
126
|
+
self.new(pairs)
|
111
127
|
end
|
112
128
|
|
113
129
|
dict.file_offset = offset
|
@@ -117,7 +133,7 @@ module Origami
|
|
117
133
|
|
118
134
|
alias to_h to_hash
|
119
135
|
|
120
|
-
def to_s(indent = 1)
|
136
|
+
def to_s(indent = 1) #:nodoc:
|
121
137
|
if indent > 0
|
122
138
|
content = TOKENS.first + EOL
|
123
139
|
self.each_pair do |key,value|
|
@@ -177,9 +193,26 @@ module Origami
|
|
177
193
|
super(key.to_o)
|
178
194
|
end
|
179
195
|
|
180
|
-
|
196
|
+
def cast_to(type)
|
197
|
+
super(type)
|
198
|
+
|
199
|
+
cast = type.new(self)
|
200
|
+
cast.parent = self.parent
|
201
|
+
cast.no, cast.generation = self.no, self.generation
|
202
|
+
if self.is_indirect?
|
203
|
+
cast.set_indirect(true)
|
204
|
+
cast.set_pdf(self.pdf)
|
205
|
+
cast.file_offset = self.file_offset # cast can replace self
|
206
|
+
end
|
181
207
|
|
182
|
-
|
208
|
+
cast.xref_cache.update(self.xref_cache)
|
209
|
+
cast.names_cache.concat(self.names_cache)
|
210
|
+
cast.strings_cache.concat(self.strings_cache)
|
211
|
+
|
212
|
+
cast
|
213
|
+
end
|
214
|
+
|
215
|
+
alias each each_value
|
183
216
|
|
184
217
|
alias value to_h
|
185
218
|
|
@@ -194,6 +227,46 @@ module Origami
|
|
194
227
|
end
|
195
228
|
end
|
196
229
|
|
230
|
+
def copy
|
231
|
+
copy = self.class.new
|
232
|
+
self.each_pair do |k,v|
|
233
|
+
copy[k] = v.copy
|
234
|
+
end
|
235
|
+
|
236
|
+
copy.parent = @parent
|
237
|
+
copy.no, copy.generation = @no, @generation
|
238
|
+
copy.set_indirect(true) if is_indirect?
|
239
|
+
copy.set_pdf(@pdf) if is_indirect?
|
240
|
+
copy
|
241
|
+
end
|
242
|
+
|
243
|
+
def self.native_type; Dictionary end
|
244
|
+
|
245
|
+
def self.add_type_info(typeclass, key, value) #:nodoc:
|
246
|
+
if not @@cast_fingerprints.has_key?(typeclass) and typeclass.superclass != Dictionary and
|
247
|
+
@@cast_fingerprints.has_key?(typeclass.superclass)
|
248
|
+
@@cast_fingerprints[typeclass] = @@cast_fingerprints[typeclass.superclass].dup
|
249
|
+
end
|
250
|
+
|
251
|
+
@@cast_fingerprints[typeclass] ||= {}
|
252
|
+
@@cast_fingerprints[typeclass][key.to_o] = value.to_o
|
253
|
+
end
|
254
|
+
|
255
|
+
def self.guess_type(hash) #:nodoc:
|
256
|
+
best_type = self
|
257
|
+
|
258
|
+
@@cast_fingerprints.each_pair do |typeclass, keys|
|
259
|
+
best_type = typeclass if keys.all? { |k,v|
|
260
|
+
hash.has_key?(k) and hash[k] == v
|
261
|
+
} and typeclass < best_type
|
262
|
+
end
|
263
|
+
|
264
|
+
best_type
|
265
|
+
end
|
266
|
+
|
267
|
+
def self.hint_type(name); nil end #:nodoc:
|
268
|
+
|
197
269
|
end #class
|
198
270
|
|
199
|
-
end
|
271
|
+
end
|
272
|
+
# Origami
|
data/lib/origami/encryption.rb
CHANGED
@@ -23,6 +23,12 @@
|
|
23
23
|
|
24
24
|
=end
|
25
25
|
|
26
|
+
begin
|
27
|
+
require 'openssl' if Origami::OPTIONS[:use_openssl]
|
28
|
+
rescue LoadError
|
29
|
+
Origami::OPTIONS[:use_openssl] = false
|
30
|
+
end
|
31
|
+
|
26
32
|
require 'digest/md5'
|
27
33
|
require 'digest/sha2'
|
28
34
|
|
@@ -163,20 +169,18 @@ module Origami
|
|
163
169
|
obj.equal?(encrypt_dict[:Perms]) or
|
164
170
|
(obj.parent.is_a?(Signature::DigitalSignature) and obj.equal?(obj.parent[:Contents]))
|
165
171
|
|
166
|
-
obj.extend(Encryption::EncryptedString)
|
172
|
+
obj.extend(Encryption::EncryptedString) unless obj.is_a?(Encryption::EncryptedString)
|
167
173
|
obj.encryption_handler = handler
|
168
174
|
obj.encryption_key = encryption_key
|
169
175
|
obj.algorithm = str_algo
|
170
|
-
obj.decrypted = false
|
171
176
|
obj.decrypt!
|
172
177
|
|
173
178
|
when Stream
|
174
179
|
next if obj.is_a?(XRefStream) or (not encrypt_metadata and obj.equal?(metadata))
|
175
|
-
obj.extend(Encryption::EncryptedStream)
|
180
|
+
obj.extend(Encryption::EncryptedStream) unless obj.is_a?(Encryption::EncryptedStream)
|
176
181
|
obj.encryption_handler = handler
|
177
182
|
obj.encryption_key = encryption_key
|
178
183
|
obj.algorithm = stm_algo
|
179
|
-
obj.decrypted = false
|
180
184
|
end
|
181
185
|
end
|
182
186
|
end
|
@@ -293,6 +297,26 @@ module Origami
|
|
293
297
|
#
|
294
298
|
module Encryption
|
295
299
|
|
300
|
+
#
|
301
|
+
# Generates _n_ random bytes from a fast PRNG.
|
302
|
+
#
|
303
|
+
def self.rand_bytes(n)
|
304
|
+
::Array.new(n) { rand(256) }.pack("C*")
|
305
|
+
end
|
306
|
+
|
307
|
+
#
|
308
|
+
# Generates _n_ random bytes from a crypto PRNG.
|
309
|
+
#
|
310
|
+
def self.strong_rand_bytes(n)
|
311
|
+
if Origami::OPTIONS[:use_openssl]
|
312
|
+
OpenSSL::Random.random_bytes(n)
|
313
|
+
elsif RUBY_VERSION >= '1.9'
|
314
|
+
Random.new.bytes(n)
|
315
|
+
else
|
316
|
+
self.rand_bytes(n)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
296
320
|
module EncryptedDocument
|
297
321
|
|
298
322
|
attr_writer :encryption_key
|
@@ -442,7 +466,7 @@ module Origami
|
|
442
466
|
if @algorithm == ARC4 or @algorithm == Identity
|
443
467
|
@algorithm.encrypt(key, self.value)
|
444
468
|
else
|
445
|
-
iv =
|
469
|
+
iv = Encryption.rand_bytes(AES::BLOCKSIZE)
|
446
470
|
@algorithm.encrypt(key, iv, self.value)
|
447
471
|
end
|
448
472
|
|
@@ -482,7 +506,7 @@ module Origami
|
|
482
506
|
if @algorithm == ARC4 or @algorithm == Identity
|
483
507
|
@algorithm.encrypt(key, self.rawdata)
|
484
508
|
else
|
485
|
-
iv =
|
509
|
+
iv = Encryption.rand_bytes(AES::BLOCKSIZE)
|
486
510
|
@algorithm.encrypt(key, iv, @rawdata)
|
487
511
|
end
|
488
512
|
|
@@ -1043,6 +1067,7 @@ module Origami
|
|
1043
1067
|
module Standard
|
1044
1068
|
|
1045
1069
|
PADDING = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A" #:nodoc:
|
1070
|
+
PADDING.force_encoding('binary') if RUBY_VERSION > '1.8'
|
1046
1071
|
|
1047
1072
|
#
|
1048
1073
|
# Permission constants for encrypted documents.
|
@@ -1090,6 +1115,7 @@ module Origami
|
|
1090
1115
|
|
1091
1116
|
if self.R < 5
|
1092
1117
|
padded = pad_password(userpassword)
|
1118
|
+
padded.force_encoding('binary') if RUBY_VERSION > '1.8'
|
1093
1119
|
|
1094
1120
|
padded << self.O
|
1095
1121
|
padded << [ self.P ].pack("i")
|
@@ -1097,7 +1123,7 @@ module Origami
|
|
1097
1123
|
padded << fileid
|
1098
1124
|
|
1099
1125
|
encrypt_metadata = self.EncryptMetadata != false
|
1100
|
-
padded << "
|
1126
|
+
padded << [ -1 ].pack("i") if self.R >= 4 and not encrypt_metadata
|
1101
1127
|
|
1102
1128
|
key = Digest::MD5.digest(padded)
|
1103
1129
|
|
@@ -1135,9 +1161,9 @@ module Origami
|
|
1135
1161
|
oks = self.O[40, 8]
|
1136
1162
|
|
1137
1163
|
if self.R == 5
|
1138
|
-
okey = Digest::SHA256.digest(passwd + oks)
|
1164
|
+
okey = Digest::SHA256.digest(passwd + oks + self.U)
|
1139
1165
|
else
|
1140
|
-
okey = compute_hardened_hash(passwd, oks)
|
1166
|
+
okey = compute_hardened_hash(passwd, oks, self.U)
|
1141
1167
|
end
|
1142
1168
|
|
1143
1169
|
iv = ::Array.new(AES::BLOCKSIZE, 0).pack("C*")
|
@@ -1163,35 +1189,31 @@ module Origami
|
|
1163
1189
|
upass = password_to_utf8(userpassword)
|
1164
1190
|
opass = password_to_utf8(ownerpassword)
|
1165
1191
|
|
1166
|
-
uvs, uks, ovs, oks = ::Array.new(4) {
|
1167
|
-
file_key =
|
1192
|
+
uvs, uks, ovs, oks = ::Array.new(4) { Encryption.rand_bytes(8) }
|
1193
|
+
file_key = Encryption.strong_rand_bytes(32)
|
1168
1194
|
iv = ::Array.new(AES::BLOCKSIZE, 0).pack("C*")
|
1169
1195
|
|
1170
1196
|
if self.R == 5
|
1197
|
+
self.U = Digest::SHA256.digest(upass + uvs) + uvs + uks
|
1198
|
+
self.O = Digest::SHA256.digest(opass + ovs + self.U) + ovs + oks
|
1171
1199
|
ukey = Digest::SHA256.digest(upass + uks)
|
1172
|
-
okey = Digest::SHA256.digest(opass + oks)
|
1200
|
+
okey = Digest::SHA256.digest(opass + oks + self.U)
|
1173
1201
|
else
|
1202
|
+
self.U = compute_hardened_hash(upass, uvs) + uvs + uks
|
1203
|
+
self.O = compute_hardened_hash(opass, ovs, self.U) + ovs + oks
|
1174
1204
|
ukey = compute_hardened_hash(upass, uks)
|
1175
|
-
okey = compute_hardened_hash(
|
1205
|
+
okey = compute_hardened_hash(opass, oks, self.U)
|
1176
1206
|
end
|
1177
1207
|
|
1178
1208
|
self.UE = AES.new(ukey, iv, false).encrypt(file_key)[iv.size, 32]
|
1179
1209
|
self.OE = AES.new(okey, iv, false).encrypt(file_key)[iv.size, 32]
|
1180
|
-
|
1181
|
-
if self.R == 5
|
1182
|
-
self.U = Digest::SHA256.digest(upass + uvs) + uvs + uks
|
1183
|
-
self.O = Digest::SHA256.digest(opass + ovs + self.U) + ovs + oks
|
1184
|
-
else
|
1185
|
-
self.U = compute_hardened_hash(upass, uvs) + uvs + uks
|
1186
|
-
self.O = compute_hardened_hash(opass, ovs, self.U) + ovs + oks
|
1187
|
-
end
|
1188
1210
|
|
1189
1211
|
perms =
|
1190
1212
|
[ self.P ].pack("V") + # 0-3
|
1191
|
-
"
|
1213
|
+
[ -1 ].pack("V") + # 4-7
|
1192
1214
|
(self.EncryptMetadata == true ? "T" : "F") + # 8
|
1193
1215
|
"adb" + # 9-11
|
1194
|
-
"
|
1216
|
+
[ 0 ].pack("V") # 12-15
|
1195
1217
|
|
1196
1218
|
self.Perms = AES.new(file_key, iv, false).encrypt(perms)[iv.size, 16]
|
1197
1219
|
|
@@ -1294,7 +1316,7 @@ module Origami
|
|
1294
1316
|
|
1295
1317
|
19.times { |i| user_key = ARC4.encrypt(xor(key,i+1), user_key) }
|
1296
1318
|
|
1297
|
-
user_key.ljust(32,
|
1319
|
+
user_key.ljust(32, 0xFF.chr)
|
1298
1320
|
end
|
1299
1321
|
end
|
1300
1322
|
|
data/lib/origami/file.rb
CHANGED
@@ -182,8 +182,7 @@ module Origami
|
|
182
182
|
# A class representing a file outside the current PDF file.
|
183
183
|
#
|
184
184
|
class ExternalFile < FileSpec
|
185
|
-
|
186
|
-
field :Type, :Type => Name, :Default => :FileSpec, :Required => true
|
185
|
+
field :Type, :Type => Name, :Default => :FileSpec #, :Required => true
|
187
186
|
|
188
187
|
#
|
189
188
|
# Creates a new external file specification.
|