From: Mark Wooding Date: Wed, 27 Nov 2019 15:11:08 +0000 (+0000) Subject: Merge branch '1.2.x' into 1.3.x X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/commitdiff_plain/7f38dc76ee0809207e67be7b2a2ddc600aba54d5 Merge branch '1.2.x' into 1.3.x * 1.2.x: (89 commits) t/: Add a test suite. ec.c: Don't lose error status when constructing points from a sequence. ec.c: Free partially constructed points coordinatewise. *.c: Be more careful about `PySequence_Size'. key.c: Reformat the rest of the `KeyError' constructor. key.c: Parse `KeyError' constructor arguments by hand. catacomb-python.h: Add a macro for raising `OverflowError'. key.c: Collect `KeyError' argument count as a separate step. key.c: Use tuple functions on `KeyError' argument tuple. key.c: Rename sad-path label to `end'. key.c: Delete duplicate setting of `errstring'. util.c (mkexc): Populate dictionary before constructing exception class. key.c: Only set the error code. catacomb.c, util.c: Publish negative constants correctly. field.c: Delete the completely unused `getfe' function. key.c (convfilter): Fix sense of error tests. buffer.c, ec.c: Fix required size for EC `buffer' encoding. algorithms.c: Fix `max' property name in docstrings. catacomb/__init__.py (_HashBase): Check that integers are within bounds. debian/rules: Build using the provided Makefile. ... --- 7f38dc76ee0809207e67be7b2a2ddc600aba54d5 diff --cc MANIFEST.in index 36bf4c2,c09417b..33ce54a --- a/MANIFEST.in +++ b/MANIFEST.in @@@ -8,16 -8,11 +8,17 @@@ include MANIFEST.in setup.py Makefil ## C extension code. include *.c *.h + include t/*.py t/keyring include algorithms.py exclude algorithms.h + +## Scripts. +include pock include pwsafe +## Manual pages. +include *.[13] + ## Python wrapping. recursive-include catacomb *.py diff --cc catacomb-python.h index df29099,ad27461..6c1ae21 --- a/catacomb-python.h +++ b/catacomb-python.h @@@ -134,8 -133,8 +134,9 @@@ goto end; \ } while (0) #define VALERR(str) EXCERR(PyExc_ValueError, str) + #define OVFERR(str) EXCERR(PyExc_OverflowError, str) #define TYERR(str) EXCERR(PyExc_TypeError, str) +#define IXERR(str) EXCERR(PyExc_IndexError, str) #define ZDIVERR(str) EXCERR(PyExc_ZeroDivisionError, str) #define SYSERR(str) EXCERR(PyExc_SystemError, str) #define NIERR(str) EXCERR(PyExc_NotImplementedError, str) @@@ -233,9 -234,8 +236,10 @@@ MODULES(DO return (d); \ } +#define KWLIST (/*unconst*/ char **)kwlist + - struct nameval { const char *name; unsigned long value; }; + struct nameval { const char *name; unsigned f; unsigned long value; }; + #define CF_SIGNED 1u extern void setconstants(PyObject *, const struct nameval *); extern PyObject *mexp_common(PyObject *, PyObject *, size_t, diff --cc debian/changelog index 866bc90,ca06b5c..0398864 --- a/debian/changelog +++ b/debian/changelog @@@ -1,26 -1,9 +1,32 @@@ +catacomb-python (1.3.0.1) experimental; urgency=medium + + * Fix required Catacomb version in `setup.py' script. Only affects the + source package. + + -- Mark Wooding Sun, 22 Sep 2019 01:21:28 +0100 + +catacomb-python (1.3.0) experimental; urgency=medium + + * catacomb: Bindings for new blockcipher-based MACs, and AEAD schemes. + * catacomb: Invalidate `grand' objects passed into Python through prime- + generation events. + * catacomb: Improve class docstrings. (They're still extremely terse.) + * catacomb: Add missing `copy' methods on hash and Keccak objects. + * catacomb: Add `WriteBuffer.contents' as a more convenient way to + extract the contents than coercing to `str' or `ByteString'. + * catacomb: Set `RTLD_DEEPBIND' while loading the native module to work + around #868366. + * pock: New program for generating efficiently verifiable prime numbers, + and for verifying their certificates. + + -- Mark Wooding Sat, 21 Sep 2019 23:00:25 +0100 + + catacomb-python (1.2.1.1) experimental; urgency=medium + + * Fixing to build against Debian `stretch'. + + -- Mark Wooding Mon, 24 Dec 2018 15:21:08 +0000 + catacomb-python (1.2.1) experimental; urgency=low * Fix use-after-free bug in ECPt hashing causing hash instability. diff --cc debian/control index 24197f4,61f54a8..1bde721 --- a/debian/control +++ b/debian/control @@@ -3,9 -3,9 +3,9 @@@ Section: pytho Priority: extra XS-Python-Version: >= 2.6, << 2.8 Maintainer: Mark Wooding - Build-Depends: debhelper (>= 9), pkg-config, + Build-Depends: debhelper (>= 9), dh-python, pkg-config, python (>= 2.6.6-3~), python-all-dev, - mlib-dev (>= 2.2.2.1), catacomb-dev (>= 2.4.0) + mlib-dev (>= 2.2.2.1), catacomb-dev (>= 2.5.0) Standards-Version: 3.8.0 Package: python-catacomb diff --cc ec.c index f7d6181,361bbf5..184dc9e --- a/ec.c +++ b/ec.c @@@ -297,11 -290,12 +290,12 @@@ static PyObject *epmeth_ec2osp(PyObjec char *p; ec_curve *c = ECPT_C(me); ec pp = EC_INIT; - int f = EC_EXPLY; + unsigned f = EC_EXPLY; int len; - char *kwlist[] = { "flags", 0 }; + static const char *const kwlist[] = { "flags", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|i:ectosp", KWLIST, &f)) - if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:ec2osp", kwlist, ++ if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:ec2osp", KWLIST, + convuint, &f)) return (0); len = c->f->noctets * 2 + 1; rc = bytestring_pywrap(0, len); @@@ -863,12 -860,12 +862,12 @@@ static PyObject *meth__ECPtCurve_os2ecp buf b; PyObject *rc = 0; ec_curve *cc; - int f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY; + unsigned f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY; ec pp = EC_INIT; - static const char *const kwlist[] = { "buf", "flags", 0 }; - char *kwlist[] = { "class", "buf", "flags", 0 }; ++ static const char *const kwlist[] = { "class", "buf", "flags", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|f:os2ecp", KWLIST, - &me, &p, &len, &f)) - if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|O&:os2ecp", kwlist, ++ if (!PyArg_ParseTupleAndKeywords(arg, kw, "Os#|O&:os2ecp", KWLIST, + &me, &p, &len, convuint, &f)) return (0); buf_init(&b, p, len); cc = ECCURVE_C(me); diff --cc group.c index b5a1815,e00e3fb..3d29070 --- a/group.c +++ b/group.c @@@ -92,12 -92,14 +92,14 @@@ static PyObject *meth__DHInfo_generate( unsigned ql = 0, pl; unsigned steps = 0; grand *r = &rand_global; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; - char *kwlist[] = + static const char *const kwlist[] = { "class", "pbits", "qbits", "event", "rng", "nsteps", 0 }; PyObject *rc = 0; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", KWLIST, &me, convuint, &pl, convuint, &ql, convpgev, &evt, convgrand, &r, convuint, &steps)) @@@ -117,19 -119,19 +119,21 @@@ static PyObject *meth__DHInfo_genlimlee unsigned ql, pl; unsigned steps = 0; grand *r = &rand_global; - pgev oe = { 0 }, ie = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev oe = { { 0 } }, ie = { { 0 } }; int subgroupp = 1; unsigned f = 0; - char *kwlist[] = { "class", "pbits", "qbits", "event", "ievent", - "rng", "nsteps", "subgroupp", 0 }; + static const char *const kwlist[] = { + "class", "pbits", "qbits", "event", "ievent", + "rng", "nsteps", "subgroupp", 0 + }; size_t i, nf; mp **v = 0; PyObject *rc = 0, *vec = 0; + oe.exc = ie.exc = &exc; if (!PyArg_ParseTupleAndKeywords(arg, kw, - "OO&O&|O&O&O&O&O&:genlimlee", kwlist, + "OO&O&|O&O&O&O&O&:genlimlee", KWLIST, &me, convuint, &pl, convuint, &ql, convpgev, &oe, convpgev, &ie, convgrand, &r, convuint, &steps, @@@ -156,13 -158,15 +160,15 @@@ static PyObject *meth__DHInfo_genkcdsa( unsigned ql, pl; unsigned steps = 0; grand *r = &rand_global; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; - char *kwlist[] = { "class", "pbits", "qbits", - "event", "rng", "nsteps", 0 }; + static const char *const kwlist[] = + { "class", "pbits", "qbits", "event", "rng", "nsteps", 0 }; mp *v = MP_NEW; PyObject *rc = 0; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&|O&O&O&:genkcdsa", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&|O&O&O&:genkcdsa", KWLIST, &me, convuint, &pl, convuint, &ql, convpgev, &evt, convgrand, &r, convuint, &steps)) @@@ -187,12 -191,14 +193,14 @@@ static PyObject *meth__DHInfo_gendsa(Py dsa_seed ds; char *k; Py_ssize_t ksz; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; - char *kwlist[] = + static const char *const kwlist[] = { "class", "pbits", "qbits", "seed", "event", "nsteps", 0 }; PyObject *rc = 0; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&s#|O&O&:gendsa", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&O&s#|O&O&:gendsa", KWLIST, &me, convuint, &pl, convuint, &ql, &k, &ksz, convpgev, &evt, convuint, &steps)) diff --cc mp.c index e0f72d4,ab15d3f..1448bc2 --- a/mp.c +++ b/mp.c @@@ -1712,10 -1720,11 +1720,11 @@@ static void mpcrt_pydealloc(PyObject *m static PyObject *mpcrt_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { mpcrt_mod *v = 0; - int n, i = 0; + Py_ssize_t n, i = 0, j; - char *kwlist[] = { "mv", 0 }; + static const char *const kwlist[] = { "mv", 0 }; PyObject *q = 0, *x; - mp *xx; + mp *xx = MP_NEW, *y = MP_NEW, *g = MP_NEW; + mpmul mm; mpcrt_pyobj *c = 0; if (PyTuple_Size(arg) > 1) diff --cc pgen.c index 18b0c26,9460310..9f9e1a2 --- a/pgen.c +++ b/pgen.c @@@ -548,15 -549,14 +549,14 @@@ static int pgev_python(int rq, pgen_eve PyObject *rc = 0; int st = PGEN_ABORT; long l; - char *meth[] = { - "pg_abort", "pg_done", "pg_begin", "pg_try", "pg_fail", "pg_pass" - }; + static const char *const meth[] = + { "pg_abort", "pg_done", "pg_begin", "pg_try", "pg_fail", "pg_pass" }; - Py_INCREF(py); rq++; if (rq > N(meth)) SYSERR("event code out of range"); pyev = pgevent_pywrap(ev); - if ((rc = PyObject_CallMethod(py, (/*unconst*/ char *)meth[rq], - if ((rc = PyObject_CallMethod(pg->obj, meth[rq], "(O)", pyev)) == 0) ++ if ((rc = PyObject_CallMethod(pg->obj, (/*unconst*/ char *)meth[rq], + "(O)", pyev)) == 0) goto end; if (rc == Py_None) st = PGEN_TRY; @@@ -926,14 -925,16 +925,16 @@@ static PyObject *meth_pgen(PyObject *me char *p = "p"; pgen_filterctx fc = { 2 }; rabin tc; - pgev step = { 0 }, test = { 0 }, evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev step = { { 0 } }, test = { { 0 } }, evt = { { 0 } }; unsigned nsteps = 0, ntests = 0; - char *kwlist[] = { "start", "name", "stepper", "tester", "event", - "nsteps", "ntests", 0 }; + static const char *const kwlist[] = + { "start", "name", "stepper", "tester", "event", "nsteps", "ntests", 0 }; - step.proc = pgen_filter; step.ctx = &fc; - test.proc = pgen_test; test.ctx = &tc; + step.exc = &exc; step.ev.proc = pgen_filter; step.ev.ctx = &fc; + test.exc = &exc; test.ev.proc = pgen_test; test.ev.ctx = &tc; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&O&O&:pgen", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&O&O&:pgen", KWLIST, convmp, &x, &p, convpgev, &step, convpgev, &test, convpgev, &evt, convuint, &nsteps, convuint, &ntests)) @@@ -961,12 -960,13 +960,14 @@@ static PyObject *meth_strongprime_setup unsigned nbits; char *name = "p"; unsigned n = 0; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; PyObject *rc = 0; - char *kwlist[] = { "nbits", "name", "event", "rng", "nsteps", 0 }; + static const char *const kwlist[] = + { "nbits", "name", "event", "rng", "nsteps", 0 }; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", KWLIST, convuint, &nbits, &name, convpgev, &evt, convgrand, &r, convuint, &n)) @@@ -989,12 -989,13 +990,14 @@@ static PyObject *meth_strongprime(PyObj unsigned nbits; char *name = "p"; unsigned n = 0; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; PyObject *rc = 0; - char *kwlist[] = { "nbits", "name", "event", "rng", "nsteps", 0 }; + static const char *const kwlist[] = + { "nbits", "name", "event", "rng", "nsteps", 0 }; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|sO&O&O&", KWLIST, convuint, &nbits, &name, convpgev, &evt, convgrand, &r, convuint, &n)) @@@ -1019,11 -1021,12 +1023,12 @@@ static PyObject *meth_limlee(PyObject * unsigned on = 0; size_t i, nf = 0; PyObject *rc = 0, *vec; - char *kwlist[] = { "pbits", "qbits", "name", "event", "ievent", - "rng", "nsteps", 0 }; + static const char *const kwlist[] = + { "pbits", "qbits", "name", "event", "ievent", "rng", "nsteps", 0 }; mp *x = 0, **v = 0; + ie.exc = oe.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|sO&O&O&O&:limlee", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&O&|sO&O&O&O&:limlee", KWLIST, convuint, &pl, convuint, &ql, &p, convpgev, &oe, convpgev, &ie, convgrand, &r, convuint, &on)) diff --cc pubkey.c index 9c43ca7,0abb011..5680429 --- a/pubkey.c +++ b/pubkey.c @@@ -733,12 -733,13 +733,14 @@@ static PyObject *meth__RSAPriv_generate unsigned n = 0; rsa_priv rp; mp *e = 0; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; - char *kwlist[] = { "class", "nbits", "event", "rng", "nsteps", "e", 0 }; + static const char *const kwlist[] = + { "class", "nbits", "event", "rng", "nsteps", "e", 0 }; PyObject *rc = 0; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", KWLIST, &me, convuint, &nbits, convpgev, &evt, convgrand, &r, convuint, &n, convmp, &e)) diff --cc rand.c index 9afb271,1203f76..d57795a --- a/rand.c +++ b/rand.c @@@ -503,10 -503,10 +503,10 @@@ static PyObject *trmeth_timer(PyObject static PyObject *truerand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { - char *kwlist[] = { 0 }; + static const char *const kwlist[] = { 0 }; grand *r; PyObject *rc = 0; - if (PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST)) goto end; - if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", kwlist)) goto end; ++ if (!PyArg_ParseTupleAndKeywords(arg, kw, ":new", KWLIST)) goto end; r = rand_create(); r->ops->misc(r, RAND_NOISESRC, &noise_source); r->ops->misc(r, RAND_SEED, 160); @@@ -1267,9 -1261,8 +1267,9 @@@ static PyObject *bbsget_x(PyObject *me static int bbsset_x(PyObject *me, PyObject *val, void *hunoz) { - mp *x = 0; grand *r = GRAND_R(me); int rc = -1; if (!x) NIERR("__del__"); + mp *x = 0; grand *r = GRAND_R(me); int rc = -1; if (!val) NIERR("__del__"); - if ((x = getmp(val)) == 0) goto end; r->ops->misc(r, BBS_SET, x); rc = 0; + if ((x = getmp(val)) == 0) goto end; + r->ops->misc(r, BBS_SET, x); rc = 0; end: mp_drop(x); return (rc); } @@@ -1383,14 -1376,15 +1383,16 @@@ static PyObject *meth__BBSPriv_generate { bbs_priv bp = { 0 }; mp *x = MP_TWO; - pgev evt = { 0 }; + struct excinfo exc = EXCINFO_INIT; + pypgev evt = { { 0 } }; unsigned nbits, n = 0; grand *r = &rand_global; - char *kwlist[] = { "class", "nbits", "event", "rng", "nsteps", "seed", 0 }; + static const char *const kwlist[] = + { "class", "nbits", "event", "rng", "nsteps", "seed", 0 }; bbspriv_pyobj *rc = 0; + evt.exc = &exc; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", kwlist, + if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO&|O&O&O&O&:generate", KWLIST, &me, convuint, &nbits, convpgev, &evt, convgrand, &r, convuint, &n, convmp, &x)) goto end; diff --cc setup.py index efa922b,80a1547..d778177 --- a/setup.py +++ b/setup.py @@@ -23,7 -23,11 +23,12 @@@ MS.setup(name = 'catacomb-python' author_email = 'mdw@distorted.org.uk', license = 'GNU General Public License', packages = ['catacomb'], - scripts = ['pwsafe'], + scripts = ['pock', 'pwsafe'], + data_files = [('share/man/man1', ['pock.1', 'pwsafe.1'])], genfiles = [MS.Generate('algorithms.h')], + unittest_dir = "t", + unittests = ["t-misc", "t-algorithms", "t-bytes", "t-buffer", + "t-convert", "t-ec", "t-field", "t-group", "t-key", + "t-mp", "t-passphrase", "t-pgen", "t-pubkey", + "t-rand", "t-rat", "t-share"], ext_modules = [cat]) diff --cc util.c index 2e6ee25,29f7d12..723c819 --- a/util.c +++ b/util.c @@@ -609,9 -743,7 +743,9 @@@ PyObject *gmapmeth_get(PyObject *me, Py { PyObject *k, *def = Py_None, *v; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO:get", - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:get", def_kwlist, &k, &def)) ++ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:get", + (/*unconst*/ char **)def_kwlist, + &k, &def)) return (0); if ((v = PyObject_GetItem(me, k)) != 0) return (v); PyErr_Clear(); @@@ -622,9 -754,8 +756,9 @@@ PyObject *gmapmeth_setdefault(PyObject { PyObject *k, *def = Py_None, *v; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO:setdefault", + if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:setdefault", - def_kwlist, &k, &def)) + (/*unconst*/ char **)def_kwlist, + &k, &def)) return (0); if ((v = PyObject_GetItem(me, k)) != 0) return (v); PyErr_Clear(); @@@ -636,9 -767,7 +770,9 @@@ PyObject *gmapmeth_pop(PyObject *me, Py { PyObject *k, *def = 0, *v; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "OO:pop", - if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:pop", def_kwlist, &k, &def)) ++ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O|O:pop", + (/*unconst*/ char **)def_kwlist, + &k, &def)) return (0); if ((v = PyObject_GetItem(me, k)) != 0) { PyObject_DelItem(me, k);