shithub: riscv

Download patch

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