Beispiel #1
0
 def init_params(self):
     self.v = int_value(self.param.get('V', 0))
     self.r = int_value(self.param['R'])
     self.p = int_value(self.param['P'])
     self.o = str_value(self.param['O'])
     self.u = str_value(self.param['U'])
     self.length = int_value(self.param.get('Length', 40))
Beispiel #2
0
 def create_widget(obj):
     if 'Subtype' in obj and obj.get('Subtype') is LITERAL_WIDGET:
         wtype = get_widget_type(obj)
         if wtype:
             return LTWidget(list_value(obj.get('Rect')), wtype, str_value(obj.get('T')))
         elif 'Parent' in obj:
             p = resolve1(obj.get('Parent'))
             return LTWidget(list_value(obj.get('Rect')), get_widget_type(p), str_value(p.get('T')))
Beispiel #3
0
    def initialize(self, password=''):
        """Perform the initialization with a given password.

        This step is mandatory even if there's no password associated with the document.
        """
        if not self.encryption:
            self.is_printable = self.is_modifiable = self.is_extractable = True
            return
        (docid, param) = self.encryption
        if literal_name(param.get('Filter')) != 'Standard':
            raise PDFEncryptionError('Unknown filter: param=%r' % param)
        V = int_value(param.get('V', 0))
        if not (V == 1 or V == 2):
            raise PDFEncryptionError('Unknown algorithm: param=%r' % param)
        length = int_value(param.get('Length', 40))  # Key length (bits)
        O = str_value(param['O'])
        R = int_value(param['R'])  # Revision
        if 5 <= R:
            raise PDFEncryptionError('Unknown revision: %r' % R)
        U = str_value(param['U'])
        P = int_value(param['P'])
        self.is_printable = bool(P & 4)
        self.is_modifiable = bool(P & 8)
        self.is_extractable = bool(P & 16)
        # Algorithm 3.2
        password = (password + self.PASSWORD_PADDING)[:32]  # 1
        md5hash = md5.md5(password)  # 2
        md5hash.update(O)  # 3
        md5hash.update(struct.pack('<l', P))  # 4
        md5hash.update(docid[0])  # 5
        if 4 <= R:
            # 6
            raise PDFNotImplementedError('Revision 4 encryption is currently unsupported')
        if 3 <= R:
            # 8
            for _ in xrange(50):
                md5hash = md5.md5(md5hash.digest()[:length / 8])
        key = md5hash.digest()[:length / 8]
        if R == 2:
            # Algorithm 3.4
            u1 = Arcfour(key).process(self.PASSWORD_PADDING)
        elif R == 3:
            # Algorithm 3.5
            md5hash = md5.md5(self.PASSWORD_PADDING)  # 2
            md5hash.update(docid[0])  # 3
            x = Arcfour(key).process(md5hash.digest()[:16])  # 4
            for i in xrange(1, 19 + 1):
                k = ''.join(chr(ord(c) ^ i) for c in key)
                x = Arcfour(k).process(x)
            u1 = x + x  # 32bytes total
        if R == 2:
            is_authenticated = (u1 == U)
        else:
            is_authenticated = (u1[:16] == U[:16])
        if not is_authenticated:
            raise PDFPasswordIncorrect
        self.decrypt_key = key
        self.decipher = self.decrypt_rc4  # XXX may be AES
Beispiel #4
0
 def initialize(self, password=''):
     if not self.encryption:
         self.is_printable = self.is_modifiable = self.is_extractable = True
         self._initialized = True
         return
     (docid, param) = self.encryption
     if literal_name(param['Filter']) != 'Standard':
         raise PDFEncryptionError('Unknown filter: param=%r' % param)
     V = int_value(param.get('V', 0))
     if not (V == 1 or V == 2):
         raise PDFEncryptionError('Unknown algorithm: param=%r' % param)
     length = int_value(param.get('Length', 40))  # Key length (bits)
     O = str_value(param['O'])
     R = int_value(param['R'])  # Revision
     if 5 <= R:
         raise PDFEncryptionError('Unknown revision: %r' % R)
     U = str_value(param['U'])
     P = int_value(param['P'])
     self.is_printable = bool(P & 4)
     self.is_modifiable = bool(P & 8)
     self.is_extractable = bool(P & 16)
     # Algorithm 3.2
     password = (password + self.PASSWORD_PADDING)[:32]  # 1
     hash = md5.md5(password)  # 2
     hash.update(O)  # 3
     hash.update(struct.pack('<l', P))  # 4
     hash.update(docid[0])  # 5
     if 4 <= R:
         # 6
         raise PDFNotImplementedError(
             'Revision 4 encryption is currently unsupported')
     if 3 <= R:
         # 8
         for _ in xrange(50):
             hash = md5.md5(hash.digest()[:length / 8])
     key = hash.digest()[:length / 8]
     if R == 2:
         # Algorithm 3.4
         u1 = Arcfour(key).process(self.PASSWORD_PADDING)
     elif R == 3:
         # Algorithm 3.5
         hash = md5.md5(self.PASSWORD_PADDING)  # 2
         hash.update(docid[0])  # 3
         x = Arcfour(key).process(hash.digest()[:16])  # 4
         for i in xrange(1, 19 + 1):
             k = ''.join(chr(ord(c) ^ i) for c in key)
             x = Arcfour(k).process(x)
         u1 = x + x  # 32bytes total
     if R == 2:
         is_authenticated = (u1 == U)
     else:
         is_authenticated = (u1[:16] == U[:16])
     if not is_authenticated:
         raise PDFPasswordIncorrect
     self.decrypt_key = key
     self.decipher = self.decrypt_rc4  # XXX may be AES
     self._initialized = True
     return
Beispiel #5
0
 def init_params(self):
     super(PDFStandardSecurityHandlerV5, self).init_params()
     self.length = 256
     self.oe = str_value(self.param['OE'])
     self.ue = str_value(self.param['UE'])
     self.o_hash = self.o[:32]
     self.o_validation_salt = self.o[32:40]
     self.o_key_salt = self.o[40:]
     self.u_hash = self.u[:32]
     self.u_validation_salt = self.u[32:40]
     self.u_key_salt = self.u[40:]
Beispiel #6
0
 def search(entry, level):
     entry = dict_value(entry)
     if 'Title' in entry:
         if 'A' in entry or 'Dest' in entry:
             title = decode_text(str_value(entry['Title']))
             dest = entry.get('Dest')
             action = entry.get('A')
             se = entry.get('SE')
             yield (level, title, dest, action, se)
     if 'First' in entry and 'Last' in entry:
         for x in search(entry['First'], level + 1):
             yield x
     if 'Next' in entry:
         for x in search(entry['Next'], level):
             yield x
     return
Beispiel #7
0
 def search(entry, level):
     entry = dict_value(entry)
     if 'Title' in entry:
         if 'A' in entry or 'Dest' in entry:
             title = decode_text(str_value(entry['Title']))
             dest = entry.get('Dest')
             action = entry.get('A')
             se = entry.get('SE')
             yield (level, title, dest, action, se)
     if 'First' in entry and 'Last' in entry:
         for x in search(entry['First'], level+1):
             yield x
     if 'Next' in entry:
         for x in search(entry['Next'], level):
             yield x
     return