refactor aes.py, aes-buffer to use pycrypto
--HG-- branch : pmacs2
This commit is contained in:
parent
8be0f59be1
commit
254ba4b0bb
|
@ -1,112 +1,29 @@
|
||||||
#!/usr/bin/python
|
import Crypto.Hash.SHA256
|
||||||
#
|
import Crypto.Cipher.AES
|
||||||
# by Erik Osheim
|
|
||||||
import os
|
|
||||||
from subprocess import Popen, PIPE
|
|
||||||
|
|
||||||
class Cipher(object):
|
class Crypter(object):
|
||||||
'''Cipher represents a particular hashing strategy (password, seed, and type). Cipher can encrypt or decrypt data.'''
|
ALIGNMENT = 16
|
||||||
def __init__(self, password, seed='aes.py', hashtype='rmd160'):
|
def __init__(self, password, salt='aes.py'):
|
||||||
self.password = password
|
self.password = password
|
||||||
self.seed = seed
|
self.salt = salt
|
||||||
self.hashtype = hashtype
|
self.hash = Crypto.Hash.SHA256.new(password + salt)
|
||||||
def encrypt(self, data):
|
self.cipher = Crypto.Cipher.AES.new(self.hash.digest())
|
||||||
return encrypt_data(data, self.password, self.seed, self.hashtype)
|
|
||||||
def decrypt(self, encrypted):
|
|
||||||
return decrypt_data(encrypted, self.password, self.seed, self.hashtype)
|
|
||||||
|
|
||||||
def _check_aespipe():
|
def pad(self, s):
|
||||||
'''This function checks if we have the "aespipe" binary in $PATH'''
|
xtra = len(s) % self.ALIGNMENT
|
||||||
result = os.system('which aespipe > /dev/null')
|
if xtra:
|
||||||
if result != 0:
|
return s + '\x00' * (self.ALIGNMENT - xtra)
|
||||||
raise Exception, "Could not find aespipe; is it installed?"
|
|
||||||
|
|
||||||
def encrypt_data(data, password, seed='aes.py', hashtype='rmd160'):
|
|
||||||
'''Uses password to encrypt data'''
|
|
||||||
_check_aespipe()
|
|
||||||
args = ["aespipe", "-S", seed, "-H", hashtype, "-p", "0"]
|
|
||||||
p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
|
||||||
(stdout, stdin, stderr) = (p.stdout, p.stdin, p.stderr)
|
|
||||||
stdin.write(password + '\n')
|
|
||||||
stdin.write(data)
|
|
||||||
stdin.close()
|
|
||||||
encrypted = stdout.read()
|
|
||||||
err = stderr.read()
|
|
||||||
if err:
|
|
||||||
raise Exception, "Problem: %s" % err
|
|
||||||
return encrypted
|
|
||||||
|
|
||||||
def encrypt_path(path, data, password, seed='aes.py', hashtype='rmd160'):
|
|
||||||
'''Uses password to encrypt data and writes result to path'''
|
|
||||||
encrypted = encrypt_data(data, password, seed, hashtype)
|
|
||||||
f = open(path, 'w')
|
|
||||||
f.write(encrypted)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
def decrypt_data(encrypted, password, seed='aes.py', hashtype='rmd160'):
|
|
||||||
'''Uses password to decrypt data'''
|
|
||||||
_check_aespipe()
|
|
||||||
args = ["aespipe", "-d", "-S", seed, "-H", hashtype, "-p", "0"]
|
|
||||||
p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
|
||||||
(stdout, stdin, stderr) = (p.stdout, p.stdin, p.stderr)
|
|
||||||
stdin.write(password + '\n')
|
|
||||||
stdin.write(encrypted)
|
|
||||||
stdin.close()
|
|
||||||
data = stdout.read()
|
|
||||||
err = stderr.read()
|
|
||||||
if err:
|
|
||||||
raise Exception, "Problem: %s" % err
|
|
||||||
|
|
||||||
# data is null-padded at the end to align on 16 or 512 bytes boundaries
|
|
||||||
i = len(data)
|
|
||||||
while i > 1:
|
|
||||||
if data[i-1] == '\x00':
|
|
||||||
i -= 1
|
|
||||||
else:
|
else:
|
||||||
break
|
return s
|
||||||
return data[:i]
|
|
||||||
|
def unpad(self, s):
|
||||||
def decrypt_path(path, password, seed='aes.py', hashtype='rmd160'):
|
l = len(s)
|
||||||
'''Uses password to decrypt data from path'''
|
while l > 0 and s[l - 1] == '\x00':
|
||||||
f = open(path, 'r')
|
l -= 1
|
||||||
encrypted = f.read()
|
return s[:l]
|
||||||
f.close()
|
|
||||||
data = decrypt_data(encrypted, password, seed, hashtype)
|
def encrypt(self, data):
|
||||||
return data
|
return self.cipher.encrypt(self.pad(data))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def decrypt(self, data):
|
||||||
import optparse, sys
|
return self.unpad(self.cipher.decrypt(self.pad(data)))
|
||||||
|
|
||||||
parser = optparse.OptionParser()
|
|
||||||
parser.set_defaults(mode='decrypt')
|
|
||||||
parser.set_defaults(password='insecure1@3$5^')
|
|
||||||
parser.set_defaults(filename='output.aes')
|
|
||||||
|
|
||||||
parser.add_option('-e', dest='mode', action='store_const', const='encrypt',
|
|
||||||
help="perform encryption on data from stdin")
|
|
||||||
parser.add_option('-d', dest='mode', action='store_const', const='decrypt',
|
|
||||||
help="perform decryption on data from stdin")
|
|
||||||
parser.add_option('-f', dest='filename', action='store', metavar='FILENAME',
|
|
||||||
help="encrypt to/from FILENAME (default: output.aes)")
|
|
||||||
parser.add_option('-p', dest='password', action='store', metavar='PASSWORD',
|
|
||||||
default="insecure1@3$5^",
|
|
||||||
help="use password PASSWORD (default: insecure1@3$5^)")
|
|
||||||
|
|
||||||
(opts, args) = parser.parse_args()
|
|
||||||
|
|
||||||
c = Cipher(opts.password)
|
|
||||||
|
|
||||||
if opts.mode == 'encrypt':
|
|
||||||
data = sys.stdin.read()
|
|
||||||
encrypted = c.encrypt(data)
|
|
||||||
f = open(opts.filename, 'w')
|
|
||||||
f.write(encrypted)
|
|
||||||
f.close()
|
|
||||||
print "data written to %r." % opts.filename
|
|
||||||
else:
|
|
||||||
print "reading data from %r:" % opts.filename
|
|
||||||
f = open(opts.filename, 'r')
|
|
||||||
encrypted = f.read()
|
|
||||||
f.close()
|
|
||||||
data = c.decrypt(encrypted)
|
|
||||||
print data
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import traceback
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
import buffer, buffer.about, buffer.color, buffer.console, buffer.data
|
import buffer, buffer.about, buffer.color, buffer.console, buffer.data
|
||||||
import buffer.fs
|
import buffer.fs, buffer.aes
|
||||||
import bufferlist, color, completer, ispell, keyinput, method, minibuffer
|
import bufferlist, color, completer, ispell, keyinput, method, minibuffer
|
||||||
import mode, util, window
|
import mode, util, window
|
||||||
from point import Point
|
from point import Point
|
||||||
|
@ -369,7 +369,7 @@ class Application(object):
|
||||||
if not password:
|
if not password:
|
||||||
raise Exception, "password is required"
|
raise Exception, "password is required"
|
||||||
if not os.path.exists(path) or os.path.isfile(path):
|
if not os.path.exists(path) or os.path.isfile(path):
|
||||||
b = buffer.AesBuffer(path, password, name=name)
|
b = buffer.aes.AesBuffer(path, password, name=name)
|
||||||
else:
|
else:
|
||||||
raise Exception, "not a file or dir: %r" % path
|
raise Exception, "not a file or dir: %r" % path
|
||||||
try:
|
try:
|
||||||
|
@ -1014,7 +1014,7 @@ class Application(object):
|
||||||
def open_aes_file(path, name=None, binary=False):
|
def open_aes_file(path, name=None, binary=False):
|
||||||
if os.path.isfile(path) or not os.path.exists(path):
|
if os.path.isfile(path) or not os.path.exists(path):
|
||||||
p = getpass.getpass("Please enter the AES password: ")
|
p = getpass.getpass("Please enter the AES password: ")
|
||||||
return buffer.AesBuffer(path, p, name)
|
return buffer.aes.AesBuffer(path, p, name)
|
||||||
else:
|
else:
|
||||||
raise Exception, "can't open %r; unsupported file type" % path
|
raise Exception, "can't open %r; unsupported file type" % path
|
||||||
def open_plain_file(path, name=None, binary=False):
|
def open_plain_file(path, name=None, binary=False):
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from util import defaultdict
|
from util import defaultdict
|
||||||
import codecs, datetime, grp, os, pwd, re, shutil, stat, string
|
import codecs, datetime, grp, os, pwd, re, shutil, stat, string
|
||||||
import fcntl, select, pty, threading
|
import fcntl, select, pty, threading
|
||||||
import aes, dirutil, regex, highlight, lex, term
|
#import aes, dirutil, regex, highlight, lex, term
|
||||||
|
import dirutil, regex, highlight, lex, term
|
||||||
from point import Point
|
from point import Point
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
from keyinput import MAP
|
from keyinput import MAP
|
||||||
|
@ -665,6 +666,7 @@ class FileBuffer(Buffer):
|
||||||
temp_path = self._temp_path()
|
temp_path = self._temp_path()
|
||||||
shutil.copyfile(self.path, temp_path)
|
shutil.copyfile(self.path, temp_path)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = self.make_string()
|
data = self.make_string()
|
||||||
if self.windows[0].mode.savetabs:
|
if self.windows[0].mode.savetabs:
|
||||||
|
@ -674,8 +676,9 @@ class FileBuffer(Buffer):
|
||||||
f2 = self._open_file_w(self.path, preserve=False)
|
f2 = self._open_file_w(self.path, preserve=False)
|
||||||
f2.write(self.bytemark + data)
|
f2.write(self.bytemark + data)
|
||||||
f2.close()
|
f2.close()
|
||||||
except:
|
except Exception, e:
|
||||||
if exists: shutil.copyfile(temp_path, self.path)
|
if exists: shutil.copyfile(temp_path, self.path)
|
||||||
|
raise e
|
||||||
else:
|
else:
|
||||||
self.store_checksum(data)
|
self.store_checksum(data)
|
||||||
self.modified = False
|
self.modified = False
|
||||||
|
@ -684,16 +687,16 @@ class FileBuffer(Buffer):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
class AesBuffer(FileBuffer):
|
#class AesBuffer(FileBuffer):
|
||||||
btype = 'aesfile'
|
# btype = 'aesfile'
|
||||||
def __init__(self, path, password, name=None):
|
# def __init__(self, path, password, name=None):
|
||||||
'''fb = FileBuffer(path)'''
|
# '''fb = FileBuffer(path)'''
|
||||||
FileBuffer.__init__(self, path, name)
|
# FileBuffer.__init__(self, path, name)
|
||||||
self.password = password
|
# self.password = password
|
||||||
def read_filter(self, data):
|
# def read_filter(self, data):
|
||||||
return aes.decrypt_data(data, self.password)
|
# return aes.decrypt_data(data, self.password)
|
||||||
def write_filter(self, data):
|
# def write_filter(self, data):
|
||||||
return aes.encrypt_data(data, self.password)
|
# return aes.encrypt_data(data, self.password)
|
||||||
|
|
||||||
class Binary32Buffer(FileBuffer):
|
class Binary32Buffer(FileBuffer):
|
||||||
btype = 'bin32file'
|
btype = 'bin32file'
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import aes
|
||||||
|
from buffer import FileBuffer
|
||||||
|
|
||||||
|
class AesBuffer(FileBuffer):
|
||||||
|
btype = 'aesfile'
|
||||||
|
def __init__(self, path, password, name=None):
|
||||||
|
'''ab = AesBuffer(path, password)'''
|
||||||
|
FileBuffer.__init__(self, path, name)
|
||||||
|
self.crypter = aes2.Crypter(password)
|
||||||
|
def read_filter(self, data):
|
||||||
|
return self.crypter.decrypt(data)
|
||||||
|
def write_filter(self, data):
|
||||||
|
return self.crypter.encrypt(data)
|
Loading…
Reference in New Issue