]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #8321: Give access to OpenSSL version numbers from the `ssl` module,
authorAntoine Pitrou <solipsis@pitrou.net>
Mon, 5 Apr 2010 21:35:07 +0000 (21:35 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Mon, 5 Apr 2010 21:35:07 +0000 (21:35 +0000)
using the new attributes `ssl.OPENSSL_VERSION`, `ssl.OPENSSL_VERSION_INFO`
and `ssl.OPENSSL_VERSION_NUMBER`.

Doc/library/ssl.rst
Lib/ssl.py
Lib/test/test_ssl.py
Misc/NEWS
Modules/_ssl.c

index a4f911f5f54929e1734622ec30596ad9c2ac96d0..5d8ca3c96bd3f414f225a92bba3f578d5838d0ba 100644 (file)
@@ -240,6 +240,36 @@ Functions, Constants, and Exceptions
    modern version, and probably the best choice for maximum protection, if both
    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
 -----------------
index 21664b94cd30c15c967ee89a41f25ac87202a80c..cd1d865c921d506a5ad8af72d9ce7440c7464b38 100644 (file)
@@ -59,6 +59,7 @@ import textwrap
 
 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 CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
 from _ssl import PROTOCOL_SSLv2, PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1
index f299d362898c2f64eb07888651df00dd899e13d2..0f9822ab85f9f7aa238a65945b9d0fce999545aa 100644 (file)
@@ -110,6 +110,34 @@ class BasicTests(unittest.TestCase):
         if (d1 != d2):
             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):
 
     def testConnect(self):
index 0ee0c07e4afb3e230b86b655cb78c0751c8e9d13..6c9e55ddf4a1566e38b2de886082d000be3e5554 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -49,6 +49,10 @@ Core and Builtins
 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 #8257: The Decimal construct now accepts a float instance
index 52fdf0ffd32ece776524c94c9d11f984e84b7fc9..6befbefc9c0373ee5cebe3da2af4dfb36693ccdc 100644 (file)
@@ -1574,7 +1574,9 @@ for documentation.");
 PyMODINIT_FUNC
 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;
 
@@ -1644,4 +1646,30 @@ init_ssl(void)
                                PY_SSL_VERSION_SSL23);
        PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
                                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;
 }