Commit f9de534c authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #8321: Give access to OpenSSL version numbers from the `ssl` module,

using the new attributes `ssl.OPENSSL_VERSION`, `ssl.OPENSSL_VERSION_INFO`
and `ssl.OPENSSL_VERSION_NUMBER`.
parent fce1d31d
...@@ -240,6 +240,36 @@ Functions, Constants, and Exceptions ...@@ -240,6 +240,36 @@ Functions, Constants, and Exceptions
modern version, and probably the best choice for maximum protection, if both modern version, and probably the best choice for maximum protection, if both
sides can speak it. sides can speak it.
.. data:: OPENSSL_VERSION
The version string of the OpenSSL library loaded by the interpreter::
>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8k 25 Mar 2009'
.. versionadded:: 2.7
.. data:: OPENSSL_VERSION_INFO
A tuple of five integers representing version information about the
OpenSSL library::
>>> ssl.OPENSSL_VERSION_INFO
(0, 9, 8, 11, 15)
.. versionadded:: 2.7
.. data:: OPENSSL_VERSION_NUMBER
The raw version number of the OpenSSL library, as a single integer::
>>> ssl.OPENSSL_VERSION_NUMBER
9470143L
>>> hex(ssl.OPENSSL_VERSION_NUMBER)
'0x9080bfL'
.. versionadded:: 2.7
SSLSocket Objects SSLSocket Objects
----------------- -----------------
......
...@@ -59,6 +59,7 @@ import textwrap ...@@ -59,6 +59,7 @@ import textwrap
import _ssl # if we can't import it, let the error propagate import _ssl # if we can't import it, let the error propagate
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
from _ssl import SSLError from _ssl import SSLError
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1 from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
......
...@@ -110,6 +110,34 @@ class BasicTests(unittest.TestCase): ...@@ -110,6 +110,34 @@ class BasicTests(unittest.TestCase):
if (d1 != d2): if (d1 != d2):
raise test_support.TestFailed("PEM-to-DER or DER-to-PEM translation failed") raise test_support.TestFailed("PEM-to-DER or DER-to-PEM translation failed")
def test_openssl_version(self):
n = ssl.OPENSSL_VERSION_NUMBER
t = ssl.OPENSSL_VERSION_INFO
s = ssl.OPENSSL_VERSION
self.assertIsInstance(n, (int, long))
self.assertIsInstance(t, tuple)
self.assertIsInstance(s, str)
# Some sanity checks follow
# >= 0.9
self.assertGreaterEqual(n, 0x900000)
# < 2.0
self.assertLess(n, 0x20000000)
major, minor, fix, patch, status = t
self.assertGreaterEqual(major, 0)
self.assertLess(major, 2)
self.assertGreaterEqual(minor, 0)
self.assertLess(minor, 256)
self.assertGreaterEqual(fix, 0)
self.assertLess(fix, 256)
self.assertGreaterEqual(patch, 0)
self.assertLessEqual(patch, 26)
self.assertGreaterEqual(status, 0)
self.assertLessEqual(status, 15)
# Version string as returned by OpenSSL, the format might change
self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
(s, t))
class NetworkedTests(unittest.TestCase): class NetworkedTests(unittest.TestCase):
def testConnect(self): def testConnect(self):
......
...@@ -49,6 +49,10 @@ Core and Builtins ...@@ -49,6 +49,10 @@ Core and Builtins
Library Library
------- -------
- Issue #8321: Give access to OpenSSL version numbers from the `ssl` module,
using the new attributes `ssl.OPENSSL_VERSION`, `ssl.OPENSSL_VERSION_INFO`
and `ssl.OPENSSL_VERSION_NUMBER`.
- Issue #8310: Allow dis to examine new style classes. - Issue #8310: Allow dis to examine new style classes.
- Issue #8257: The Decimal construct now accepts a float instance - Issue #8257: The Decimal construct now accepts a float instance
......
...@@ -1574,7 +1574,9 @@ for documentation."); ...@@ -1574,7 +1574,9 @@ for documentation.");
PyMODINIT_FUNC PyMODINIT_FUNC
init_ssl(void) init_ssl(void)
{ {
PyObject *m, *d; PyObject *m, *d, *r;
unsigned long libver;
unsigned int major, minor, fix, patch, status;
Py_TYPE(&PySSL_Type) = &PyType_Type; Py_TYPE(&PySSL_Type) = &PyType_Type;
...@@ -1644,4 +1646,30 @@ init_ssl(void) ...@@ -1644,4 +1646,30 @@ init_ssl(void)
PY_SSL_VERSION_SSL23); PY_SSL_VERSION_SSL23);
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
PY_SSL_VERSION_TLS1); PY_SSL_VERSION_TLS1);
/* OpenSSL version */
/* SSLeay() gives us the version of the library linked against,
which could be different from the headers version.
*/
libver = SSLeay();
r = PyLong_FromUnsignedLong(libver);
if (r == NULL)
return;
if (PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r))
return;
status = libver & 0xF;
libver >>= 4;
patch = libver & 0xFF;
libver >>= 8;
fix = libver & 0xFF;
libver >>= 8;
minor = libver & 0xFF;
libver >>= 8;
major = libver & 0xFF;
r = Py_BuildValue("IIIII", major, minor, fix, patch, status);
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r))
return;
r = PyString_FromString(SSLeay_version(SSLEAY_VERSION));
if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r))
return;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment