]> xmof Git - DeDRM.git/commitdiff
Python 3 fixes
authorAldo Bleeker <mail@ableeker.demon.nl>
Sun, 22 Nov 2020 15:03:45 +0000 (16:03 +0100)
committerAldo Bleeker <mail@ableeker.demon.nl>
Sun, 22 Nov 2020 15:03:45 +0000 (16:03 +0100)
DeDRM_plugin/androidkindlekey.py [changed mode: 0644->0755]
DeDRM_plugin/config.py
DeDRM_plugin/erdr2pml.py
DeDRM_plugin/ineptepub.py [changed mode: 0644->0755]
DeDRM_plugin/prefs.py [changed mode: 0644->0755]
DeDRM_plugin/zipfilerugged.py [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 0e4b648..2949535
@@ -136,7 +136,7 @@ class AndroidObfuscationV2(AndroidObfuscation):
     '''
 
     count = 503
-    password = 'Thomsun was here!'
+    password = b'Thomsun was here!'
 
     def __init__(self, salt):
         key = self.password + salt
@@ -182,7 +182,7 @@ def get_serials1(path=STORAGE1):
         obfuscation = AndroidObfuscation()
 
     def get_value(key):
-        encrypted_key = obfuscation.encrypt(key)
+        encrypted_key = obfuscation.encrypt(a2b_hex(key))
         encrypted_value = storage.get(encrypted_key)
         if encrypted_value:
             return obfuscation.decrypt(encrypted_value)
@@ -217,15 +217,14 @@ def get_serials2(path=STORAGE2):
     import sqlite3
     connection = sqlite3.connect(path)
     cursor = connection.cursor()
-    cursor.execute('''select userdata_value from userdata where userdata_key like '%/%token.device.deviceserialname%' ''')
-    userdata_keys = cursor.fetchall()
+    cursor.execute('''select device_data_value from device_data where device_data_key like '%serial.number%' ''')
+    device_data_keys = cursor.fetchall()
     dsns = []
-    for userdata_row in userdata_keys:
+    for device_data_row in device_data_keys:
         try:
-            if userdata_row and userdata_row[0]:
-                userdata_utf8 = userdata_row[0].encode('utf8')
-                if len(userdata_utf8) > 0:
-                    dsns.append(userdata_utf8)
+            if device_data_row and device_data_row[0]:
+                if len(device_data_row[0]) > 0:
+                    dsns.append(device_data_row[0])
         except:
             print("Error getting one of the device serial name keys")
             traceback.print_exc()
@@ -238,9 +237,12 @@ def get_serials2(path=STORAGE2):
     for userdata_row in userdata_keys:
         try:
             if userdata_row and userdata_row[0]:
-                userdata_utf8 = userdata_row[0].encode('utf8')
-                if len(userdata_utf8) > 0:
-                    tokens.append(userdata_utf8)
+                if len(userdata_row[0]) > 0:
+                    if ',' in userdata_row[0]:
+                        splits = userdata_row[0].split(',')
+                        for split in splits:
+                            tokens.append(split)
+                    tokens.append(userdata_row[0])
         except:
             print("Error getting one of the account token keys")
             traceback.print_exc()
@@ -249,11 +251,10 @@ def get_serials2(path=STORAGE2):
 
     serials = []
     for x in dsns:
-        serials.append(x)
         for y in tokens:
-            serials.append('%s%s' % (x, y))
-    for y in tokens:
-        serials.append(y)
+            serials.append(x)
+            serials.append(y)
+            serials.append(x+y)
     return serials
 
 def get_serials(path=STORAGE):
@@ -275,7 +276,7 @@ def get_serials(path=STORAGE):
     try :
         read = open(path, 'rb')
         head = read.read(24)
-        if head[:14] == 'ANDROID BACKUP':
+        if head[:14] == b'ANDROID BACKUP':
             output = StringIO(zlib.decompress(read.read()))
     except Exception:
         pass
@@ -313,7 +314,7 @@ def getkey(outfile, inpath):
     if len(keys) > 0:
         with open(outfile, 'w') as keyfileout:
             for key in keys:
-                keyfileout.write(key)
+                keyfileout.write(b2a_hex(key))
                 keyfileout.write("\n")
         return True
     return False
index c81b6154e1037ba9e29cd3aecf36627ef859c570..c701c4a2e08747d134b1339dd4c3f51a13b3ff11 100755 (executable)
@@ -6,7 +6,7 @@ __license__ = 'GPL v3'
 # Python 3, September 2020
 
 # Standard Python modules.
-import os, traceback, json, binascii
+import os, traceback, json, codecs
 
 from PyQt5.Qt import (Qt, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QLineEdit,
                       QGroupBox, QPushButton, QListWidget, QListWidgetItem,
@@ -378,7 +378,7 @@ class ManageKeysDialog(QDialog):
                 with open(fpath,'rb') as keyfile:
                     new_key_value = keyfile.read()
                 if self.binary_file:
-                    new_key_value = binascii.b2a_hex(new_key_value)
+                    new_key_value = codecs.encode(new_key_value,'hex')
                 elif self.json_file:
                     new_key_value = json.loads(new_key_value)
                 elif self.android_file:
@@ -433,18 +433,18 @@ class ManageKeysDialog(QDialog):
         if filename:
             if self.binary_file:
                 with open(filename, 'wb') as fname:
-                    fname.write(binascii.a2b_hex(self.plugin_keys[keyname]))
+                    fname.write(codecs.decode(self.plugin_keys[keyname],'hex'))
             elif self.json_file:
                 with open(filename, 'w') as fname:
                     fname.write(json.dumps(self.plugin_keys[keyname]))
             elif self.android_file:
                 with open(filename, 'w') as fname:
                     for key in self.plugin_keys[keyname]:
-                        fname.write(key.decode('utf-8'))
+                        fname.write(key)
                         fname.write('\n')
             else:
                 with open(filename, 'w') as fname:
-                    fname.write(self.plugin_keys[keyname].decode('utf-8'))
+                    fname.write(self.plugin_keys[keyname])
 
 
 
@@ -673,7 +673,7 @@ class AddEReaderDialog(QDialog):
     @property
     def key_value(self):
         from calibre_plugins.dedrm.erdr2pml import getuser_key as generate_ereader_key
-        return binascii.b2a_hex(generate_ereader_key(self.user_name, self.cc_number))
+        return codecs.encode(generate_ereader_key(self.user_name, self.cc_number),'hex')
 
     @property
     def user_name(self):
@@ -755,7 +755,7 @@ class AddAdeptDialog(QDialog):
 
     @property
     def key_value(self):
-        return binascii.b2a_hex(self.default_key)
+        return codecs.encode(self.default_key,'hex')
 
 
     def accept(self):
index 84a40010b311c00da24dc023ad110865d014923d..5cc395fed23719ffa5bf7ee1abaaf2c72ad40895 100755 (executable)
@@ -542,7 +542,7 @@ def usage():
     print("  It's enough to enter the last 8 digits of the credit card number")
     return
 
-def getuser_key(name, cc):
+def getuser_key(name,cc):
     newname = "".join(c for c in name.lower() if c >= 'a' and c <= 'z' or c >= '0' and c <= '9')
     cc = cc.replace(" ","")
     return struct.pack('>LL', binascii.crc32(bytes(newname.encode('utf-8'))) & 0xffffffff, binascii.crc32(bytes(cc[-8:].encode('utf-8'))) & 0xffffffff)
@@ -580,9 +580,9 @@ def cli_main():
     elif len(args)==4:
         infile, outpath, name, cc = args
 
-    print(binascii.b2a_hex(getuser_key(name, cc)))
+    print(binascii.b2a_hex(getuser_key(name,cc)))
 
-    return decryptBook(infile, outpath, make_pmlz, getuser_key(name, cc))
+    return decryptBook(infile, outpath, make_pmlz, getuser_key(name,cc))
 
 
 if __name__ == "__main__":
old mode 100644 (file)
new mode 100755 (executable)
index 1be1a89..8d88733
@@ -203,6 +203,7 @@ def _load_crypto_libcrypto():
 def _load_crypto_pycrypto():
     from Crypto.Cipher import AES as _AES
     from Crypto.PublicKey import RSA as _RSA
+    from Crypto.Cipher import PKCS1_v1_5 as _PKCS1_v1_5
 
     # ASN.1 parsing code from tlslite
     class ASN1Error(Exception):
@@ -294,14 +295,14 @@ def _load_crypto_pycrypto():
 
     class AES(object):
         def __init__(self, key):
-            self._aes = _AES.new(key, _AES.MODE_CBC, '\x00'*16)
+            self._aes = _AES.new(key, _AES.MODE_CBC, b'\x00'*16)
 
         def decrypt(self, data):
             return self._aes.decrypt(data)
 
     class RSA(object):
         def __init__(self, der):
-            key = ASN1Parser([ord(x) for x in der])
+            key = ASN1Parser([x for x in der])
             key = [key.getChild(x).value for x in range(1, 4)]
             key = [self.bytesToNumber(v) for v in key]
             self._rsa = _RSA.construct(key)
@@ -313,7 +314,7 @@ def _load_crypto_pycrypto():
             return total
 
         def decrypt(self, data):
-            return self._rsa.decrypt(data)
+            return _PKCS1_v1_5.new(self._rsa).decrypt(data, 172)
 
     return (AES, RSA)
 
@@ -410,11 +411,14 @@ def decryptBook(userkey, inpath, outpath):
                 return 1
             bookkey = rsa.decrypt(codecs.decode(bookkey.encode('ascii'), 'base64'))
             # Padded as per RSAES-PKCS1-v1_5
-            if bookkey[-17] != '\x00' and bookkey[-17] != 0:
-                print("Could not decrypt {0:s}. Wrong key".format(os.path.basename(inpath)))
-                return 2
+            if len(bookkey) != 16:
+                if bookkey[-17] != '\x00' and bookkey[-17] != 0:
+                    print("Could not decrypt {0:s}. Wrong key".format(os.path.basename(inpath)))
+                    return 2
+                else:
+                    bookkey = bookkey[-16:]
             encryption = inf.read('META-INF/encryption.xml')
-            decryptor = Decryptor(bookkey[-16:], encryption)
+            decryptor = Decryptor(bookkey, encryption)
             kwds = dict(compression=ZIP_DEFLATED, allowZip64=False)
             with closing(ZipFile(open(outpath, 'wb'), 'w', **kwds)) as outf:
                 zi = ZipInfo('mimetype')
@@ -475,9 +479,9 @@ def cli_main():
 def gui_main():
     try:
         import tkinter
-        import tkinter_constants
-        import tkinter_filedialog
-        import tkinter_messagebox
+        import tkinter.constants
+        import tkinter.filedialog
+        import tkinter.messagebox
         import traceback
     except:
         return cli_main()
@@ -486,10 +490,10 @@ def gui_main():
         def __init__(self, root):
             tkinter.Frame.__init__(self, root, border=5)
             self.status = tkinter.Label(self, text="Select files for decryption")
-            self.status.pack(fill=tkinter_constants.X, expand=1)
+            self.status.pack(fill=tkinter.constants.X, expand=1)
             body = tkinter.Frame(self)
-            body.pack(fill=tkinter_constants.X, expand=1)
-            sticky = tkinter_constants.E + tkinter_constants.W
+            body.pack(fill=tkinter.constants.X, expand=1)
+            sticky = tkinter.constants.E + tkinter.constants.W
             body.grid_columnconfigure(1, weight=2)
             tkinter.Label(body, text="Key file").grid(row=0)
             self.keypath = tkinter.Entry(body, width=30)
@@ -512,41 +516,41 @@ def gui_main():
             buttons.pack()
             botton = tkinter.Button(
                 buttons, text="Decrypt", width=10, command=self.decrypt)
-            botton.pack(side=tkinter_constants.LEFT)
-            tkinter.Frame(buttons, width=10).pack(side=tkinter_constants.LEFT)
+            botton.pack(side=tkinter.constants.LEFT)
+            tkinter.Frame(buttons, width=10).pack(side=tkinter.constants.LEFT)
             button = tkinter.Button(
                 buttons, text="Quit", width=10, command=self.quit)
-            button.pack(side=tkinter_constants.RIGHT)
+            button.pack(side=tkinter.constants.RIGHT)
 
         def get_keypath(self):
-            keypath = tkinter_filedialog.askopenfilename(
+            keypath = tkinter.filedialog.askopenfilename(
                 parent=None, title="Select Adobe Adept \'.der\' key file",
                 defaultextension=".der",
                 filetypes=[('Adobe Adept DER-encoded files', '.der'),
                            ('All Files', '.*')])
             if keypath:
                 keypath = os.path.normpath(keypath)
-                self.keypath.delete(0, tkinter_constants.END)
+                self.keypath.delete(0, tkinter.constants.END)
                 self.keypath.insert(0, keypath)
             return
 
         def get_inpath(self):
-            inpath = tkinter_filedialog.askopenfilename(
+            inpath = tkinter.filedialog.askopenfilename(
                 parent=None, title="Select ADEPT-encrypted ePub file to decrypt",
                 defaultextension=".epub", filetypes=[('ePub files', '.epub')])
             if inpath:
                 inpath = os.path.normpath(inpath)
-                self.inpath.delete(0, tkinter_constants.END)
+                self.inpath.delete(0, tkinter.constants.END)
                 self.inpath.insert(0, inpath)
             return
 
         def get_outpath(self):
-            outpath = tkinter_filedialog.asksaveasfilename(
+            outpath = tkinter.filedialog.asksaveasfilename(
                 parent=None, title="Select unencrypted ePub file to produce",
                 defaultextension=".epub", filetypes=[('ePub files', '.epub')])
             if outpath:
                 outpath = os.path.normpath(outpath)
-                self.outpath.delete(0, tkinter_constants.END)
+                self.outpath.delete(0, tkinter.constants.END)
                 self.outpath.insert(0, outpath)
             return
 
@@ -576,13 +580,13 @@ def gui_main():
             if decrypt_status == 0:
                 self.status['text'] = "File successfully decrypted"
             else:
-                self.status['text'] = "The was an error decrypting the file."
+                self.status['text'] = "There was an error decrypting the file."
 
     root = tkinter.Tk()
     root.title("Adobe Adept ePub Decrypter v.{0}".format(__version__))
     root.resizable(True, False)
     root.minsize(300, 0)
-    DecryptionDialog(root).pack(fill=tkinter_constants.X, expand=1)
+    DecryptionDialog(root).pack(fill=tkinter.constants.X, expand=1)
     root.mainloop()
     return 0
 
old mode 100644 (file)
new mode 100755 (executable)
index ee16a30..3e8d78b
@@ -6,7 +6,7 @@ __license__ = 'GPL v3'
 
 # Standard Python modules.
 import os, sys, re, hashlib
-import json
+import codecs, json
 import traceback
 
 from calibre.utils.config import dynamic, config_dir, JSONConfig
@@ -116,7 +116,7 @@ def convertprefs(always = False):
                 name, cc = keystring.split(',')
                 # Generate eReader user key from name and credit card number.
                 keyname = "{0}_{1}".format(name.strip(),cc.strip()[-4:])
-                keyvalue = getuser_key(name,cc).encode('hex')
+                keyvalue = codecs.encode(getuser_key(name,cc),'hex')
                 userkeys.append([keyname,keyvalue])
             except Exception as e:
                 traceback.print_exc()
@@ -146,7 +146,7 @@ def convertprefs(always = False):
                 key = os.path.splitext(filename)[0]
                 value = open(fpath, 'rb').read()
                 if encoding is not None:
-                    value = value.encode(encoding)
+                    value = codecs.encode(value,encoding)
                 userkeys.append([key,value])
             except:
                 traceback.print_exc()
old mode 100644 (file)
new mode 100755 (executable)
index 25aed8a..b2f3762
@@ -286,8 +286,8 @@ class ZipInfo (object):
         # This is used to ensure paths in generated ZIP files always use
         # forward slashes as the directory separator, as required by the
         # ZIP format specification.
-        if os.sep != "/" and os.sep in filename:
-            filename = filename.replace(os.sep"/")
+        if os.sep != "/" and os.sep.encode('utf-8') in filename:
+            filename = filename.replace(os.sep.encode('utf-8'), b"/")
 
         self.filename = filename        # Normalized file name
         self.date_time = date_time      # year, month, day, hour, min, sec