Blame SOURCES/00227-accept-none-keyfile-loadcertchain.patch

04a680
From c1f4979e7019f6c1ce9e5a02c2e3f8ca146645bc Mon Sep 17 00:00:00 2001
04a680
From: Charalampos Stratakis <cstratak@redhat.com>
04a680
Date: Mon, 11 Jul 2016 14:20:01 +0200
04a680
Subject: [PATCH] Allow the keyfile argument of SSLContext.load_cert_chain to
04a680
 be set to None
04a680
04a680
---
04a680
 Modules/_ssl.c | 30 +++++++++++++++++++++++-------
04a680
 1 file changed, 23 insertions(+), 7 deletions(-)
04a680
04a680
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
04a680
index 38eba1d..1786afd 100644
04a680
--- a/Modules/_ssl.c
04a680
+++ b/Modules/_ssl.c
04a680
@@ -2445,8 +2445,8 @@ static PyObject *
f63228
 load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
f63228
 {
f63228
     char *kwlist[] = {"certfile", "keyfile", "password", NULL};
f63228
-    PyObject *password = NULL;
f63228
-    char *certfile_bytes = NULL, *keyfile_bytes = NULL;
04a680
+    PyObject *keyfile = NULL, *keyfile_bytes = NULL, *password = NULL;
f63228
+    char *certfile_bytes = NULL;
04a680
     pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback;
04a680
     void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata;
04a680
     _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 };
04a680
@@ -2455,11 +2455,27 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
f63228
     errno = 0;
f63228
     ERR_clear_error();
f63228
     if (!PyArg_ParseTupleAndKeywords(args, kwds,
f63228
-            "et|etO:load_cert_chain", kwlist,
f63228
+            "et|OO:load_cert_chain", kwlist,
f63228
             Py_FileSystemDefaultEncoding, &certfile_bytes,
f63228
-            Py_FileSystemDefaultEncoding, &keyfile_bytes,
f63228
-            &password))
f63228
+            &keyfile, &password))
f63228
         return NULL;
f63228
+
f63228
+    if (keyfile && keyfile != Py_None) {
f63228
+        if (PyString_Check(keyfile)) {
f63228
+            Py_INCREF(keyfile);
f63228
+            keyfile_bytes = keyfile;
f63228
+        } else {
f63228
+            PyObject *u = PyUnicode_FromObject(keyfile);
f63228
+            if (!u)
f63228
+                goto error;
f63228
+            keyfile_bytes = PyUnicode_AsEncodedString(
f63228
+                u, Py_FileSystemDefaultEncoding, NULL);
f63228
+            Py_DECREF(u);
f63228
+            if (!keyfile_bytes)
f63228
+                goto error;
f63228
+        }
f63228
+    }
04a680
+
04a680
     if (password && password != Py_None) {
04a680
         if (PyCallable_Check(password)) {
04a680
             pw_info.callable = password;
04a680
@@ -2489,7 +2505,7 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
f63228
     }
f63228
     PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state);
f63228
     r = SSL_CTX_use_PrivateKey_file(self->ctx,
f63228
-        keyfile_bytes ? keyfile_bytes : certfile_bytes,
f63228
+        keyfile_bytes ? PyBytes_AS_STRING(keyfile_bytes) : certfile_bytes,
f63228
         SSL_FILETYPE_PEM);
f63228
     PySSL_END_ALLOW_THREADS_S(pw_info.thread_state);
f63228
     if (r != 1) {
04a680
@@ -2521,8 +2537,8 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
f63228
 error:
f63228
     SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb);
f63228
     SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata);
f63228
+    Py_XDECREF(keyfile_bytes);
f63228
     PyMem_Free(pw_info.password);
f63228
-    PyMem_Free(keyfile_bytes);
f63228
     PyMem_Free(certfile_bytes);
f63228
     return NULL;
f63228
 }
04a680
-- 
04a680
2.7.4
04a680