diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-24 10:05:19 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2011-05-24 10:05:19 (GMT) |
commit | 99c8b1614319ce0161835ade223cdd395f0126d4 (patch) | |
tree | abe0d388da458164d5fe6fcfe6a3cac5619e531d | |
parent | b7b1930fe374317c380e49add9fb4cc2267367e9 (diff) | |
download | cpython-99c8b1614319ce0161835ade223cdd395f0126d4.zip cpython-99c8b1614319ce0161835ade223cdd395f0126d4.tar.gz cpython-99c8b1614319ce0161835ade223cdd395f0126d4.tar.bz2 |
Issue #12049: Add RAND_bytes() and RAND_pseudo_bytes() functions to the ssl
module.
-rw-r--r-- | Doc/library/ssl.rst | 20 | ||||
-rw-r--r-- | Doc/whatsnew/3.3.rst | 10 | ||||
-rw-r--r-- | Lib/ssl.py | 2 | ||||
-rw-r--r-- | Lib/test/test_ssl.py | 8 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/_ssl.c | 67 |
6 files changed, 106 insertions, 4 deletions
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 5ece8cf..a528a03 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -162,6 +162,20 @@ instead. Random generation ^^^^^^^^^^^^^^^^^ +.. function:: RAND_bytes(num) + + Returns *num* cryptographically strong pseudo-random bytes. + + .. versionadded:: 3.3 + +.. function:: RAND_pseudo_bytes(num) + + Returns (bytes, is_cryptographic): bytes are *num* pseudo-random bytes, + is_cryptographic is True if the bytes generated are cryptographically + strong. + + .. versionadded:: 3.3 + .. function:: RAND_status() Returns True if the SSL pseudo-random number generator has been seeded with @@ -171,7 +185,7 @@ Random generation .. function:: RAND_egd(path) - If you are running an entropy-gathering daemon (EGD) somewhere, and ``path`` + If you are running an entropy-gathering daemon (EGD) somewhere, and *path* is the pathname of a socket connection open to it, this will read 256 bytes of randomness from the socket, and add it to the SSL pseudo-random number generator to increase the security of generated secret keys. This is @@ -182,8 +196,8 @@ Random generation .. function:: RAND_add(bytes, entropy) - Mixes the given ``bytes`` into the SSL pseudo-random number generator. The - parameter ``entropy`` (a float) is a lower bound on the entropy contained in + Mixes the given *bytes* into the SSL pseudo-random number generator. The + parameter *entropy* (a float) is a lower bound on the entropy contained in string (so you can always use :const:`0.0`). See :rfc:`1750` for more information on sources of entropy. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index d442665..529665f 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -152,6 +152,16 @@ signal instead of a RuntimeError: OSError has an errno attribute. +ssl +--- + +The :mod:`ssl` module has new functions: + + * :func:`~ssl.RAND_bytes`: generate cryptographically strong + pseudo-random bytes. + * :func:`~ssl.RAND_pseudo_bytes`: generate pseudo-random bytes. + + Optimizations ============= @@ -63,7 +63,7 @@ from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION from _ssl import _SSLContext, SSLError from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED from _ssl import OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1 -from _ssl import RAND_status, RAND_egd, RAND_add +from _ssl import RAND_status, RAND_egd, RAND_add, RAND_bytes, RAND_pseudo_bytes from _ssl import ( SSL_ERROR_ZERO_RETURN, SSL_ERROR_WANT_READ, diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index aef51e3..8c21975 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -102,6 +102,14 @@ class BasicSocketTests(unittest.TestCase): sys.stdout.write("\n RAND_status is %d (%s)\n" % (v, (v and "sufficient randomness") or "insufficient randomness")) + + data, is_cryptographic = ssl.RAND_pseudo_bytes(16) + self.assertEqual(len(data), 16) + self.assertEqual(is_cryptographic, v == 1) + if v: + data = ssl.RAND_bytes(16) + self.assertEqual(len(data), 16) + try: ssl.RAND_egd(1) except TypeError: @@ -156,6 +156,9 @@ Core and Builtins Library ------- +- Issue #12049: Add RAND_bytes() and RAND_pseudo_bytes() functions to the ssl + module. + - Issue #12125: fixed the failures under Solaris due to improper test cleanup. - Issue #6501: os.device_encoding() returns None on Windows if the application diff --git a/Modules/_ssl.c b/Modules/_ssl.c index dc11fc8..3f631e3 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1887,6 +1887,69 @@ Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\ bound on the entropy contained in string. See RFC 1750."); static PyObject * +PySSL_RAND(int len, int pseudo) +{ + int ok; + PyObject *bytes; + unsigned long err; + const char *errstr; + PyObject *v; + + bytes = PyBytes_FromStringAndSize(NULL, len); + if (bytes == NULL) + return NULL; + if (pseudo) { + ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); + if (ok == 0 || ok == 1) + return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); + } + else { + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); + if (ok == 1) + return bytes; + } + Py_DECREF(bytes); + + err = ERR_get_error(); + errstr = ERR_reason_error_string(err); + v = Py_BuildValue("(ks)", err, errstr); + if (v != NULL) { + PyErr_SetObject(PySSLErrorObject, v); + Py_DECREF(v); + } + return NULL; +} + +static PyObject * +PySSL_RAND_bytes(PyObject *self, PyObject *args) +{ + int len; + if (!PyArg_ParseTuple(args, "i:RAND_bytes", &len)) + return NULL; + return PySSL_RAND(len, 0); +} + +PyDoc_STRVAR(PySSL_RAND_bytes_doc, +"RAND_bytes(n) -> bytes\n\ +\n\ +Generate n cryptographically strong pseudo-random bytes."); + +static PyObject * +PySSL_RAND_pseudo_bytes(PyObject *self, PyObject *args) +{ + int len; + if (!PyArg_ParseTuple(args, "i:RAND_pseudo_bytes", &len)) + return NULL; + return PySSL_RAND(len, 1); +} + +PyDoc_STRVAR(PySSL_RAND_pseudo_bytes_doc, +"RAND_pseudo_bytes(n) -> (bytes, is_cryptographic)\n\ +\n\ +Generate n pseudo-random bytes. is_cryptographic is True if the bytes\ +generated are cryptographically strong."); + +static PyObject * PySSL_RAND_status(PyObject *self) { return PyLong_FromLong(RAND_status()); @@ -1939,6 +2002,10 @@ static PyMethodDef PySSL_methods[] = { #ifdef HAVE_OPENSSL_RAND {"RAND_add", PySSL_RAND_add, METH_VARARGS, PySSL_RAND_add_doc}, + {"RAND_bytes", PySSL_RAND_bytes, METH_VARARGS, + PySSL_RAND_bytes_doc}, + {"RAND_pseudo_bytes", PySSL_RAND_pseudo_bytes, METH_VARARGS, + PySSL_RAND_pseudo_bytes_doc}, {"RAND_egd", PySSL_RAND_egd, METH_VARARGS, PySSL_RAND_egd_doc}, {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, |