Skip to content
Commits on Source (81)
image: python:2.7
test:
script:
- apt-get update -q -y
- apt-get install -y swig libssl-dev libssl1.0.0
- apt-get install -y python-setuptools
- python setup.py build
- python setup.py test
language: python
addons:
apt:
packages:
- swig
- libssl-dev
- libssl1.0.0
- python-setuptools
sudo: false
python:
- 2.6
- 2.7
install:
- python setup.py install
script: python setup.py test
====================
Installing M2Crypto
====================
==================== Installing M2Crypto ====================
:Maintainer: Heikki Toivonen
:Web-Site: http://chandlerproject.org/Projects/MeTooCrypto
:Maintainer: Heikki Toivonen :Web-Site:
http://chandlerproject.org/Projects/MeTooCrypto
.. contents::
Pre-requisites
----------------
--------------
The following software packages are pre-requisites:
- **Python 2.6 or newer**
- **OpenSSL 0.9.7 or newer**
- **SWIG 1.3.28 or newer**
- **Python 2.6 or newer**
- **OpenSSL 1.0.1e or newer**
- **SWIG 1.3.40 or newer**
- Python 2.6 platforms require the Python package unittest2 to be
installed
Note about OpenSSL versions early in the 0.9.7 series
-----------------------------------------------------
Early OpenSSL 0.9.7 versions require the __i386__ symbol to be defined.
Early OpenSSL 0.9.7 versions require the **i386** symbol to be defined.
Uncomment this line in setup.py:
#'-D__i386__', # Uncomment for early OpenSSL 0.9.7 versions
#'-D\_\_i386\_\_', # Uncomment for early OpenSSL 0.9.7 versions
if you get this compile-time error:
This openssl-devel package does not work your architecture?
This openssl-devel package does not work your architecture?
Note about Fedora Core -based Distributions
-----------------------------------------------------
-------------------------------------------
Fedora Core (and RedHat, CentOS etc.) have made changes to OpenSSL
configuration compared to many other Linux distributions. If you can not
build M2Crypto normally, try the fedora_setup.sh script included with
build M2Crypto normally, try the fedora\_setup.sh script included with
M2Crypto sources.
Installing on Unix-like systems, including Cygwin
-------------------------------------------------
::
::
$ tar zxf m2crypto-<version>.tar.gz
......@@ -47,95 +48,97 @@ Installing on Unix-like systems, including Cygwin
$ python setup.py build
$ python setup.py install
If you have installed setuptools you can also optionally run tests like this:
If you have installed setuptools you can also optionally run tests like
this:
::
$ python setup.py test
This assumes OpenSSL is installed in /usr. You can provide an alternate
OpenSSL prefix location with --openssl option to build_ext command. Other
commands accept standard options if you need them.
OpenSSL prefix location with --openssl option to build\_ext command.
Other commands accept standard options if you need them.
Some distributions, like Fedora Core, package OpenSSL headers in a different
location from OpenSSL itself. In that case you need to tell build_ext the
additional include location with -I option.
Some distributions, like Fedora Core, package OpenSSL headers in a
different location from OpenSSL itself. In that case you need to tell
build\_ext the additional include location with -I option.
Differences when installing on Windows
--------------------------------------
Before building from source, you need to install OpenSSL's include files,
import libraries and DLLs. By default setup.py assumes that OpenSSL include
files are in ``c:\pkg\openssl\include``, and the import libraries
in ``c:\pkg\openssl\lib``. As with other platforms, you can specify a different
OpenSSL location with --openssl option to build_ext command.
Before building from source, you need to install OpenSSL's include
files, import libraries and DLLs. By default setup.py assumes that
OpenSSL include files are in ``c:\pkg\openssl\include``, and the import
libraries in ``c:\pkg\openssl\lib``. As with other platforms, you can
specify a different OpenSSL location with --openssl option to build\_ext
command.
Using OpenSSL 0.9.8 on Windows requires Python be built with applink.c
(add an include statement in python.c). This is not a requirement for
Linux or MacOSX. (applink.c is provided by OpenSSL.)
Using OpenSSL 0.9.8 on Windows requires Python be built with applink.c
(add an include statement in python.c). This is not a requirement for
Linux or MacOSX. (applink.c is provided by OpenSSL.)
MSVC++
~~~~~~~~
MSVC++ ~\ :sub:`:sub:`:sub:`~```
setup.py is already configured to work with MSVC++ by default.
With MSVC++, the OpenSSL DLLs, as built, are named ``libeay32.dll``
and ``ssleay32.dll``. Install these somewhere on your PATH; for example
in ``c:\bin``, together with ``openssl.exe``.
With MSVC++, the OpenSSL DLLs, as built, are named ``libeay32.dll`` and
``ssleay32.dll``. Install these somewhere on your PATH; for example in
``c:\bin``, together with ``openssl.exe``.
For MSVC++, the import libraries, as built by OpenSSL, are named
``libeay32.lib`` and ``ssleay32.lib``.
MINGW :sub:`:sub:`:sub:`~```
MINGW
~~~~~~~
.. NOTE::
The following instructions for building M2Crypto with MINGW are from
M2Crypto 0.12. These instructions should continue to work for this release,
although I have not tested them.
.. NOTE:: The following instructions for building M2Crypto with MINGW
are from M2Crypto 0.12. These instructions should continue to work for
this release, although I have not tested them.
Read Sebastien Sauvage's webpage:
::
http://sebsauvage.net/python/mingw.html
For mingw32, the OpenSSL import libraries are named ``libeay32.a`` and
``libssl32.a``. You may need to edit setup.py file for these.
You'll also need to create ``libpython2[123].a``, depending on your version
of Python.
You'll also need to create ``libpython2[123].a``, depending on your
version of Python.
OpenSSL DLLs for mingw32 are named ``libeay32.dll`` and ``libssl32.dll``.
Install these somewhere on your PATH; for example in
OpenSSL DLLs for mingw32 are named ``libeay32.dll`` and
``libssl32.dll``. Install these somewhere on your PATH; for example in
``c:\bin``, together with ``openssl.exe``.
Build M2Crypto:
::
python setup.py build -cmingw32
python setup.py install
BC++ :sub:`:sub:`~``\ ~
BC++
~~~~~~
.. NOTE::
The following instructions for building M2Crypto with MSVC++ 6.0 and
BC++ 5.5 free compiler suite are from M2Crypto 0.10. These instructions
should continue to work for this release, although I have not tested
them.
.. NOTE:: The following instructions for building M2Crypto with MSVC++
6.0 and BC++ 5.5 free compiler suite are from M2Crypto 0.10. These
instructions should continue to work for this release, although I have
not tested them.
For BC++ these files are created from the MSVC++-built ones using the
tool ``coff2omf.exe``. I call them ``libeay32_bc.lib`` and
``ssleay32_bc.lib``, respectively. You will need to edit setup.py file
``ssleay32_bc.lib``, respectively. You will need to edit setup.py file
for these.
You'll also need Python's import library, e.g., ``python22.lib``, to
be the BC++-compatible version; i.e., create ``python22_bc.lib`` from
``python22.lib``, save a copy of ``python22.lib`` (as ``python22_vc.lib``,
say), then rename ``python22_bc.lib`` to ``python22.lib``.
You'll also need Python's import library, e.g., ``python22.lib``, to be
the BC++-compatible version; i.e., create ``python22_bc.lib`` from
``python22.lib``, save a copy of ``python22.lib`` (as
``python22_vc.lib``, say), then rename ``python22_bc.lib`` to
``python22.lib``.
Now you are ready to build M2Crypto. Do one of the following::
::
python setup.py build
python setup.py build -cbcpp
......@@ -143,43 +146,42 @@ Then,
::
python setup.py install
::
python setup.py install
MacOSX
------
Follow the standard instructions to build and install M2Crypto.
However, should you encounter difficulties, you may want to consider
| Follow the standard instructions to build and install M2Crypto.
| However, should you encounter difficulties, you may want to consider
the following possibilities.
- Distutils from Python 2.5 provides support for universal builds (ppc
and i386) and Distutils requires a recent version of Xcode. See
http://developer.apple.com/tools/download/
- OpenSSL 0.9.7l gets installed in /usr with Apple's Security
Update 2006-007. If you need features in OpenSSL 0.9.8, you
should consider installing 0.9.8 in /usr/local. The commands
are:
OpenSSL:
./config shared --prefix=/usr/local
make
make test
sudo make install [or... install_sw]
M2Crypto:
python setup.py build build_ext --openssl=/usr/local
sudo python setup.py install build_ext --openssl=/usr/local
- Distutils from Python 2.5 provides support for universal builds (ppc
and i386) and Distutils requires a recent version of Xcode. See
http://developer.apple.com/tools/download/
- OpenSSL 0.9.7l gets installed in /usr with Apple's Security Update
2006-007. If you need features in OpenSSL 0.9.8, you should consider
installing 0.9.8 in /usr/local. The commands are:
OpenSSL: ./config shared --prefix=/usr/local make make test sudo make
install [or... install\_sw]
M2Crypto: python setup.py build build\_ext --openssl=/usr/local sudo
python setup.py install build\_ext --openssl=/usr/local
To make Universal builds, you will need to uncomment a line in setup.py:
extra_link_args = ['-Wl,-search_paths_first'],
If that does not work, here is what Marc Hedlund was able to get working:
extra\_link\_args = ['-Wl,-search\_paths\_first'],
First, download OpenSSL 0.9.8d and unpack it. Edit the OpenSSL Makefiles
per PROBLEMS. Then:
If that does not work, here is what Marc Hedlund was able to get
working:
First, download OpenSSL 0.9.8d and unpack it. Edit the OpenSSL Makefiles
per PROBLEMS. Then:
::
./config no-shared no-asm --prefix=/usr/local
make
......@@ -200,8 +202,10 @@ If that does not work, here is what Marc Hedlund was able to get working:
/bin/ls -1 build/i386/ > libnames.tmp
mkdir universal
Create a script in the OpenSSL directory called 'make_universal', with these
contents:
Create a script in the OpenSSL directory called 'make\_universal', with
these contents:
::
#!/bin/sh
for lib in `cat libnames.tmp`; do
......@@ -209,7 +213,9 @@ If that does not work, here is what Marc Hedlund was able to get working:
done
exit 0
Then:
Then:
::
sh make_universal
lipo -info universal/lib*
......@@ -217,10 +223,11 @@ If that does not work, here is what Marc Hedlund was able to get working:
lipo -info /usr/local/lib/lib{crypto,ssl}*
cd ../m2crypto-0.17
Then edit the m2crypto setup.py and uncomment the extra_link_args line at
the end.
Then edit the m2crypto setup.py and uncomment the extra\_link\_args line
at the end.
::
python setup.py build build_ext --openssl=/usr/local
sudo python setup.py install build_ext --openssl=/usr/local
......@@ -13,8 +13,8 @@ import BIO
import m2
MBSTRING_FLAG = 0x1000
MBSTRING_ASC = MBSTRING_FLAG | 1
MBSTRING_BMP = MBSTRING_FLAG | 2
MBSTRING_ASC = MBSTRING_FLAG | 1
MBSTRING_BMP = MBSTRING_FLAG | 2
class ASN1_Integer:
......@@ -24,7 +24,7 @@ class ASN1_Integer:
def __init__(self, asn1int, _pyfree=0):
self.asn1int = asn1int
self._pyfree = _pyfree
def __cmp__(self, other):
return m2.asn1_integer_cmp(self.asn1int, other.asn1int)
......@@ -34,39 +34,39 @@ class ASN1_Integer:
class ASN1_String:
m2_asn1_string_free = m2.asn1_string_free
def __init__(self, asn1str, _pyfree=0):
self.asn1str = asn1str
self._pyfree = _pyfree
def __str__(self):
buf = BIO.MemoryBuffer()
m2.asn1_string_print( buf.bio_ptr(), self.asn1str )
m2.asn1_string_print(buf.bio_ptr(), self.asn1str)
return buf.read_all()
def __del__(self):
if getattr(self, '_pyfree', 0):
self.m2_asn1_string_free(self.asn1str)
def _ptr(self):
return self.asn1str
def as_text(self, flags=0):
buf = BIO.MemoryBuffer()
m2.asn1_string_print_ex( buf.bio_ptr(), self.asn1str, flags)
m2.asn1_string_print_ex(buf.bio_ptr(), self.asn1str, flags)
return buf.read_all()
class ASN1_Object:
m2_asn1_object_free = m2.asn1_object_free
def __init__(self, asn1obj, _pyfree=0):
self.asn1obj = asn1obj
self._pyfree = _pyfree
def __del__(self):
if self._pyfree:
self.m2_asn1_object_free(self.asn1obj)
......@@ -77,10 +77,10 @@ class ASN1_Object:
class _UTC(datetime.tzinfo):
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return datetime.timedelta(0)
def utcoffset(self, dt):
return datetime.timedelta(0)
......@@ -92,9 +92,9 @@ UTC = _UTC()
class LocalTimezone(datetime.tzinfo):
""" Localtimezone from datetime manual """
def __init__(self):
self._stdoffset = datetime.timedelta(seconds = -time.timezone)
self._stdoffset = datetime.timedelta(seconds=-time.timezone)
if time.daylight:
self._dstoffset = datetime.timedelta(seconds = -time.altzone)
self._dstoffset = datetime.timedelta(seconds=-time.altzone)
else:
self._dstoffset = self._stdoffset
self._dstdiff = self._dstoffset - self._stdoffset
......@@ -135,36 +135,36 @@ class ASN1_UTCTIME:
self.asn1_utctime = asn1_utctime
self._pyfree = _pyfree
else:
self.asn1_utctime = m2.asn1_utctime_new ()
self.asn1_utctime = m2.asn1_utctime_new()
self._pyfree = 1
def __del__(self):
if getattr(self, '_pyfree', 0):
self.m2_asn1_utctime_free(self.asn1_utctime)
def __str__(self):
assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
buf = BIO.MemoryBuffer()
m2.asn1_utctime_print( buf.bio_ptr(), self.asn1_utctime )
m2.asn1_utctime_print(buf.bio_ptr(), self.asn1_utctime)
return buf.read_all()
def _ptr(self):
assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
return self.asn1_utctime
def set_string (self, string):
def set_string(self, string):
"""
Set time from UTC string.
"""
assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
return m2.asn1_utctime_set_string( self.asn1_utctime, string )
return m2.asn1_utctime_set_string(self.asn1_utctime, string)
def set_time (self, time):
def set_time(self, time):
"""
Set time from seconds since epoch (long).
"""
assert m2.asn1_utctime_type_check(self.asn1_utctime), "'asn1_utctime' type error'"
return m2.asn1_utctime_set( self.asn1_utctime, time )
return m2.asn1_utctime_set(self.asn1_utctime, time)
def get_datetime(self):
date = str(self)
......
......@@ -5,12 +5,12 @@ Copyright (c) 1999-2002 Ng Pheng Siong. All rights reserved."""
# M2Crypto
import Rand, m2
# Python. Cookie is bundled with Python 2.x.
# Python. Cookie is bundled with Python 2.x.
import Cookie, binascii, re, time
_MIX_FORMAT = 'exp=%s&data=%s&digest='
_MIX_RE = re.compile('exp=(\d+\.\d+)&data=(.+)&digest=(\S*)')
_MIX_RE = re.compile('exp=(\d+\.\d+)&data=(.+)&digest=(\S*)')
def mix(expiry, data, format=_MIX_FORMAT):
return format % (repr(expiry), data)
......@@ -38,10 +38,10 @@ class AuthCookieJar:
def __init__(self):
self._key = Rand.rand_bytes(self._keylen)
def _hmac(self, key, data):
return binascii.b2a_base64(m2.hmac(key, data, m2.sha1()))[:-1]
def makeCookie(self, expiry, data):
dough = mix(expiry, data)
return AuthCookie(expiry, data, dough, self._hmac(self._key, dough))
......@@ -57,9 +57,9 @@ class AuthCookieJar:
and (c.output() == cookie.output())
def isGoodCookieString(self, cookie_str):
c = Cookie.SmartCookie()
c = Cookie.SmartCookie()
c.load(cookie_str)
if not c.has_key(_TOKEN):
if _TOKEN not in c:
return 0
undough = unmix3(c[_TOKEN].value)
if undough is None:
......@@ -70,7 +70,7 @@ class AuthCookieJar:
class AuthCookie:
def __init__(self, expiry, data, dough, mac):
self._expiry = expiry
self._data = data
......@@ -104,11 +104,10 @@ class AuthCookie:
"""Return 1 if the cookie has expired, 0 otherwise."""
return (time.time() > self._expiry)
# XXX Following methods are for WebKit only. These should be pushed
# XXX Following methods are for WebKit only. These should be pushed
# to WKAuthCookie.
def name(self):
return self._name
def headerValue(self):
return self.value()
......@@ -2,17 +2,19 @@
Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved."""
import m2
import m2
from cStringIO import StringIO
# Deprecated
from m2 import bio_do_handshake as bio_do_ssl_handshake
from m2 import bio_do_handshake as bio_do_ssl_handshake # noqa
from cStringIO import StringIO
class BIOError(Exception): pass
class BIOError(Exception):
pass
m2.bio_init(BIOError)
class BIO:
"""Abstract object interface to the BIO API."""
......@@ -25,7 +27,7 @@ class BIO:
self._close_cb = _close_cb
self.closed = 0
self.write_closed = 0
def __del__(self):
if self._pyfree:
self.m2_bio_free(self.bio)
......@@ -44,33 +46,34 @@ class BIO:
def read(self, size=None):
if not self.readable():
raise IOError, 'cannot read'
raise IOError('cannot read')
if size is None:
buf = StringIO()
while 1:
data = m2.bio_read(self.bio, 4096)
if not data: break
if not data:
break
buf.write(data)
return buf.getvalue()
elif size == 0:
return ''
elif size < 0:
raise ValueError, 'read count is negative'
raise ValueError('read count is negative')
else:
return m2.bio_read(self.bio, size)
def readline(self, size=4096):
if not self.readable():
raise IOError, 'cannot read'
raise IOError('cannot read')
buf = m2.bio_gets(self.bio, size)
return buf
def readlines(self, sizehint='ignored'):
if not self.readable():
raise IOError, 'cannot read'
lines=[]
raise IOError('cannot read')
lines = []
while 1:
buf=m2.bio_gets(self.bio, 4096)
buf = m2.bio_gets(self.bio, 4096)
if buf is None:
break
lines.append(buf)
......@@ -78,10 +81,10 @@ class BIO:
def writeable(self):
return (not self.closed) and (not self.write_closed)
def write(self, data):
if not self.writeable():
raise IOError, 'cannot write'
raise IOError('cannot write')
return m2.bio_write(self.bio, data)
def write_close(self):
......@@ -104,10 +107,10 @@ class BIO:
def should_retry(self):
"""
Can the call be attempted again, or was there an error
ie do_handshake
ie do_handshake
"""
return m2.bio_should_retry(self.bio)
return m2.bio_should_retry(self.bio)
def should_read(self):
"""
......@@ -115,23 +118,31 @@ class BIO:
should read more data
"""
return m2.bio_should_read(self.bio)
def should_write(self):
"""
Returns whether the cause of the condition is the bio
should write more data
"""
return m2.bio_should_write(self.bio)
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
class MemoryBuffer(BIO):
"""
Object interface to BIO_s_mem.
Empirical testing suggests that this class performs less well than cStringIO,
because cStringIO is implemented in C, whereas this class is implemented in
Python. Thus, the recommended practice is to use cStringIO for regular work and
convert said cStringIO object to a MemoryBuffer object only when necessary.
Object interface to BIO_s_mem.
Empirical testing suggests that this class performs less well than
cStringIO, because cStringIO is implemented in C, whereas this class
is implemented in Python. Thus, the recommended practice is to use
cStringIO for regular work and convert said cStringIO object to
a MemoryBuffer object only when necessary.
"""
def __init__(self, data=None):
......@@ -146,12 +157,12 @@ class MemoryBuffer(BIO):
def read(self, size=0):
if not self.readable():
raise IOError, 'cannot read'
raise IOError('cannot read')
if size:
return m2.bio_read(self.bio, size)
else:
return m2.bio_read(self.bio, m2.bio_ctrl_pending(self.bio))
# Backwards-compatibility.
getvalue = read_all = read
......@@ -165,8 +176,8 @@ class MemoryBuffer(BIO):
class File(BIO):
"""
Object interface to BIO_s_fp.
Object interface to BIO_s_fp.
This class interfaces Python to OpenSSL functions that expect BIO *. For
general file manipulation in Python, use Python's builtin file object.
"""
......@@ -182,6 +193,7 @@ class File(BIO):
if self.close_pyfile:
self.pyfile.close()
def openfile(filename, mode='rb'):
return File(open(filename, mode))
......@@ -189,8 +201,8 @@ def openfile(filename, mode='rb'):
class IOBuffer(BIO):
"""
Object interface to BIO_f_buffer.
Object interface to BIO_f_buffer.
Its principal function is to be BIO_push()'ed on top of a BIO_f_ssl, so
that makefile() of said underlying SSL socket works.
"""
......@@ -203,12 +215,12 @@ class IOBuffer(BIO):
self.io = m2.bio_new(m2.bio_f_buffer())
self.bio = m2.bio_push(self.io, under_bio._ptr())
# This reference keeps the underlying BIO alive while we're not closed.
self._under_bio = under_bio
self._under_bio = under_bio
if 'w' in mode:
self.write_closed = 0
else:
self.write_closed = 1
def __del__(self):
if getattr(self, '_pyfree', 0):
self.m2_bio_pop(self.bio)
......@@ -234,7 +246,7 @@ class CipherStream(BIO):
self.obio = obio
self.bio = m2.bio_new(m2.bio_f_cipher())
self.closed = 0
def __del__(self):
if not getattr(self, 'closed', 1):
self.close()
......@@ -243,44 +255,42 @@ class CipherStream(BIO):
self.m2_bio_pop(self.bio)
self.m2_bio_free(self.bio)
self.closed = 1
def write_close(self):
self.obio.write_close()
def set_cipher(self, algo, key, iv, op):
cipher = getattr(m2, algo, None)
if cipher is None:
raise ValueError, ('unknown cipher', algo)
m2.bio_set_cipher(self.bio, cipher(), key, iv, op)
raise ValueError('unknown cipher', algo)
m2.bio_set_cipher(self.bio, cipher(), key, iv, op)
m2.bio_push(self.bio, self.obio._ptr())
class SSLBio(BIO):
"""
Object interface to BIO_f_ssl
Object interface to BIO_f_ssl
"""
def __init__(self, _pyfree=1):
BIO.__init__(self, _pyfree)
self.bio = m2.bio_new(m2.bio_f_ssl())
self.closed = 0
def set_ssl(self, conn, close_flag=m2.bio_noclose):
"""
Sets the bio to the SSL pointer which is
contained in the connection object.
contained in the connection object.
"""
self._pyfree = 0
self._pyfree = 0
m2.bio_set_ssl(self.bio, conn.ssl, close_flag)
if close_flag == m2.bio_noclose:
conn.set_ssl_close_flag(m2.bio_close)
def do_handshake(self):
"""
Do the handshake.
Return 1 if the handshake completes
Return 0 or a negative number if there is a problem
"""
return m2.bio_do_handshake(self.bio)
......@@ -9,7 +9,7 @@ import m2
def rand(bits, top=-1, bottom=0):
"""
Generate cryptographically strong random number.
@param bits: Length of random number in bits.
@param top: If -1, the most significant bit can be 0. If 0, the most
significant bit is 1, and if 1, the two most significant
......@@ -22,7 +22,7 @@ def rand(bits, top=-1, bottom=0):
def rand_range(range):
"""
Generate a random number in a range.
@param range: Upper limit for range.
@return: A random number in the range [0, range)
"""
......@@ -43,5 +43,5 @@ def randfname(length):
fname = []
for x in range(length):
fname += [letters[m2.bn_rand_range(lettersLen)]]
return ''.join(fname)
......@@ -22,7 +22,7 @@ class DH:
assert m2.dh_type_check(dh)
self.dh = dh
self._pyfree = _pyfree
def __del__(self):
if getattr(self, '_pyfree', 0):
self.m2_dh_free(self.dh)
......@@ -41,9 +41,9 @@ class DH:
def __setattr__(self, name, value):
if name in ('p', 'g'):
raise DHError, 'set (p, g) via set_params()'
elif name in ('pub','priv'):
raise DHError, 'generate (pub, priv) via gen_key()'
raise DHError('set (p, g) via set_params()')
elif name in ('pub', 'priv'):
raise DHError('generate (pub, priv) via gen_key()')
else:
self.__dict__[name] = value
......@@ -53,10 +53,10 @@ class DH:
def check_params(self):
assert m2.dh_type_check(self.dh), "'dh' type error"
return m2.dh_check(self.dh)
def gen_key(self):
assert m2.dh_type_check(self.dh), "'dh' type error"
m2.dh_generate_key(self.dh)
m2.dh_generate_key(self.dh)
def compute_key(self, pubkey):
assert m2.dh_type_check(self.dh), "'dh' type error"
......@@ -87,10 +87,9 @@ def set_params(p, g):
return DH(dh, 1)
#def free_params(cptr):
# def free_params(cptr):
# m2.dh_free(cptr)
DH_GENERATOR_2 = m2.DH_GENERATOR_2
DH_GENERATOR_5 = m2.DH_GENERATOR_5
from __future__ import print_function
"""
M2Crypto wrapper for OpenSSL DSA API.
......@@ -19,24 +21,24 @@ class DSA:
"""
This class is a context supporting DSA key and parameter
values, signing and verifying.
Simple example::
from M2Crypto import EVP, DSA, util
message = 'Kilroy was here!'
md = EVP.MessageDigest('sha1')
md.update(message)
md.update(message)
digest = md.final()
dsa = DSA.gen_params(1024)
dsa.gen_key()
r, s = dsa.sign(digest)
good = dsa.verify(digest, r, s)
if good:
print ' ** success **'
print(' ** success **')
else:
print ' ** verification failed **'
print(' ** verification failed **')
"""
m2_dsa_free = m2.dsa_free
......@@ -48,7 +50,7 @@ class DSA:
assert m2.dsa_type_check(dsa), "'dsa' type error"
self.dsa = dsa
self._pyfree = _pyfree
def __del__(self):
if getattr(self, '_pyfree', 0):
self.m2_dsa_free(self.dsa)
......@@ -56,7 +58,7 @@ class DSA:
def __len__(self):
"""
Return the key length.
@rtype: int
@return: the DSA key length in bits
"""
......@@ -66,9 +68,9 @@ class DSA:
def __getattr__(self, name):
"""
Return specified DSA parameters and key values.
@type name: str
@param name: name of variable to be returned. Must be
@param name: name of variable to be returned. Must be
one of 'p', 'q', 'g', 'pub', 'priv'.
@rtype: str
@return: value of specified variable (a "byte string")
......@@ -83,7 +85,7 @@ class DSA:
def __setattr__(self, name, value):
if name in ['p', 'q', 'g']:
raise DSAError('set (p, q, g) via set_params()')
elif name in ['pub','priv']:
elif name in ['pub', 'priv']:
raise DSAError('generate (pub, priv) via gen_key()')
else:
self.__dict__[name] = value
......@@ -91,7 +93,7 @@ class DSA:
def set_params(self, p, q, g):
"""
Set new parameters.
@warning: This does not change the private key, so it may be
unsafe to use this method. It is better to use
gen_params function to create a new DSA object.
......@@ -105,12 +107,12 @@ class DSA:
Generate a key pair.
"""
assert m2.dsa_type_check(self.dsa), "'dsa' type error"
m2.dsa_gen_key(self.dsa)
m2.dsa_gen_key(self.dsa)
def save_params(self, filename):
"""
Save the DSA parameters to a file.
@type filename: str
@param filename: Save the DSA parameters to this file.
@return: 1 (true) if successful
......@@ -123,18 +125,18 @@ class DSA:
def save_params_bio(self, bio):
"""
Save DSA parameters to a BIO object.
@type bio: M2Crypto.BIO object
@param bio: Save DSA parameters to this object.
@return: 1 (true) if successful
"""
return m2.dsa_write_params_bio(self.dsa, bio._ptr())
def save_key(self, filename, cipher='aes_128_cbc',
def save_key(self, filename, cipher='aes_128_cbc',
callback=util.passphrase_callback):
"""
Save the DSA key pair to a file.
@type filename: str
@param filename: Save the DSA key pair to this file.
@type cipher: str
......@@ -147,11 +149,11 @@ class DSA:
bio.close()
return ret
def save_key_bio(self, bio, cipher='aes_128_cbc',
def save_key_bio(self, bio, cipher='aes_128_cbc',
callback=util.passphrase_callback):
"""
Save DSA key pair to a BIO object.
@type bio: M2Crypto.BIO object
@param bio: Save DSA parameters to this object.
@type cipher: str
......@@ -160,7 +162,7 @@ class DSA:
@return: 1 (true) if successful
"""
if cipher is None:
return m2.dsa_write_key_bio_no_cipher(self.dsa,
return m2.dsa_write_key_bio_no_cipher(self.dsa,
bio._ptr(), callback)
else:
ciph = getattr(m2, cipher, None)
......@@ -173,9 +175,9 @@ class DSA:
def save_pub_key(self, filename):
"""
Save the DSA public key (with parameters) to a file.
@type filename: str
@param filename: Save DSA public key (with parameters)
@param filename: Save DSA public key (with parameters)
to this file.
@return: 1 (true) if successful
"""
......@@ -187,9 +189,9 @@ class DSA:
def save_pub_key_bio(self, bio):
"""
Save DSA public key (with parameters) to a BIO object.
@type bio: M2Crypto.BIO object
@param bio: Save DSA public key (with parameters)
@param bio: Save DSA public key (with parameters)
to this object.
@return: 1 (true) if successful
"""
......@@ -198,9 +200,9 @@ class DSA:
def sign(self, digest):
"""
Sign the digest.
@type digest: str
@param digest: SHA-1 hash of message (same as output
@param digest: SHA-1 hash of message (same as output
from MessageDigest, a "byte string")
@rtype: tuple
@return: DSA signature, a tuple of two values, r and s,
......@@ -208,14 +210,14 @@ class DSA:
"""
assert self.check_key(), 'key is not initialised'
return m2.dsa_sign(self.dsa, digest)
def verify(self, digest, r, s):
"""
Verify a newly calculated digest against the signature
Verify a newly calculated digest against the signature
values r and s.
@type digest: str
@param digest: SHA-1 hash of message (same as output
@param digest: SHA-1 hash of message (same as output
from MessageDigest, a "byte string")
@type r: str
@param r: r value of the signature, a "byte string"
......@@ -230,7 +232,7 @@ class DSA:
def sign_asn1(self, digest):
assert self.check_key(), 'key is not initialised'
return m2.dsa_sign_asn1(self.dsa, digest)
def verify_asn1(self, digest, blob):
assert self.check_key(), 'key is not initialised'
return m2.dsa_verify_asn1(self.dsa, digest, blob)
......@@ -238,22 +240,22 @@ class DSA:
def check_key(self):
"""
Check to be sure the DSA object has a valid private key.
@rtype: int
@return: 1 (true) if a valid private key
"""
assert m2.dsa_type_check(self.dsa), "'dsa' type error"
return m2.dsa_check_key(self.dsa)
class DSA_pub(DSA):
"""
This class is a DSA context that only supports a public key
and verification. It does NOT support a private key or
This class is a DSA context that only supports a public key
and verification. It does NOT support a private key or
signing.
"""
def sign(self, *argv):
......@@ -263,25 +265,25 @@ class DSA_pub(DSA):
def check_key(self):
return m2.dsa_check_pub_key(self.dsa)
save_key = DSA.save_pub_key
save_key_bio = DSA.save_pub_key_bio
#---------------------------------------------------------------
# factories and other functions
# factories and other functions
def gen_params(bits, callback=util.genparam_callback):
"""
Factory function that generates DSA parameters and
Factory function that generates DSA parameters and
instantiates a DSA object from the output.
@type bits: int
@param bits: The length of the prime to be generated. If
@param bits: The length of the prime to be generated. If
'bits' < 512, it is set to 512.
@type callback: function
@param callback: A Python callback object that will be
invoked during parameter generation; it usual
@param callback: A Python callback object that will be
invoked during parameter generation; it usual
purpose is to provide visual feedback.
@rtype: DSA
@return: instance of DSA.
......@@ -313,15 +315,15 @@ def set_params(p, q, g):
def load_params(file, callback=util.passphrase_callback):
"""
Factory function that instantiates a DSA object with DSA
Factory function that instantiates a DSA object with DSA
parameters from a file.
@type file: str
@param file: Names the file (a path) that contains the PEM
representation of the DSA parameters.
@param file: Names the file (a path) that contains the PEM
representation of the DSA parameters.
@type callback: A Python callable
@param callback: A Python callback object that will be
invoked if the DSA parameters file is
@param callback: A Python callback object that will be
invoked if the DSA parameters file is
passphrase-protected.
@rtype: DSA
@return: instance of DSA.
......@@ -338,11 +340,11 @@ def load_params_bio(bio, callback=util.passphrase_callback):
parameters from a M2Crypto.BIO object.
@type bio: M2Crypto.BIO object
@param bio: Contains the PEM representation of the DSA
parameters.
@param bio: Contains the PEM representation of the DSA
parameters.
@type callback: A Python callable
@param callback: A Python callback object that will be
invoked if the DSA parameters file is
@param callback: A Python callback object that will be
invoked if the DSA parameters file is
passphrase-protected.
@rtype: DSA
@return: instance of DSA.
......@@ -359,11 +361,11 @@ def load_key(file, callback=util.passphrase_callback):
PEM encoded DSA key pair.
@type file: str
@param file: Names the file (a path) that contains the PEM
representation of the DSA key pair.
@param file: Names the file (a path) that contains the PEM
representation of the DSA key pair.
@type callback: A Python callable
@param callback: A Python callback object that will be
invoked if the DSA key pair is
@param callback: A Python callback object that will be
invoked if the DSA key pair is
passphrase-protected.
@rtype: DSA
@return: instance of DSA.
......@@ -380,11 +382,11 @@ def load_key_bio(bio, callback=util.passphrase_callback):
PEM encoded DSA key pair.
@type bio: M2Crypto.BIO object
@param bio: Contains the PEM representation of the DSA
key pair.
@param bio: Contains the PEM representation of the DSA
key pair.
@type callback: A Python callable
@param callback: A Python callback object that will be
invoked if the DSA key pair is
@param callback: A Python callback object that will be
invoked if the DSA key pair is
passphrase-protected.
@rtype: DSA
@return: instance of DSA.
......@@ -398,15 +400,15 @@ def load_key_bio(bio, callback=util.passphrase_callback):
def load_pub_key(file, callback=util.passphrase_callback):
"""
Factory function that instantiates a DSA_pub object using
a DSA public key contained in PEM file. The PEM file
a DSA public key contained in PEM file. The PEM file
must contain the parameters in addition to the public key.
@type file: str
@param file: Names the file (a path) that contains the PEM
representation of the DSA public key.
@param file: Names the file (a path) that contains the PEM
representation of the DSA public key.
@type callback: A Python callable
@param callback: A Python callback object that will be
invoked should the DSA public key be
@param callback: A Python callback object that will be
invoked should the DSA public key be
passphrase-protected.
@rtype: DSA_pub
@return: instance of DSA_pub.
......@@ -420,15 +422,15 @@ def load_pub_key(file, callback=util.passphrase_callback):
def load_pub_key_bio(bio, callback=util.passphrase_callback):
"""
Factory function that instantiates a DSA_pub object using
a DSA public key contained in PEM format. The PEM
a DSA public key contained in PEM format. The PEM
must contain the parameters in addition to the public key.
@type bio: M2Crypto.BIO object
@param bio: Contains the PEM representation of the DSA
public key (with params).
@param bio: Contains the PEM representation of the DSA
public key (with params).
@type callback: A Python callable
@param callback: A Python callback object that will be
invoked should the DSA public key be
@param callback: A Python callback object that will be
invoked should the DSA public key be
passphrase-protected.
@rtype: DSA_pub
@return: instance of DSA_pub.
......
......@@ -5,7 +5,7 @@ M2Crypto wrapper for OpenSSL ECDH/ECDSA API.
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.
Portions copyright (c) 2005-2006 Vrije Universiteit Amsterdam.
All rights reserved."""
import util, BIO, m2
......@@ -37,7 +37,7 @@ NID_sect163r1 = m2.NID_sect163r1
NID_sect163r2 = m2.NID_sect163r2
NID_sect193r1 = m2.NID_sect193r1
NID_sect193r2 = m2.NID_sect193r2
NID_sect233k1 = m2.NID_sect233k1 # default for secg.org TLS test server
NID_sect233k1 = m2.NID_sect233k1 # default for secg.org TLS test server
NID_sect233r1 = m2.NID_sect233r1
NID_sect239k1 = m2.NID_sect239k1
NID_sect283k1 = m2.NID_sect283k1
......@@ -71,23 +71,23 @@ NID_X9_62_c2tnb359v1 = m2.NID_X9_62_c2tnb359v1
NID_X9_62_c2pnb368w1 = m2.NID_X9_62_c2pnb368w1
NID_X9_62_c2tnb431r1 = m2.NID_X9_62_c2tnb431r1
NID_wap_wsg_idm_ecid_wtls1 = m2.NID_wap_wsg_idm_ecid_wtls1
NID_wap_wsg_idm_ecid_wtls3 = m2.NID_wap_wsg_idm_ecid_wtls3
NID_wap_wsg_idm_ecid_wtls4 = m2.NID_wap_wsg_idm_ecid_wtls4
NID_wap_wsg_idm_ecid_wtls5 = m2.NID_wap_wsg_idm_ecid_wtls5
NID_wap_wsg_idm_ecid_wtls6 = m2.NID_wap_wsg_idm_ecid_wtls6
NID_wap_wsg_idm_ecid_wtls7 = m2.NID_wap_wsg_idm_ecid_wtls7
NID_wap_wsg_idm_ecid_wtls8 = m2.NID_wap_wsg_idm_ecid_wtls8
NID_wap_wsg_idm_ecid_wtls9 = m2.NID_wap_wsg_idm_ecid_wtls9
NID_wap_wsg_idm_ecid_wtls1 = m2.NID_wap_wsg_idm_ecid_wtls1
NID_wap_wsg_idm_ecid_wtls3 = m2.NID_wap_wsg_idm_ecid_wtls3
NID_wap_wsg_idm_ecid_wtls4 = m2.NID_wap_wsg_idm_ecid_wtls4
NID_wap_wsg_idm_ecid_wtls5 = m2.NID_wap_wsg_idm_ecid_wtls5
NID_wap_wsg_idm_ecid_wtls6 = m2.NID_wap_wsg_idm_ecid_wtls6
NID_wap_wsg_idm_ecid_wtls7 = m2.NID_wap_wsg_idm_ecid_wtls7
NID_wap_wsg_idm_ecid_wtls8 = m2.NID_wap_wsg_idm_ecid_wtls8
NID_wap_wsg_idm_ecid_wtls9 = m2.NID_wap_wsg_idm_ecid_wtls9
NID_wap_wsg_idm_ecid_wtls10 = m2.NID_wap_wsg_idm_ecid_wtls10
NID_wap_wsg_idm_ecid_wtls11 = m2.NID_wap_wsg_idm_ecid_wtls11
NID_wap_wsg_idm_ecid_wtls12 = m2.NID_wap_wsg_idm_ecid_wtls12
# The following two curves, according to OpenSSL, have a
# "Questionable extension field!" and are not supported by
# The following two curves, according to OpenSSL, have a
# "Questionable extension field!" and are not supported by
# the OpenSSL inverse function. ECError: no inverse.
# As such they cannot be used for signing. They might,
# however, be usable for encryption but that has not
# As such they cannot be used for signing. They might,
# however, be usable for encryption but that has not
# been tested. Until thir usefulness can be established,
# they are not supported at this time.
# NID_ipsec3 = m2.NID_ipsec3
......@@ -101,7 +101,7 @@ class EC:
"""
m2_ec_key_free = m2.ec_key_free
def __init__(self, ec, _pyfree=0):
assert m2.ec_key_type_check(ec), "'ec' type error"
self.ec = ec
......@@ -123,7 +123,7 @@ class EC:
to create an EC key pair.
"""
assert m2.ec_key_type_check(self.ec), "'ec' type error"
m2.ec_key_gen_key(self.ec)
m2.ec_key_gen_key(self.ec)
def pub(self):
# Don't let python free
......@@ -136,7 +136,7 @@ class EC:
"""
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_sign(self.ec, digest)
def verify_dsa(self, digest, r, s):
"""
Verify the given digest using ECDSA. r and s are the ECDSA
......@@ -148,16 +148,16 @@ class EC:
def sign_dsa_asn1(self, digest):
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_sign_asn1(self.ec, digest)
def verify_dsa_asn1(self, digest, blob):
assert self._check_key_type(), "'ec' type error"
return m2.ecdsa_verify_asn1(self.ec, digest, blob)
def compute_dh_key(self,pub_key):
def compute_dh_key(self, pub_key):
"""
Compute the ECDH shared key of this key pair and the given public
key object. They must both use the same curve. Returns the
shared key in binary as a buffer object. No Key Derivation Function is
Compute the ECDH shared key of this key pair and the given public
key object. They must both use the same curve. Returns the
shared key in binary as a buffer object. No Key Derivation Function is
applied.
"""
assert self.check_key(), 'key is not initialised'
......@@ -207,14 +207,14 @@ class EC:
"""
bio = BIO.openfile(file, 'wb')
return self.save_key_bio(bio, cipher, callback)
def save_pub_key_bio(self, bio):
"""
Save the public key to an M2Crypto.BIO.BIO object in PEM format.
@type bio: M2Crypto.BIO.BIO
@param bio: M2Crypto.BIO.BIO object to save key to.
"""
"""
return m2.ec_key_write_pubkey(self.ec, bio._ptr())
def save_pub_key(self, file):
......@@ -226,7 +226,7 @@ class EC:
"""
bio = BIO.openfile(file, 'wb')
return m2.ec_key_write_pubkey(self.ec, bio._ptr())
def _check_key_type(self):
return m2.ec_key_type_check(self.ec)
......@@ -234,15 +234,15 @@ class EC:
assert m2.ec_key_type_check(self.ec), "'ec' type error"
return m2.ec_key_check_key(self.ec)
class EC_pub(EC):
"""
Object interface to an EC public key.
Object interface to an EC public key.
((don't like this implementation inheritance))
"""
def __init__(self,ec,_pyfree=0):
EC.__init__(self,ec,_pyfree)
def __init__(self, ec, _pyfree=0):
EC.__init__(self, ec, _pyfree)
self.der = None
def get_der(self):
......@@ -261,10 +261,10 @@ class EC_pub(EC):
def gen_params(curve):
"""
Factory function that generates EC parameters and
Factory function that generates EC parameters and
instantiates a EC object from the output.
@param curve: This is the OpenSSL nid of the curve to use.
@param curve: This is the OpenSSL nid of the curve to use.
"""
return EC(m2.ec_key_new_by_curve_name(curve), 1)
......@@ -273,10 +273,10 @@ def load_key(file, callback=util.passphrase_callback):
"""
Factory function that instantiates a EC object.
@param file: Names the file that contains the PEM representation
@param file: Names the file that contains the PEM representation
of the EC key pair.
@param callback: Python callback object that will be invoked
@param callback: Python callback object that will be invoked
if the EC key pair is passphrase-protected.
"""
bio = BIO.openfile(file)
......@@ -288,9 +288,9 @@ def load_key_bio(bio, callback=util.passphrase_callback):
Factory function that instantiates a EC object.
@param bio: M2Crypto.BIO object that contains the PEM
representation of the EC key pair.
representation of the EC key pair.
@param callback: Python callback object that will be invoked
@param callback: Python callback object that will be invoked
if the EC key pair is passphrase-protected.
"""
return EC(m2.ec_key_read_bio(bio._ptr(), callback), 1)
......@@ -305,7 +305,7 @@ def load_pub_key(file):
@rtype: M2Crypto.EC.EC_pub
@return: M2Crypto.EC.EC_pub object.
"""
bio = BIO.openfile(file)
bio = BIO.openfile(file)
return load_pub_key_bio(bio)
......@@ -319,14 +319,14 @@ def load_pub_key_bio(bio):
@rtype: M2Crypto.EC.EC_pub
@return: M2Crypto.EC.EC_pub object.
"""
"""
ec = m2.ec_key_read_pubkey(bio._ptr())
if ec is None:
ec_error()
return EC_pub(ec, 1)
def ec_error():
raise ECError, m2.err_reason_error_string(m2.err_get_error())
raise ECError(m2.err_reason_error_string(m2.err_get_error()))
def pub_key_from_der(der):
"""
......
......@@ -17,13 +17,13 @@ m2.evp_init(EVPError)
def pbkdf2(password, salt, iter, keylen):
"""
Derive a key from password using PBKDF2 algorithm specified in RFC 2898.
@param password: Derive the key from this password.
@type password: str
@param salt: Salt.
@type salt: str
@param iter: Number of iterations to perform.
@type iter: int
@type iter: int
@param keylen: Length of key to produce.
@type keylen: int
@return: Key.
......@@ -40,11 +40,11 @@ class MessageDigest:
def __init__(self, algo):
md = getattr(m2, algo, None)
if md is None:
raise ValueError, ('unknown algorithm', algo)
self.md=md()
self.ctx=m2.md_ctx_new()
raise ValueError('unknown algorithm', algo)
self.md = md()
self.ctx = m2.md_ctx_new()
m2.digest_init(self.ctx, self.md)
def __del__(self):
if getattr(self, 'ctx', None):
self.m2_md_ctx_free(self.ctx)
......@@ -52,7 +52,7 @@ class MessageDigest:
def update(self, data):
"""
Add data to be digested.
@return: -1 for Python error, 1 for success, 0 for OpenSSL failure.
"""
return m2.digest_update(self.ctx, data)
......@@ -61,21 +61,21 @@ class MessageDigest:
return m2.digest_final(self.ctx)
# Deprecated.
digest = final
digest = final
class HMAC:
m2_hmac_ctx_free = m2.hmac_ctx_free
def __init__(self, key, algo='sha1'):
md = getattr(m2, algo, None)
if md is None:
raise ValueError, ('unknown algorithm', algo)
self.md=md()
self.ctx=m2.hmac_ctx_new()
raise ValueError('unknown algorithm', algo)
self.md = md()
self.ctx = m2.hmac_ctx_new()
m2.hmac_init(self.ctx, key, self.md)
def __del__(self):
if getattr(self, 'ctx', None):
self.m2_hmac_ctx_free(self.ctx)
......@@ -88,13 +88,13 @@ class HMAC:
def final(self):
return m2.hmac_final(self.ctx)
digest=final
digest = final
def hmac(key, data, algo='sha1'):
md = getattr(m2, algo, None)
if md is None:
raise ValueError, ('unknown algorithm', algo)
raise ValueError('unknown algorithm', algo)
return m2.hmac(key, data, md())
......@@ -105,20 +105,20 @@ class Cipher:
def __init__(self, alg, key, iv, op, key_as_bytes=0, d='md5', salt='12345678', i=1, padding=1):
cipher = getattr(m2, alg, None)
if cipher is None:
raise ValueError, ('unknown cipher', alg)
self.cipher=cipher()
raise ValueError('unknown cipher', alg)
self.cipher = cipher()
if key_as_bytes:
kmd = getattr(m2, d, None)
if kmd is None:
raise ValueError, ('unknown message digest', d)
raise ValueError('unknown message digest', d)
key = m2.bytes_to_key(self.cipher, kmd(), key, salt, iv, i)
self.ctx=m2.cipher_ctx_new()
self.ctx = m2.cipher_ctx_new()
m2.cipher_init(self.ctx, self.cipher, key, iv, op)
self.set_padding(padding)
del key
def __del__(self):
if getattr(self, 'ctx', None):
if getattr(self, 'ctx', None):
self.m2_cipher_ctx_free(self.ctx)
def update(self, data):
......@@ -128,14 +128,14 @@ class Cipher:
return m2.cipher_final(self.ctx)
def set_padding(self, padding=1):
return m2.cipher_set_padding(self.ctx, padding)
return m2.cipher_set_padding(self.ctx, padding)
class PKey:
"""
Public Key
"""
m2_pkey_free = m2.pkey_free
m2_md_ctx_free = m2.md_ctx_free
......@@ -147,7 +147,7 @@ class PKey:
self.pkey = m2.pkey_new()
self._pyfree = 1
self._set_context(md)
def __del__(self):
if getattr(self, '_pyfree', 0):
self.m2_pkey_free(self.pkey)
......@@ -160,7 +160,7 @@ class PKey:
def _set_context(self, md):
mda = getattr(m2, md, None)
if mda is None:
raise ValueError, ('unknown message digest', md)
raise ValueError('unknown message digest', md)
self.md = mda()
self.ctx = m2.md_ctx_new()
......@@ -239,7 +239,7 @@ class PKey:
@param capture: If true (default), this PKey object will own the RSA
object, meaning that once the PKey object gets
deleted it is no longer safe to use the RSA object.
@rtype: int
@return: Return 1 for success and 0 for failure.
"""
......@@ -259,7 +259,7 @@ class PKey:
rsa_ptr = m2.pkey_get1_rsa(self.pkey)
if rsa_ptr is None:
raise ValueError("PKey instance is not holding a RSA key")
rsa = RSA.RSA_pub(rsa_ptr, 1)
return rsa
......@@ -277,7 +277,7 @@ class PKey:
@type callback: Python callable
@param callback: A Python callable object that is invoked
to acquire a passphrase with which to protect the key.
to acquire a passphrase with which to protect the key.
The default is util.passphrase_callback.
"""
bio = BIO.openfile(file, 'wb')
......@@ -297,7 +297,7 @@ class PKey:
@type callback: Python callable
@param callback: A Python callable object that is invoked
to acquire a passphrase with which to protect the key.
to acquire a passphrase with which to protect the key.
The default is util.passphrase_callback.
"""
if cipher is None:
......@@ -305,7 +305,7 @@ class PKey:
else:
proto = getattr(m2, cipher, None)
if proto is None:
raise ValueError, 'no such cipher %s' % cipher
raise ValueError('no such cipher %s' % cipher)
return m2.pkey_write_pem(self.pkey, bio._ptr(), proto(), callback)
def as_pem(self, cipher='aes_128_cbc', callback=util.passphrase_callback):
......@@ -319,7 +319,7 @@ class PKey:
@type callback: Python callable
@param callback: A Python callable object that is invoked
to acquire a passphrase with which to protect the key.
to acquire a passphrase with which to protect the key.
The default is util.passphrase_callback.
"""
bio = BIO.MemoryBuffer()
......@@ -333,19 +333,19 @@ class PKey:
buf = m2.pkey_as_der(self.pkey)
bio = BIO.MemoryBuffer(buf)
return bio.read_all()
def size(self):
"""
Return the size of the key in bytes.
"""
return m2.pkey_size(self.pkey)
def get_modulus(self):
"""
Return the modulus in hex format.
"""
return m2.pkey_get_modulus(self.pkey)
def load_key(file, callback=util.passphrase_callback):
"""
......@@ -404,5 +404,4 @@ def load_key_string(string, callback=util.passphrase_callback):
@return: M2Crypto.EVP.PKey object.
"""
bio = BIO.MemoryBuffer(string)
return load_key_bio( bio, callback)
return load_key_bio(bio, callback)
......@@ -16,8 +16,8 @@ class Engine:
"""Wrapper for ENGINE object."""
m2_engine_free = m2.engine_free
def __init__(self, id = None, _ptr = None, _pyfree = 1):
def __init__(self, id=None, _ptr=None, _pyfree=1):
"""Create new Engine from ENGINE pointer or obtain by id"""
if not _ptr and not id:
raise ValueError("No engine id specified")
......@@ -34,15 +34,15 @@ class Engine:
def init(self):
"""Obtain a functional reference to the engine.
@return: 0 on error, non-zero on success."""
return m2.engine_init(self._ptr)
def finish(self):
"""Release a functional and structural reference to the engine."""
return m2.engine_finish(self._ptr)
def ctrl_cmd_string(self, cmd, arg, optional = 0):
def ctrl_cmd_string(self, cmd, arg, optional=0):
"""Call ENGINE_ctrl_cmd_string"""
if not m2.engine_ctrl_cmd_string(self._ptr, cmd, arg, optional):
raise EngineError(Err.get_error())
......@@ -55,12 +55,12 @@ class Engine:
"""Return engine id"""
return m2.engine_get_id(self._ptr)
def set_default(self, methods = m2.ENGINE_METHOD_ALL):
def set_default(self, methods=m2.ENGINE_METHOD_ALL):
"""Use this engine as default for methods specified in argument
Possible values are bitwise OR of m2.ENGINE_METHOD_*"""
return m2.engine_set_default(self._ptr, methods)
def _engine_load_key(self, func, name, pin = None):
def _engine_load_key(self, func, name, pin=None):
"""Helper function for loading keys"""
ui = m2.ui_openssl()
cbd = m2.engine_pkcs11_data_new(pin)
......@@ -68,18 +68,18 @@ class Engine:
kptr = func(self._ptr, name, ui, cbd)
if not kptr:
raise EngineError(Err.get_error())
key = EVP.PKey(kptr, _pyfree = 1)
key = EVP.PKey(kptr, _pyfree=1)
finally:
m2.engine_pkcs11_data_free(cbd)
return key
def load_private_key(self, name, pin = None):
def load_private_key(self, name, pin=None):
"""Load private key with engine methods (e.g from smartcard).
If pin is not set it will be asked
"""
return self._engine_load_key(m2.engine_load_private_key, name, pin)
def load_public_key(self, name, pin = None):
def load_public_key(self, name, pin=None):
"""Load public key with engine methods (e.g from smartcard)."""
return self._engine_load_key(m2.engine_load_public_key, name, pin)
......@@ -89,7 +89,7 @@ class Engine:
cptr = m2.engine_load_certificate(self._ptr, name)
if not cptr:
raise EngineError("Certificate or card not found")
return X509.X509(cptr, _pyfree = 1)
return X509.X509(cptr, _pyfree=1)
def load_dynamic_engine(id, sopath):
......
......@@ -6,7 +6,7 @@ import BIO
import m2
def get_error():
err=BIO.MemoryBuffer()
err = BIO.MemoryBuffer()
m2.err_print_errors(err.bio_ptr())
return err.getvalue()
......@@ -45,5 +45,3 @@ class SSLError(Exception):
class M2CryptoError(Exception):
pass
......@@ -28,15 +28,15 @@ class PublicKey:
def add_signature(self, userid, s_pkt):
assert isinstance(s_pkt, signature_packet)
assert self._userid.has_key(userid)
if self._signature.has_key(userid):
assert userid in self._userid
if userid in self._signature:
self._signature.append(s_pkt)
else:
self._signature = [s_pkt]
def __getitem__(self, id):
return self._userid[id]
def __setitem__(self, *args):
raise NotImplementedError
......
......@@ -23,7 +23,7 @@ class PublicKeyRing:
ps = packet_stream(self._keyring)
while 1:
pkt = ps.read()
pkt = ps.read()
if pkt is None:
break
......@@ -51,7 +51,7 @@ class PublicKeyRing:
self._spurious.append(pkt)
ps.close()
def __getitem__(self, id):
return self._userid[id][0]
......
......@@ -16,7 +16,7 @@ class RSA_pub(_RSA.RSA_pub):
pass
def new_pub_key((e, n)):
def new_pub_key(e_n):
"""
Factory function that instantiates an RSA_pub object from a (e, n) tuple.
......@@ -25,10 +25,11 @@ def new_pub_key((e, n)):
'n' is the RSA composite of primes; it is a string in OpenSSL's binary format,
i.e., a number of bytes in big-endian.
"""
"""
import warnings
warnings.warn('Deprecated. No maintainer for PGP. If you use this, please inform M2Crypto maintainer.', DeprecationWarning)
(e, n) = e_n
rsa = m2.rsa_new()
m2.rsa_set_e_bin(rsa, e)
m2.rsa_set_n_bin(rsa, n)
......
......@@ -2,8 +2,8 @@
This module implements PGP packets per RFC1991 and various source distributions.
Each packet type is represented by a class; packet classes derive from
the abstract 'packet' class.
Each packet type is represented by a class; packet classes derive from
the abstract 'packet' class.
The 'message digest' packet type, mentioned but not documented in RFC1991,
is not implemented.
......@@ -13,16 +13,24 @@ Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
# XXX Work-in-progress.
# Be liberal in what you accept.
# Be conservative in what you send.
# Be conservative in what you send.
# Be lazy in what you eval.
import struct, time
import struct
import sys
import time
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
# Python 2 has int() and long().
# Python 3 and higher only has int().
# Work around this.
if sys.version_info > (3,):
long = int
from M2Crypto import EVP, RSA
from M2Crypto.util import octx_to_num
......@@ -37,7 +45,7 @@ class packet:
def __init__(self, ctb, body=None):
import warnings
warnings.warn('Deprecated. No maintainer for PGP. If you use this, please inform M2Crypto maintainer.', DeprecationWarning)
self.ctb = ctb
if body is not None:
self.body = StringIO(body)
......@@ -48,7 +56,7 @@ class packet:
return 1
def pack(self):
raise NotImplementedError, '%s.pack(): abstract method' % (self.__class__,)
raise NotImplementedError('%s.pack(): abstract method' % (self.__class__,))
def version(self):
if hasattr(self, '_version'):
......@@ -75,12 +83,12 @@ class packet:
return None
def _llf(self, lenf):
if lenf < 256:
if lenf < 256:
return (0, chr(lenf))
elif lenf < 65536:
return (1, struct.pack('>H', lenf))
else:
assert lenf < 2L**32
else:
assert lenf < long(2)**32
return (2, struct.pack('>L', lenf))
def _ctb(self, llf):
......@@ -100,7 +108,7 @@ class public_key_packet(packet):
self._nlen = self.body.read(2)
nlen = (struct.unpack('>H', self._nlen)[0] + 7) / 8
self._n = self.body.read(nlen)
self._elen = self.body.read(2)
elen = (struct.unpack('>H', self._elen)[0] + 7) / 8
self._e = self.body.read(elen)
......@@ -147,7 +155,7 @@ class userid_packet(packet):
self.body = self.body.getvalue()
return self.ctb + self.body
def userid(self):
def userid(self):
return self._userid
......@@ -217,7 +225,7 @@ class private_key_packet(packet):
self._nlen = self.body.read(2)
nlen = (struct.unpack('>H', self._nlen)[0] + 7) / 8
self._n = self.body.read(nlen)
self._elen = self.body.read(2)
elen = (struct.unpack('>H', self._elen)[0] + 7) / 8
self._e = self.body.read(elen)
......@@ -227,13 +235,13 @@ class private_key_packet(packet):
self._iv = self.body.read(8)
else:
self._iv = None
for param in ['d', 'p', 'q', 'u']:
_plen = self.body.read(2)
setattr(self, '_'+param+'len', _plen)
plen = (struct.unpack('>H', _plen)[0] + 7) / 8
setattr(self, '_'+param, self.body.read(plen))
self._cksum = self.body.read(2)
def is_encrypted(self):
......@@ -256,7 +264,7 @@ class pke_packet(packet):
self._version = self.body.read(1)
self._keyid = self.body.read(8)
self._pkc = ord(self.body.read(1))
deklen = (struct.unpack('>H', self.body.read(2))[0] + 7 ) / 8
self._dek = octx_to_num(self.body.read(deklen))
......@@ -291,7 +299,7 @@ class compressed_packet(packet):
return stream
_FACTORY = {
_FACTORY = {
1 : pke_packet,
2 : signature_packet,
#3 : message_digest_packet, # XXX not implemented
......@@ -305,7 +313,7 @@ _FACTORY = {
14 : comment_packet,
pke_packet : 1,
signature_packet : 2,
#3 : message_digest_packet,
#3 : message_digest_packet,
private_key_packet : 5,
public_key_packet : 6,
#8 : compressed_packet,
......@@ -357,15 +365,15 @@ class packet_stream:
elif llf == 2:
lenf = struct.unpack('>L', self.stream.read(4))[0]
else: # llf == 3
raise XXXError, 'impossible case'
raise XXXError('impossible case')
body = self.stream.read(lenf)
if not body or (len(body) != lenf):
raise XXXError, 'corrupted packet'
raise XXXError('corrupted packet')
self._count = self.stream.tell()
try:
return _FACTORY[ctbt](ctb0, body)
try:
return _FACTORY[ctbt](ctb0, body)
except KeyError:
return packet(ctb0, body)
......
......@@ -14,18 +14,16 @@ class RC4:
self.cipher = rc4_new()
if key:
rc4_set_key(self.cipher, key)
def __del__(self):
if getattr(self, 'cipher', None):
if getattr(self, 'cipher', None):
self.rc4_free(self.cipher)
def set_key(self, key):
rc4_set_key(self.cipher, key)
rc4_set_key(self.cipher, key)
def update(self, data):
return rc4_update(self.cipher, data)
def final(self):
return ''
......@@ -26,7 +26,7 @@ class RSA:
assert m2.rsa_type_check(rsa), "'rsa' type error"
self.rsa = rsa
self._pyfree = _pyfree
def __del__(self):
if getattr(self, '_pyfree', 0):
self.m2_rsa_free(self.rsa)
......@@ -84,7 +84,7 @@ class RSA:
else:
ciph = getattr(m2, cipher, None)
if ciph is None:
raise RSAError, 'not such cipher %s' % cipher
raise RSAError('not such cipher %s' % cipher)
else:
ciph = ciph()
return m2.rsa_write_key(self.rsa, bio._ptr(), ciph, callback)
......@@ -144,7 +144,7 @@ class RSA:
@type bio: M2Crypto.BIO.BIO
@param bio: M2Crypto.BIO.BIO object to save key to.
"""
"""
return m2.rsa_write_pub_key(self.rsa, bio._ptr())
def save_pub_key(self, file):
......@@ -163,7 +163,7 @@ class RSA:
def sign_rsassa_pss(self, digest, algo='sha1', salt_length=20):
"""
Signs a digest with the private key using RSASSA-PSS
@requires: OpenSSL 0.9.7h or later.
@type digest: str
......@@ -171,7 +171,7 @@ class RSA:
@type salt_length: int
@param salt_length: The length of the salt to use
@type algo: str
@param algo: The hash algorithm to use
......@@ -179,11 +179,11 @@ class RSA:
"""
hash = getattr(m2, algo, None)
if hash is None:
raise ValueError('not such hash algorithm %s' % hash_algo)
raise ValueError('not such hash algorithm %s' % hash_algo)
signature = m2.rsa_padding_add_pkcs1_pss(self.rsa, digest, hash(), salt_length)
return self.private_encrypt(signature, m2.no_padding)
return self.private_encrypt(signature, m2.no_padding)
def verify_rsassa_pss(self, data, signature, algo='sha1', salt_length=20):
"""
......@@ -196,7 +196,7 @@ class RSA:
@type signature: str
@param signature: The signature signed with RSASSA-PSS
@type salt_length: int
@param salt_length: The length of the salt that was used
......@@ -204,14 +204,14 @@ class RSA:
@param algo: The hash algorithm to use
@return: 1 or 0, depending on whether the signature was
verified or not.
verified or not.
"""
hash = getattr(m2, algo, None)
if hash is None:
raise ValueError('not such hash algorithm %s' % hash_algo)
raise ValueError('not such hash algorithm %s' % hash_algo)
plain_signature = self.public_decrypt(signature, m2.no_padding)
return m2.rsa_verify_pkcs1_pss(self.rsa, data, plain_signature, hash(), salt_length)
def sign(self, digest, algo='sha1'):
......@@ -223,17 +223,17 @@ class RSA:
@type algo: str
@param algo: The method that created the digest.
Legal values are 'sha1','sha224', 'sha256', 'ripemd160',
Legal values are 'sha1','sha224', 'sha256', 'ripemd160',
and 'md5'.
@return: a string which is the signature
"""
digest_type = getattr(m2, 'NID_' + algo, None)
digest_type = getattr(m2, 'NID_' + algo, None)
if digest_type is None:
raise ValueError, ('unknown algorithm', algo)
return m2.rsa_sign(self.rsa, digest, digest_type)
raise ValueError('unknown algorithm', algo)
return m2.rsa_sign(self.rsa, digest, digest_type)
def verify(self, data, signature, algo='sha1'):
"""
Verifies the signature with the public key
......@@ -245,18 +245,18 @@ class RSA:
@param signature: The signature signed with the private key
@type algo: str
@param algo: The method use to create digest from the data
@param algo: The method use to create digest from the data
before it was signed. Legal values are 'sha1','sha224',
'sha256', 'ripemd160', and 'md5'.
@return: True or False, depending on whether the signature was
verified.
verified.
"""
digest_type = getattr(m2, 'NID_' + algo, None)
if digest_type is None:
raise ValueError, ('unknown algorithm', algo)
return m2.rsa_verify(self.rsa, data, signature, digest_type)
raise ValueError('unknown algorithm', algo)
return m2.rsa_verify(self.rsa, data, signature, digest_type)
class RSA_pub(RSA):
......@@ -267,16 +267,15 @@ class RSA_pub(RSA):
def __setattr__(self, name, value):
if name in ['e', 'n']:
raise RSAError, \
'use factory function new_pub_key() to set (e, n)'
raise RSAError('use factory function new_pub_key() to set (e, n)')
else:
self.__dict__[name] = value
def private_encrypt(self, *argv):
raise RSAError, 'RSA_pub object has no private key'
raise RSAError('RSA_pub object has no private key')
def private_decrypt(self, *argv):
raise RSAError, 'RSA_pub object has no private key'
raise RSAError('RSA_pub object has no private key')
def save_key(self, file, *args, **kw):
"""
......@@ -290,23 +289,23 @@ class RSA_pub(RSA):
"""
return self.save_pub_key_bio(bio)
#save_key_der
# save_key_der
#save_key_der_bio
# save_key_der_bio
def check_key(self):
return m2.rsa_check_pub_key(self.rsa)
def rsa_error():
raise RSAError, m2.err_reason_error_string(m2.err_get_error())
raise RSAError(m2.err_reason_error_string(m2.err_get_error()))
def keygen_callback(p, n, out=sys.stdout):
"""
Default callback for gen_key().
"""
ch = ['.','+','*','\n']
ch = ['.', '+', '*', '\n']
out.write(ch[p])
out.flush()
......@@ -328,7 +327,7 @@ def gen_key(bits, e, callback=keygen_callback):
@rtype: M2Crypto.RSA.RSA
@return: M2Crypto.RSA.RSA object.
"""
"""
return RSA(m2.rsa_generate_key(bits, e, callback), 1)
......@@ -402,7 +401,7 @@ def load_pub_key(file):
@rtype: M2Crypto.RSA.RSA_pub
@return: M2Crypto.RSA.RSA_pub object.
"""
bio = BIO.openfile(file)
bio = BIO.openfile(file)
return load_pub_key_bio(bio)
......@@ -416,33 +415,32 @@ def load_pub_key_bio(bio):
@rtype: M2Crypto.RSA.RSA_pub
@return: M2Crypto.RSA.RSA_pub object.
"""
"""
rsa = m2.rsa_read_pub_key(bio._ptr())
if rsa is None:
rsa_error()
return RSA_pub(rsa, 1)
def new_pub_key((e, n)):
def new_pub_key(e_n):
"""
Instantiate an RSA_pub object from an (e, n) tuple.
@type e: string
@param e: The RSA public exponent; it is a string in OpenSSL's MPINT
format - 4-byte big-endian bit-count followed by the appropriate
@param e: The RSA public exponent; it is a string in OpenSSL's MPINT
format - 4-byte big-endian bit-count followed by the appropriate
number of bits.
@type n: string
@param n: The RSA composite of primes; it is a string in OpenSSL's MPINT
format - 4-byte big-endian bit-count followed by the appropriate
@param n: The RSA composite of primes; it is a string in OpenSSL's MPINT
format - 4-byte big-endian bit-count followed by the appropriate
number of bits.
@rtype: M2Crypto.RSA.RSA_pub
@return: M2Crypto.RSA.RSA_pub object.
"""
"""
(e, n) = e_n
rsa = m2.rsa_new()
m2.rsa_set_e(rsa, e)
m2.rsa_set_n(rsa, n)
return RSA_pub(rsa, 1)
......@@ -7,11 +7,9 @@ __all__ = ['rand_seed', 'rand_add', 'load_file', 'save_file', 'rand_bytes',
import m2
rand_seed = m2.rand_seed
rand_add = m2.rand_add
load_file = m2.rand_load_file
save_file = m2.rand_save_file
rand_bytes = m2.rand_bytes
rand_pseudo_bytes = m2.rand_pseudo_bytes
rand_seed = m2.rand_seed
rand_add = m2.rand_add
load_file = m2.rand_load_file
save_file = m2.rand_save_file
rand_bytes = m2.rand_bytes
rand_pseudo_bytes = m2.rand_pseudo_bytes