diff options
| author | Thorsten Behrens <sbehrens@gmx.li> | 2010-12-28 16:26:52 -0500 |
|---|---|---|
| committer | Thorsten Behrens <sbehrens@gmx.li> | 2010-12-28 16:26:52 -0500 |
| commit | 295ce314d9f5c750d9569ac75a4f78331fae9992 (patch) | |
| tree | 943c5f2e5237b3cf0665dd8fed278e4efa518770 /src | |
| parent | 1873473e13161587b870adadc70c1d625f8bc5cf (diff) | |
| download | pycrypto-295ce314d9f5c750d9569ac75a4f78331fae9992.tar.gz | |
Changes to allow pycrpyto to work on Python 3.x as well as 2.1 through 2.7
Diffstat (limited to 'src')
| -rw-r--r-- | src/MD2.c | 3 | ||||
| -rw-r--r-- | src/MD4.c | 5 | ||||
| -rw-r--r-- | src/RIPEMD160.c | 3 | ||||
| -rw-r--r-- | src/SHA256.c | 3 | ||||
| -rw-r--r-- | src/_counter.c | 162 | ||||
| -rw-r--r-- | src/_counter.h | 5 | ||||
| -rwxr-xr-x | src/_fastmath.c | 281 | ||||
| -rw-r--r-- | src/block_template.c | 178 | ||||
| -rw-r--r-- | src/hash_template.c | 141 | ||||
| -rw-r--r-- | src/pycrypto_compat.h | 20 | ||||
| -rw-r--r-- | src/stream_template.c | 175 | ||||
| -rw-r--r-- | src/strxor.c | 46 | ||||
| -rw-r--r-- | src/winrand.c | 111 |
13 files changed, 942 insertions, 191 deletions
@@ -29,6 +29,7 @@ #include <string.h> #include "Python.h" +#include "pycrypto_compat.h" #define MODULE_NAME MD2 #define DIGEST_SIZE 16 @@ -128,7 +129,7 @@ hash_digest (const hash_state *self) for(i=0; i<padlen; i++) padding[i]=padlen; hash_update(&temp, padding, padlen); hash_update(&temp, temp.C, 16); - return PyString_FromStringAndSize((char *) temp.X, 16); + return PyBytes_FromStringAndSize((char *) temp.X, 16); } #include "hash_template.c" @@ -28,7 +28,8 @@ #include <string.h> -#include <Python.h> +#include "Python.h" +#include "pycrypto_compat.h" #define MODULE_NAME MD4 #define DIGEST_SIZE 16 @@ -213,7 +214,7 @@ hash_digest (const hash_state *self) digest[14]=(temp.D >> 16) & 255; digest[15]=(temp.D >> 24) & 255; - return PyString_FromStringAndSize((char *) digest, 16); + return PyBytes_FromStringAndSize((char *) digest, 16); } #include "hash_template.c" diff --git a/src/RIPEMD160.c b/src/RIPEMD160.c index da2e72c..a018d3f 100644 --- a/src/RIPEMD160.c +++ b/src/RIPEMD160.c @@ -47,6 +47,7 @@ #include <stdint.h> #include <string.h> #include "Python.h" +#include "pycrypto_compat.h" #define RIPEMD160_DIGEST_SIZE 20 @@ -402,7 +403,7 @@ static PyObject *hash_digest(hash_state *self) PyObject *retval; if (ripemd160_digest(self, (unsigned char *) buf)) { - retval = PyString_FromStringAndSize(buf, DIGEST_SIZE); + retval = PyBytes_FromStringAndSize(buf, DIGEST_SIZE); } else { PyErr_SetString(PyExc_RuntimeError, "Internal error occurred while executing ripemd160_digest"); retval = NULL; diff --git a/src/SHA256.c b/src/SHA256.c index 8150242..117b016 100644 --- a/src/SHA256.c +++ b/src/SHA256.c @@ -32,6 +32,7 @@ * */ #include "Python.h" +#include "pycrypto_compat.h" #define MODULE_NAME SHA256 #define DIGEST_SIZE 32 @@ -224,7 +225,7 @@ hash_digest (const hash_state *self) hash_copy((hash_state*)self,&temp); sha_done(&temp,digest); - return PyString_FromStringAndSize((char *)digest, 32); + return PyBytes_FromStringAndSize((char *)digest, 32); } #include "hash_template.c" diff --git a/src/_counter.c b/src/_counter.c index 8a5522a..9b396e4 100644 --- a/src/_counter.c +++ b/src/_counter.c @@ -25,16 +25,23 @@ #include <assert.h> #include <stddef.h> #include <string.h> - +#include "Python.h" +#include "pycrypto_compat.h" #include "_counter.h" -#include "pycrypto_compat.h" +#ifndef IS_PY3K +#define PyLong_FromLong PyInt_FromLong +#endif /* NB: This can be called multiple times for a given object, via the __init__ method. Be careful. */ static int CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) { - PyStringObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#ifdef IS_PY3K + PyBytesObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#else + PyStringObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#endif int allow_wraparound = 0; int disable_shortcut = 0; Py_ssize_t size; @@ -44,7 +51,7 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) return -1; /* Check string size and set nbytes */ - size = PyString_GET_SIZE(initval); + size = PyBytes_GET_SIZE(initval); if (size < 1) { PyErr_SetString(PyExc_ValueError, "initval length too small (must be >= 1 byte)"); return -1; @@ -55,7 +62,7 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) self->nbytes = (uint16_t) size; /* Check prefix length */ - size = PyString_GET_SIZE(prefix); + size = PyBytes_GET_SIZE(prefix); assert(size >= 0); if (size > 0xffff) { PyErr_SetString(PyExc_ValueError, "prefix length too large (must be <= 65535 bytes)"); @@ -63,7 +70,7 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) } /* Check suffix length */ - size = PyString_GET_SIZE(suffix); + size = PyBytes_GET_SIZE(suffix); assert(size >= 0); if (size > 0xffff) { PyErr_SetString(PyExc_ValueError, "suffix length too large (must be <= 65535 bytes)"); @@ -89,24 +96,24 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) /* Allocate new buffer */ /* buf_size won't overflow because the length of each string will always be <= 0xffff */ - self->buf_size = PyString_GET_SIZE(prefix) + PyString_GET_SIZE(suffix) + self->nbytes; + self->buf_size = PyBytes_GET_SIZE(prefix) + PyBytes_GET_SIZE(suffix) + self->nbytes; self->val = self->p = PyMem_Malloc(self->buf_size); if (self->val == NULL) { self->buf_size = 0; return -1; } - self->p = self->val + PyString_GET_SIZE(prefix); + self->p = self->val + PyBytes_GET_SIZE(prefix); /* Sanity-check pointers */ assert(self->val <= self->p); assert(self->p + self->nbytes <= self->val + self->buf_size); - assert(self->val + PyString_GET_SIZE(self->prefix) == self->p); - assert(PyString_GET_SIZE(self->prefix) + self->nbytes + PyString_GET_SIZE(self->suffix) == self->buf_size); + assert(self->val + PyBytes_GET_SIZE(self->prefix) == self->p); + assert(PyBytes_GET_SIZE(self->prefix) + self->nbytes + PyBytes_GET_SIZE(self->suffix) == self->buf_size); /* Copy the prefix, suffix, and initial value into the buffer. */ - memcpy(self->val, PyString_AS_STRING(prefix), PyString_GET_SIZE(prefix)); - memcpy(self->p, PyString_AS_STRING(initval), self->nbytes); - memcpy(self->p + self->nbytes, PyString_AS_STRING(suffix), PyString_GET_SIZE(suffix)); + memcpy(self->val, PyBytes_AS_STRING(prefix), PyBytes_GET_SIZE(prefix)); + memcpy(self->p, PyBytes_AS_STRING(initval), self->nbytes); + memcpy(self->p + self->nbytes, PyBytes_AS_STRING(suffix), PyBytes_GET_SIZE(suffix)); /* Set shortcut_disabled and allow_wraparound */ self->shortcut_disabled = disable_shortcut; @@ -154,7 +161,7 @@ _CounterObject_next_value(PCT_CounterObject *self, int little_endian) goto err_out; } - eight = PyInt_FromLong(8); + eight = PyLong_FromLong(8); if (!eight) goto err_out; @@ -179,7 +186,7 @@ _CounterObject_next_value(PCT_CounterObject *self, int little_endian) /* ch = ord(p) */ Py_CLEAR(ch); /* delete old ch */ - ch = PyInt_FromLong((long) *p); + ch = PyLong_FromLong((long) *p); if (!ch) goto err_out; @@ -274,7 +281,7 @@ CounterObject_call(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) return NULL; } - retval = (PyObject *)PyString_FromStringAndSize((const char *)self->val, self->buf_size); + retval = (PyObject *)PyBytes_FromStringAndSize((const char *)self->val, self->buf_size); self->inc_func(self); @@ -297,45 +304,94 @@ static PyMethodDef CounterBEObject_methods[] = { /* Python 2.1 doesn't allow us to assign methods or attributes to an object, * so we hack it here. */ + static PyObject * +#ifdef IS_PY3K +CounterLEObject_getattro(PyObject *s, PyObject *attr) +#else CounterLEObject_getattr(PyObject *s, char *name) +#endif { PCT_CounterObject *self = (PCT_CounterObject *)s; +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "carry") == 0) { +#else if (strcmp(name, "carry") == 0) { - return PyInt_FromLong((long)self->carry); +#endif + return PyLong_FromLong((long)self->carry); +#ifdef IS_PY3K + } else if (!self->shortcut_disabled && PyUnicode_CompareWithASCIIString(attr, "__PCT_CTR_SHORTCUT__") == 0) { +#else } else if (!self->shortcut_disabled && strcmp(name, "__PCT_CTR_SHORTCUT__") == 0) { +#endif /* Shortcut hack - See block_template.c */ Py_INCREF(Py_True); return Py_True; } +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else return Py_FindMethod(CounterLEObject_methods, (PyObject *)self, name); +#endif } static PyObject * +#ifdef IS_PY3K +CounterBEObject_getattro(PyObject *s, PyObject *attr) +#else CounterBEObject_getattr(PyObject *s, char *name) +#endif { PCT_CounterObject *self = (PCT_CounterObject *)s; +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "carry") == 0) { +#else if (strcmp(name, "carry") == 0) { - return PyInt_FromLong((long)self->carry); +#endif + return PyLong_FromLong((long)self->carry); +#ifdef IS_PY3K + } else if (!self->shortcut_disabled && PyUnicode_CompareWithASCIIString(attr, "__PCT_CTR_SHORTCUT__") == 0) { +#else } else if (!self->shortcut_disabled && strcmp(name, "__PCT_CTR_SHORTCUT__") == 0) { +#endif /* Shortcut hack - See block_template.c */ Py_INCREF(Py_True); return Py_True; } - +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else return Py_FindMethod(CounterBEObject_methods, (PyObject *)self, name); +#endif } static PyTypeObject my_CounterLEType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /* ob_size */ +#endif "_counter.CounterLE", /* tp_name */ sizeof(PCT_CounterObject), /* tp_basicsize */ 0, /* tp_itemsize */ + /* methods */ (destructor)CounterObject_dealloc, /* tp_dealloc */ 0, /* tp_print */ +#ifdef IS_PY3K + 0, /* tp_getattr */ +#else CounterLEObject_getattr, /* tp_getattr */ +#endif 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -345,23 +401,44 @@ my_CounterLEType = { 0, /* tp_hash */ (ternaryfunc)CounterObject_call, /* tp_call */ 0, /* tp_str */ +#ifdef IS_PY3K + CounterLEObject_getattro, /* tp_getattro */ +#else 0, /* tp_getattro */ +#endif 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Counter (little endian)", /* tp_doc */ +#ifdef IS_PY3K + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + CounterLEObject_methods, /*tp_methods*/ +#endif }; static PyTypeObject my_CounterBEType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /* ob_size */ +#endif "_counter.CounterBE", /* tp_name */ sizeof(PCT_CounterObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)CounterObject_dealloc, /* tp_dealloc */ 0, /* tp_print */ +#ifdef IS_PY3K + 0, /* tp_getattr */ +#else CounterBEObject_getattr, /* tp_getattr */ +#endif 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -371,11 +448,24 @@ my_CounterBEType = { 0, /* tp_hash */ (ternaryfunc)CounterObject_call, /* tp_call */ 0, /* tp_str */ +#ifdef IS_PY3K + CounterBEObject_getattro, /* tp_getattro */ +#else 0, /* tp_getattro */ +#endif 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Counter (big endian)", /* tp_doc */ +#ifdef IS_PY3K + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + CounterBEObject_methods, /*tp_methods*/ +#endif }; /* @@ -444,21 +534,51 @@ static PyMethodDef module_methods[] = { {NULL, NULL, 0, NULL} /* end-of-list sentinel value */ }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_counter", + NULL, + -1, + module_methods, + NULL, + NULL, + NULL, + NULL +}; +#endif PyMODINIT_FUNC +#ifdef IS_PY3K +PyInit__counter(void) +#else init_counter(void) +#endif { PyObject *m; /* TODO - Is the error handling here correct? */ +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&my_CounterLEType) < 0) + return NULL; + if (PyType_Ready(&my_CounterBEType) < 0) + return NULL; /* Initialize the module */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; + + return m; +#else m = Py_InitModule("_counter", module_methods); if (m == NULL) return; - - my_CounterLEType.ob_type = &PyType_Type; + + my_CounterLEType.ob_type = &PyType_Type; my_CounterBEType.ob_type = &PyType_Type; +#endif } /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/_counter.h b/src/_counter.h index faaf63f..47dd494 100644 --- a/src/_counter.h +++ b/src/_counter.h @@ -25,12 +25,11 @@ #define PCT__COUNTER_H #include <stdint.h> -#include "Python.h" typedef struct { PyObject_HEAD - PyStringObject *prefix; /* Prefix (useful for a nonce) */ - PyStringObject *suffix; /* Suffix (useful for a nonce) */ + PyBytesObject *prefix; /* Prefix (useful for a nonce) */ + PyBytesObject *suffix; /* Suffix (useful for a nonce) */ uint8_t *val; /* Buffer for our output string */ uint32_t buf_size; /* Size of the buffer */ uint8_t *p; /* Pointer to the part of the buffer that we're allowed to update */ diff --git a/src/_fastmath.c b/src/_fastmath.c index b592ef9..4656181 100755 --- a/src/_fastmath.c +++ b/src/_fastmath.c @@ -29,7 +29,8 @@ #include <stdio.h> #include <string.h> -#include <Python.h> +#include "Python.h" +#include "pycrypto_compat.h" #include <longintrepr.h> /* for conversions */ #include <gmp.h> @@ -51,15 +52,26 @@ longObjToMPZ (mpz_t m, PyLongObject * p) mpz_t temp, temp2; mpz_init (temp); mpz_init (temp2); +#ifdef IS_PY3K + if (p->ob_base.ob_size > 0) + size = p->ob_base.ob_size; + else + size = -p->ob_base.ob_size; +#else if (p->ob_size > 0) size = p->ob_size; else size = -p->ob_size; +#endif mpz_set_ui (m, 0); for (i = 0; i < size; i++) { mpz_set_ui (temp, p->ob_digit[i]); +#ifdef IS_PY3K + mpz_mul_2exp (temp2, temp, PyLong_SHIFT * i); +#else mpz_mul_2exp (temp2, temp, SHIFT * i); +#endif mpz_add (m, m, temp2); } mpz_clear (temp); @@ -70,7 +82,11 @@ static PyObject * mpzToLongObj (mpz_t m) { /* borrowed from gmpy */ +#ifdef IS_PY3K + int size = (mpz_sizeinbase (m, 2) + PyLong_SHIFT - 1) / PyLong_SHIFT; +#else int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT; +#endif int i; mpz_t temp; PyLongObject *l = _PyLong_New (size); @@ -79,13 +95,22 @@ mpzToLongObj (mpz_t m) mpz_init_set (temp, m); for (i = 0; i < size; i++) { +#ifdef IS_PY3K + l->ob_digit[i] = (digit) (mpz_get_ui (temp) & PyLong_MASK); + mpz_fdiv_q_2exp (temp, temp, PyLong_SHIFT); +#else l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK); mpz_fdiv_q_2exp (temp, temp, SHIFT); +#endif } i = size; while ((i > 0) && (l->ob_digit[i - 1] == 0)) i--; +#ifdef IS_PY3K + l->ob_base.ob_size = i; +#else l->ob_size = i; +#endif mpz_clear (temp); return (PyObject *) l; } @@ -115,14 +140,22 @@ static PyObject *rsaKey_new (PyObject *, PyObject *); static PyObject *dsaKey_new (PyObject *, PyObject *); static void dsaKey_dealloc (dsaKey *); +#ifdef IS_PY3K +static PyObject *dsaKey_getattro (dsaKey *, PyObject *); +#else static PyObject *dsaKey_getattr (dsaKey *, char *); +#endif static PyObject *dsaKey__sign (dsaKey *, PyObject *); static PyObject *dsaKey__verify (dsaKey *, PyObject *); static PyObject *dsaKey_size (dsaKey *, PyObject *); static PyObject *dsaKey_has_private (dsaKey *, PyObject *); static void rsaKey_dealloc (rsaKey *); +#ifdef IS_PY3K +static PyObject *rsaKey_getattro (rsaKey *, PyObject *); +#else static PyObject *rsaKey_getattr (rsaKey *, char *); +#endif static PyObject *rsaKey__encrypt (rsaKey *, PyObject *); static PyObject *rsaKey__decrypt (rsaKey *, PyObject *); static PyObject *rsaKey__verify (rsaKey *, PyObject *); @@ -285,25 +318,6 @@ rsaUnBlind (rsaKey * key, mpz_t v, mpz_t b) mpz_mod (v, v, key->n); return 0; } - - -static PyTypeObject dsaKeyType = { - PyObject_HEAD_INIT (NULL) 0, - "dsaKey", - sizeof (dsaKey), - 0, - (destructor) dsaKey_dealloc, /* dealloc */ - 0, /* print */ - (getattrfunc) dsaKey_getattr, /* getattr */ - 0, /* setattr */ - 0, /* compare */ - 0, /* repr */ - 0, /* as_number */ - 0, /* as_sequence */ - 0, /* as_mapping */ - 0, /* hash */ - 0, /* call */ -}; static PyMethodDef dsaKey__methods__[] = { {"_sign", (PyCFunction) dsaKey__sign, METH_VARARGS, @@ -317,26 +331,6 @@ static PyMethodDef dsaKey__methods__[] = { {NULL, NULL, 0, NULL} }; -static PyObject *fastmathError; /* raised on errors */ - -static PyTypeObject rsaKeyType = { - PyObject_HEAD_INIT (NULL) 0, - "rsaKey", - sizeof (rsaKey), - 0, - (destructor) rsaKey_dealloc, /* dealloc */ - 0, /* print */ - (getattrfunc) rsaKey_getattr, /* getattr */ - 0, /* setattr */ - 0, /* compare */ - 0, /* repr */ - 0, /* as_number */ - 0, /* as_sequence */ - 0, /* as_mapping */ - 0, /* hash */ - 0, /* call */ -}; - static PyMethodDef rsaKey__methods__[] = { {"_encrypt", (PyCFunction) rsaKey__encrypt, METH_VARARGS, "Encrypt the given long."}, @@ -357,6 +351,92 @@ static PyMethodDef rsaKey__methods__[] = { {NULL, NULL, 0, NULL} }; +static PyObject *fastmathError; /* raised on errors */ + +static PyTypeObject dsaKeyType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT (NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ +#endif + "dsaKey", + sizeof (dsaKey), + 0, + (destructor) dsaKey_dealloc, /* dealloc */ + 0, /* print */ +#ifdef IS_PY3K + 0, /* getattr */ +#else + (getattrfunc) dsaKey_getattr, /* getattr */ +#endif + 0, /* setattr */ + 0, /* compare */ + 0, /* repr */ + 0, /* as_number */ + 0, /* as_sequence */ + 0, /* as_mapping */ + 0, /* hash */ + 0, /* call */ +#ifdef IS_PY3K + 0, /*tp_str*/ + dsaKey_getattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + dsaKey__methods__, /*tp_methods*/ +#endif +}; + +static PyTypeObject rsaKeyType = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT (NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ +#endif + "rsaKey", + sizeof (rsaKey), + 0, + (destructor) rsaKey_dealloc, /* dealloc */ + 0, /* print */ +#ifdef IS_PY3k + 0, /* getattr */ +#else + (getattrfunc) rsaKey_getattr, /* getattr */ +#endif + 0, /* setattr */ + 0, /* compare */ + 0, /* repr */ + 0, /* as_number */ + 0, /* as_sequence */ + 0, /* as_mapping */ + 0, /* hash */ + 0, /* call */ +#ifdef IS_PY3K + 0, /*tp_str*/ + rsaKey_getattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + rsaKey__methods__, /*tp_methods*/ +#endif +}; + static PyObject * dsaKey_new (PyObject * self, PyObject * args) { @@ -396,17 +476,43 @@ dsaKey_dealloc (dsaKey * key) } static PyObject * +#ifdef IS_PY3K +dsaKey_getattr (dsaKey * key, PyObject *attr) +#else dsaKey_getattr (dsaKey * key, char *attr) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + if (PyUnicode_CompareWithASCIIString(attr,"y") == 0) +#else if (strcmp (attr, "y") == 0) +#endif return mpzToLongObj (key->y); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "g") == 0) +#else else if (strcmp (attr, "g") == 0) +#endif return mpzToLongObj (key->g); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "p") == 0) +#else else if (strcmp (attr, "p") == 0) +#endif return mpzToLongObj (key->p); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "q") == 0) +#else else if (strcmp (attr, "q") == 0) +#endif return mpzToLongObj (key->q); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "x") == 0) +#else else if (strcmp (attr, "x") == 0) +#endif { if (mpz_size (key->x) == 0) { @@ -417,9 +523,12 @@ dsaKey_getattr (dsaKey * key, char *attr) return mpzToLongObj (key->x); } else - { +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr((PyObject *) key, attr); +#else return Py_FindMethod (dsaKey__methods__, (PyObject *) key, attr); - } +#endif } static PyObject * @@ -559,13 +668,31 @@ rsaKey_dealloc (rsaKey * key) } static PyObject * +#ifdef IS_PY3K +rsaKey_getattro (rsaKey * key, PyObject *attr) +#else rsaKey_getattr (rsaKey * key, char *attr) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + if (PyUnicode_CompareWithASCIIString(attr, "n") == 0) +#else if (strcmp (attr, "n") == 0) +#endif return mpzToLongObj (key->n); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "e") == 0) +#else else if (strcmp (attr, "e") == 0) +#endif return mpzToLongObj (key->e); +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "d") == 0) +#else else if (strcmp (attr, "d") == 0) +#endif { if (mpz_size (key->d) == 0) { @@ -575,7 +702,11 @@ rsaKey_getattr (rsaKey * key, char *attr) } return mpzToLongObj (key->d); } +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "p") == 0) +#else else if (strcmp (attr, "p") == 0) +#endif { if (mpz_size (key->p) == 0) { @@ -585,7 +716,11 @@ rsaKey_getattr (rsaKey * key, char *attr) } return mpzToLongObj (key->p); } +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "q") == 0) +#else else if (strcmp (attr, "q") == 0) +#endif { if (mpz_size (key->q) == 0) { @@ -595,7 +730,11 @@ rsaKey_getattr (rsaKey * key, char *attr) } return mpzToLongObj (key->q); } +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "u") == 0) +#else else if (strcmp (attr, "u") == 0) +#endif { if (mpz_size (key->u) == 0) { @@ -606,10 +745,13 @@ rsaKey_getattr (rsaKey * key, char *attr) return mpzToLongObj (key->u); } else - { +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr((PyObject *) key, attr); +#else return Py_FindMethod (rsaKey__methods__, (PyObject *) key, attr); - } +#endif } static PyObject * @@ -932,7 +1074,7 @@ getRandomInteger (mpz_t n, unsigned long int bits, PyObject *randfunc_) arglist = Py_BuildValue ("(l)", (long int)bytes); rand_bytes = PyObject_CallObject (randfunc, arglist); Py_DECREF (arglist); - if (!PyString_Check (rand_bytes)) + if (!PyBytes_Check (rand_bytes)) { PyErr_SetString (PyExc_TypeError, "randfunc must return a string of random bytes"); @@ -940,7 +1082,7 @@ getRandomInteger (mpz_t n, unsigned long int bits, PyObject *randfunc_) goto cleanup; } - bytes_to_mpz (n, (unsigned char *)PyString_AsString(rand_bytes), bytes); + bytes_to_mpz (n, (unsigned char *)PyBytes_AsString(rand_bytes), bytes); /* remove superflous bits by right-shifting */ mpz_fdiv_q_2exp (n, n, 8 - odd_bits); @@ -1385,21 +1527,54 @@ static PyMethodDef _fastmath__methods__[] = { {NULL, NULL} }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_fastmath", + NULL, + -1, + _fastmath__methods__, + NULL, + NULL, + NULL, + NULL +}; +#endif + +#ifdef IS_PY3K +PyMODINIT_FUNC +PyInit__fastmath (void) +#else void init_fastmath (void) +#endif { - PyObject *_fastmath_module; - PyObject *_fastmath_dict; - + PyObject *_fastmath_module; + PyObject *_fastmath_dict; + +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&rsaKeyType) < 0) + return NULL; + if (PyType_Ready(&dsaKeyType) < 0) + return NULL; + + _fastmath_module = PyModule_Create(&moduledef); + if (_fastmath_module == NULL) + return NULL; +#else rsaKeyType.ob_type = &PyType_Type; dsaKeyType.ob_type = &PyType_Type; _fastmath_module = Py_InitModule ("_fastmath", _fastmath__methods__); - _fastmath_dict = PyModule_GetDict (_fastmath_module); +#endif + _fastmath_dict = PyModule_GetDict (_fastmath_module); fastmathError = PyErr_NewException ("_fastmath.error", NULL, NULL); - PyDict_SetItemString (_fastmath_dict, "error", fastmathError); -} - + PyDict_SetItemString (_fastmath_dict, "error", fastmathError); +#ifdef IS_PY3K + return _fastmath_module; +#endif +} /* The first 10000 primes to be used as a base for sieving */ static unsigned int sieve_base[10000] = { diff --git a/src/block_template.c b/src/block_template.c index 9ce2de6..91247b2 100644 --- a/src/block_template.c +++ b/src/block_template.c @@ -34,6 +34,7 @@ #endif #include "Python.h" +#include "pycrypto_compat.h" #include "modsupport.h" #include "_counter.h" @@ -51,7 +52,11 @@ #define _XSTR(x) _STR(x) #define _PASTE(x,y) x##y #define _PASTE2(x,y) _PASTE(x,y) +#ifdef IS_PY3K +#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME) +#else #define _MODULE_NAME _PASTE2(init,MODULE_NAME) +#endif #define _MODULE_STRING _XSTR(MODULE_NAME) typedef struct @@ -64,9 +69,17 @@ typedef struct block_state st; } ALGobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; - #define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -95,6 +108,7 @@ ALGdealloc(PyObject *ptr) } + static char ALGnew__doc__[] = "new(key, [mode], [IV]): Return a new " _MODULE_STRING " encryption object."; @@ -168,13 +182,16 @@ ALGnew(PyObject *self, PyObject *args, PyObject *kwdict) return NULL; } } - if (mode == MODE_CTR) { if (counter == NULL) { PyErr_SetString(PyExc_TypeError, "'counter' keyword parameter is required with CTR mode"); return NULL; +#ifdef IS_PY3K + } else if (PyObject_HasAttr(counter, PyUnicode_FromString("__PCT_CTR_SHORTCUT__"))) { +#else } else if (PyObject_HasAttrString(counter, "__PCT_CTR_SHORTCUT__")) { +#endif counter_shortcut = 1; } else if (!PyCallable_Check(counter)) { PyErr_SetString(PyExc_ValueError, @@ -246,7 +263,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) return NULL; if (len==0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } if ( (len % BLOCK_SIZE) !=0 && (self->mode!=MODE_CFB) && (self->mode!=MODE_PGP) && @@ -438,25 +455,33 @@ ALG_Encrypt(ALGobject *self, PyObject *args) free(buffer); return NULL; } - if (!PyString_Check(ctr)) + if (!PyBytes_Check(ctr)) { PyErr_SetString(PyExc_TypeError, +#ifdef IS_PY3K + "CTR counter function didn't return bytes"); +#else "CTR counter function didn't return a string"); +#endif Py_DECREF(ctr); free(buffer); return NULL; } - if (PyString_Size(ctr) != BLOCK_SIZE) { + if (PyBytes_Size(ctr) != BLOCK_SIZE) { PyErr_Format(PyExc_TypeError, "CTR counter function returned " +#ifdef IS_PY3K + "bytes not of length %i", +#else "string not of length %i", +#endif BLOCK_SIZE); Py_DECREF(ctr); free(buffer); return NULL; } Py_UNBLOCK_THREADS; - block_encrypt(&(self->st), (unsigned char *)PyString_AsString(ctr), + block_encrypt(&(self->st), (unsigned char *)PyBytes_AsString(ctr), self->IV); Py_BLOCK_THREADS; Py_DECREF(ctr); @@ -478,7 +503,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) return NULL; } Py_END_ALLOW_THREADS; - result=PyString_FromStringAndSize((char *) buffer, len); + result=PyBytes_FromStringAndSize((char *) buffer, len); free(buffer); return(result); } @@ -487,6 +512,8 @@ static char ALG_Decrypt__doc__[] = "decrypt(string): Decrypt the provided string of binary data."; + + static PyObject * ALG_Decrypt(ALGobject *self, PyObject *args) { @@ -503,7 +530,7 @@ ALG_Decrypt(ALGobject *self, PyObject *args) return NULL; if (len==0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } if ( (len % BLOCK_SIZE) !=0 && (self->mode!=MODE_CFB && self->mode!=MODE_PGP)) @@ -643,7 +670,7 @@ ALG_Decrypt(ALGobject *self, PyObject *args) return NULL; } Py_END_ALLOW_THREADS; - result=PyString_FromStringAndSize((char *) buffer, len); + result=PyBytes_FromStringAndSize((char *) buffer, len); free(buffer); return(result); } @@ -694,17 +721,25 @@ void PrintState(self, msg) #endif -/* ALG object methods */ + + + + +/* ALG object methods */ static PyMethodDef ALGmethods[] = { +#ifdef IS_PY3K + {"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__}, + {"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__}, +#else {"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__}, {"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__}, +#endif {"sync", (PyCFunction) ALG_Sync, METH_VARARGS, ALG_Sync__doc__}, {NULL, NULL} /* sentinel */ }; - static int ALGsetattr(PyObject *ptr, char *name, PyObject *v) { @@ -722,44 +757,77 @@ ALGsetattr(PyObject *ptr, char *name, PyObject *v) "Can't delete IV attribute of block cipher object"); return -1; } - if (!PyString_Check(v)) + if (!PyBytes_Check(v)) { PyErr_SetString(PyExc_TypeError, +#ifdef IS_PY3K + "IV attribute of block cipher object must be bytes"); +#else "IV attribute of block cipher object must be string"); +#endif return -1; } - if (PyString_Size(v)!=BLOCK_SIZE) + if (PyBytes_Size(v)!=BLOCK_SIZE) { PyErr_Format(PyExc_ValueError, _MODULE_STRING " IV must be %i bytes long", BLOCK_SIZE); return -1; } - memcpy(self->IV, PyString_AsString(v), BLOCK_SIZE); + memcpy(self->IV, PyBytes_AsString(v), BLOCK_SIZE); return 0; } static PyObject * +#ifdef IS_PY3K +ALGgetattro(PyObject *s, PyObject *attr) +#else ALGgetattr(PyObject *s, char *name) +#endif { ALGobject *self = (ALGobject*)s; + +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "IV") == 0) +#else if (strcmp(name, "IV") == 0) +#endif { - return(PyString_FromStringAndSize((char *) self->IV, BLOCK_SIZE)); + return(PyBytes_FromStringAndSize((char *) self->IV, BLOCK_SIZE)); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "mode") == 0) +#else if (strcmp(name, "mode") == 0) +#endif { - return(PyInt_FromLong((long)(self->mode))); + return(PyLong_FromLong((long)(self->mode))); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "block_size") == 0) +#else if (strcmp(name, "block_size") == 0) +#endif { - return PyInt_FromLong(BLOCK_SIZE); + return PyLong_FromLong(BLOCK_SIZE); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "key_size") == 0) +#else if (strcmp(name, "key_size") == 0) +#endif { - return PyInt_FromLong(KEY_SIZE); + return PyLong_FromLong(KEY_SIZE); } - return Py_FindMethod(ALGmethods, (PyObject *) self, name); +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else + return Py_FindMethod(ALGmethods, (PyObject *) self, name); +#endif } /* List of functions defined in the module */ @@ -772,38 +840,95 @@ static struct PyMethodDef modulemethods[] = static PyTypeObject ALGtype = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ +#endif _MODULE_STRING, /*tp_name*/ sizeof(ALGobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ - ALGdealloc, /*tp_dealloc*/ + (destructor) ALGdealloc, /*tp_dealloc*/ 0, /*tp_print*/ - ALGgetattr, /*tp_getattr*/ +#ifdef IS_PY3K + 0, /*tp_getattr*/ +#else + ALGgetattr, /*tp_getattr*/ +#endif ALGsetattr, /*tp_setattr*/ 0, /*tp_compare*/ - (reprfunc) 0, /*tp_repr*/ + (reprfunc) 0, /*tp_repr*/ 0, /*tp_as_number*/ +#ifdef IS_PY3K + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + ALGgetattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + ALGmethods, /*tp_methods*/ +#endif +}; + +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "Crypto.Cipher." _MODULE_STRING, + NULL, + -1, + modulemethods, + NULL, + NULL, + NULL, + NULL }; +#endif /* Initialization function for the module */ +/* Deal with old API in Python 2.1 */ #if PYTHON_API_VERSION < 1011 #define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ if (o!=NULL) \ {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} #endif + +#ifdef IS_PY3K +PyMODINIT_FUNC +#else void +#endif _MODULE_NAME (void) { PyObject *m; - ALGtype.ob_type = &PyType_Type; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&ALGtype) < 0) + return NULL; /* Create the module and add the functions */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else + ALGtype.ob_type = &PyType_Type; + /* Create the module and add the functions */ m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods); +#endif PyModule_AddIntConstant(m, "MODE_ECB", MODE_ECB); PyModule_AddIntConstant(m, "MODE_CBC", MODE_CBC); @@ -817,6 +942,9 @@ _MODULE_NAME (void) /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("can't initialize module " _MODULE_STRING); -} -/* vim:set ts=8 sw=8 sts=0 noexpandtab: */ +#ifdef IS_PY3K + return m; +#endif +} +/* vim:set ts=4 sw=4 sts=0 noexpandtab: */ diff --git a/src/hash_template.c b/src/hash_template.c index 78e37be..7bb9139 100644 --- a/src/hash_template.c +++ b/src/hash_template.c @@ -30,12 +30,18 @@ #ifdef _HAVE_STDC_HEADERS #include <string.h> #endif +#include "Python.h" +#include "pycrypto_compat.h" #define _STR(x) #x #define _XSTR(x) _STR(x) #define _PASTE(x,y) x##y #define _PASTE2(x,y) _PASTE(x,y) +#ifdef IS_PY3K +#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME) +#else #define _MODULE_NAME _PASTE2(init,MODULE_NAME) +#endif #define _MODULE_STRING _XSTR(MODULE_NAME) typedef struct { @@ -43,9 +49,17 @@ typedef struct { hash_state st; } ALGobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; - #define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -117,22 +131,27 @@ ALG_hexdigest(ALGobject *self, PyObject *args) /* Get the raw (binary) digest value */ value = (PyObject *)hash_digest(&(self->st)); - size = PyString_Size(value); - raw_digest = (unsigned char *) PyString_AsString(value); + size = PyBytes_Size(value); + raw_digest = (unsigned char *) PyBytes_AsString(value); /* Create a new string */ - retval = PyString_FromStringAndSize(NULL, size * 2 ); - hex_digest = (unsigned char *) PyString_AsString(retval); + retval = PyBytes_FromStringAndSize(NULL, size * 2 ); + hex_digest = (unsigned char *) PyBytes_AsString(retval); /* Make hex version of the digest */ - for(i=j=0; i<size; i++) + for(i=j=0; i<size; i++) { char c; c = raw_digest[i] / 16; c = (c>9) ? c+'a'-10 : c + '0'; hex_digest[j++] = c; c = raw_digest[i] % 16; c = (c>9) ? c+'a'-10 : c + '0'; hex_digest[j++] = c; - } + } +#ifdef IS_PY3K + /* Create a text string return value */ + retval = PyUnicode_FromEncodedObject(retval,"latin-1","strict"); +#endif + Py_DECREF(value); return retval; } @@ -150,47 +169,90 @@ ALG_update(ALGobject *self, PyObject *args) return NULL; Py_BEGIN_ALLOW_THREADS; + hash_update(&(self->st), cp, len); Py_END_ALLOW_THREADS; Py_INCREF(Py_None); + return Py_None; } static PyMethodDef ALG_methods[] = { {"copy", (PyCFunction)ALG_copy, METH_VARARGS, ALG_copy__doc__}, {"digest", (PyCFunction)ALG_digest, METH_VARARGS, ALG_digest__doc__}, - {"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS, - ALG_hexdigest__doc__}, + {"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS, ALG_hexdigest__doc__}, {"update", (PyCFunction)ALG_update, METH_VARARGS, ALG_update__doc__}, {NULL, NULL} /* sentinel */ }; static PyObject * +#ifdef IS_PY3K +ALG_getattro(PyObject *self, PyObject *attr) +#else ALG_getattr(PyObject *self, char *name) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "digest_size")==0) +#else if (strcmp(name, "digest_size")==0) - return PyInt_FromLong(DIGEST_SIZE); - +#endif + return PyLong_FromLong(DIGEST_SIZE); + +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(self, attr); +#else return Py_FindMethod(ALG_methods, self, name); +#endif } static PyTypeObject ALGtype = { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - _MODULE_STRING, /*tp_name*/ - sizeof(ALGobject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - ALG_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ +#endif + _MODULE_STRING, /*tp_name*/ + sizeof(ALGobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) ALG_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +#ifdef IS_PY3K + 0, /*tp_getattr*/ +#else ALG_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ -}; - +#endif + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ +#ifdef IS_PY3K + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + ALG_getattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + ALG_methods, /*tp_methods*/ +#endif + }; /* The single module-level function: new() */ @@ -231,7 +293,6 @@ ALG_new(PyObject *self, PyObject *args) return (PyObject *)new; } - /* List of functions exported by this module */ static struct PyMethodDef ALG_functions[] = { @@ -239,22 +300,51 @@ static struct PyMethodDef ALG_functions[] = { {NULL, NULL} /* Sentinel */ }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "Crypto.Hash." _MODULE_STRING, + NULL, + -1, + ALG_functions, + NULL, + NULL, + NULL, + NULL +}; +#endif /* Initialize this module. */ +/* Deal with old API in Python 2.1 */ #if PYTHON_API_VERSION < 1011 #define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ if (o!=NULL) \ {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} #endif +#ifdef IS_PY3K +PyMODINIT_FUNC +#else void +#endif _MODULE_NAME (void) { PyObject *m; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&ALGtype) < 0) + return NULL; + + /* Create the module and add the functions */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else ALGtype.ob_type = &PyType_Type; m = Py_InitModule("Crypto.Hash." _MODULE_STRING, ALG_functions); +#endif /* Add some symbolic constants to the module */ PyModule_AddIntConstant(m, "digest_size", DIGEST_SIZE); @@ -263,4 +353,7 @@ _MODULE_NAME (void) if (PyErr_Occurred()) Py_FatalError("can't initialize module " _MODULE_STRING); +#ifdef IS_PY3K + return m; +#endif } diff --git a/src/pycrypto_compat.h b/src/pycrypto_compat.h index c40d4b5..eaaebdb 100644 --- a/src/pycrypto_compat.h +++ b/src/pycrypto_compat.h @@ -23,6 +23,26 @@ */ #ifndef PYCRYPTO_COMPAT_H #define PYCRYPTO_COMPAT_H +#include "Python.h" + +/* + * Python 3.x defines, for conditional compiles + */ + +#if PY_MAJOR_VERSION >= 3 +#define IS_PY3K +#else +#define PyBytes_GET_SIZE PyString_GET_SIZE +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_Check PyString_Check +#define PyBytes_Size PyString_Size +#define PyBytes_AsString PyString_AsString +#define PyBytesObject PyStringObject +#if PY_MINOR_VERSION <= 5 /* PyUnicode_FromString exists from Python 2.6 on up */ +#define PyUnicode_FromString PyString_FromString +#endif +#endif /* * Py_CLEAR for Python < 2.4 diff --git a/src/stream_template.c b/src/stream_template.c index e1db5b1..c3effa4 100644 --- a/src/stream_template.c +++ b/src/stream_template.c @@ -34,13 +34,18 @@ #endif #include "Python.h" +#include "pycrypto_compat.h" #include "modsupport.h" #define _STR(x) #x #define _XSTR(x) _STR(x) #define _PASTE(x,y) x##y #define _PASTE2(x,y) _PASTE(x,y) +#ifdef IS_PY3K +#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME) +#else #define _MODULE_NAME _PASTE2(init,MODULE_NAME) +#endif #define _MODULE_STRING _XSTR(MODULE_NAME) /* @@ -55,9 +60,17 @@ typedef struct stream_state st; } ALGobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; - #define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -134,7 +147,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) return NULL; if (len == 0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } buffer = malloc(len); if (buffer == NULL) @@ -147,7 +160,7 @@ ALG_Encrypt(ALGobject *self, PyObject *args) memcpy(buffer, str, len); stream_encrypt(&(self->st), buffer, len); Py_END_ALLOW_THREADS; - result = PyString_FromStringAndSize((char *)buffer, len); + result = PyBytes_FromStringAndSize((char *)buffer, len); free(buffer); return (result); } @@ -166,7 +179,7 @@ ALG_Decrypt(ALGobject *self, PyObject *args) return NULL; if (len == 0) /* Handle empty string */ { - return PyString_FromStringAndSize(NULL, 0); + return PyBytes_FromStringAndSize(NULL, 0); } buffer = malloc(len); if (buffer == NULL) @@ -179,35 +192,58 @@ ALG_Decrypt(ALGobject *self, PyObject *args) memcpy(buffer, str, len); stream_decrypt(&(self->st), buffer, len); Py_END_ALLOW_THREADS; - result = PyString_FromStringAndSize((char *)buffer, len); + result = PyBytes_FromStringAndSize((char *)buffer, len); free(buffer); return (result); } /* ALGobject methods */ - static PyMethodDef ALGmethods[] = -{ + { +#ifdef IS_PY3K + {"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__}, + {"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__}, +#else {"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__}, {"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__}, - {NULL, NULL} /* sentinel */ -}; +#endif + {NULL, NULL} /* sentinel */ + }; static PyObject * +#ifdef IS_PY3K +ALGgetattro(PyObject *self, PyObject *attr) +#else ALGgetattr(PyObject *self, char *name) +#endif { +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + + if (PyUnicode_CompareWithASCIIString(attr, "block_size") == 0) +#else if (strcmp(name, "block_size") == 0) +#endif { - return PyInt_FromLong(BLOCK_SIZE); + return PyLong_FromLong(BLOCK_SIZE); } +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "key_size") == 0) +#else if (strcmp(name, "key_size") == 0) +#endif { - return PyInt_FromLong(KEY_SIZE); + return PyLong_FromLong(KEY_SIZE); } +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(self, attr); +#else return Py_FindMethod(ALGmethods, self, name); +#endif } - /* List of functions defined in the module */ static struct PyMethodDef modulemethods[] = @@ -218,50 +254,111 @@ static struct PyMethodDef modulemethods[] = }; static PyTypeObject ALGtype = -{ + { +#ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - _MODULE_STRING, /*tp_name*/ - sizeof(ALGobject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - ALGdealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - ALGgetattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ +#endif + _MODULE_STRING, /*tp_name*/ + sizeof(ALGobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) ALGdealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +#ifdef IS_PY3K + 0, /*tp_getattr*/ +#else + ALGgetattr, /*tp_getattr*/ +#endif + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ +#ifdef IS_PY3K + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + ALGgetattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + ALGmethods, /*tp_methods*/ +#endif + }; + +#ifdef IS_PY3K + static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "Crypto.Cipher." _MODULE_STRING, + NULL, + -1, + modulemethods, + NULL, + NULL, + NULL, + NULL }; +#endif /* Initialization function for the module */ +/* Deal with old API in Python 2.1 */ #if PYTHON_API_VERSION < 1011 #define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ if (o!=NULL) \ {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} #endif +#ifdef IS_PY3K +PyMODINIT_FUNC +#else void -_MODULE_NAME (void) -{ - PyObject *m, *d, *x; +#endif + _MODULE_NAME (void) + { + PyObject *m, *d, *x; + +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&ALGtype) < 0) + return NULL; + /* Create the module and add the functions */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else ALGtype.ob_type = &PyType_Type; /* Create the module and add the functions */ m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods); - - /* Add some symbolic constants to the module */ - d = PyModule_GetDict(m); - x = PyString_FromString(_MODULE_STRING ".error"); - PyDict_SetItemString(d, "error", x); - - PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); +#endif + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + x = PyUnicode_FromString(_MODULE_STRING ".error"); + PyDict_SetItemString(d, "error", x); + + PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); PyModule_AddIntConstant(m, "key_size", KEY_SIZE); - /* Check for errors */ - if (PyErr_Occurred()) - Py_FatalError("can't initialize module " _MODULE_STRING); -} + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module " _MODULE_STRING); -/* vim:set ts=8 sw=8 sts=0 noexpandtab: */ +#ifdef IS_PY3K + return m; +#endif + } + +/* vim:set ts=4 sw=4 sts=0 noexpandtab: */ diff --git a/src/strxor.c b/src/strxor.c index 1b91631..7cbbc1c 100644 --- a/src/strxor.c +++ b/src/strxor.c @@ -139,8 +139,8 @@ strxor_function(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "SS", &a, &b)) return NULL; - len_a = PyString_GET_SIZE(a); - len_b = PyString_GET_SIZE(b); + len_a = PyBytes_GET_SIZE(a); + len_b = PyBytes_GET_SIZE(b); assert(len_a >= 0); assert(len_b >= 0); @@ -151,13 +151,13 @@ strxor_function(PyObject *self, PyObject *args) } /* Create return string */ - retval = PyString_FromStringAndSize(NULL, len_a); + retval = PyBytes_FromStringAndSize(NULL, len_a); if (!retval) { return NULL; } /* retval := a ^ b */ - xor_strings(PyString_AS_STRING(retval), PyString_AS_STRING(a), PyString_AS_STRING(b), len_a); + xor_strings(PyBytes_AS_STRING(retval), PyBytes_AS_STRING(a), PyBytes_AS_STRING(b), len_a); return retval; } @@ -186,17 +186,17 @@ strxor_c_function(PyObject *self, PyObject *args) return NULL; } - length = PyString_GET_SIZE(s); + length = PyBytes_GET_SIZE(s); assert(length >= 0); /* Create return string */ - retval = PyString_FromStringAndSize(NULL, length); + retval = PyBytes_FromStringAndSize(NULL, length); if (!retval) { return NULL; } /* retval := a ^ chr(c)*length */ - xor_string_with_char(PyString_AS_STRING(retval), PyString_AS_STRING(s), (char) c, length); + xor_string_with_char(PyBytes_AS_STRING(retval), PyBytes_AS_STRING(s), (char) c, length); return retval; } @@ -212,18 +212,46 @@ static PyMethodDef strxor_methods[] = { {NULL, NULL, 0, NULL} /* end-of-list sentinel value */ }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "strxor", + NULL, + -1, + strxor_methods, + NULL, + NULL, + NULL, + NULL +}; +#endif + PyMODINIT_FUNC +#ifdef IS_PY3K +PyInit_strxor(void) +#else initstrxor(void) +#endif { - PyObject *m; + PyObject *m; /* Initialize the module */ +#ifdef IS_PY3K + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else m = Py_InitModule("strxor", strxor_methods); if (m == NULL) return; - +#endif + /* Perform runtime tests */ runtime_test(); + +#ifdef IS_PY3K + return m; +#endif } /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/winrand.c b/src/winrand.c index 8a2107d..d505e54 100644 --- a/src/winrand.c +++ b/src/winrand.c @@ -31,6 +31,7 @@ /* Author: Mark Moraes */ #include "Python.h" +#include "pycrypto_compat.h" #ifdef MS_WIN32 @@ -48,15 +49,24 @@ #endif /* To-Do: store provider name and type for print/repr? */ + typedef struct { PyObject_HEAD HCRYPTPROV hcp; } WRobject; +/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. + * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize + */ +#ifdef IS_PY3K +static PyTypeObject WRtype; +#define is_WRobject(v) (Py_TYPE(v) == &WRtype) +#else staticforward PyTypeObject WRtype; - #define is_WRobject(v) ((v)->ob_type == &WRtype) +#define PyLong_FromLong PyInt_FromLong /* for Python 2.x */ +#endif static void WRdealloc(PyObject *ptr) @@ -156,6 +166,7 @@ WR_get_bytes(WRobject *self, PyObject *args) * from an RC4 stream, they should be relatively * cheap. */ + if (! CryptGenRandom(self->hcp, (DWORD) nbytes, (BYTE *) buf)) { PyErr_Format(PyExc_SystemError, "CryptGenRandom failed, error 0x%x", @@ -163,7 +174,8 @@ WR_get_bytes(WRobject *self, PyObject *args) PyMem_Free(buf); return NULL; } - res = PyString_FromStringAndSize(buf, n); + + res = PyBytes_FromStringAndSize(buf, n); PyMem_Free(buf); return res; } @@ -185,9 +197,12 @@ static PyMethodDef WR_mod_methods[] = { {NULL, NULL} /* Sentinel */ }; - static PyObject * +#ifdef IS_PY3K +WRgetattro(PyObject *s, PyObject *attr) +#else WRgetattr(PyObject *s, char *name) +#endif { WRobject *self = (WRobject*)s; if (! is_WRobject(self)) { @@ -195,30 +210,99 @@ WRgetattr(PyObject *s, char *name) "WinRandom trying to getattr with non-WinRandom object"); return NULL; } +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; + if (PyUnicode_CompareWithASCIIString(attr, "hcp") == 0) +#else if (strcmp(name, "hcp") == 0) - return PyInt_FromLong((long) self->hcp); +#endif + return PyLong_FromLong((long) self->hcp); +#ifdef IS_PY3K + generic: + return PyObject_GenericGetAttr(s, attr); +#else return Py_FindMethod(WRmethods, (PyObject *) self, name); +#endif } static PyTypeObject WRtype = -{ + { + #ifdef IS_PY3K + PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "winrandom.WinRandom", /*tp_name*/ - sizeof(WRobject), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - WRdealloc, /*tp_dealloc*/ - 0, /*tp_print*/ +#endif + "winrandom.WinRandom", /*tp_name*/ + sizeof(WRobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor) WRdealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +#ifndef IS_PY3K WRgetattr, /*tp_getattr*/ +#else + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number */ + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + WRgetattro, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + WRmethods, /*tp_methods*/ +#endif }; +#ifdef IS_PY3K +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "winrandom", + NULL, + -1, + WR_mod_methods, + NULL, + NULL, + NULL, + NULL + }; +#endif + +#ifdef IS_PY3K +PyMODINIT_FUNC +PyInit_winrandom() +#else void initwinrandom() +#endif { PyObject *m; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&WRtype) < 0) + return NULL; + /* Initialize the module */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; +#else WRtype.ob_type = &PyType_Type; m = Py_InitModule("winrandom", WR_mod_methods); +#endif /* define Windows CSP Provider Types */ #ifdef PROV_RSA_FULL @@ -296,8 +380,11 @@ initwinrandom() if (PyErr_Occurred()) Py_FatalError("can't initialize module winrandom"); -} +#ifdef IS_PY3K + return m; +#endif +} /* CryptGenRandom usage is described in |
