How to make cryptlib_py work on 64-bit platforms
Cryptlib is a totally fascinating cross-platform crypto library with Python bindings. Unfortunately, the current version (3.3.3) is unusable on 64-bit platforms. The good news though it is easily fixable. Let's look what's going on there:
$ python Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> >>> from cryptlib_py import * >>> cryptInit() >>> sess = cryptCreateSession(CRYPT_UNUSED, CRYPT_SESSION_SSH) >>> sess.CRYPT_SESSINFO_SERVER_NAME = "myserver.com" Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 32, in __setattr__ cryptlib_py.CryptException: (-2, 'Bad argument, parameter 2') >>>
No good. The problem is the way PyObject_AsWriteBuffer (and PyObject_AsCharBuffer) is called. The last parameter is declared as a pointer to Py_ssize_t type, which can be either 32 or 64 bit depending on the platform. Here is the actual declaration in the abstract.h file:
PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj,
void **buffer,
Py_ssize_t *buffer_len);Now, here is how this function is used in cryptlib_py (python.c, line 21):
if (PyObject_AsWriteBuffer(objPtr, bytesPtrPtr, lengthPtr) == -1)
Where lengthPtr is declared as "int* lengthPtr". See the problem? This is what happens: the function expects a pointer to a 8-byte blob but instead it is provided with a pointer to a 4-byte int. Being unaware of that, the function smashes the variable next to the one pointed by lengthPtr. The solution is to patch cryptlibConverter.py, the script generating bindings/python.c. Although this problem is very likely to be fixed in the next cryptlib release, here is what you do if you can't wait:
mkdir cryptlib; cd cryptlib curl -O ftp://ftp.franken.de/pub/crypt/cryptlib/cl333.zip unzip cl333.zip curl -O http://mikeivanov.com/pc/cryptlibConverter.py.patch patch -p0 < cryptlibConverter.py.patch python tools/cryptlibConverter.py cryptlib.h bindings python make cd bindings python setup.py build sudo python setup.py install
Fixed! The patched version is working just fine:
$ python
Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from cryptlib_py import *
>>> cryptInit()
>>> sess = cryptCreateSession(CRYPT_UNUSED, CRYPT_SESSION_SSH)
>>> sess.CRYPT_SESSINFO_SERVER_NAME = "myserver.com"
>>> sess.CRYPT_SESSINFO_USERNAME = "mike"
>>> sess.CRYPT_SESSINFO_PASSWORD = raw_input("pwd=")
pwd=mypassword
>>> sess.CRYPT_SESSINFO_ACTIVE = 1
>>> data = array('c', '\0' * 1024)
>>> recv = cryptPopData(sess, data, 1024)
>>> print data.tostring()[:recv]
Linux myserver.com 2.6 XXXXXXXXX x86_64 GNU/Linux
Ubuntu 10.04 LTS
.......
>>> cryptPushData(sess, "uptime\n")
7
>>> cryptFlushData(sess)
>>> recv = cryptPopData(sess, data, 1024)
>>> print data.tostring()[:recv]
uptime
18:17:15 up 6 days, 1:54, 13 users, load average: 0.30, 0.27, 0.26
mike@myserver:~$
>>>