python: remove openssl support, use ape/libsec for cryptographics hash functions
This commit is contained in:
parent
8f4db30e78
commit
4e04698ab6
6 changed files with 400 additions and 96 deletions
|
@ -51,88 +51,24 @@ More condensed:
|
|||
|
||||
"""
|
||||
|
||||
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"
|
||||
|
|
|
@ -765,7 +765,7 @@ typedef struct fd_set {
|
|||
#endif
|
||||
|
||||
#ifndef Py_ULL
|
||||
#define Py_ULL(x) Py_LL(x##U)
|
||||
#define Py_ULL(x) x##ULL
|
||||
#endif
|
||||
|
||||
#endif /* Py_PYPORT_H */
|
||||
|
|
|
@ -4,15 +4,17 @@ _csv
|
|||
#_curses_panel
|
||||
_elementtree
|
||||
_functools
|
||||
_hashlib
|
||||
#_hashlib
|
||||
_locale
|
||||
_lsprof
|
||||
_md5
|
||||
#_md5
|
||||
_random
|
||||
_sha
|
||||
_sha256
|
||||
_sechash
|
||||
#_sha
|
||||
#_sha256
|
||||
#_sha512
|
||||
_sre
|
||||
_ssl
|
||||
#_ssl
|
||||
_struct
|
||||
_symtable
|
||||
_testcapi
|
||||
|
|
|
@ -12,14 +12,14 @@ OFILES=\
|
|||
# _cursesmodule.$O\
|
||||
_elementtree.$O\
|
||||
_functoolsmodule.$O\
|
||||
_hashopenssl.$O\
|
||||
# _hashopenssl.$O\
|
||||
_heapqmodule.$O\
|
||||
# _hotshot.$O\
|
||||
_localemodule.$O\
|
||||
_lsprof.$O\
|
||||
_randommodule.$O\
|
||||
_sre.$O\
|
||||
_ssl.$O\
|
||||
# _ssl.$O\
|
||||
_struct.$O\
|
||||
_testcapimodule.$O\
|
||||
# _tkinter.$O\
|
||||
|
@ -60,8 +60,8 @@ OFILES=\
|
|||
# linuxaudiodev.$O\
|
||||
main.$O\
|
||||
mathmodule.$O\
|
||||
md5.$O\
|
||||
md5module.$O\
|
||||
# md5.$O\
|
||||
# md5module.$O\
|
||||
# mmapmodule.$O\
|
||||
# nismodule.$O\
|
||||
operator.$O\
|
||||
|
@ -77,9 +77,10 @@ OFILES=\
|
|||
rotatingtree.$O\
|
||||
selectmodule.$O\
|
||||
# sgimodule.$O\
|
||||
sha256module.$O\
|
||||
# sha256module.$O\
|
||||
# sha512module.$O\
|
||||
shamodule.$O\
|
||||
# shamodule.$O\
|
||||
sechashmodule.$O\
|
||||
signalmodule.$O\
|
||||
socketmodule.$O\
|
||||
# spwdmodule.$O\
|
||||
|
|
367
sys/src/cmd/python/Modules/sechashmodule.c
Normal file
367
sys/src/cmd/python/Modules/sechashmodule.c
Normal file
|
@ -0,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);
|
||||
}
|
|
@ -14,8 +14,6 @@ OFILES=\
|
|||
|
||||
LIB= \
|
||||
/$objtype/lib/ape/libpython.a\
|
||||
/$objtype/lib/ape/libssl.a\
|
||||
/$objtype/lib/ape/libcrypto.a
|
||||
|
||||
LIBDIRS=Modules Objects Parser Python
|
||||
|
||||
|
|
Loading…
Reference in a new issue