refactor aes.py, aes-buffer to use pycrypto

--HG--
branch : pmacs2
This commit is contained in:
Erik Osheim 2009-05-21 10:24:29 -04:00
parent 8be0f59be1
commit 254ba4b0bb
4 changed files with 56 additions and 123 deletions

133
aes.py Executable file → Normal file
View File

@ -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

View File

@ -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):

View File

@ -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'

13
buffer/aes.py Normal file
View File

@ -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)