2002-04-03 18:45:09 -07:00
|
|
|
#! /usr/bin/env python
|
2009-08-03 15:14:44 -04:00
|
|
|
#
|
|
|
|
# setup.py : Distutils setup script
|
|
|
|
#
|
|
|
|
# Part of the Python Cryptography Toolkit
|
|
|
|
#
|
|
|
|
# ===================================================================
|
|
|
|
# Portions Copyright (c) 2001, 2002, 2003 Python Software Foundation;
|
|
|
|
# All Rights Reserved
|
|
|
|
#
|
|
|
|
# This file contains code from the Python 2.2 setup.py module (the
|
|
|
|
# "Original Code"), with modifications made after it was incorporated
|
|
|
|
# into PyCrypto (the "Modifications").
|
|
|
|
#
|
|
|
|
# To the best of our knowledge, the Python Software Foundation is the
|
|
|
|
# copyright holder of the Original Code, and has licensed it under the
|
|
|
|
# Python 2.2 license. See the file LEGAL/copy/LICENSE.python-2.2 for
|
|
|
|
# details.
|
|
|
|
#
|
|
|
|
# The Modifications to this file are dedicated to the public domain.
|
|
|
|
# To the extent that dedication to the public domain is not available,
|
|
|
|
# everyone is granted a worldwide, perpetual, royalty-free,
|
|
|
|
# non-exclusive license to exercise all rights associated with the
|
|
|
|
# contents of this file for any purpose whatsoever. No rights are
|
|
|
|
# reserved.
|
|
|
|
#
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
|
|
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
# SOFTWARE.
|
|
|
|
# ===================================================================
|
2002-07-11 14:31:19 -07:00
|
|
|
|
2008-08-06 21:27:50 -04:00
|
|
|
__revision__ = "$Id$"
|
2002-07-11 14:31:19 -07:00
|
|
|
|
2003-02-28 17:55:21 -07:00
|
|
|
from distutils import core
|
2008-11-21 13:04:18 -05:00
|
|
|
from distutils.core import Extension, Command
|
2003-02-28 17:38:29 -07:00
|
|
|
from distutils.command.build_ext import build_ext
|
|
|
|
import os, sys
|
2008-09-15 21:32:58 -04:00
|
|
|
import struct
|
2002-04-03 18:45:09 -07:00
|
|
|
|
2002-07-18 13:05:37 -07:00
|
|
|
if sys.version[0:1] == '1':
|
|
|
|
raise RuntimeError, ("The Python Cryptography Toolkit requires "
|
|
|
|
"Python 2.x to build.")
|
|
|
|
|
2002-06-19 13:07:12 -07:00
|
|
|
if sys.platform == 'win32':
|
|
|
|
HTONS_LIBS = ['ws2_32']
|
2002-10-23 04:52:20 -07:00
|
|
|
plat_ext = [
|
2008-09-17 11:00:45 -04:00
|
|
|
Extension("Crypto.Random.OSRNG.winrandom",
|
2002-10-23 04:52:20 -07:00
|
|
|
libraries = HTONS_LIBS + ['advapi32'],
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/winrand.c"])
|
|
|
|
]
|
2002-06-19 13:07:12 -07:00
|
|
|
else:
|
|
|
|
HTONS_LIBS = []
|
2002-10-23 04:52:20 -07:00
|
|
|
plat_ext = []
|
2003-02-28 17:38:29 -07:00
|
|
|
|
2008-08-13 23:11:05 -04:00
|
|
|
# List of pure Python modules that will be excluded from the binary packages.
|
|
|
|
# The list consists of (package, module_name) tuples
|
|
|
|
from distutils.command.build_py import build_py
|
|
|
|
EXCLUDE_PY = [
|
2008-08-14 16:57:22 -04:00
|
|
|
('Crypto.Hash', 'RIPEMD160'), # Included for your amusement, but the C version is much faster.
|
2008-08-13 23:11:05 -04:00
|
|
|
]
|
|
|
|
|
2003-02-28 17:38:29 -07:00
|
|
|
# Functions for finding libraries and files, copied from Python's setup.py.
|
|
|
|
|
|
|
|
def find_file(filename, std_dirs, paths):
|
|
|
|
"""Searches for the directory where a given file is located,
|
|
|
|
and returns a possibly-empty list of additional directories, or None
|
|
|
|
if the file couldn't be found at all.
|
|
|
|
|
|
|
|
'filename' is the name of a file, such as readline.h or libcrypto.a.
|
|
|
|
'std_dirs' is the list of standard system directories; if the
|
|
|
|
file is found in one of them, no additional directives are needed.
|
|
|
|
'paths' is a list of additional locations to check; if the file is
|
|
|
|
found in one of them, the resulting list will contain the directory.
|
|
|
|
"""
|
|
|
|
|
|
|
|
# Check the standard locations
|
|
|
|
for dir in std_dirs:
|
|
|
|
f = os.path.join(dir, filename)
|
|
|
|
if os.path.exists(f): return []
|
|
|
|
|
|
|
|
# Check the additional directories
|
|
|
|
for dir in paths:
|
|
|
|
f = os.path.join(dir, filename)
|
|
|
|
if os.path.exists(f):
|
|
|
|
return [dir]
|
|
|
|
|
|
|
|
# Not found anywhere
|
|
|
|
return None
|
|
|
|
|
|
|
|
def find_library_file(compiler, libname, std_dirs, paths):
|
|
|
|
filename = compiler.library_filename(libname, lib_type='shared')
|
|
|
|
result = find_file(filename, std_dirs, paths)
|
|
|
|
if result is not None: return result
|
|
|
|
|
|
|
|
filename = compiler.library_filename(libname, lib_type='static')
|
|
|
|
result = find_file(filename, std_dirs, paths)
|
|
|
|
return result
|
|
|
|
|
2008-09-15 21:32:58 -04:00
|
|
|
def endianness_macro():
|
2008-09-16 12:48:24 -04:00
|
|
|
s = struct.pack("@I", 0x33221100)
|
2008-09-15 21:32:58 -04:00
|
|
|
if s == "\x00\x11\x22\x33": # little endian
|
|
|
|
return ('PCT_LITTLE_ENDIAN', 1)
|
|
|
|
elif s == "\x33\x22\x11\x00": # big endian
|
|
|
|
return ('PCT_BIG_ENDIAN', 1)
|
|
|
|
raise AssertionError("Machine is neither little-endian nor big-endian")
|
|
|
|
|
2003-02-28 17:38:29 -07:00
|
|
|
class PCTBuildExt (build_ext):
|
|
|
|
def build_extensions(self):
|
|
|
|
self.extensions += [
|
|
|
|
# Hash functions
|
|
|
|
Extension("Crypto.Hash.MD4",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/MD4.c"]),
|
2003-12-19 15:24:25 -07:00
|
|
|
Extension("Crypto.Hash.SHA256",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/SHA256.c"]),
|
2008-08-14 16:57:22 -04:00
|
|
|
Extension("Crypto.Hash.RIPEMD160",
|
|
|
|
include_dirs=['src/'],
|
2008-09-15 21:32:58 -04:00
|
|
|
sources=["src/RIPEMD160.c"],
|
|
|
|
define_macros=[endianness_macro()]),
|
2003-02-28 17:38:29 -07:00
|
|
|
|
|
|
|
# Block encryption algorithms
|
|
|
|
Extension("Crypto.Cipher.AES",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/AES.c"]),
|
|
|
|
Extension("Crypto.Cipher.ARC2",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/ARC2.c"]),
|
2009-03-01 10:00:45 -05:00
|
|
|
Extension("Crypto.Cipher.Blowfish",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/Blowfish.c"]),
|
2003-02-28 17:38:29 -07:00
|
|
|
Extension("Crypto.Cipher.CAST",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/CAST.c"]),
|
2009-03-01 16:10:59 -05:00
|
|
|
Extension("Crypto.Cipher.DES",
|
|
|
|
include_dirs=['src/', 'src/libtom/'],
|
|
|
|
sources=["src/DES.c"]),
|
|
|
|
Extension("Crypto.Cipher.DES3",
|
|
|
|
include_dirs=['src/', 'src/libtom/'],
|
|
|
|
sources=["src/DES3.c"]),
|
2003-02-28 17:38:29 -07:00
|
|
|
|
|
|
|
# Stream ciphers
|
|
|
|
Extension("Crypto.Cipher.ARC4",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/ARC4.c"]),
|
2009-08-02 13:39:55 -04:00
|
|
|
Extension("Crypto.Cipher.XOR",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/XOR.c"]),
|
2008-09-14 18:13:35 -04:00
|
|
|
|
|
|
|
# Utility modules
|
|
|
|
Extension("Crypto.Util.strxor",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=['src/strxor.c']),
|
2008-08-16 20:17:01 -04:00
|
|
|
|
|
|
|
# Counter modules
|
|
|
|
Extension("Crypto.Util._counter",
|
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=['src/_counter.c']),
|
2003-02-28 17:38:29 -07:00
|
|
|
]
|
|
|
|
|
2008-09-14 21:38:28 -04:00
|
|
|
# Platform-specific modules
|
|
|
|
self.extensions += plat_ext
|
|
|
|
|
2003-02-28 17:38:29 -07:00
|
|
|
# Detect which modules should be compiled
|
|
|
|
self.detect_modules()
|
2009-03-10 23:40:47 -04:00
|
|
|
|
|
|
|
# Speed up execution by tweaking compiler options. This especially
|
|
|
|
# helps the DES modules.
|
|
|
|
if not self.debug and self.compiler.compiler_type in ('unix', 'cygwin', 'mingw32'):
|
|
|
|
self.__remove_compiler_option("-g")
|
|
|
|
self.__remove_compiler_option("-O")
|
|
|
|
self.__remove_compiler_option("-O2")
|
|
|
|
self.__add_compiler_option("-O3")
|
|
|
|
self.__add_compiler_option("-fomit-frame-pointer")
|
|
|
|
|
|
|
|
# Call the superclass's build_extensions method
|
2003-02-28 17:38:29 -07:00
|
|
|
build_ext.build_extensions(self)
|
|
|
|
|
|
|
|
def detect_modules (self):
|
2008-11-16 11:39:38 -05:00
|
|
|
if self.compiler.compiler_type == 'msvc':
|
|
|
|
self.compiler.include_dirs.insert(0, "src/inc-msvc/")
|
2003-02-28 17:38:29 -07:00
|
|
|
lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib']
|
|
|
|
inc_dirs = self.compiler.include_dirs + ['/usr/include']
|
|
|
|
exts = []
|
|
|
|
if (self.compiler.find_library_file(lib_dirs, 'gmp')):
|
2003-04-03 19:17:41 -07:00
|
|
|
exts.append(Extension("Crypto.PublicKey._fastmath",
|
2003-02-28 17:38:29 -07:00
|
|
|
include_dirs=['src/'],
|
|
|
|
libraries=['gmp'],
|
2003-04-03 19:17:41 -07:00
|
|
|
sources=["src/_fastmath.c"]))
|
2008-09-20 17:25:34 -04:00
|
|
|
else:
|
|
|
|
print >>sys.stderr, "warning: GMP library not found; Not building Crypto.PublicKey._fastmath."
|
2003-02-28 17:38:29 -07:00
|
|
|
self.extensions += exts
|
|
|
|
|
2009-03-10 23:40:47 -04:00
|
|
|
def __remove_compiler_option(self, option):
|
|
|
|
"""Remove the specified compiler option.
|
|
|
|
|
|
|
|
Return true if the option was found. Return false otherwise.
|
|
|
|
"""
|
|
|
|
found = 0
|
|
|
|
for attrname in ('compiler', 'compiler_so'):
|
|
|
|
compiler = getattr(self.compiler, attrname, None)
|
|
|
|
if compiler is not None:
|
|
|
|
while option in compiler:
|
|
|
|
compiler.remove(option)
|
|
|
|
found += 1
|
|
|
|
return found
|
|
|
|
|
|
|
|
def __add_compiler_option(self, option):
|
|
|
|
for attrname in ('compiler', 'compiler_so'):
|
|
|
|
compiler = getattr(self.compiler, attrname, None)
|
|
|
|
if compiler is not None:
|
|
|
|
compiler.append(option)
|
|
|
|
|
2008-08-13 23:11:05 -04:00
|
|
|
class PCTBuildPy(build_py):
|
|
|
|
def find_package_modules(self, package, package_dir, *args, **kwargs):
|
|
|
|
modules = build_py.find_package_modules(self, package, package_dir, *args, **kwargs)
|
|
|
|
|
|
|
|
# Exclude certain modules
|
2008-09-15 18:16:11 -04:00
|
|
|
retval = []
|
|
|
|
for item in modules:
|
|
|
|
pkg, module = item[:2]
|
2008-08-13 23:11:05 -04:00
|
|
|
if (pkg, module) in EXCLUDE_PY:
|
|
|
|
continue
|
2008-09-15 18:16:11 -04:00
|
|
|
retval.append(item)
|
|
|
|
return retval
|
2008-08-13 23:11:05 -04:00
|
|
|
|
2008-11-21 13:04:18 -05:00
|
|
|
class TestCommand(Command):
|
|
|
|
|
|
|
|
description = "Run self-test"
|
|
|
|
|
|
|
|
user_options = [
|
|
|
|
('skip-slow-tests', None,
|
|
|
|
'Skip slow tests')
|
|
|
|
]
|
|
|
|
|
|
|
|
def initialize_options(self):
|
|
|
|
self.build_dir = None
|
|
|
|
self.skip_slow_tests = None
|
|
|
|
|
|
|
|
def finalize_options(self):
|
|
|
|
self.set_undefined_options('install', ('build_lib', 'build_dir'))
|
|
|
|
self.config = {'slow_tests': not self.skip_slow_tests}
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
# Run SelfTest
|
|
|
|
self.announce("running self-tests")
|
|
|
|
old_path = sys.path[:]
|
|
|
|
try:
|
|
|
|
sys.path.insert(0, self.build_dir)
|
|
|
|
from Crypto import SelfTest
|
|
|
|
SelfTest.run(verbosity=self.verbose, stream=sys.stdout, config=self.config)
|
|
|
|
finally:
|
|
|
|
# Restore sys.path
|
|
|
|
sys.path[:] = old_path
|
|
|
|
|
|
|
|
# Run slower self-tests
|
|
|
|
self.announce("running extended self-tests")
|
|
|
|
|
2003-02-28 17:55:21 -07:00
|
|
|
kw = {'name':"pycrypto",
|
2009-08-18 20:18:29 -04:00
|
|
|
'version':"2.1.0a2", # See also: lib/Crypto/__init__.py
|
2003-02-28 17:55:21 -07:00
|
|
|
'description':"Cryptographic modules for Python.",
|
|
|
|
'author':"A.M. Kuchling",
|
2003-03-07 21:32:47 -07:00
|
|
|
'author_email':"amk@amk.ca",
|
2004-08-14 11:48:18 -07:00
|
|
|
'url':"http://www.amk.ca/python/code/crypto",
|
2003-02-28 17:38:29 -07:00
|
|
|
|
2008-11-21 13:04:18 -05:00
|
|
|
'cmdclass' : {'build_ext':PCTBuildExt, 'build_py': PCTBuildPy, 'test': TestCommand },
|
2003-02-28 17:55:21 -07:00
|
|
|
'packages' : ["Crypto", "Crypto.Hash", "Crypto.Cipher", "Crypto.Util",
|
2008-09-17 11:00:45 -04:00
|
|
|
"Crypto.Random",
|
2008-09-20 12:04:40 -04:00
|
|
|
"Crypto.Random.Fortuna",
|
2008-09-17 11:00:45 -04:00
|
|
|
"Crypto.Random.OSRNG",
|
2008-09-12 15:26:24 -04:00
|
|
|
"Crypto.SelfTest",
|
2008-09-13 00:13:29 -04:00
|
|
|
"Crypto.SelfTest.Cipher",
|
2008-09-12 15:26:24 -04:00
|
|
|
"Crypto.SelfTest.Hash",
|
2008-11-21 13:05:35 -05:00
|
|
|
"Crypto.SelfTest.Protocol",
|
2008-09-18 23:48:38 -04:00
|
|
|
"Crypto.SelfTest.PublicKey",
|
2008-09-17 13:35:25 -04:00
|
|
|
"Crypto.SelfTest.Random",
|
2008-09-20 12:04:40 -04:00
|
|
|
"Crypto.SelfTest.Random.Fortuna",
|
2008-09-17 13:35:25 -04:00
|
|
|
"Crypto.SelfTest.Random.OSRNG",
|
2008-09-15 18:59:25 -04:00
|
|
|
"Crypto.SelfTest.Util",
|
2002-05-23 13:22:04 -07:00
|
|
|
"Crypto.Protocol", "Crypto.PublicKey"],
|
2009-02-28 13:17:31 -05:00
|
|
|
'package_dir' : { "Crypto": "lib/Crypto" },
|
2003-02-28 17:38:29 -07:00
|
|
|
# One module is defined here, because build_ext won't be
|
|
|
|
# called unless there's at least one extension module defined.
|
2003-02-28 17:55:21 -07:00
|
|
|
'ext_modules':[Extension("Crypto.Hash.MD2",
|
2003-02-28 17:38:29 -07:00
|
|
|
include_dirs=['src/'],
|
|
|
|
sources=["src/MD2.c"])],
|
2003-02-28 17:55:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
# If we're running Python 2.3, add extra information
|
|
|
|
if hasattr(core, 'setup_keywords'):
|
|
|
|
if 'classifiers' in core.setup_keywords:
|
|
|
|
kw['classifiers'] = [
|
|
|
|
'Development Status :: 4 - Beta',
|
|
|
|
'License :: Public Domain',
|
|
|
|
'Intended Audience :: Developers',
|
|
|
|
'Operating System :: Unix',
|
|
|
|
'Operating System :: Microsoft :: Windows',
|
|
|
|
'Operating System :: MacOS :: MacOS X',
|
|
|
|
'Topic :: Security :: Cryptography',
|
|
|
|
]
|
|
|
|
if 'download_url' in core.setup_keywords:
|
2003-04-07 16:09:41 -07:00
|
|
|
kw['download_url'] = ('http://www.amk.ca/files/python/crypto/'
|
2003-02-28 17:55:21 -07:00
|
|
|
'%s-%s.tar.gz' % (kw['name'], kw['version']) )
|
|
|
|
|
|
|
|
core.setup(**kw)
|
2002-04-03 18:45:09 -07:00
|
|
|
|