@ -2,6 +2,8 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from __future__ import absolute_import
from __future__ import print_function
# ineptepub.pyw, version 6.6
# Copyright © 2009-2010 by i♥cabbages
@ -51,6 +53,8 @@ Decrypt Adobe Digital Editions encrypted ePub books.
__license__ = ' GPL v3 '
__version__ = " 6.6 "
import six
from six . moves import range
import sys
import os
import traceback
@ -70,7 +74,7 @@ class SafeUnbuffered:
if self . encoding == None :
self . encoding = " utf-8 "
def write ( self , data ) :
if isinstance ( data , unicod e) :
if isinstance ( data , six. text_typ e) :
data = data . encode ( self . encoding , " replace " )
self . stream . write ( data )
self . stream . flush ( )
@ -111,13 +115,13 @@ def unicode_argv():
# Remove Python executable and commands if present
start = argc . value - len ( sys . argv )
return [ argv [ i ] for i in
x range( start , argc . value ) ]
range( start , argc . value ) ]
return [ u " ineptepub.py " ]
else :
argvencoding = sys . stdin . encoding
if argvencoding == None :
argvencoding = " utf-8 "
return [ arg if ( type ( arg ) == unicode) else unicod e( arg , argvencoding ) for arg in sys . argv ]
return [ arg if ( type ( arg ) == six. text_type ) else six . text_typ e( arg , argvencoding ) for arg in sys . argv ]
class ADEPTError ( Exception ) :
@ -315,12 +319,12 @@ def _load_crypto_pycrypto():
class RSA ( object ) :
def __init__ ( self , der ) :
key = ASN1Parser ( [ ord ( x ) for x in der ] )
key = [ key . getChild ( x ) . value for x in x range( 1 , 4 ) ]
key = [ key . getChild ( x ) . value for x in range( 1 , 4 ) ]
key = [ self . bytesToNumber ( v ) for v in key ]
self . _rsa = _RSA . construct ( key )
def bytesToNumber ( self , bytes ) :
total = 0 L
total = 0
for byte in bytes :
total = ( total << 8 ) + byte
return total
@ -405,7 +409,7 @@ def decryptBook(userkey, inpath, outpath):
namelist = set ( inf . namelist ( ) )
if ' META-INF/rights.xml ' not in namelist or \
' META-INF/encryption.xml ' not in namelist :
print u " {0:s} is DRM-free. " . format ( os . path . basename ( inpath ) )
print ( u " {0:s} is DRM-free. " . format ( os . path . basename ( inpath ) ) )
return 1
for name in META_NAMES :
namelist . remove ( name )
@ -415,12 +419,12 @@ def decryptBook(userkey, inpath, outpath):
expr = ' .// %s ' % ( adept ( ' encryptedKey ' ) , )
bookkey = ' ' . join ( rights . findtext ( expr ) )
if len ( bookkey ) != 172 :
print u " {0:s} is not a secure Adobe Adept ePub. " . format ( os . path . basename ( inpath ) )
print ( u " {0:s} is not a secure Adobe Adept ePub. " . format ( os . path . basename ( inpath ) ) )
return 1
bookkey = rsa . decrypt ( bookkey . decode ( ' base64 ' ) )
# Padded as per RSAES-PKCS1-v1_5
if bookkey [ - 17 ] != ' \x00 ' :
print u " Could not decrypt {0:s} . Wrong key " . format ( os . path . basename ( inpath ) )
print ( u " Could not decrypt {0:s} . Wrong key " . format ( os . path . basename ( inpath ) ) )
return 2
encryption = inf . read ( ' META-INF/encryption.xml ' )
decryptor = Decryptor ( bookkey [ - 16 : ] , encryption )
@ -461,7 +465,7 @@ def decryptBook(userkey, inpath, outpath):
pass
outf . writestr ( zi , decryptor . decrypt ( path , data ) )
except :
print u " Could not decrypt {0:s} because of an exception: \n {1:s} " . format ( os . path . basename ( inpath ) , traceback . format_exc ( ) )
print ( u " Could not decrypt {0:s} because of an exception: \n {1:s} " . format ( os . path . basename ( inpath ) , traceback . format_exc ( ) ) )
return 2
return 0
@ -472,90 +476,90 @@ def cli_main():
argv = unicode_argv ( )
progname = os . path . basename ( argv [ 0 ] )
if len ( argv ) != 4 :
print u " usage: {0} <keyfile.der> <inbook.epub> <outbook.epub> " . format ( progname )
print ( u " usage: {0} <keyfile.der> <inbook.epub> <outbook.epub> " . format ( progname ) )
return 1
keypath , inpath , outpath = argv [ 1 : ]
userkey = open ( keypath , ' rb ' ) . read ( )
result = decryptBook ( userkey , inpath , outpath )
if result == 0 :
print u " Successfully decrypted {0:s} as {1:s} " . format ( os . path . basename ( inpath ) , os . path . basename ( outpath ) )
print ( u " Successfully decrypted {0:s} as {1:s} " . format ( os . path . basename ( inpath ) , os . path . basename ( outpath ) ) )
return result
def gui_main ( ) :
try :
import T kinter
import Tk constants
import tkFileD ialog
import tkMessageB ox
import six. moves . t kinter
import six. moves . tkinter_ constants
import six. moves . tkinter_filed ialog
import six. moves . tkinter_messageb ox
import traceback
except :
return cli_main ( )
class DecryptionDialog ( T kinter. Frame ) :
class DecryptionDialog ( six. moves . t kinter. Frame ) :
def __init__ ( self , root ) :
T kinter. Frame . __init__ ( self , root , border = 5 )
self . status = T kinter. Label ( self , text = u " Select files for decryption " )
self . status . pack ( fill = Tk constants. X , expand = 1 )
body = T kinter. Frame ( self )
body . pack ( fill = Tk constants. X , expand = 1 )
sticky = Tkconstants. E + Tk constants. W
six. moves . t kinter. Frame . __init__ ( self , root , border = 5 )
self . status = six. moves . t kinter. Label ( self , text = u " Select files for decryption " )
self . status . pack ( fill = six. moves . tkinter_ constants. X , expand = 1 )
body = six. moves . t kinter. Frame ( self )
body . pack ( fill = six. moves . tkinter_ constants. X , expand = 1 )
sticky = six. moves . tkinter_constants . E + six . moves . tkinter_ constants. W
body . grid_columnconfigure ( 1 , weight = 2 )
T kinter. Label ( body , text = u " Key file " ) . grid ( row = 0 )
self . keypath = T kinter. Entry ( body , width = 30 )
six. moves . t kinter. Label ( body , text = u " Key file " ) . grid ( row = 0 )
self . keypath = six. moves . t kinter. Entry ( body , width = 30 )
self . keypath . grid ( row = 0 , column = 1 , sticky = sticky )
if os . path . exists ( u " adeptkey.der " ) :
self . keypath . insert ( 0 , u " adeptkey.der " )
button = T kinter. Button ( body , text = u " ... " , command = self . get_keypath )
button = six. moves . t kinter. Button ( body , text = u " ... " , command = self . get_keypath )
button . grid ( row = 0 , column = 2 )
T kinter. Label ( body , text = u " Input file " ) . grid ( row = 1 )
self . inpath = T kinter. Entry ( body , width = 30 )
six. moves . t kinter. Label ( body , text = u " Input file " ) . grid ( row = 1 )
self . inpath = six. moves . t kinter. Entry ( body , width = 30 )
self . inpath . grid ( row = 1 , column = 1 , sticky = sticky )
button = T kinter. Button ( body , text = u " ... " , command = self . get_inpath )
button = six. moves . t kinter. Button ( body , text = u " ... " , command = self . get_inpath )
button . grid ( row = 1 , column = 2 )
T kinter. Label ( body , text = u " Output file " ) . grid ( row = 2 )
self . outpath = T kinter. Entry ( body , width = 30 )
six. moves . t kinter. Label ( body , text = u " Output file " ) . grid ( row = 2 )
self . outpath = six. moves . t kinter. Entry ( body , width = 30 )
self . outpath . grid ( row = 2 , column = 1 , sticky = sticky )
button = T kinter. Button ( body , text = u " ... " , command = self . get_outpath )
button = six. moves . t kinter. Button ( body , text = u " ... " , command = self . get_outpath )
button . grid ( row = 2 , column = 2 )
buttons = T kinter. Frame ( self )
buttons = six. moves . t kinter. Frame ( self )
buttons . pack ( )
botton = T kinter. Button (
botton = six. moves . t kinter. Button (
buttons , text = u " Decrypt " , width = 10 , command = self . decrypt )
botton . pack ( side = Tk constants. LEFT )
T kinter. Frame ( buttons , width = 10 ) . pack ( side = Tk constants. LEFT )
button = T kinter. Button (
botton . pack ( side = six. moves . tkinter_ constants. LEFT )
six. moves . t kinter. Frame ( buttons , width = 10 ) . pack ( side = six. moves . tkinter_ constants. LEFT )
button = six. moves . t kinter. Button (
buttons , text = u " Quit " , width = 10 , command = self . quit )
button . pack ( side = Tk constants. RIGHT )
button . pack ( side = six. moves . tkinter_ constants. RIGHT )
def get_keypath ( self ) :
keypath = tkFileD ialog. askopenfilename (
keypath = six. moves . tkinter_filed ialog. askopenfilename (
parent = None , title = u " Select Adobe Adept \' .der \' key file " ,
defaultextension = u " .der " ,
filetypes = [ ( ' Adobe Adept DER-encoded files ' , ' .der ' ) ,
( ' All Files ' , ' .* ' ) ] )
if keypath :
keypath = os . path . normpath ( keypath )
self . keypath . delete ( 0 , Tk constants. END )
self . keypath . delete ( 0 , six. moves . tkinter_ constants. END )
self . keypath . insert ( 0 , keypath )
return
def get_inpath ( self ) :
inpath = tkFileD ialog. askopenfilename (
inpath = six. moves . tkinter_filed ialog. askopenfilename (
parent = None , title = u " Select ADEPT-encrypted ePub file to decrypt " ,
defaultextension = u " .epub " , filetypes = [ ( ' ePub files ' , ' .epub ' ) ] )
if inpath :
inpath = os . path . normpath ( inpath )
self . inpath . delete ( 0 , Tk constants. END )
self . inpath . delete ( 0 , six. moves . tkinter_ constants. END )
self . inpath . insert ( 0 , inpath )
return
def get_outpath ( self ) :
outpath = tkFileD ialog. asksaveasfilename (
outpath = six. moves . tkinter_filed ialog. asksaveasfilename (
parent = None , title = u " Select unencrypted ePub file to produce " ,
defaultextension = u " .epub " , filetypes = [ ( ' ePub files ' , ' .epub ' ) ] )
if outpath :
outpath = os . path . normpath ( outpath )
self . outpath . delete ( 0 , Tk constants. END )
self . outpath . delete ( 0 , six. moves . tkinter_ constants. END )
self . outpath . insert ( 0 , outpath )
return
@ -579,7 +583,7 @@ def gui_main():
self . status [ ' text ' ] = u " Decrypting... "
try :
decrypt_status = decryptBook ( userkey , inpath , outpath )
except Exception , e :
except Exception as e :
self . status [ ' text ' ] = u " Error: {0} " . format ( e . args [ 0 ] )
return
if decrypt_status == 0 :
@ -587,11 +591,11 @@ def gui_main():
else :
self . status [ ' text ' ] = u " The was an error decrypting the file. "
root = T kinter. Tk ( )
root = six. moves . t kinter. Tk ( )
root . title ( u " Adobe Adept ePub Decrypter v. {0} " . format ( __version__ ) )
root . resizable ( True , False )
root . minsize ( 300 , 0 )
DecryptionDialog ( root ) . pack ( fill = Tk constants. X , expand = 1 )
DecryptionDialog ( root ) . pack ( fill = six. moves . tkinter_ constants. X , expand = 1 )
root . mainloop ( )
return 0