summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakuchling <akuchling@rivest.dlitz.net>2005-05-09 14:20:57 -0700
committerakuchling <akuchling@rivest.dlitz.net>2005-05-09 14:20:57 -0700
commit816b39cfe28a6727f7535383a89c86dc7b2860aa (patch)
tree1a5257836fe8f22b652c386271d45cb7a142843a
parent44c61eb34ccac60ba5e3e5aacb93ae24c1311fe0 (diff)
downloadpycrypto-816b39cfe28a6727f7535383a89c86dc7b2860aa.tar.gz
[project @ akuchling-20050509212057-55ab47f8ceaba662]
[project @ 2005-05-09 14:20:54 by akuchling] Remove Demo/ directory -- the code is old and possibly misleading, and no one is going to modernize it
-rw-r--r--Demo/README29
-rw-r--r--Demo/chaum.py129
-rwxr-xr-xDemo/cipher150
-rwxr-xr-xDemo/enc.py334
-rw-r--r--Demo/secimp/README24
-rw-r--r--Demo/secimp/secimp.py84
-rwxr-xr-xDemo/secimp/sign.py46
-rw-r--r--Demo/secimp/testkey.py41
-rw-r--r--Doc/pycrypt.tex96
-rw-r--r--MANIFEST8
-rw-r--r--TODO5
11 files changed, 0 insertions, 946 deletions
diff --git a/Demo/README b/Demo/README
deleted file mode 100644
index 0e48d7c..0000000
--- a/Demo/README
+++ /dev/null
@@ -1,29 +0,0 @@
-This directory contains demonstration files that use the modules
-included in the Python Cryptography Toolkit.
-
-Note: These programs have version numbers of their own, which are not
-necessarily the same as the version number of the Toolkit package.
-
-cipher Encrypt and decrypt sensitive files; type 'cipher -h'
- for a usage message.
-
-voice Allows secure voice communication over a TCP/IP link.
- Currently this is Linux-specific; changes to make it
- run on other systems would be greatly appreciated.
-
-RSAgen.py Generates a new RSA key. Demonstrates using
- randpool.py, and maintains a file of random data in
- "randseed". Requires that the IDEA and MD5 modules
- are installed.
-
-testkey.py RSA public/private key pair used by example programs.
-
-Secure importing of Python modules:
-
- sign.py Sign all *.pyc files in a directory, using the
- key defined in testkey.py.
-
- secimp.py Implementation of the secure 'import' command.
-
-
-
diff --git a/Demo/chaum.py b/Demo/chaum.py
deleted file mode 100644
index a2d3ec2..0000000
--- a/Demo/chaum.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/usr/bin/env python
-
-""" Example of Chaumian blinding """
-
-import time, pprint, os, sha
-from Crypto.PublicKey import *
-from Crypto.Util.randpool import RandomPool
-from Crypto.Util import number
-import cPickle as pickle
-
-# Globals
-pool = RandomPool()
-pool.stir()
-
-# use SHA-1 by default, if you want to use SHA-256, SHA-384 or SHA-512 you
-# need shax-py from http://philosophysw.com/software/
-digest = sha.sha
-
-KEYSIZE = 1024
-KEYFILE = "tokenkey.pickle"
-HASHSIZE = sha.digestsize*8
-
-### Initialization ###
-
-if os.path.isfile(KEYFILE):
- # Load existing key """
- print "Server: load key..."
- ff = file(KEYFILE, 'r')
- key = pickle.load(ff)
- rsa = RSA.construct(key)
-else:
- # Generate an RSA key-pair of KEYSIZE bits and store the key
- print "Server: create key (will take a while, but only has to be done once)..."
- begintime=time.time()
- rsa=RSA.generate(KEYSIZE, pool.get_bytes)
- endtime=time.time()
- print "Server: Generate %d bit RSA key: %f s" % (KEYSIZE, endtime-begintime)
-
- key = (rsa.n, rsa.e, rsa.d, rsa.p, rsa.q, rsa.u)
- ff = file(KEYFILE, 'w')
- pickle.dump(key, ff)
-
-print "RSA key:"
-print "n = %s" % pprint.pformat(rsa.n) # Public key
-print "e = %s" % pprint.pformat(rsa.e) # Public key
-
-print "d = %s" % pprint.pformat(rsa.d) # Private key
-# Values below are not really needed, but cause a big speedup since the Chinese Remainders Theorem can be used
-print "p = %s" % pprint.pformat(rsa.p) # Private key
-print "q = %s" % pprint.pformat(rsa.q) # Private key
-print "u = %s" % pprint.pformat(rsa.u) # Private key
-print
-
-### Client ###
-
-# Generate random tokenId of HASHSIZE bits
-tokenId = number.getRandomNumber(HASHSIZE, pool.get_bytes)
-
-# Generate random blindingFactor of KEYSIZE-1 (so it can still be signed) bits
-while 1:
- blindingFactor = number.getRandomNumber(KEYSIZE-1, pool.get_bytes)
- # Verify that GCD(r, n) ==1
- if number.GCD(blindingFactor, rsa.n)==1:
- break
-
-# Calculate the hash of the tokenId
-tokenHash = number.bytes_to_long(digest(number.long_to_bytes(tokenId)).digest())
-
-print "tokenId = %s" % pprint.pformat(tokenId)
-print "blindingFactor = %s" % pprint.pformat(blindingFactor)
-print "tokenHash = %s" % pprint.pformat(tokenHash)
-print
-
-# Blind the hashed tokenId with blindingFactor
-begintime=time.time()
-blindedToken=rsa.blind(tokenHash, blindingFactor)
-endtime=time.time()
-print "Client: Blinding: %f s" % (endtime-begintime)
-print "blindedToken = %s" % pprint.pformat(blindedToken)
-
-# Send blindedToken to the server
-print "Client -> Server: blindedToken"
-print
-
-### Server ###
-
-# Sign the blindedToken
-begintime=time.time()
-blindedSignature=rsa.sign(blindedToken, None)[0]
-endtime=time.time()
-print "Server: Signing: %f s" % (endtime-begintime)
-print "blindedSignature = %s" % pprint.pformat(blindedSignature)
-
-# Send the blindedSignature back to the client
-print "Server -> Client: blindedSignature"
-print
-
-### Client ###
-
-# Unblind the blindedSignature
-begintime=time.time()
-signature=rsa.unblind(blindedSignature, blindingFactor)
-endtime=time.time()
-print "Client: Unblinding: %f s" % (endtime-begintime)
-print "signature = %s" % pprint.pformat(signature)
-print
-
-# Token is ready
-token = (tokenId, signature)
-print "Client: token = %s" % pprint.pformat(token)
-
-print
-print "... user can now use the token..."
-print "Client -> Server: token"
-print
-
-### Server ###
-
-# Verify that the signature of hash(tokenId) is right
-begintime=time.time()
-v=rsa.verify(number.bytes_to_long(digest(number.long_to_bytes(token[0])).digest()), (token[1],))
-endtime=time.time()
-print "Server: Verifying: %f s" % (endtime-begintime)
-
-if v:
- print "Server: SIGNATURE OK"
-else:
- print "Server: SIGNATURE NOT OK"
-
diff --git a/Demo/cipher b/Demo/cipher
deleted file mode 100755
index 8533c87..0000000
--- a/Demo/cipher
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/usr/bin/env python
-# -*-Python-*-
-# Cipher 1.00
-#
-# Part of the Python Cryptography Toolkit
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-
-import sys, getopt, os
-
-# Determine the name of this executable
-executable = os.path.basename(sys.argv[0])
-if executable=='': executable='cipher'
-cipher = '' # Unknown ciphering algorithm
-key = (0, '') # Empty key
-magic = 'ctx\001' # Magic string prefixed to the data
-NoInputFile = '' # Exceptions raised on file errors
-NoOutputFile = ''
-
-def PrintUsage():
- print 'Usage: cipher [OPTIONS] file1 file2 ...'
- print '\n -c ciphername Force use of ciphername to encrypt/decrypt'
- print ' -k key Key to use for encryption/decryption'
- print '\nThe default cipher algorithm is IDEA; if no key is set on the command'
- print 'line, you will be prompted to enter a key.'
- print 'Files are read completely into memory, so do not try to encrypt'
- print 'very large files.'
-
-def GenerateIV(length):
- import whrandom
- IV=''
- for i in range(0, length):
- IV=IV + chr(int(256*whrandom.random()))
- return IV
-
-def Encipher(filename, cipher, key):
- if (cipher==''): cipher='IDEA'
- try:
- exec ('from Crypto.Cipher import '+cipher)
- module=eval(cipher)
- except ImportError:
- print executable+ ':', cipher, ': Cipher does not exist.'
- sys.exit(1)
- import Crypto.Hash.MD5
- try:
- input=open(filename, 'r')
- except IOError:
- raise NoInputFile
- try:
- output=open(filename+'.cip', 'w')
- except IOError:
- raise NoOutputFile, filename+'.cip'
-
- if (key[0]==0):
- key=raw_input('Enter encryption key for '+ filename+ ':')
- else: key=key[1]
- key=Crypto.Hash.MD5.new(key).digest()
- IV=''
- for i in range(0, module.blocksize): IV=IV+'A'
- if (module.keysize==0):
- cipherobj=module.new(key, module.CBC, IV)
- else:
- cipherobj=module.new(key[0:module.keysize], module.CBC, IV)
- output.write(magic+cipher+'\0')
- data = GenerateIV(module.blocksize)
- filedata=input.read()
- data = data + magic + str(len(filedata))+'\0'+filename+'\0'
- data = data + filedata
- input.close()
- padding=module.blocksize - (len(data) % module.blocksize)
- for i in range(0, padding):
- data = data + chr(i)
- ciphertext=cipherobj.encrypt(data)
- output.write(ciphertext)
- output.close()
-
-def Decipher(filename, cipher, key):
- import Crypto.Hash.MD5, string
- try:
- input=open(filename, 'r')
- except IOError:
- raise NoInputFile
- if (input.read(len(magic))!=magic):
- print executable+':', filename+': Does not seem to be a ciphered file'
- return
- t=''
- while (1):
- c=input.read(1)
- if (ord(c)==0): break
- t=t+c
- if (cipher==''): cipher=t
- try:
- from Crypto.Cipher import *
- module=eval(cipher)
- except ImportError:
- print executable+ ':', cipher, ': Cipher does not exist.'
- sys.exit(1)
- if (key[0]==0):
- key=raw_input('Enter encryption key for '+ filename+ ':')
- else: key=key[1]
- key=Crypto.Hash.MD5.new(key).digest()
- IV = ''
- for i in range(0, module.blocksize): IV=IV+'A'
- data=input.read()
- if (module.keysize==0):
- cipherobj=module.new(key, module.CBC, IV)
- else:
- cipherobj=module.new(key[0:module.keysize], module.CBC, IV)
- plain=cipherobj.decrypt(data) # Decrypt the data
- plain=plain[module.blocksize:] # Discard first block of random data
- if (plain[0:len(magic)]!=magic):
- print executable+':', filename+': Incorrect key or cipher algorithm'
- return
- else: plain=plain[len(magic):]
- i=string.find(plain, '\0')
- length=string.atoi(plain[0:i])
- j=string.find(plain, '\0', i+1)
- newfilename=plain[i+1:j]
- try:
- output=open(newfilename, 'w')
- except IOError:
- raise NoOutputFile, newfilename
- output.write(plain[j+1:j+1+length])
- output.close()
-
-if len(sys.argv)==1: PrintUsage() ; sys.exit(0)
-
-options, args=getopt.getopt(sys.argv[1:], 'c:k:hH')
-for opt in options:
- letter, param = opt
- if (letter=='-c'): cipher = param
- if (letter=='-k'): key = (1, param)
- if (letter=='-h' or letter=='-H'):
- PrintUsage()
- sys.exit(0)
-
-for file in args:
- try:
- if (file[-4:]=='.cip'):
- Decipher(file, cipher, key)
- else:
- Encipher(file, cipher, key)
- except NoInputFile:
- print executable+ ':', file+ ': No such file.'
- except NoOutputFile, filename:
- print executable+ ':', filename+ ': Cannot open file'
-
diff --git a/Demo/enc.py b/Demo/enc.py
deleted file mode 100755
index 1d6924c..0000000
--- a/Demo/enc.py
+++ /dev/null
@@ -1,334 +0,0 @@
-#!/usr/local/bin/python -Ou
-
-""" enc - encrypt/decrypt files using one of SSLeay's ciphers.
-
- Copyright (c) 1998 by Marc-Andre Lemburg; All Rights Reserved;
- mailto:mal@lemburg.com; See the documentation for further
- copyright information or contact the author.
-
- DISCLAIMER & WARNING: This tool comes with NO WARRANTY. Use at
- YOUR OWN RISK. It may destroy data ! There is NO way to recover a
- forgotten pass phrase !
-"""
-import exceptions,os,string,time,sys
-from CryptoWorld import Ciphers,Hashes,Utils
-from CommandLine import Application,SwitchOption,ArgumentOption
-
-# Globals
-verbose = 0
-
-# Maximum block size used for en/decryption
-MAX_BLOCKSIZE = 1024 * 1000
-
-class OperationalError(exceptions.StandardError):
- pass
-
-def filesize(file):
-
- oldpos = file.tell()
- file.seek(0,2)
- size = file.tell()
- file.seek(oldpos)
- return size
-
-def invisible_input(prompt='>>> '):
-
- """ Adapted from the Python 1.5.1 docs example getpass()
- """
- import termios,TERMIOS
- fd = sys.stdin.fileno()
- old = termios.tcgetattr(fd)
- new = termios.tcgetattr(fd)
- new[3] = new[3] & ~TERMIOS.ECHO # fix lflags
- try:
- termios.tcsetattr(fd, TERMIOS.TCSADRAIN, new)
- passwd = raw_input(prompt)
- finally:
- termios.tcsetattr(fd, TERMIOS.TCSADRAIN, old)
- print
- return passwd
-
-def tempfile(filename='tmp',
-
- maxint=sys.maxint,time=time.time,int=int,hex=hex,
- exists=os.path.exists):
-
- """ Return a new filename for a temporary file (based on filename).
- """
- temp = filename + '.' + hex(maxint % int(time())) + '.tmp'
- if not exists(temp):
- return temp
- # Ok, find an alternative name
- i = 0
- while 1:
- temp = '%s.%s-%i.tmp' % (filename,hex(maxint % int(time())),i)
- if not exists(temp):
- return temp
- i = i + 1
-
-# Global key
-_key = ''
-
-def get_cipher(name,check=0):
-
- global _key
-
- cc = getattr(Ciphers,name)
- keysize = cc.keysize
- if not _key:
- while 1:
- key1 = invisible_input('Please enter the key phrase: ')
- if check:
- key2 = invisible_input('Please reenter the phrase: ')
- if key1 != key2:
- print "Phrases don't match. Please start again..."
- continue
- if len(key1) == 0:
- print "Empty key phrase. Please start again..."
- else:
- break
- _key = key1
- key = _key
- # Fit key
- if keysize > 0:
- if len(key) < keysize:
- key = key + \
- 'Do not change this string, it is important !'\
- [:keysize - len(key)]
- elif len(key) > keysize:
- key = key[:keysize]
- cipher = cc(key,Ciphers.CBC)
- return cipher
-
-def reset_key():
-
- global _key
-
- _key = ''
-
-###
-
-def encrypt(filename,ciphername,overwrite=0):
-
- if verbose:
- print 'Encrypting:',filename
- if filename[-4:] == '.enc':
- raise OperationalError,'already encrypted'
- if not os.path.isfile(filename):
- raise OperationalError,'not a file or not found'
-
- # Check overwrites
- if os.path.exists(filename + '.enc'):
- if not overwrite:
- raise OperationalError,'would overwrite an existing file'
- elif os.path.samefile(filename, filename + '.enc'):
- raise OperationalError,'would overwrite the original file'
-
- # Open plain file
- f = open(filename,'rb')
- size = filesize(f)
- if verbose:
- print ' total size: %i bytes' % size
-
- # Open work file
- workfilename = tempfile(filename)
- out = open(workfilename,'wb')
-
- try:
- # Init cipher and write header
- cipher = get_cipher(ciphername,check=1)
- out.write('enc %s %s %i\n' % \
- (repr(filename),ciphername,size))
-
- # Init hash and blocksize
- hash = Hashes.MD5()
- blocksize = size
- if blocksize > MAX_BLOCKSIZE:
- blocksize = MAX_BLOCKSIZE
- blocksize = ((blocksize + cipher.blocksize - 1) / cipher.blocksize) \
- * cipher.blocksize
-
- # Write the encrypted data in blocks
- bytesread = 0
- while bytesread < size:
- if verbose:
- print ' reading %i bytes...' % blocksize,
- block = f.read(blocksize)
- if verbose:
- print 'read %i bytes' % len(block)
- bytesread = bytesread + len(block)
- hash.update(block)
- if bytesread == size:
- # Final block
- offset = len(block) % cipher.blocksize
- if offset:
- padsize = cipher.blocksize - offset
- block = block + '\0'*padsize
- if verbose:
- print ' padding with %i bytes' % (padsize)
- encblock = cipher.encrypt(block)
- out.write(encblock)
-
- # Write hash value
- hash_value = hash.digest()
- if verbose:
- print ' hash value:',repr(hash_value)
- out.write(hash_value)
-
- # Copy work file to .enc file
- out.close()
- f.close()
- os.rename(workfilename,filename+'.enc')
- workfilename = None
-
- finally:
- if workfilename:
- if not out.closed:
- out.close()
- os.remove(workfilename)
-
-###
-
-def decrypt(filename,overwrite=0):
-
- if verbose:
- print 'Decrypting:',filename
- if filename[-4:] != '.enc':
- raise OperationalError,'decrypt a plain file'
- if not os.path.isfile(filename):
- raise OperationalError,'not a file or not found'
-
- # Read header from cipher file
- f = open(filename,'rb')
- header = string.split(f.readline())
- if len(header) != 4:
- raise OperationalError,'wrong header format:'+ str(header)
- origfilename = eval(header[1])
- ciphername = header[2]
- size = string.atoi(header[3])
- if verbose:
- print ' total size: %i bytes' % size
-
- # Check overwrites
- if os.path.exists(origfilename):
- if not overwrite:
- raise OperationalError,'would overwrite an existing file'
- elif os.path.samefile(origfilename, filename):
- raise OperationalError,'would overwrite the encrypted file'
-
- # Open work file
- workfilename = tempfile(filename)
- out = open(workfilename,'wb')
-
- try:
-
- # Load cipher and init hash
- cipher = get_cipher(ciphername)
- hash = Hashes.MD5()
-
- # Read the encrypted data in blocks
- blocksize = size
- if blocksize > MAX_BLOCKSIZE:
- blocksize = MAX_BLOCKSIZE
- blocksize = ((blocksize + cipher.blocksize - 1) / cipher.blocksize) \
- * cipher.blocksize
- bytesread = 0
- while bytesread < size:
- if size - bytesread < blocksize:
- # Read remaining data only
- blocksize = size - bytesread
- blocksize = ((blocksize + cipher.blocksize - 1) / \
- cipher.blocksize) * cipher.blocksize
- if verbose:
- print ' reading %i bytes...' % blocksize,
- encblock = f.read(blocksize)
- if verbose:
- print 'read %i bytes' % len(encblock)
- bytesread = bytesread + len(encblock)
- block = cipher.decrypt(encblock)
- if bytesread > size:
- # Depad
- padsize = bytesread - size
- block = block[:-padsize]
- if verbose:
- print ' depadded last block by %i bytes' % (padsize)
- hash.update(block)
- out.write(block)
-
- # Check hash value
- hash_value = f.read(hash.digestsize)
- if verbose:
- print ' hash value:',repr(hash_value)
- if hash_value != hash.digest():
- raise OperationalError,'data corrupt'
-
- # Copy workfile to origfile
- out.close()
- f.close()
- os.rename(workfilename,origfilename)
- workfilename = None
-
- finally:
- if workfilename:
- if not out.closed:
- out.close()
- os.remove(workfilename)
-
-###
-
-class Encrypt(Application):
-
- header = "File encryption utility using the SSLeay ciphers"
-
- about = """\
-Encrypts or decrypts the files given on the command line. If no
-options are given the filenames extensions are taken as hint: '.enc'
-means encrypted, everything else not encrypted. The utility then goes
-and switches the state of the files. Overwriting of files only takes
-place in case the '-O' switch is set.
-
-The following ciphers are supported:
- RC2, RC4, RC5, IDEA, Blowfish, DES, DES3, CAST
-
-This tool comes with NO WARRANTY. Use at YOUR OWN RISK. It may destroy
-data ! There is NO way to recover a forgotten pass phrase !
-"""
-
- options = [SwitchOption('-e', 'encrypt'),
- SwitchOption('-d', 'decyrpt'),
- SwitchOption('-a', 'use the same key for all files'),
- SwitchOption('-O', 'allow overwrites (use with care)'),
- ArgumentOption('-c', 'cipher to use', 'RC5'),
- ]
-
- def main(self):
-
- overwrite = self.values['-O']
- ciphername = self.values['-c']
- samekey = self.values['-a']
- for file in self.files:
- if not samekey:
- reset_key()
- print '-'*78
- print 'Working on file:',file
- try:
- if self.values['-e']:
- encrypt(file,ciphername,overwrite)
- elif self.values['-d']:
- decrypt(file,overwrite)
- elif file[-4:] != '.enc':
- encrypt(file,ciphername,overwrite)
- else:
- decrypt(file,overwrite)
- except OperationalError,why:
- print '%s skipped -- %s' % (file,why)
- except IOError,(code,why):
- print '%s skipped -- %s' % (file,why)
- except os.error,why:
- print '%s skipped -- %s' % (file,why)
- except KeyboardInterrupt:
- print '*user break*'
- break
-
-if __name__ == '__main__':
- Encrypt()
diff --git a/Demo/secimp/README b/Demo/secimp/README
deleted file mode 100644
index 94a6e30..0000000
--- a/Demo/secimp/README
+++ /dev/null
@@ -1,24 +0,0 @@
-
-This is a simple demonstration of adding an import hook that verifies
-a digital signature on a Python code object before allowing it to be
-imported. There are three files:
-
- * sign.py, which signs all the *.pyc files in the directories
-listed on the command line. The contents of the .pyc file is stored
-along with the signature in a file whose name ends with .pys .
-
- * secimp.py, which implements a secimport() function which
-will use *.pys files.
-
- * testkey.py is the key used to sign and verify *.pys files.
-
-To try it out:
- 1. Run "sign.py ." to compile and sign all the *.py files in
-the current directory.
-
- 2. Run secimp.py from the command-line; it will try to
-securely import testkey.pys, which should succeed.
-
- 3. Fire up your favorite editor, and change a single byte in a
-string somewhere in testkey.pys. Run secimp.py again; it should raise
-an exception when the signature can't be verified.
diff --git a/Demo/secimp/secimp.py b/Demo/secimp/secimp.py
deleted file mode 100644
index d4f38fc..0000000
--- a/Demo/secimp/secimp.py
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/local/bin/python
-
-import sys ; sys.path = ['../../../'] + sys.path
-
-import imp, os
-from sys import modules
-
-# Secure import:
-def secimport(name, globals=None, locals=None, fromlist=None):
- # Fast path: let's see if it's already in sys.modules.
- # Two speed optimizations are worth mentioning:
- # - We use 'modules' instead of 'sys.modules'; this saves a
- # dictionary look-up per call.
- # - It's also faster to use a try-except statement than
- # to use modules.has_key(name) to check if it's there.
- try:
- return modules[name]
- except KeyError:
- pass
-
- # See if it's a built-in module
- m = imp.init_builtin(name)
- if m:
- return m
-
- # See if it's a frozen module
- m = imp.init_frozen(name)
- if m:
- return m
-
- # Search the default path (i.e. sys.path).
- # If this raises an exception, the module is not found --
- # let the caller handle the exception.
- fp, pathname, (suffix, mode, type) = imp.find_module(name)
-
- # See what we got...
- # Note that fp will be closed automatically when we return.
-
- # Extensions are written in C, and can just be loaded.
- if type == imp.C_EXTENSION:
- return imp.load_dynamic(name, pathname)
-
- # For a compiled or source file, we'll check if there is a *.pys file
- # present in the same directory.
- if type == imp.PY_COMPILED or type == imp.PY_SOURCE:
- root, ext = os.path.splitext(pathname)
- testfile = root + '.pys'
- try:
- print testfile
- secfile=open(testfile, 'rb')
- except IOError, tuple:
- if (tuple[0]==2): pass # Ignore 'file not found' error
- else: raise IOError, tuple
- else:
- # Check the signature (a signed hash of the code object).
- # We could sign the whole code object, but that would
- # require a huge key and would double the size of the
- # *.pys file.
- import marshal
- from Crypto.Hash import MD5
- fp.close() # Close the original *.pyc file
- from testkey import key # Get the key for verification
- signature=marshal.load(secfile) # Read signature
- position=secfile.tell() # Save position
- data=secfile.read() # Read code object
- hash=MD5.new(data).digest() # Compute its hash value
- ##print 'sigcheck:', key.verify(hash, signature)
- if (not key.verify(hash, signature)):
- raise ImportError, 'Signature check of '+ testfile + ' failed'
- secfile.seek(position) # Rewind pointer to the
- # beginning of the code object
- fp=secfile
- del secfile
- # Now we can happily import the compiled code object.
- return imp.load_compiled(name, pathname, fp)
-
- # Shouldn't get here at all.
- raise ImportError, '%s: unknown module type (%d)' % (name, type)
-
-if __name__=='__main__':
- # A sample invocation of the secure import looks like this:
- print 'Attempting secure import'
- r=secimport('testkey')
- print 'Secure import succeeded'
diff --git a/Demo/secimp/sign.py b/Demo/secimp/sign.py
deleted file mode 100755
index f989159..0000000
--- a/Demo/secimp/sign.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/env python
-
-# Using the public key defined in testkey.py, sign all *.pyc files in
-# the listed directories.
-
-from testkey import *
-from Crypto.Hash import MD5
-import os, glob, sys
-import marshal, compileall
-
-filelist = []
-if (len(sys.argv)>1):
- for dir in sys.argv[1:]:
- dir=os.path.join(dir, '')
- compileall.compile_dir(dir)
- filelist=filelist + glob.glob(dir + '*.pyc')
-else:
- print "Usage: sign.py dir1 dir2 dir3 ..."
- print " All *.pyc files in the listed directories will be signed,"
- print "leaving the signatures in *.pys files."
- sys.exit(0)
-
-if len(filelist)==0:
- print "No *.pyc files found"
- sys.exit(0)
-
-for file in filelist:
- input=open(file, 'rb')
- try:
- os.unlink(file[:-4]+'.pys') # Delete any existing signed file
- except os.error, tuple:
- if (tuple[0]==2): pass # Ignore 'file not found' error
- else: raise os.error, tuple
- output=open(file[:-4]+'.pys', 'wb')
- data=input.read()
- hash=MD5.new(data).digest() # Compute hash of the code object
- K = "random bytes"
- signature=key.sign(hash, K) # Sign the hash value
- marshal.dump(signature, output) # Save signature to the file
- output.write(data) # Copy code object to signed file
- input.close()
- output.close()
- print os.path.basename(file)+ ' processed.'
-
-
-
diff --git a/Demo/secimp/testkey.py b/Demo/secimp/testkey.py
deleted file mode 100644
index e8fef6c..0000000
--- a/Demo/secimp/testkey.py
+++ /dev/null
@@ -1,41 +0,0 @@
-
-import sys
-import Crypto.PublicKey.DSA
-
-key = Crypto.PublicKey.DSA.construct((
- # y
- 0x43E9162E224CBD1B66D7C27EB7E795392310B5E7AC6E0B1F60021F5E03F90E851CB7F76603FAE73907154371AE04EDBF0D9D557DF03488F34C18324B8DFEF5D2L,
- # g
- 0x4D6DB63479E55D0BE31CF1BEA58AB9365FC5EA267FFCD8424B56390E6EE7DD9BF788F696EED8475516353E61F37B8441137FA4F8DC82A9F84FA52BCD37517C32L,
- # p
- 0x8000011124427A59DC0AF8AC982B490C75B1B3E94042F50F500E0636391C6FCC8C13E628528B4B75E158618A34592D5A68CA684371F9678BBA54DD40C0020F25L,
- # q
- 0x9B128544B02353FF961E1774D2FA94E52E078F5DL,
- # x
- 0x991386B7B92C221E42B1386D61255F5C58FD79A7L,
-))
-
-if __name__ == '__main__':
- # Running this script directly will generate a new key and print it out
- from Crypto.PublicKey import DSA
- from Crypto.Util.randpool import KeyboardRandomPool
-
- pool = KeyboardRandomPool(numbytes = 64)
- pool.randomize()
-
- if len(sys.argv) == 2:
- keylen = int(sys.argv[1])
- elif len(sys.argv) == 1:
- keylen = 512
- else:
- print >>sys.stderr, 'Usage: '+sys.argv[0]+' [keylen]'
- sys.exit(1)
- key = DSA.generate(keylen, pool.get_bytes, sys.stdout.write)
- print "key = Crypto.PublicKey.DSA.construct(("
- for field in key.keydata:
- print " #", field
- print " " + hex(getattr(key, field)) + ","
- print '))'
-
-
-
diff --git a/Doc/pycrypt.tex b/Doc/pycrypt.tex
index 926c422..1e38640 100644
--- a/Doc/pycrypt.tex
+++ b/Doc/pycrypt.tex
@@ -1065,102 +1065,6 @@ the number of words in \var{string} must be a multiple of 6.
%======================================================================
-\section{The Demonstration Programs}
-
-The Python Cryptography Toolkit comes with various demonstration
-programs, located in the \file{Demo/} directory. None of them is
-particularly well-finished or suitable for serious use. Rather,
-they're intended to illustrate how the toolkit is used, and to provide
-some interesting possible uses. Feel free to incorporate the code (or
-modifications of it) into your own programs.
-
-\subsection{Demo 1: \file{cipher}}
-
-\file{cipher} encrypts and decrypts files. On most Unix systems, the
-\file{crypt} program uses a variant of the Enigma cipher. This is not
-secure, and there exists a freely available program called ``Crypt
-Breaker's Workbench'' which helps in breaking the cipher if you have
-some knowledge of the encrypted data.
-
-\file{cipher} is a more secure file encryption program. Simply list
-the names of the files to be encrypted on the command line.
-\file{cipher} will go through the list and encrypt or decrypt them;
-\file{cipher} can recognize files it has previously encrypted. The
-ciphertext of a file is placed in a file of the same name with
-'\samp{.cip}' appended; the original file is not deleted, since I'm
-not sure that all errors during operation are caught, and I don't want
-people to accidentally erase important files.
-
-There are two command-line options: \programopt{-c} and
-\programopt{-k}. Both of them require an argument. \code{-c
-\var{ciphername}} uses the given encryption algorithm
-\var{ciphername}; for example, \code{-c des} will use the DES
-algorithm. The name should be the same as an available module name;
-thus it should be in lowercase letters. The default cipher is IDEA.
-
-\code{-k \var{key}} can be used to set the encryption key to be used.
-Note that on a multiuser Unix system, the \code{ps} command can be
-used to view the arguments of commands executed by other users, so
-this is insecure; if you're the only user (say, on your home computer
-running Linux) you don't have to worry about this. If no key is set
-on the command line, \file{cipher} will prompt the user to input a key
-on standard input.
-
-
-\subsubsection{Technical Details}
-
-The encrypted file is not pure ciphertext. First comes a magic
-string; this is currently the sequence \samp{ctx} and a byte
-containing 1 (the version number of \file{cipher}).
-This is followed by the null-terminated name of the encryption
-algorithm, and the rest of the file contains the ciphertext.
-
-The plaintext is encrypted in CBC mode. The initial value for the
-feedback is always set to a block filled with the letter 'A', and then
-a block of random data is encrypted. This garbage block will be
-discarded on decryption. Note that the random data is not generated
-in a cryptographically secure way, and this may provide a tiny foothold for
-an attacker.
-
-After the random block is generated, the magic string, length of the
-original file, and original filename are all encrypted before the file
-data is finally processed. Some extra characters of padding may be
-added to obtain an integer number of blocks. This padding will also
-be discarded on decryption. Note that the plaintext file will be
-completely read into memory before encryption is performed; no
-buffering is done. Therefore, don't encrypt 20-megabyte files unless
-you're willing to face the consequences of a 20-megabyte process.
-
-Areas for improvements to \file{cipher} are: cryptographically secure
-generation of random data for padding, key entry, and buffering of
-file input.
-
-
-\subsection{Demo 2: \file{secimp} and \file{sign}}
-
-\file{secimp} demonstrates an application of the Toolkit that may be
-useful if Python is being used as an extension language for mail and Web
-clients: secure importing of Python modules. To use it, run
-\file{sign.py} in a directory with several compiled Python files
-present. It will use the key in \file{testkey.py} to generate digital
-signatures for the compiled Python code, and save both the signature and
-the code in a file ending in \samp{.pys}. Then run \code{python -i
-secimp.py}, and import a file by using \code{secimport}.
-
-For example, if \file{foo.pys} was constructed, do
-\code{secimport('foo')}. The import should succeed. Now fire up Emacs
-or some other editor, and change a string in the code in \file{foo.pys};
-you might try changing a letter in the name of a variable. When you run
-\code{secimport('foo')}, it should raise an exception reporting the
-failed signature. If you execute the statement \code{__import__ =
-secimport}, the secure import will be used by default for all future
-module imports. Alternatively, if you were creating a restricted
-execution environment using \file{rexec.py}, you could place
-\code{secimport()} in the restricted environment's namespace as the
-default import function.
-
-
-%======================================================================
\section{Extending the Toolkit}
Preserving the a common interface for cryptographic routines is a good
diff --git a/MANIFEST b/MANIFEST
index 0a98d89..d19134e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,14 +1,6 @@
ACKS
ChangeLog
Cipher/__init__.py
-Demo/README
-Demo/chaum.py
-Demo/cipher
-Demo/enc.py
-Demo/secimp/README
-Demo/secimp/secimp.py
-Demo/secimp/sign.py
-Demo/secimp/testkey.py
Doc/pycrypt.tex
Hash/HMAC.py
Hash/MD5.py
diff --git a/TODO b/TODO
index 70459f2..a79ad71 100644
--- a/TODO
+++ b/TODO
@@ -3,8 +3,6 @@
* Manual and Web page: point to SF project for bug reports
-* Update the demos
-
* Update documentation (mention dodgy status of PublicKey code)
* Clean up markup in pycrypt.tex
@@ -27,9 +25,6 @@ time.
* A secret sharing module should be added to Util or Protocols.
-Demo programs:
- Shadowing of files into X parts
-
Documentation:
Document chaff/winnow better
Add docstrings everywhere.