MCPcopy Index your code
hub / github.com/clips/pattern / initialize

Method initialize

pattern/web/pdf/pdfparser.py:344–398  ·  view source on GitHub ↗
(self, password='')

Source from the content-addressed store, hash-verified

342 # with the document.
343 PASSWORD_PADDING = '(\xbfN^Nu\x8aAd\x00NV\xff\xfa\x01\x08..\x00\xb6\xd0h>\x80/\x0c\xa9\xfedSiz'
344 def initialize(self, password=''):
345 if not self.encryption:
346 self.is_printable = self.is_modifiable = self.is_extractable = True
347 return
348 (docid, param) = self.encryption
349 if literal_name(param.get('Filter')) != 'Standard':
350 raise PDFEncryptionError('Unknown filter: param=%r' % param)
351 V = int_value(param.get('V', 0))
352 if not (V == 1 or V == 2):
353 raise PDFEncryptionError('Unknown algorithm: param=%r' % param)
354 length = int_value(param.get('Length', 40)) # Key length (bits)
355 O = str_value(param['O'])
356 R = int_value(param['R']) # Revision
357 if 5 <= R:
358 raise PDFEncryptionError('Unknown revision: %r' % R)
359 U = str_value(param['U'])
360 P = int_value(param['P'])
361 self.is_printable = bool(P & 4)
362 self.is_modifiable = bool(P & 8)
363 self.is_extractable = bool(P & 16)
364 # Algorithm 3.2
365 password = (password+self.PASSWORD_PADDING)[:32] # 1
366 hash = md5.md5(password) # 2
367 hash.update(O) # 3
368 hash.update(struct.pack('<l', P)) # 4
369 hash.update(docid[0]) # 5
370 if 4 <= R:
371 # 6
372 raise PDFNotImplementedError('Revision 4 encryption is currently unsupported')
373 if 3 <= R:
374 # 8
375 for _ in xrange(50):
376 hash = md5.md5(hash.digest()[:length/8])
377 key = hash.digest()[:length/8]
378 if R == 2:
379 # Algorithm 3.4
380 u1 = Arcfour(key).process(self.PASSWORD_PADDING)
381 elif R == 3:
382 # Algorithm 3.5
383 hash = md5.md5(self.PASSWORD_PADDING) # 2
384 hash.update(docid[0]) # 3
385 x = Arcfour(key).process(hash.digest()[:16]) # 4
386 for i in xrange(1,19+1):
387 k = ''.join( chr(ord(c) ^ i) for c in key )
388 x = Arcfour(k).process(x)
389 u1 = x+x # 32bytes total
390 if R == 2:
391 is_authenticated = (u1 == U)
392 else:
393 is_authenticated = (u1[:16] == U[:16])
394 if not is_authenticated:
395 raise PDFPasswordIncorrect
396 self.decrypt_key = key
397 self.decipher = self.decrypt_rc4 # XXX may be AES
398 return
399
400 def decrypt_rc4(self, objid, genno, data):
401 key = self.decrypt_key + struct.pack('<L',objid)[:3]+struct.pack('<L',genno)[:2]

Callers 1

process_pdfFunction · 0.95

Calls 9

literal_nameFunction · 0.90
int_valueFunction · 0.90
str_valueFunction · 0.90
ArcfourClass · 0.90
PDFEncryptionErrorClass · 0.85
processMethod · 0.80
getMethod · 0.45
updateMethod · 0.45

Tested by

no test coverage detected