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

057d67
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
057d67
--- a/Modules/_ssl.c
057d67
+++ b/Modules/_ssl.c
057d67
@@ -2681,8 +2681,8 @@ static PyObject *
057d67
 load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
057d67
 {
057d67
     char *kwlist[] = {"certfile", "keyfile", "password", NULL};
057d67
-    PyObject *password = NULL;
057d67
-    char *certfile_bytes = NULL, *keyfile_bytes = NULL;
057d67
+    PyObject *keyfile = NULL, *keyfile_bytes = NULL, *password = NULL;
057d67
+    char *certfile_bytes = NULL;
057d67
     pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback;
057d67
     void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata;
057d67
     _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 };
057d67
@@ -2690,11 +2690,27 @@ load_cert_chain(PySSLContext *self, PyOb
057d67
     errno = 0;
057d67
     ERR_clear_error();
057d67
     if (!PyArg_ParseTupleAndKeywords(args, kwds,
057d67
-            "et|etO:load_cert_chain", kwlist,
057d67
+            "et|OO:load_cert_chain", kwlist,
057d67
             Py_FileSystemDefaultEncoding, &certfile_bytes,
057d67
-            Py_FileSystemDefaultEncoding, &keyfile_bytes,
057d67
-            &password))
057d67
+            &keyfile, &password))
057d67
         return NULL;
057d67
+
057d67
+    if (keyfile && keyfile != Py_None) {
057d67
+        if (PyString_Check(keyfile)) {
057d67
+            Py_INCREF(keyfile);
057d67
+            keyfile_bytes = keyfile;
057d67
+        } else {
057d67
+            PyObject *u = PyUnicode_FromObject(keyfile);
057d67
+            if (!u)
057d67
+                goto error;
057d67
+            keyfile_bytes = PyUnicode_AsEncodedString(
057d67
+                u, Py_FileSystemDefaultEncoding, NULL);
057d67
+            Py_DECREF(u);
057d67
+            if (!keyfile_bytes)
057d67
+                goto error;
057d67
+        }
057d67
+    }
057d67
+
057d67
     if (password && password != Py_None) {
057d67
         if (PyCallable_Check(password)) {
057d67
             pw_info.callable = password;
057d67
@@ -2725,7 +2741,7 @@ load_cert_chain(PySSLContext *self, PyOb
057d67
     }
057d67
     PySSL_BEGIN_ALLOW_THREADS_S(pw_info.thread_state);
057d67
     r = SSL_CTX_use_PrivateKey_file(self->ctx,
057d67
-        keyfile_bytes ? keyfile_bytes : certfile_bytes,
057d67
+        keyfile_bytes ? PyBytes_AS_STRING(keyfile_bytes) : certfile_bytes,
057d67
         SSL_FILETYPE_PEM);
057d67
     PySSL_END_ALLOW_THREADS_S(pw_info.thread_state);
057d67
     if (r != 1) {
057d67
@@ -2756,8 +2772,8 @@ load_cert_chain(PySSLContext *self, PyOb
057d67
 error:
057d67
     SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb);
057d67
     SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata);
057d67
+    Py_XDECREF(keyfile_bytes);
057d67
     PyMem_Free(pw_info.password);
057d67
-    PyMem_Free(keyfile_bytes);
057d67
     PyMem_Free(certfile_bytes);
057d67
     return NULL;
057d67
 }
057d67
057d67