ref: 4e04698ab6fddc1efe41b97be54fcf120810bf5d
parent: 8f4db30e7865232f9179f5850fe0e1ca759302cc
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Apr 11 16:31:14 EDT 2016
python: remove openssl support, use ape/libsec for cryptographics hash functions
--- a/sys/lib/python/hashlib.py
+++ b/sys/lib/python/hashlib.py
@@ -51,88 +51,24 @@
"""
+import _sechash
-def __get_builtin_constructor(name):
- if name in ('SHA1', 'sha1'):
- import _sha
- return _sha.new
- elif name in ('MD5', 'md5'):
- import _md5
- return _md5.new
- elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'):
- import _sha256
- bs = name[3:]
- if bs == '256':
- return _sha256.sha256
- elif bs == '224':
- return _sha256.sha224
-# elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'):
-# import _sha512
-# bs = name[3:]
-# if bs == '512':
-# return _sha512.sha512
-# elif bs == '384':
-# return _sha512.sha384
+md5 = _sechash.md5
+sha1 = _sechash.sha1
+sha224 = _sechash.sha224
+sha256 = _sechash.sha256
+sha384 = _sechash.sha384
+sha512 = _sechash.sha512
- raise ValueError, "unsupported hash type"
+algs = dict()
+for a in [md5, sha1, sha224, sha256, sha384, sha512]:
+ algs[a().name.lower()] = a
-
-def __py_new(name, string=''):
- """new(name, string='') - Return a new hashing object using the named algorithm;
- optionally initialized with a string.
- """
- return __get_builtin_constructor(name)(string)
-
-
-def __hash_new(name, string=''):
- """new(name, string='') - Return a new hashing object using the named algorithm;
- optionally initialized with a string.
- """
- try:
- return _hashlib.new(name, string)
- except ValueError:
- # If the _hashlib module (OpenSSL) doesn't support the named
- # hash, try using our builtin implementations.
- # This allows for SHA224/256 and SHA384/512 support even though
- # the OpenSSL library prior to 0.9.8 doesn't provide them.
- return __get_builtin_constructor(name)(string)
-
-
-try:
- import _hashlib
- # use the wrapper of the C implementation
- new = __hash_new
-
- for opensslFuncName in filter(lambda n: n.startswith('openssl_'), dir(_hashlib)):
- funcName = opensslFuncName[len('openssl_'):]
- try:
- # try them all, some may not work due to the OpenSSL
- # version not supporting that algorithm.
- f = getattr(_hashlib, opensslFuncName)
- f()
- # Use the C function directly (very fast)
- exec funcName + ' = f'
- except ValueError:
- try:
- # Use the builtin implementation directly (fast)
- exec funcName + ' = __get_builtin_constructor(funcName)'
- except ValueError:
- # this one has no builtin implementation, don't define it
- pass
- # clean up our locals
- del f
- del opensslFuncName
- del funcName
-
-except ImportError:
- # We don't have the _hashlib OpenSSL module?
- # use the built in legacy interfaces via a wrapper function
- new = __py_new
-
- # lookup the C function to use directly for the named constructors
- md5 = __get_builtin_constructor('md5')
- sha1 = __get_builtin_constructor('sha1')
- sha224 = __get_builtin_constructor('sha224')
- sha256 = __get_builtin_constructor('sha256')
- sha384 = __get_builtin_constructor('sha384')
- sha512 = __get_builtin_constructor('sha512')
+def new(name, string=''):
+ """new(name, string='') - Return a new hashing object using the named algorithm;
+ optionally initialized with a string.
+ """
+ a = algs[name.lower()]
+ if a != None:
+ return a(string)
+ raise ValueError, "unsupported hash type"
--- a/sys/src/cmd/python/Include/pyport.h
+++ b/sys/src/cmd/python/Include/pyport.h
@@ -765,7 +765,7 @@
#endif
#ifndef Py_ULL
-#define Py_ULL(x) Py_LL(x##U)
+#define Py_ULL(x) x##ULL
#endif
#endif /* Py_PYPORT_H */
--- a/sys/src/cmd/python/Modules/config
+++ b/sys/src/cmd/python/Modules/config
@@ -4,15 +4,17 @@
#_curses_panel
_elementtree
_functools
-_hashlib
+#_hashlib
_locale
_lsprof
-_md5
+#_md5
_random
-_sha
-_sha256
+_sechash
+#_sha
+#_sha256
+#_sha512
_sre
-_ssl
+#_ssl
_struct
_symtable
_testcapi
--- a/sys/src/cmd/python/Modules/mkfile
+++ b/sys/src/cmd/python/Modules/mkfile
@@ -12,7 +12,7 @@
# _cursesmodule.$O\
_elementtree.$O\
_functoolsmodule.$O\
- _hashopenssl.$O\
+# _hashopenssl.$O\
_heapqmodule.$O\
# _hotshot.$O\
_localemodule.$O\
@@ -19,7 +19,7 @@
_lsprof.$O\
_randommodule.$O\
_sre.$O\
- _ssl.$O\
+# _ssl.$O\
_struct.$O\
_testcapimodule.$O\
# _tkinter.$O\
@@ -60,8 +60,8 @@
# linuxaudiodev.$O\
main.$O\
mathmodule.$O\
- md5.$O\
- md5module.$O\
+# md5.$O\
+# md5module.$O\
# mmapmodule.$O\
# nismodule.$O\
operator.$O\
@@ -77,9 +77,10 @@
rotatingtree.$O\
selectmodule.$O\
# sgimodule.$O\
- sha256module.$O\
+# sha256module.$O\
# sha512module.$O\
- shamodule.$O\
+# shamodule.$O\
+ sechashmodule.$O\
signalmodule.$O\
socketmodule.$O\
# spwdmodule.$O\
--- /dev/null
+++ b/sys/src/cmd/python/Modules/sechashmodule.c
@@ -1,0 +1,367 @@
+/* Plan 9 sechash(2) module */
+
+#include "Python.h"
+#include "structmember.h"
+
+#define _PLAN9_SOURCE
+#include <libsec.h>
+
+typedef struct {
+ PyObject_HEAD
+
+ char *t;
+ int n, b;
+ DigestState *(*f)(uchar *, ulong, uchar *, DigestState *);
+ DigestState s;
+} SHobject;
+
+static PyTypeObject MD5type;
+static PyTypeObject SHA1type;
+static PyTypeObject SHA224type;
+static PyTypeObject SHA256type;
+static PyTypeObject SHA384type;
+static PyTypeObject SHA512type;
+
+static void
+sh_copy(SHobject *src, SHobject *dest)
+{
+ dest->t = src->t;
+ dest->n = src->n;
+ dest->b = src->b;
+ dest->f = src->f;
+ dest->s = src->s;
+}
+
+static void
+sh_update(SHobject *s, uchar *buffer, int count)
+{
+ (*s->f)(buffer, count, NULL, &s->s);
+}
+
+static void
+sh_final(SHobject *s, uchar digest[])
+{
+ (*s->f)(NULL, 0, (uchar*)digest, &s->s);
+}
+
+static void
+sh_dealloc(PyObject *ptr)
+{
+ PyObject_Del(ptr);
+}
+
+PyDoc_STRVAR(SH_copy__doc__, "Return a copy of the hash object.");
+
+static PyObject *
+SH_copy(SHobject *self, PyObject *unused)
+{
+ SHobject *newobj;
+
+ newobj = PyObject_New(SHobject, ((PyObject*)self)->ob_type);
+ if(newobj != NULL)
+ sh_copy(self, newobj);
+ return (PyObject *)newobj;
+}
+
+PyDoc_STRVAR(SH_digest__doc__,
+"Return the digest value as a string of binary data.");
+
+static PyObject *
+SH_digest(SHobject *self, PyObject *unused)
+{
+ uchar digest[64];
+ SHobject temp;
+
+ sh_copy(self, &temp);
+ sh_final(&temp, digest);
+ return PyString_FromStringAndSize((const char *)digest, self->n);
+}
+
+PyDoc_STRVAR(SH_hexdigest__doc__,
+"Return the digest value as a string of hexadecimal digits.");
+
+static PyObject *
+SH_hexdigest(SHobject *self, PyObject *unused)
+{
+ uchar digest[64];
+ SHobject temp;
+ PyObject *retval;
+ char *hex_digest;
+ int i, j;
+
+ /* Get the raw (binary) digest value */
+ sh_copy(self, &temp);
+ sh_final(&temp, digest);
+
+ /* Create a new string */
+ retval = PyString_FromStringAndSize(NULL, self->n * 2);
+ if (!retval)
+ return NULL;
+ hex_digest = PyString_AsString(retval);
+ if (!hex_digest) {
+ Py_DECREF(retval);
+ return NULL;
+ }
+
+ /* Make hex version of the digest */
+ for (i=j=0; i<self->n; i++) {
+ char c;
+ c = (digest[i] >> 4) & 0xf;
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ c = (digest[i] & 0xf);
+ c = (c>9) ? c+'a'-10 : c + '0';
+ hex_digest[j++] = c;
+ }
+ return retval;
+}
+
+PyDoc_STRVAR(SH_update__doc__,
+"Update this hash object's state with the provided string.");
+
+static PyObject *
+SH_update(SHobject *self, PyObject *args)
+{
+ uchar *cp;
+ int len;
+
+ if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
+ return NULL;
+ sh_update(self, cp, len);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef SH_methods[] = {
+ {"copy", (PyCFunction)SH_copy, METH_NOARGS, SH_copy__doc__},
+ {"digest", (PyCFunction)SH_digest, METH_NOARGS, SH_digest__doc__},
+ {"hexdigest", (PyCFunction)SH_hexdigest, METH_NOARGS, SH_hexdigest__doc__},
+ {"update", (PyCFunction)SH_update, METH_VARARGS, SH_update__doc__},
+ {NULL, NULL}
+};
+
+static PyObject *
+SH_get_block_size(PyObject *self, void *closure)
+{
+ return PyInt_FromLong(((SHobject*)self)->b);
+}
+
+static PyObject *
+SH_get_name(PyObject *self, void *closure)
+{
+ char *s = ((SHobject*)self)->t;
+ return PyString_FromStringAndSize(s, strlen(s));
+}
+
+static PyGetSetDef SH_getseters[] = {
+ {"block_size", (getter)SH_get_block_size, NULL, NULL, NULL},
+ {"name", (getter)SH_get_name, NULL, NULL, NULL},
+ {NULL}
+};
+
+static PyMemberDef SH_members[] = {
+ {"digest_size", T_INT, offsetof(SHobject, n), READONLY, NULL},
+ {"digestsize", T_INT, offsetof(SHobject, n), READONLY, NULL},
+ {NULL}
+};
+
+static PyTypeObject MD5type = {PyObject_HEAD_INIT(NULL)0,"_sechash.md5",sizeof(SHobject),0,sh_dealloc,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,Py_TPFLAGS_DEFAULT,0,0,0,0,0,0,0,SH_methods,SH_members,SH_getseters};
+static PyTypeObject SHA1type = {PyObject_HEAD_INIT(NULL)0,"_sechash.sha1",sizeof(SHobject),0,sh_dealloc,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,Py_TPFLAGS_DEFAULT,0,0,0,0,0,0,0,SH_methods,SH_members,SH_getseters};
+static PyTypeObject SHA224type = {PyObject_HEAD_INIT(NULL)0,"_sechash.sha224",sizeof(SHobject),0,sh_dealloc,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,Py_TPFLAGS_DEFAULT,0,0,0,0,0,0,0,SH_methods,SH_members,SH_getseters};
+static PyTypeObject SHA256type = {PyObject_HEAD_INIT(NULL)0,"_sechash.sha256",sizeof(SHobject),0,sh_dealloc,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,Py_TPFLAGS_DEFAULT,0,0,0,0,0,0,0,SH_methods,SH_members,SH_getseters};
+static PyTypeObject SHA384type = {PyObject_HEAD_INIT(NULL)0,"_sechash.sha384",sizeof(SHobject),0,sh_dealloc,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,Py_TPFLAGS_DEFAULT,0,0,0,0,0,0,0,SH_methods,SH_members,SH_getseters};
+static PyTypeObject SHA512type = {PyObject_HEAD_INIT(NULL)0,"_sechash.sha512",sizeof(SHobject),0,sh_dealloc,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,Py_TPFLAGS_DEFAULT,0,0,0,0,0,0,0,SH_methods,SH_members,SH_getseters};
+
+
+PyDoc_STRVAR(SHA512_new__doc__,
+"Return a new SHA-512 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHobject *new;
+ uchar *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist, &cp, &len))
+ return NULL;
+ if ((new = (SHobject *)PyObject_New(SHobject, &SHA512type)) == NULL)
+ return NULL;
+ memset(&new->s, 0, sizeof(new->s));
+ new->t = "SHA512";
+ new->b = 128;
+ new->n = SHA2_512dlen;
+ new->f = sha2_512;
+ if (cp)
+ sh_update(new, cp, len);
+ return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA384_new__doc__,
+"Return a new SHA-384 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHobject *new;
+ uchar *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist, &cp, &len))
+ return NULL;
+ if ((new = (SHobject *)PyObject_New(SHobject, &SHA384type)) == NULL)
+ return NULL;
+ memset(&new->s, 0, sizeof(new->s));
+ new->t = "SHA384";
+ new->b = 128;
+ new->n = SHA2_384dlen;
+ new->f = sha2_384;
+ if (cp)
+ sh_update(new, cp, len);
+ return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA256_new__doc__,
+"Return a new SHA-256 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHobject *new;
+ uchar *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist, &cp, &len))
+ return NULL;
+ if ((new = (SHobject *)PyObject_New(SHobject, &SHA256type)) == NULL)
+ return NULL;
+ memset(&new->s, 0, sizeof(new->s));
+ new->t = "SHA256";
+ new->b = 64;
+ new->n = SHA2_256dlen;
+ new->f = sha2_256;
+ if (cp)
+ sh_update(new, cp, len);
+ return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA224_new__doc__,
+"Return a new SHA-224 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHobject *new;
+ uchar *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist, &cp, &len))
+ return NULL;
+ if ((new = (SHobject *)PyObject_New(SHobject, &SHA224type)) == NULL)
+ return NULL;
+ memset(&new->s, 0, sizeof(new->s));
+ new->t = "SHA224";
+ new->b = 64;
+ new->n = SHA2_224dlen;
+ new->f = sha2_224;
+ if (cp)
+ sh_update(new, cp, len);
+ return (PyObject *)new;
+}
+
+PyDoc_STRVAR(SHA1_new__doc__,
+"Return a new SHA1 hash object; optionally initialized with a string.");
+
+static PyObject *
+SHA1_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHobject *new;
+ uchar *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist, &cp, &len))
+ return NULL;
+ if ((new = (SHobject *)PyObject_New(SHobject, &SHA1type)) == NULL)
+ return NULL;
+ memset(&new->s, 0, sizeof(new->s));
+ new->t = "SHA1";
+ new->b = 64;
+ new->n = SHA1dlen;
+ new->f = sha1;
+ if (cp)
+ sh_update(new, cp, len);
+ return (PyObject *)new;
+}
+
+PyDoc_STRVAR(MD5_new__doc__,
+"Return a new MD5 hash object; optionally initialized with a string.");
+
+static PyObject *
+MD5_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+ static char *kwlist[] = {"string", NULL};
+ SHobject *new;
+ uchar *cp = NULL;
+ int len;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist, &cp, &len))
+ return NULL;
+ if ((new = (SHobject *)PyObject_New(SHobject, &MD5type)) == NULL)
+ return NULL;
+ memset(&new->s, 0, sizeof(new->s));
+ new->t = "MD5";
+ new->b = 16;
+ new->n = MD5dlen;
+ new->f = md5;
+ if (cp)
+ sh_update(new, cp, len);
+ return (PyObject *)new;
+}
+
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef SH_functions[] = {
+ {"sha512", (PyCFunction)SHA512_new, METH_VARARGS|METH_KEYWORDS, SHA512_new__doc__},
+ {"sha384", (PyCFunction)SHA384_new, METH_VARARGS|METH_KEYWORDS, SHA384_new__doc__},
+ {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__},
+ {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__},
+ {"sha1", (PyCFunction)SHA1_new, METH_VARARGS|METH_KEYWORDS, SHA1_new__doc__},
+ {"md5", (PyCFunction)MD5_new, METH_VARARGS|METH_KEYWORDS, MD5_new__doc__},
+ {NULL, NULL} /* Sentinel */
+};
+
+PyMODINIT_FUNC
+init_sechash(void)
+{
+ MD5type.ob_type = &PyType_Type;
+ if (PyType_Ready(&MD5type) < 0)
+ return;
+ SHA1type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA1type) < 0)
+ return;
+ SHA224type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA224type) < 0)
+ return;
+ SHA256type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA256type) < 0)
+ return;
+ SHA384type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA384type) < 0)
+ return;
+ SHA512type.ob_type = &PyType_Type;
+ if (PyType_Ready(&SHA512type) < 0)
+ return;
+ Py_InitModule("_sechash", SH_functions);
+}
--- a/sys/src/cmd/python/mkfile
+++ b/sys/src/cmd/python/mkfile
@@ -14,8 +14,6 @@
LIB= \
/$objtype/lib/ape/libpython.a\
- /$objtype/lib/ape/libssl.a\
- /$objtype/lib/ape/libcrypto.a
LIBDIRS=Modules Objects Parser Python