]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.2/Modules/_ssl.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Modules / _ssl.c
diff --git a/AppPkg/Applications/Python/Python-2.7.2/Modules/_ssl.c b/AppPkg/Applications/Python/Python-2.7.2/Modules/_ssl.c
deleted file mode 100644 (file)
index 9452138..0000000
+++ /dev/null
@@ -1,1751 +0,0 @@
-/* SSL socket module\r
-\r
-   SSL support based on patches by Brian E Gallew and Laszlo Kovacs.\r
-   Re-worked a bit by Bill Janssen to add server-side support and\r
-   certificate decoding.  Chris Stawarz contributed some non-blocking\r
-   patches.\r
-\r
-   This module is imported by ssl.py. It should *not* be used\r
-   directly.\r
-\r
-   XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE?\r
-\r
-   XXX integrate several "shutdown modes" as suggested in\r
-       http://bugs.python.org/issue8108#msg102867 ?\r
-*/\r
-\r
-#include "Python.h"\r
-\r
-#ifdef WITH_THREAD\r
-#include "pythread.h"\r
-#define PySSL_BEGIN_ALLOW_THREADS { \\r
-            PyThreadState *_save = NULL;  \\r
-            if (_ssl_locks_count>0) {_save = PyEval_SaveThread();}\r
-#define PySSL_BLOCK_THREADS     if (_ssl_locks_count>0){PyEval_RestoreThread(_save)};\r
-#define PySSL_UNBLOCK_THREADS   if (_ssl_locks_count>0){_save = PyEval_SaveThread()};\r
-#define PySSL_END_ALLOW_THREADS if (_ssl_locks_count>0){PyEval_RestoreThread(_save);} \\r
-         }\r
-\r
-#else   /* no WITH_THREAD */\r
-\r
-#define PySSL_BEGIN_ALLOW_THREADS\r
-#define PySSL_BLOCK_THREADS\r
-#define PySSL_UNBLOCK_THREADS\r
-#define PySSL_END_ALLOW_THREADS\r
-\r
-#endif\r
-\r
-enum py_ssl_error {\r
-    /* these mirror ssl.h */\r
-    PY_SSL_ERROR_NONE,\r
-    PY_SSL_ERROR_SSL,\r
-    PY_SSL_ERROR_WANT_READ,\r
-    PY_SSL_ERROR_WANT_WRITE,\r
-    PY_SSL_ERROR_WANT_X509_LOOKUP,\r
-    PY_SSL_ERROR_SYSCALL,     /* look at error stack/return value/errno */\r
-    PY_SSL_ERROR_ZERO_RETURN,\r
-    PY_SSL_ERROR_WANT_CONNECT,\r
-    /* start of non ssl.h errorcodes */\r
-    PY_SSL_ERROR_EOF,         /* special case of SSL_ERROR_SYSCALL */\r
-    PY_SSL_ERROR_INVALID_ERROR_CODE\r
-};\r
-\r
-enum py_ssl_server_or_client {\r
-    PY_SSL_CLIENT,\r
-    PY_SSL_SERVER\r
-};\r
-\r
-enum py_ssl_cert_requirements {\r
-    PY_SSL_CERT_NONE,\r
-    PY_SSL_CERT_OPTIONAL,\r
-    PY_SSL_CERT_REQUIRED\r
-};\r
-\r
-enum py_ssl_version {\r
-#ifndef OPENSSL_NO_SSL2\r
-    PY_SSL_VERSION_SSL2,\r
-#endif\r
-    PY_SSL_VERSION_SSL3=1,\r
-    PY_SSL_VERSION_SSL23,\r
-    PY_SSL_VERSION_TLS1\r
-};\r
-\r
-/* Include symbols from _socket module */\r
-#include "socketmodule.h"\r
-\r
-#if defined(HAVE_POLL_H)\r
-#include <poll.h>\r
-#elif defined(HAVE_SYS_POLL_H)\r
-#include <sys/poll.h>\r
-#endif\r
-\r
-/* Include OpenSSL header files */\r
-#include "openssl/rsa.h"\r
-#include "openssl/crypto.h"\r
-#include "openssl/x509.h"\r
-#include "openssl/x509v3.h"\r
-#include "openssl/pem.h"\r
-#include "openssl/ssl.h"\r
-#include "openssl/err.h"\r
-#include "openssl/rand.h"\r
-\r
-/* SSL error object */\r
-static PyObject *PySSLErrorObject;\r
-\r
-#ifdef WITH_THREAD\r
-\r
-/* serves as a flag to see whether we've initialized the SSL thread support. */\r
-/* 0 means no, greater than 0 means yes */\r
-\r
-static unsigned int _ssl_locks_count = 0;\r
-\r
-#endif /* def WITH_THREAD */\r
-\r
-/* SSL socket object */\r
-\r
-#define X509_NAME_MAXLEN 256\r
-\r
-/* RAND_* APIs got added to OpenSSL in 0.9.5 */\r
-#if OPENSSL_VERSION_NUMBER >= 0x0090500fL\r
-# define HAVE_OPENSSL_RAND 1\r
-#else\r
-# undef HAVE_OPENSSL_RAND\r
-#endif\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-    PySocketSockObject *Socket;         /* Socket on which we're layered */\r
-    SSL_CTX*            ctx;\r
-    SSL*                ssl;\r
-    X509*               peer_cert;\r
-    char                server[X509_NAME_MAXLEN];\r
-    char                issuer[X509_NAME_MAXLEN];\r
-    int                 shutdown_seen_zero;\r
-\r
-} PySSLObject;\r
-\r
-static PyTypeObject PySSL_Type;\r
-static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);\r
-static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);\r
-static int check_socket_and_wait_for_timeout(PySocketSockObject *s,\r
-                                             int writing);\r
-static PyObject *PySSL_peercert(PySSLObject *self, PyObject *args);\r
-static PyObject *PySSL_cipher(PySSLObject *self);\r
-\r
-#define PySSLObject_Check(v)    (Py_TYPE(v) == &PySSL_Type)\r
-\r
-typedef enum {\r
-    SOCKET_IS_NONBLOCKING,\r
-    SOCKET_IS_BLOCKING,\r
-    SOCKET_HAS_TIMED_OUT,\r
-    SOCKET_HAS_BEEN_CLOSED,\r
-    SOCKET_TOO_LARGE_FOR_SELECT,\r
-    SOCKET_OPERATION_OK\r
-} timeout_state;\r
-\r
-/* Wrap error strings with filename and line # */\r
-#define STRINGIFY1(x) #x\r
-#define STRINGIFY2(x) STRINGIFY1(x)\r
-#define ERRSTR1(x,y,z) (x ":" y ": " z)\r
-#define ERRSTR(x) ERRSTR1("_ssl.c", STRINGIFY2(__LINE__), x)\r
-\r
-/* XXX It might be helpful to augment the error message generated\r
-   below with the name of the SSL function that generated the error.\r
-   I expect it's obvious most of the time.\r
-*/\r
-\r
-static PyObject *\r
-PySSL_SetError(PySSLObject *obj, int ret, char *filename, int lineno)\r
-{\r
-    PyObject *v;\r
-    char buf[2048];\r
-    char *errstr;\r
-    int err;\r
-    enum py_ssl_error p = PY_SSL_ERROR_NONE;\r
-\r
-    assert(ret <= 0);\r
-\r
-    if (obj->ssl != NULL) {\r
-        err = SSL_get_error(obj->ssl, ret);\r
-\r
-        switch (err) {\r
-        case SSL_ERROR_ZERO_RETURN:\r
-            errstr = "TLS/SSL connection has been closed";\r
-            p = PY_SSL_ERROR_ZERO_RETURN;\r
-            break;\r
-        case SSL_ERROR_WANT_READ:\r
-            errstr = "The operation did not complete (read)";\r
-            p = PY_SSL_ERROR_WANT_READ;\r
-            break;\r
-        case SSL_ERROR_WANT_WRITE:\r
-            p = PY_SSL_ERROR_WANT_WRITE;\r
-            errstr = "The operation did not complete (write)";\r
-            break;\r
-        case SSL_ERROR_WANT_X509_LOOKUP:\r
-            p = PY_SSL_ERROR_WANT_X509_LOOKUP;\r
-            errstr = "The operation did not complete (X509 lookup)";\r
-            break;\r
-        case SSL_ERROR_WANT_CONNECT:\r
-            p = PY_SSL_ERROR_WANT_CONNECT;\r
-            errstr = "The operation did not complete (connect)";\r
-            break;\r
-        case SSL_ERROR_SYSCALL:\r
-        {\r
-            unsigned long e = ERR_get_error();\r
-            if (e == 0) {\r
-                if (ret == 0 || !obj->Socket) {\r
-                    p = PY_SSL_ERROR_EOF;\r
-                    errstr = "EOF occurred in violation of protocol";\r
-                } else if (ret == -1) {\r
-                    /* underlying BIO reported an I/O error */\r
-                    ERR_clear_error();\r
-                    return obj->Socket->errorhandler();\r
-                } else { /* possible? */\r
-                    p = PY_SSL_ERROR_SYSCALL;\r
-                    errstr = "Some I/O error occurred";\r
-                }\r
-            } else {\r
-                p = PY_SSL_ERROR_SYSCALL;\r
-                /* XXX Protected by global interpreter lock */\r
-                errstr = ERR_error_string(e, NULL);\r
-            }\r
-            break;\r
-        }\r
-        case SSL_ERROR_SSL:\r
-        {\r
-            unsigned long e = ERR_get_error();\r
-            p = PY_SSL_ERROR_SSL;\r
-            if (e != 0)\r
-                /* XXX Protected by global interpreter lock */\r
-                errstr = ERR_error_string(e, NULL);\r
-            else {              /* possible? */\r
-                errstr = "A failure in the SSL library occurred";\r
-            }\r
-            break;\r
-        }\r
-        default:\r
-            p = PY_SSL_ERROR_INVALID_ERROR_CODE;\r
-            errstr = "Invalid error code";\r
-        }\r
-    } else {\r
-        errstr = ERR_error_string(ERR_peek_last_error(), NULL);\r
-    }\r
-    PyOS_snprintf(buf, sizeof(buf), "_ssl.c:%d: %s", lineno, errstr);\r
-    ERR_clear_error();\r
-    v = Py_BuildValue("(is)", p, buf);\r
-    if (v != NULL) {\r
-        PyErr_SetObject(PySSLErrorObject, v);\r
-        Py_DECREF(v);\r
-    }\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-_setSSLError (char *errstr, int errcode, char *filename, int lineno) {\r
-\r
-    char buf[2048];\r
-    PyObject *v;\r
-\r
-    if (errstr == NULL) {\r
-        errcode = ERR_peek_last_error();\r
-        errstr = ERR_error_string(errcode, NULL);\r
-    }\r
-    PyOS_snprintf(buf, sizeof(buf), "_ssl.c:%d: %s", lineno, errstr);\r
-    ERR_clear_error();\r
-    v = Py_BuildValue("(is)", errcode, buf);\r
-    if (v != NULL) {\r
-        PyErr_SetObject(PySSLErrorObject, v);\r
-        Py_DECREF(v);\r
-    }\r
-    return NULL;\r
-}\r
-\r
-static PySSLObject *\r
-newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,\r
-               enum py_ssl_server_or_client socket_type,\r
-               enum py_ssl_cert_requirements certreq,\r
-               enum py_ssl_version proto_version,\r
-               char *cacerts_file, char *ciphers)\r
-{\r
-    PySSLObject *self;\r
-    char *errstr = NULL;\r
-    int ret;\r
-    int verification_mode;\r
-\r
-    self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */\r
-    if (self == NULL)\r
-        return NULL;\r
-    memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);\r
-    memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);\r
-    self->peer_cert = NULL;\r
-    self->ssl = NULL;\r
-    self->ctx = NULL;\r
-    self->Socket = NULL;\r
-\r
-    /* Make sure the SSL error state is initialized */\r
-    (void) ERR_get_state();\r
-    ERR_clear_error();\r
-\r
-    if ((key_file && !cert_file) || (!key_file && cert_file)) {\r
-        errstr = ERRSTR("Both the key & certificate files "\r
-                        "must be specified");\r
-        goto fail;\r
-    }\r
-\r
-    if ((socket_type == PY_SSL_SERVER) &&\r
-        ((key_file == NULL) || (cert_file == NULL))) {\r
-        errstr = ERRSTR("Both the key & certificate files "\r
-                        "must be specified for server-side operation");\r
-        goto fail;\r
-    }\r
-\r
-    PySSL_BEGIN_ALLOW_THREADS\r
-    if (proto_version == PY_SSL_VERSION_TLS1)\r
-        self->ctx = SSL_CTX_new(TLSv1_method()); /* Set up context */\r
-    else if (proto_version == PY_SSL_VERSION_SSL3)\r
-        self->ctx = SSL_CTX_new(SSLv3_method()); /* Set up context */\r
-#ifndef OPENSSL_NO_SSL2\r
-    else if (proto_version == PY_SSL_VERSION_SSL2)\r
-        self->ctx = SSL_CTX_new(SSLv2_method()); /* Set up context */\r
-#endif\r
-    else if (proto_version == PY_SSL_VERSION_SSL23)\r
-        self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */\r
-    PySSL_END_ALLOW_THREADS\r
-\r
-    if (self->ctx == NULL) {\r
-        errstr = ERRSTR("Invalid SSL protocol variant specified.");\r
-        goto fail;\r
-    }\r
-\r
-    if (ciphers != NULL) {\r
-        ret = SSL_CTX_set_cipher_list(self->ctx, ciphers);\r
-        if (ret == 0) {\r
-            errstr = ERRSTR("No cipher can be selected.");\r
-            goto fail;\r
-        }\r
-    }\r
-\r
-    if (certreq != PY_SSL_CERT_NONE) {\r
-        if (cacerts_file == NULL) {\r
-            errstr = ERRSTR("No root certificates specified for "\r
-                            "verification of other-side certificates.");\r
-            goto fail;\r
-        } else {\r
-            PySSL_BEGIN_ALLOW_THREADS\r
-            ret = SSL_CTX_load_verify_locations(self->ctx,\r
-                                                cacerts_file,\r
-                                                NULL);\r
-            PySSL_END_ALLOW_THREADS\r
-            if (ret != 1) {\r
-                _setSSLError(NULL, 0, __FILE__, __LINE__);\r
-                goto fail;\r
-            }\r
-        }\r
-    }\r
-    if (key_file) {\r
-        PySSL_BEGIN_ALLOW_THREADS\r
-        ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file,\r
-                                          SSL_FILETYPE_PEM);\r
-        PySSL_END_ALLOW_THREADS\r
-        if (ret != 1) {\r
-            _setSSLError(NULL, ret, __FILE__, __LINE__);\r
-            goto fail;\r
-        }\r
-\r
-        PySSL_BEGIN_ALLOW_THREADS\r
-        ret = SSL_CTX_use_certificate_chain_file(self->ctx,\r
-                                                 cert_file);\r
-        PySSL_END_ALLOW_THREADS\r
-        if (ret != 1) {\r
-            /*\r
-            fprintf(stderr, "ret is %d, errcode is %lu, %lu, with file \"%s\"\n",\r
-                ret, ERR_peek_error(), ERR_peek_last_error(), cert_file);\r
-                */\r
-            if (ERR_peek_last_error() != 0) {\r
-                _setSSLError(NULL, ret, __FILE__, __LINE__);\r
-                goto fail;\r
-            }\r
-        }\r
-    }\r
-\r
-    /* ssl compatibility */\r
-    SSL_CTX_set_options(self->ctx, SSL_OP_ALL);\r
-\r
-    verification_mode = SSL_VERIFY_NONE;\r
-    if (certreq == PY_SSL_CERT_OPTIONAL)\r
-        verification_mode = SSL_VERIFY_PEER;\r
-    else if (certreq == PY_SSL_CERT_REQUIRED)\r
-        verification_mode = (SSL_VERIFY_PEER |\r
-                             SSL_VERIFY_FAIL_IF_NO_PEER_CERT);\r
-    SSL_CTX_set_verify(self->ctx, verification_mode,\r
-                       NULL); /* set verify lvl */\r
-\r
-    PySSL_BEGIN_ALLOW_THREADS\r
-    self->ssl = SSL_new(self->ctx); /* New ssl struct */\r
-    PySSL_END_ALLOW_THREADS\r
-    SSL_set_fd(self->ssl, Sock->sock_fd);       /* Set the socket for SSL */\r
-#ifdef SSL_MODE_AUTO_RETRY\r
-    SSL_set_mode(self->ssl, SSL_MODE_AUTO_RETRY);\r
-#endif\r
-\r
-    /* If the socket is in non-blocking mode or timeout mode, set the BIO\r
-     * to non-blocking mode (blocking is the default)\r
-     */\r
-    if (Sock->sock_timeout >= 0.0) {\r
-        /* Set both the read and write BIO's to non-blocking mode */\r
-        BIO_set_nbio(SSL_get_rbio(self->ssl), 1);\r
-        BIO_set_nbio(SSL_get_wbio(self->ssl), 1);\r
-    }\r
-\r
-    PySSL_BEGIN_ALLOW_THREADS\r
-    if (socket_type == PY_SSL_CLIENT)\r
-        SSL_set_connect_state(self->ssl);\r
-    else\r
-        SSL_set_accept_state(self->ssl);\r
-    PySSL_END_ALLOW_THREADS\r
-\r
-    self->Socket = Sock;\r
-    Py_INCREF(self->Socket);\r
-    return self;\r
- fail:\r
-    if (errstr)\r
-        PyErr_SetString(PySSLErrorObject, errstr);\r
-    Py_DECREF(self);\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-PySSL_sslwrap(PyObject *self, PyObject *args)\r
-{\r
-    PySocketSockObject *Sock;\r
-    int server_side = 0;\r
-    int verification_mode = PY_SSL_CERT_NONE;\r
-    int protocol = PY_SSL_VERSION_SSL23;\r
-    char *key_file = NULL;\r
-    char *cert_file = NULL;\r
-    char *cacerts_file = NULL;\r
-    char *ciphers = NULL;\r
-\r
-    if (!PyArg_ParseTuple(args, "O!i|zziizz:sslwrap",\r
-                          PySocketModule.Sock_Type,\r
-                          &Sock,\r
-                          &server_side,\r
-                          &key_file, &cert_file,\r
-                          &verification_mode, &protocol,\r
-                          &cacerts_file, &ciphers))\r
-        return NULL;\r
-\r
-    /*\r
-    fprintf(stderr,\r
-        "server_side is %d, keyfile %p, certfile %p, verify_mode %d, "\r
-        "protocol %d, certs %p\n",\r
-        server_side, key_file, cert_file, verification_mode,\r
-        protocol, cacerts_file);\r
-     */\r
-\r
-    return (PyObject *) newPySSLObject(Sock, key_file, cert_file,\r
-                                       server_side, verification_mode,\r
-                                       protocol, cacerts_file,\r
-                                       ciphers);\r
-}\r
-\r
-PyDoc_STRVAR(ssl_doc,\r
-"sslwrap(socket, server_side, [keyfile, certfile, certs_mode, protocol,\n"\r
-"                              cacertsfile, ciphers]) -> sslobject");\r
-\r
-/* SSL object methods */\r
-\r
-static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)\r
-{\r
-    int ret;\r
-    int err;\r
-    int sockstate, nonblocking;\r
-\r
-    /* just in case the blocking state of the socket has been changed */\r
-    nonblocking = (self->Socket->sock_timeout >= 0.0);\r
-    BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);\r
-    BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);\r
-\r
-    /* Actually negotiate SSL connection */\r
-    /* XXX If SSL_do_handshake() returns 0, it's also a failure. */\r
-    do {\r
-        PySSL_BEGIN_ALLOW_THREADS\r
-        ret = SSL_do_handshake(self->ssl);\r
-        err = SSL_get_error(self->ssl, ret);\r
-        PySSL_END_ALLOW_THREADS\r
-        if(PyErr_CheckSignals()) {\r
-            return NULL;\r
-        }\r
-        if (err == SSL_ERROR_WANT_READ) {\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);\r
-        } else if (err == SSL_ERROR_WANT_WRITE) {\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);\r
-        } else {\r
-            sockstate = SOCKET_OPERATION_OK;\r
-        }\r
-        if (sockstate == SOCKET_HAS_TIMED_OUT) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            ERRSTR("The handshake operation timed out"));\r
-            return NULL;\r
-        } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            ERRSTR("Underlying socket has been closed."));\r
-            return NULL;\r
-        } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            ERRSTR("Underlying socket too large for select()."));\r
-            return NULL;\r
-        } else if (sockstate == SOCKET_IS_NONBLOCKING) {\r
-            break;\r
-        }\r
-    } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);\r
-    if (ret < 1)\r
-        return PySSL_SetError(self, ret, __FILE__, __LINE__);\r
-\r
-    if (self->peer_cert)\r
-        X509_free (self->peer_cert);\r
-    PySSL_BEGIN_ALLOW_THREADS\r
-    if ((self->peer_cert = SSL_get_peer_certificate(self->ssl))) {\r
-        X509_NAME_oneline(X509_get_subject_name(self->peer_cert),\r
-                          self->server, X509_NAME_MAXLEN);\r
-        X509_NAME_oneline(X509_get_issuer_name(self->peer_cert),\r
-                          self->issuer, X509_NAME_MAXLEN);\r
-    }\r
-    PySSL_END_ALLOW_THREADS\r
-\r
-    Py_INCREF(Py_None);\r
-    return Py_None;\r
-}\r
-\r
-static PyObject *\r
-PySSL_server(PySSLObject *self)\r
-{\r
-    return PyString_FromString(self->server);\r
-}\r
-\r
-static PyObject *\r
-PySSL_issuer(PySSLObject *self)\r
-{\r
-    return PyString_FromString(self->issuer);\r
-}\r
-\r
-static PyObject *\r
-_create_tuple_for_attribute (ASN1_OBJECT *name, ASN1_STRING *value) {\r
-\r
-    char namebuf[X509_NAME_MAXLEN];\r
-    int buflen;\r
-    PyObject *name_obj;\r
-    PyObject *value_obj;\r
-    PyObject *attr;\r
-    unsigned char *valuebuf = NULL;\r
-\r
-    buflen = OBJ_obj2txt(namebuf, sizeof(namebuf), name, 0);\r
-    if (buflen < 0) {\r
-        _setSSLError(NULL, 0, __FILE__, __LINE__);\r
-        goto fail;\r
-    }\r
-    name_obj = PyString_FromStringAndSize(namebuf, buflen);\r
-    if (name_obj == NULL)\r
-        goto fail;\r
-\r
-    buflen = ASN1_STRING_to_UTF8(&valuebuf, value);\r
-    if (buflen < 0) {\r
-        _setSSLError(NULL, 0, __FILE__, __LINE__);\r
-        Py_DECREF(name_obj);\r
-        goto fail;\r
-    }\r
-    value_obj = PyUnicode_DecodeUTF8((char *) valuebuf,\r
-                                     buflen, "strict");\r
-    OPENSSL_free(valuebuf);\r
-    if (value_obj == NULL) {\r
-        Py_DECREF(name_obj);\r
-        goto fail;\r
-    }\r
-    attr = PyTuple_New(2);\r
-    if (attr == NULL) {\r
-        Py_DECREF(name_obj);\r
-        Py_DECREF(value_obj);\r
-        goto fail;\r
-    }\r
-    PyTuple_SET_ITEM(attr, 0, name_obj);\r
-    PyTuple_SET_ITEM(attr, 1, value_obj);\r
-    return attr;\r
-\r
-  fail:\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-_create_tuple_for_X509_NAME (X509_NAME *xname)\r
-{\r
-    PyObject *dn = NULL;    /* tuple which represents the "distinguished name" */\r
-    PyObject *rdn = NULL;   /* tuple to hold a "relative distinguished name" */\r
-    PyObject *rdnt;\r
-    PyObject *attr = NULL;   /* tuple to hold an attribute */\r
-    int entry_count = X509_NAME_entry_count(xname);\r
-    X509_NAME_ENTRY *entry;\r
-    ASN1_OBJECT *name;\r
-    ASN1_STRING *value;\r
-    int index_counter;\r
-    int rdn_level = -1;\r
-    int retcode;\r
-\r
-    dn = PyList_New(0);\r
-    if (dn == NULL)\r
-        return NULL;\r
-    /* now create another tuple to hold the top-level RDN */\r
-    rdn = PyList_New(0);\r
-    if (rdn == NULL)\r
-        goto fail0;\r
-\r
-    for (index_counter = 0;\r
-         index_counter < entry_count;\r
-         index_counter++)\r
-    {\r
-        entry = X509_NAME_get_entry(xname, index_counter);\r
-\r
-        /* check to see if we've gotten to a new RDN */\r
-        if (rdn_level >= 0) {\r
-            if (rdn_level != entry->set) {\r
-                /* yes, new RDN */\r
-                /* add old RDN to DN */\r
-                rdnt = PyList_AsTuple(rdn);\r
-                Py_DECREF(rdn);\r
-                if (rdnt == NULL)\r
-                    goto fail0;\r
-                retcode = PyList_Append(dn, rdnt);\r
-                Py_DECREF(rdnt);\r
-                if (retcode < 0)\r
-                    goto fail0;\r
-                /* create new RDN */\r
-                rdn = PyList_New(0);\r
-                if (rdn == NULL)\r
-                    goto fail0;\r
-            }\r
-        }\r
-        rdn_level = entry->set;\r
-\r
-        /* now add this attribute to the current RDN */\r
-        name = X509_NAME_ENTRY_get_object(entry);\r
-        value = X509_NAME_ENTRY_get_data(entry);\r
-        attr = _create_tuple_for_attribute(name, value);\r
-        /*\r
-        fprintf(stderr, "RDN level %d, attribute %s: %s\n",\r
-            entry->set,\r
-            PyString_AS_STRING(PyTuple_GET_ITEM(attr, 0)),\r
-            PyString_AS_STRING(PyTuple_GET_ITEM(attr, 1)));\r
-        */\r
-        if (attr == NULL)\r
-            goto fail1;\r
-        retcode = PyList_Append(rdn, attr);\r
-        Py_DECREF(attr);\r
-        if (retcode < 0)\r
-            goto fail1;\r
-    }\r
-    /* now, there's typically a dangling RDN */\r
-    if ((rdn != NULL) && (PyList_Size(rdn) > 0)) {\r
-        rdnt = PyList_AsTuple(rdn);\r
-        Py_DECREF(rdn);\r
-        if (rdnt == NULL)\r
-            goto fail0;\r
-        retcode = PyList_Append(dn, rdnt);\r
-        Py_DECREF(rdnt);\r
-        if (retcode < 0)\r
-            goto fail0;\r
-    }\r
-\r
-    /* convert list to tuple */\r
-    rdnt = PyList_AsTuple(dn);\r
-    Py_DECREF(dn);\r
-    if (rdnt == NULL)\r
-        return NULL;\r
-    return rdnt;\r
-\r
-  fail1:\r
-    Py_XDECREF(rdn);\r
-\r
-  fail0:\r
-    Py_XDECREF(dn);\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-_get_peer_alt_names (X509 *certificate) {\r
-\r
-    /* this code follows the procedure outlined in\r
-       OpenSSL's crypto/x509v3/v3_prn.c:X509v3_EXT_print()\r
-       function to extract the STACK_OF(GENERAL_NAME),\r
-       then iterates through the stack to add the\r
-       names. */\r
-\r
-    int i, j;\r
-    PyObject *peer_alt_names = Py_None;\r
-    PyObject *v, *t;\r
-    X509_EXTENSION *ext = NULL;\r
-    GENERAL_NAMES *names = NULL;\r
-    GENERAL_NAME *name;\r
-    const X509V3_EXT_METHOD *method;\r
-    BIO *biobuf = NULL;\r
-    char buf[2048];\r
-    char *vptr;\r
-    int len;\r
-    /* Issue #2973: ASN1_item_d2i() API changed in OpenSSL 0.9.6m */\r
-#if OPENSSL_VERSION_NUMBER >= 0x009060dfL\r
-    const unsigned char *p;\r
-#else\r
-    unsigned char *p;\r
-#endif\r
-\r
-    if (certificate == NULL)\r
-        return peer_alt_names;\r
-\r
-    /* get a memory buffer */\r
-    biobuf = BIO_new(BIO_s_mem());\r
-\r
-    i = 0;\r
-    while ((i = X509_get_ext_by_NID(\r
-                    certificate, NID_subject_alt_name, i)) >= 0) {\r
-\r
-        if (peer_alt_names == Py_None) {\r
-            peer_alt_names = PyList_New(0);\r
-            if (peer_alt_names == NULL)\r
-                goto fail;\r
-        }\r
-\r
-        /* now decode the altName */\r
-        ext = X509_get_ext(certificate, i);\r
-        if(!(method = X509V3_EXT_get(ext))) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            ERRSTR("No method for internalizing subjectAltName!"));\r
-            goto fail;\r
-        }\r
-\r
-        p = ext->value->data;\r
-        if (method->it)\r
-            names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL,\r
-                                                    &p,\r
-                                                    ext->value->length,\r
-                                                    ASN1_ITEM_ptr(method->it)));\r
-        else\r
-            names = (GENERAL_NAMES*) (method->d2i(NULL,\r
-                                                  &p,\r
-                                                  ext->value->length));\r
-\r
-        for(j = 0; j < sk_GENERAL_NAME_num(names); j++) {\r
-\r
-            /* get a rendering of each name in the set of names */\r
-\r
-            name = sk_GENERAL_NAME_value(names, j);\r
-            if (name->type == GEN_DIRNAME) {\r
-\r
-                /* we special-case DirName as a tuple of tuples of attributes */\r
-\r
-                t = PyTuple_New(2);\r
-                if (t == NULL) {\r
-                    goto fail;\r
-                }\r
-\r
-                v = PyString_FromString("DirName");\r
-                if (v == NULL) {\r
-                    Py_DECREF(t);\r
-                    goto fail;\r
-                }\r
-                PyTuple_SET_ITEM(t, 0, v);\r
-\r
-                v = _create_tuple_for_X509_NAME (name->d.dirn);\r
-                if (v == NULL) {\r
-                    Py_DECREF(t);\r
-                    goto fail;\r
-                }\r
-                PyTuple_SET_ITEM(t, 1, v);\r
-\r
-            } else {\r
-\r
-                /* for everything else, we use the OpenSSL print form */\r
-\r
-                (void) BIO_reset(biobuf);\r
-                GENERAL_NAME_print(biobuf, name);\r
-                len = BIO_gets(biobuf, buf, sizeof(buf)-1);\r
-                if (len < 0) {\r
-                    _setSSLError(NULL, 0, __FILE__, __LINE__);\r
-                    goto fail;\r
-                }\r
-                vptr = strchr(buf, ':');\r
-                if (vptr == NULL)\r
-                    goto fail;\r
-                t = PyTuple_New(2);\r
-                if (t == NULL)\r
-                    goto fail;\r
-                v = PyString_FromStringAndSize(buf, (vptr - buf));\r
-                if (v == NULL) {\r
-                    Py_DECREF(t);\r
-                    goto fail;\r
-                }\r
-                PyTuple_SET_ITEM(t, 0, v);\r
-                v = PyString_FromStringAndSize((vptr + 1), (len - (vptr - buf + 1)));\r
-                if (v == NULL) {\r
-                    Py_DECREF(t);\r
-                    goto fail;\r
-                }\r
-                PyTuple_SET_ITEM(t, 1, v);\r
-            }\r
-\r
-            /* and add that rendering to the list */\r
-\r
-            if (PyList_Append(peer_alt_names, t) < 0) {\r
-                Py_DECREF(t);\r
-                goto fail;\r
-            }\r
-            Py_DECREF(t);\r
-        }\r
-    }\r
-    BIO_free(biobuf);\r
-    if (peer_alt_names != Py_None) {\r
-        v = PyList_AsTuple(peer_alt_names);\r
-        Py_DECREF(peer_alt_names);\r
-        return v;\r
-    } else {\r
-        return peer_alt_names;\r
-    }\r
-\r
-\r
-  fail:\r
-    if (biobuf != NULL)\r
-        BIO_free(biobuf);\r
-\r
-    if (peer_alt_names != Py_None) {\r
-        Py_XDECREF(peer_alt_names);\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-static PyObject *\r
-_decode_certificate (X509 *certificate, int verbose) {\r
-\r
-    PyObject *retval = NULL;\r
-    BIO *biobuf = NULL;\r
-    PyObject *peer;\r
-    PyObject *peer_alt_names = NULL;\r
-    PyObject *issuer;\r
-    PyObject *version;\r
-    PyObject *sn_obj;\r
-    ASN1_INTEGER *serialNumber;\r
-    char buf[2048];\r
-    int len;\r
-    ASN1_TIME *notBefore, *notAfter;\r
-    PyObject *pnotBefore, *pnotAfter;\r
-\r
-    retval = PyDict_New();\r
-    if (retval == NULL)\r
-        return NULL;\r
-\r
-    peer = _create_tuple_for_X509_NAME(\r
-        X509_get_subject_name(certificate));\r
-    if (peer == NULL)\r
-        goto fail0;\r
-    if (PyDict_SetItemString(retval, (const char *) "subject", peer) < 0) {\r
-        Py_DECREF(peer);\r
-        goto fail0;\r
-    }\r
-    Py_DECREF(peer);\r
-\r
-    if (verbose) {\r
-        issuer = _create_tuple_for_X509_NAME(\r
-            X509_get_issuer_name(certificate));\r
-        if (issuer == NULL)\r
-            goto fail0;\r
-        if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) {\r
-            Py_DECREF(issuer);\r
-            goto fail0;\r
-        }\r
-        Py_DECREF(issuer);\r
-\r
-        version = PyInt_FromLong(X509_get_version(certificate) + 1);\r
-        if (PyDict_SetItemString(retval, "version", version) < 0) {\r
-            Py_DECREF(version);\r
-            goto fail0;\r
-        }\r
-        Py_DECREF(version);\r
-    }\r
-\r
-    /* get a memory buffer */\r
-    biobuf = BIO_new(BIO_s_mem());\r
-\r
-    if (verbose) {\r
-\r
-        (void) BIO_reset(biobuf);\r
-        serialNumber = X509_get_serialNumber(certificate);\r
-        /* should not exceed 20 octets, 160 bits, so buf is big enough */\r
-        i2a_ASN1_INTEGER(biobuf, serialNumber);\r
-        len = BIO_gets(biobuf, buf, sizeof(buf)-1);\r
-        if (len < 0) {\r
-            _setSSLError(NULL, 0, __FILE__, __LINE__);\r
-            goto fail1;\r
-        }\r
-        sn_obj = PyString_FromStringAndSize(buf, len);\r
-        if (sn_obj == NULL)\r
-            goto fail1;\r
-        if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) {\r
-            Py_DECREF(sn_obj);\r
-            goto fail1;\r
-        }\r
-        Py_DECREF(sn_obj);\r
-\r
-        (void) BIO_reset(biobuf);\r
-        notBefore = X509_get_notBefore(certificate);\r
-        ASN1_TIME_print(biobuf, notBefore);\r
-        len = BIO_gets(biobuf, buf, sizeof(buf)-1);\r
-        if (len < 0) {\r
-            _setSSLError(NULL, 0, __FILE__, __LINE__);\r
-            goto fail1;\r
-        }\r
-        pnotBefore = PyString_FromStringAndSize(buf, len);\r
-        if (pnotBefore == NULL)\r
-            goto fail1;\r
-        if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) {\r
-            Py_DECREF(pnotBefore);\r
-            goto fail1;\r
-        }\r
-        Py_DECREF(pnotBefore);\r
-    }\r
-\r
-    (void) BIO_reset(biobuf);\r
-    notAfter = X509_get_notAfter(certificate);\r
-    ASN1_TIME_print(biobuf, notAfter);\r
-    len = BIO_gets(biobuf, buf, sizeof(buf)-1);\r
-    if (len < 0) {\r
-        _setSSLError(NULL, 0, __FILE__, __LINE__);\r
-        goto fail1;\r
-    }\r
-    pnotAfter = PyString_FromStringAndSize(buf, len);\r
-    if (pnotAfter == NULL)\r
-        goto fail1;\r
-    if (PyDict_SetItemString(retval, "notAfter", pnotAfter) < 0) {\r
-        Py_DECREF(pnotAfter);\r
-        goto fail1;\r
-    }\r
-    Py_DECREF(pnotAfter);\r
-\r
-    /* Now look for subjectAltName */\r
-\r
-    peer_alt_names = _get_peer_alt_names(certificate);\r
-    if (peer_alt_names == NULL)\r
-        goto fail1;\r
-    else if (peer_alt_names != Py_None) {\r
-        if (PyDict_SetItemString(retval, "subjectAltName",\r
-                                 peer_alt_names) < 0) {\r
-            Py_DECREF(peer_alt_names);\r
-            goto fail1;\r
-        }\r
-        Py_DECREF(peer_alt_names);\r
-    }\r
-\r
-    BIO_free(biobuf);\r
-    return retval;\r
-\r
-  fail1:\r
-    if (biobuf != NULL)\r
-        BIO_free(biobuf);\r
-  fail0:\r
-    Py_XDECREF(retval);\r
-    return NULL;\r
-}\r
-\r
-\r
-static PyObject *\r
-PySSL_test_decode_certificate (PyObject *mod, PyObject *args) {\r
-\r
-    PyObject *retval = NULL;\r
-    char *filename = NULL;\r
-    X509 *x=NULL;\r
-    BIO *cert;\r
-    int verbose = 1;\r
-\r
-    if (!PyArg_ParseTuple(args, "s|i:test_decode_certificate", &filename, &verbose))\r
-        return NULL;\r
-\r
-    if ((cert=BIO_new(BIO_s_file())) == NULL) {\r
-        PyErr_SetString(PySSLErrorObject, "Can't malloc memory to read file");\r
-        goto fail0;\r
-    }\r
-\r
-    if (BIO_read_filename(cert,filename) <= 0) {\r
-        PyErr_SetString(PySSLErrorObject, "Can't open file");\r
-        goto fail0;\r
-    }\r
-\r
-    x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL);\r
-    if (x == NULL) {\r
-        PyErr_SetString(PySSLErrorObject, "Error decoding PEM-encoded file");\r
-        goto fail0;\r
-    }\r
-\r
-    retval = _decode_certificate(x, verbose);\r
-    X509_free(x);\r
-\r
-  fail0:\r
-\r
-    if (cert != NULL) BIO_free(cert);\r
-    return retval;\r
-}\r
-\r
-\r
-static PyObject *\r
-PySSL_peercert(PySSLObject *self, PyObject *args)\r
-{\r
-    PyObject *retval = NULL;\r
-    int len;\r
-    int verification;\r
-    PyObject *binary_mode = Py_None;\r
-\r
-    if (!PyArg_ParseTuple(args, "|O:peer_certificate", &binary_mode))\r
-        return NULL;\r
-\r
-    if (!self->peer_cert)\r
-        Py_RETURN_NONE;\r
-\r
-    if (PyObject_IsTrue(binary_mode)) {\r
-        /* return cert in DER-encoded format */\r
-\r
-        unsigned char *bytes_buf = NULL;\r
-\r
-        bytes_buf = NULL;\r
-        len = i2d_X509(self->peer_cert, &bytes_buf);\r
-        if (len < 0) {\r
-            PySSL_SetError(self, len, __FILE__, __LINE__);\r
-            return NULL;\r
-        }\r
-        retval = PyString_FromStringAndSize((const char *) bytes_buf, len);\r
-        OPENSSL_free(bytes_buf);\r
-        return retval;\r
-\r
-    } else {\r
-\r
-        verification = SSL_CTX_get_verify_mode(self->ctx);\r
-        if ((verification & SSL_VERIFY_PEER) == 0)\r
-            return PyDict_New();\r
-        else\r
-            return _decode_certificate (self->peer_cert, 0);\r
-    }\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_peercert_doc,\r
-"peer_certificate([der=False]) -> certificate\n\\r
-\n\\r
-Returns the certificate for the peer.  If no certificate was provided,\n\\r
-returns None.  If a certificate was provided, but not validated, returns\n\\r
-an empty dictionary.  Otherwise returns a dict containing information\n\\r
-about the peer certificate.\n\\r
-\n\\r
-If the optional argument is True, returns a DER-encoded copy of the\n\\r
-peer certificate, or None if no certificate was provided.  This will\n\\r
-return the certificate even if it wasn't validated.");\r
-\r
-static PyObject *PySSL_cipher (PySSLObject *self) {\r
-\r
-    PyObject *retval, *v;\r
-    const SSL_CIPHER *current;\r
-    char *cipher_name;\r
-    char *cipher_protocol;\r
-\r
-    if (self->ssl == NULL)\r
-        Py_RETURN_NONE;\r
-    current = SSL_get_current_cipher(self->ssl);\r
-    if (current == NULL)\r
-        Py_RETURN_NONE;\r
-\r
-    retval = PyTuple_New(3);\r
-    if (retval == NULL)\r
-        return NULL;\r
-\r
-    cipher_name = (char *) SSL_CIPHER_get_name(current);\r
-    if (cipher_name == NULL) {\r
-        Py_INCREF(Py_None);\r
-        PyTuple_SET_ITEM(retval, 0, Py_None);\r
-    } else {\r
-        v = PyString_FromString(cipher_name);\r
-        if (v == NULL)\r
-            goto fail0;\r
-        PyTuple_SET_ITEM(retval, 0, v);\r
-    }\r
-    cipher_protocol = SSL_CIPHER_get_version(current);\r
-    if (cipher_protocol == NULL) {\r
-        Py_INCREF(Py_None);\r
-        PyTuple_SET_ITEM(retval, 1, Py_None);\r
-    } else {\r
-        v = PyString_FromString(cipher_protocol);\r
-        if (v == NULL)\r
-            goto fail0;\r
-        PyTuple_SET_ITEM(retval, 1, v);\r
-    }\r
-    v = PyInt_FromLong(SSL_CIPHER_get_bits(current, NULL));\r
-    if (v == NULL)\r
-        goto fail0;\r
-    PyTuple_SET_ITEM(retval, 2, v);\r
-    return retval;\r
-\r
-  fail0:\r
-    Py_DECREF(retval);\r
-    return NULL;\r
-}\r
-\r
-static void PySSL_dealloc(PySSLObject *self)\r
-{\r
-    if (self->peer_cert)        /* Possible not to have one? */\r
-        X509_free (self->peer_cert);\r
-    if (self->ssl)\r
-        SSL_free(self->ssl);\r
-    if (self->ctx)\r
-        SSL_CTX_free(self->ctx);\r
-    Py_XDECREF(self->Socket);\r
-    PyObject_Del(self);\r
-}\r
-\r
-/* If the socket has a timeout, do a select()/poll() on the socket.\r
-   The argument writing indicates the direction.\r
-   Returns one of the possibilities in the timeout_state enum (above).\r
- */\r
-\r
-static int\r
-check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)\r
-{\r
-    fd_set fds;\r
-    struct timeval tv;\r
-    int rc;\r
-\r
-    /* Nothing to do unless we're in timeout mode (not non-blocking) */\r
-    if (s->sock_timeout < 0.0)\r
-        return SOCKET_IS_BLOCKING;\r
-    else if (s->sock_timeout == 0.0)\r
-        return SOCKET_IS_NONBLOCKING;\r
-\r
-    /* Guard against closed socket */\r
-    if (s->sock_fd < 0)\r
-        return SOCKET_HAS_BEEN_CLOSED;\r
-\r
-    /* Prefer poll, if available, since you can poll() any fd\r
-     * which can't be done with select(). */\r
-#ifdef HAVE_POLL\r
-    {\r
-        struct pollfd pollfd;\r
-        int timeout;\r
-\r
-        pollfd.fd = s->sock_fd;\r
-        pollfd.events = writing ? POLLOUT : POLLIN;\r
-\r
-        /* s->sock_timeout is in seconds, timeout in ms */\r
-        timeout = (int)(s->sock_timeout * 1000 + 0.5);\r
-        PySSL_BEGIN_ALLOW_THREADS\r
-        rc = poll(&pollfd, 1, timeout);\r
-        PySSL_END_ALLOW_THREADS\r
-\r
-        goto normal_return;\r
-    }\r
-#endif\r
-\r
-    /* Guard against socket too large for select*/\r
-#ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE\r
-    if (s->sock_fd >= FD_SETSIZE)\r
-        return SOCKET_TOO_LARGE_FOR_SELECT;\r
-#endif\r
-\r
-    /* Construct the arguments to select */\r
-    tv.tv_sec = (int)s->sock_timeout;\r
-    tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);\r
-    FD_ZERO(&fds);\r
-    FD_SET(s->sock_fd, &fds);\r
-\r
-    /* See if the socket is ready */\r
-    PySSL_BEGIN_ALLOW_THREADS\r
-    if (writing)\r
-        rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv);\r
-    else\r
-        rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);\r
-    PySSL_END_ALLOW_THREADS\r
-\r
-#ifdef HAVE_POLL\r
-normal_return:\r
-#endif\r
-    /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise\r
-       (when we are able to write or when there's something to read) */\r
-    return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK;\r
-}\r
-\r
-static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)\r
-{\r
-    Py_buffer buf;\r
-    int len;\r
-    int sockstate;\r
-    int err;\r
-    int nonblocking;\r
-\r
-    if (!PyArg_ParseTuple(args, "s*:write", &buf))\r
-        return NULL;\r
-\r
-    /* just in case the blocking state of the socket has been changed */\r
-    nonblocking = (self->Socket->sock_timeout >= 0.0);\r
-    BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);\r
-    BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);\r
-\r
-    sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);\r
-    if (sockstate == SOCKET_HAS_TIMED_OUT) {\r
-        PyErr_SetString(PySSLErrorObject,\r
-                        "The write operation timed out");\r
-        goto error;\r
-    } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {\r
-        PyErr_SetString(PySSLErrorObject,\r
-                        "Underlying socket has been closed.");\r
-        goto error;\r
-    } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {\r
-        PyErr_SetString(PySSLErrorObject,\r
-                        "Underlying socket too large for select().");\r
-        goto error;\r
-    }\r
-    do {\r
-        PySSL_BEGIN_ALLOW_THREADS\r
-        len = SSL_write(self->ssl, buf.buf, buf.len);\r
-        err = SSL_get_error(self->ssl, len);\r
-        PySSL_END_ALLOW_THREADS\r
-        if (PyErr_CheckSignals()) {\r
-            goto error;\r
-        }\r
-        if (err == SSL_ERROR_WANT_READ) {\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);\r
-        } else if (err == SSL_ERROR_WANT_WRITE) {\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);\r
-        } else {\r
-            sockstate = SOCKET_OPERATION_OK;\r
-        }\r
-        if (sockstate == SOCKET_HAS_TIMED_OUT) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            "The write operation timed out");\r
-            goto error;\r
-        } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            "Underlying socket has been closed.");\r
-            goto error;\r
-        } else if (sockstate == SOCKET_IS_NONBLOCKING) {\r
-            break;\r
-        }\r
-    } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);\r
-\r
-    PyBuffer_Release(&buf);\r
-    if (len > 0)\r
-        return PyInt_FromLong(len);\r
-    else\r
-        return PySSL_SetError(self, len, __FILE__, __LINE__);\r
-\r
-error:\r
-    PyBuffer_Release(&buf);\r
-    return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_SSLwrite_doc,\r
-"write(s) -> len\n\\r
-\n\\r
-Writes the string s into the SSL object.  Returns the number\n\\r
-of bytes written.");\r
-\r
-static PyObject *PySSL_SSLpending(PySSLObject *self)\r
-{\r
-    int count = 0;\r
-\r
-    PySSL_BEGIN_ALLOW_THREADS\r
-    count = SSL_pending(self->ssl);\r
-    PySSL_END_ALLOW_THREADS\r
-    if (count < 0)\r
-        return PySSL_SetError(self, count, __FILE__, __LINE__);\r
-    else\r
-        return PyInt_FromLong(count);\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_SSLpending_doc,\r
-"pending() -> count\n\\r
-\n\\r
-Returns the number of already decrypted bytes available for read,\n\\r
-pending on the connection.\n");\r
-\r
-static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)\r
-{\r
-    PyObject *buf;\r
-    int count = 0;\r
-    int len = 1024;\r
-    int sockstate;\r
-    int err;\r
-    int nonblocking;\r
-\r
-    if (!PyArg_ParseTuple(args, "|i:read", &len))\r
-        return NULL;\r
-\r
-    if (!(buf = PyString_FromStringAndSize((char *) 0, len)))\r
-        return NULL;\r
-\r
-    /* just in case the blocking state of the socket has been changed */\r
-    nonblocking = (self->Socket->sock_timeout >= 0.0);\r
-    BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);\r
-    BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);\r
-\r
-    /* first check if there are bytes ready to be read */\r
-    PySSL_BEGIN_ALLOW_THREADS\r
-    count = SSL_pending(self->ssl);\r
-    PySSL_END_ALLOW_THREADS\r
-\r
-    if (!count) {\r
-        sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);\r
-        if (sockstate == SOCKET_HAS_TIMED_OUT) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            "The read operation timed out");\r
-            Py_DECREF(buf);\r
-            return NULL;\r
-        } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            "Underlying socket too large for select().");\r
-            Py_DECREF(buf);\r
-            return NULL;\r
-        } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {\r
-            if (SSL_get_shutdown(self->ssl) !=\r
-                SSL_RECEIVED_SHUTDOWN)\r
-            {\r
-                Py_DECREF(buf);\r
-                PyErr_SetString(PySSLErrorObject,\r
-                                "Socket closed without SSL shutdown handshake");\r
-                return NULL;\r
-            } else {\r
-                /* should contain a zero-length string */\r
-                _PyString_Resize(&buf, 0);\r
-                return buf;\r
-            }\r
-        }\r
-    }\r
-    do {\r
-        PySSL_BEGIN_ALLOW_THREADS\r
-        count = SSL_read(self->ssl, PyString_AsString(buf), len);\r
-        err = SSL_get_error(self->ssl, count);\r
-        PySSL_END_ALLOW_THREADS\r
-        if(PyErr_CheckSignals()) {\r
-            Py_DECREF(buf);\r
-            return NULL;\r
-        }\r
-        if (err == SSL_ERROR_WANT_READ) {\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);\r
-        } else if (err == SSL_ERROR_WANT_WRITE) {\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);\r
-        } else if ((err == SSL_ERROR_ZERO_RETURN) &&\r
-                   (SSL_get_shutdown(self->ssl) ==\r
-                    SSL_RECEIVED_SHUTDOWN))\r
-        {\r
-            _PyString_Resize(&buf, 0);\r
-            return buf;\r
-        } else {\r
-            sockstate = SOCKET_OPERATION_OK;\r
-        }\r
-        if (sockstate == SOCKET_HAS_TIMED_OUT) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            "The read operation timed out");\r
-            Py_DECREF(buf);\r
-            return NULL;\r
-        } else if (sockstate == SOCKET_IS_NONBLOCKING) {\r
-            break;\r
-        }\r
-    } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);\r
-    if (count <= 0) {\r
-        Py_DECREF(buf);\r
-        return PySSL_SetError(self, count, __FILE__, __LINE__);\r
-    }\r
-    if (count != len)\r
-        _PyString_Resize(&buf, count);\r
-    return buf;\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_SSLread_doc,\r
-"read([len]) -> string\n\\r
-\n\\r
-Read up to len bytes from the SSL socket.");\r
-\r
-static PyObject *PySSL_SSLshutdown(PySSLObject *self)\r
-{\r
-    int err, ssl_err, sockstate, nonblocking;\r
-    int zeros = 0;\r
-\r
-    /* Guard against closed socket */\r
-    if (self->Socket->sock_fd < 0) {\r
-        PyErr_SetString(PySSLErrorObject,\r
-                        "Underlying socket has been closed.");\r
-        return NULL;\r
-    }\r
-\r
-    /* Just in case the blocking state of the socket has been changed */\r
-    nonblocking = (self->Socket->sock_timeout >= 0.0);\r
-    BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);\r
-    BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);\r
-\r
-    while (1) {\r
-        PySSL_BEGIN_ALLOW_THREADS\r
-        /* Disable read-ahead so that unwrap can work correctly.\r
-         * Otherwise OpenSSL might read in too much data,\r
-         * eating clear text data that happens to be\r
-         * transmitted after the SSL shutdown.\r
-         * Should be safe to call repeatedly everytime this\r
-         * function is used and the shutdown_seen_zero != 0\r
-         * condition is met.\r
-         */\r
-        if (self->shutdown_seen_zero)\r
-            SSL_set_read_ahead(self->ssl, 0);\r
-        err = SSL_shutdown(self->ssl);\r
-        PySSL_END_ALLOW_THREADS\r
-        /* If err == 1, a secure shutdown with SSL_shutdown() is complete */\r
-        if (err > 0)\r
-            break;\r
-        if (err == 0) {\r
-            /* Don't loop endlessly; instead preserve legacy\r
-               behaviour of trying SSL_shutdown() only twice.\r
-               This looks necessary for OpenSSL < 0.9.8m */\r
-            if (++zeros > 1)\r
-                break;\r
-            /* Shutdown was sent, now try receiving */\r
-            self->shutdown_seen_zero = 1;\r
-            continue;\r
-        }\r
-\r
-        /* Possibly retry shutdown until timeout or failure */\r
-        ssl_err = SSL_get_error(self->ssl, err);\r
-        if (ssl_err == SSL_ERROR_WANT_READ)\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);\r
-        else if (ssl_err == SSL_ERROR_WANT_WRITE)\r
-            sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);\r
-        else\r
-            break;\r
-        if (sockstate == SOCKET_HAS_TIMED_OUT) {\r
-            if (ssl_err == SSL_ERROR_WANT_READ)\r
-                PyErr_SetString(PySSLErrorObject,\r
-                                "The read operation timed out");\r
-            else\r
-                PyErr_SetString(PySSLErrorObject,\r
-                                "The write operation timed out");\r
-            return NULL;\r
-        }\r
-        else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {\r
-            PyErr_SetString(PySSLErrorObject,\r
-                            "Underlying socket too large for select().");\r
-            return NULL;\r
-        }\r
-        else if (sockstate != SOCKET_OPERATION_OK)\r
-            /* Retain the SSL error code */\r
-            break;\r
-    }\r
-\r
-    if (err < 0)\r
-        return PySSL_SetError(self, err, __FILE__, __LINE__);\r
-    else {\r
-        Py_INCREF(self->Socket);\r
-        return (PyObject *) (self->Socket);\r
-    }\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_SSLshutdown_doc,\r
-"shutdown(s) -> socket\n\\r
-\n\\r
-Does the SSL shutdown handshake with the remote end, and returns\n\\r
-the underlying socket object.");\r
-\r
-static PyMethodDef PySSLMethods[] = {\r
-    {"do_handshake", (PyCFunction)PySSL_SSLdo_handshake, METH_NOARGS},\r
-    {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,\r
-     PySSL_SSLwrite_doc},\r
-    {"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,\r
-     PySSL_SSLread_doc},\r
-    {"pending", (PyCFunction)PySSL_SSLpending, METH_NOARGS,\r
-     PySSL_SSLpending_doc},\r
-    {"server", (PyCFunction)PySSL_server, METH_NOARGS},\r
-    {"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},\r
-    {"peer_certificate", (PyCFunction)PySSL_peercert, METH_VARARGS,\r
-     PySSL_peercert_doc},\r
-    {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS},\r
-    {"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS,\r
-     PySSL_SSLshutdown_doc},\r
-    {NULL, NULL}\r
-};\r
-\r
-static PyObject *PySSL_getattr(PySSLObject *self, char *name)\r
-{\r
-    return Py_FindMethod(PySSLMethods, (PyObject *)self, name);\r
-}\r
-\r
-static PyTypeObject PySSL_Type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "ssl.SSLContext",                   /*tp_name*/\r
-    sizeof(PySSLObject),                /*tp_basicsize*/\r
-    0,                                  /*tp_itemsize*/\r
-    /* methods */\r
-    (destructor)PySSL_dealloc,          /*tp_dealloc*/\r
-    0,                                  /*tp_print*/\r
-    (getattrfunc)PySSL_getattr,         /*tp_getattr*/\r
-    0,                                  /*tp_setattr*/\r
-    0,                                  /*tp_compare*/\r
-    0,                                  /*tp_repr*/\r
-    0,                                  /*tp_as_number*/\r
-    0,                                  /*tp_as_sequence*/\r
-    0,                                  /*tp_as_mapping*/\r
-    0,                                  /*tp_hash*/\r
-};\r
-\r
-#ifdef HAVE_OPENSSL_RAND\r
-\r
-/* helper routines for seeding the SSL PRNG */\r
-static PyObject *\r
-PySSL_RAND_add(PyObject *self, PyObject *args)\r
-{\r
-    char *buf;\r
-    int len;\r
-    double entropy;\r
-\r
-    if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy))\r
-        return NULL;\r
-    RAND_add(buf, len, entropy);\r
-    Py_INCREF(Py_None);\r
-    return Py_None;\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_RAND_add_doc,\r
-"RAND_add(string, entropy)\n\\r
-\n\\r
-Mix string into the OpenSSL PRNG state.  entropy (a float) is a lower\n\\r
-bound on the entropy contained in string.  See RFC 1750.");\r
-\r
-static PyObject *\r
-PySSL_RAND_status(PyObject *self)\r
-{\r
-    return PyInt_FromLong(RAND_status());\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_RAND_status_doc,\r
-"RAND_status() -> 0 or 1\n\\r
-\n\\r
-Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\\r
-It is necessary to seed the PRNG with RAND_add() on some platforms before\n\\r
-using the ssl() function.");\r
-\r
-static PyObject *\r
-PySSL_RAND_egd(PyObject *self, PyObject *arg)\r
-{\r
-    int bytes;\r
-\r
-    if (!PyString_Check(arg))\r
-        return PyErr_Format(PyExc_TypeError,\r
-                            "RAND_egd() expected string, found %s",\r
-                            Py_TYPE(arg)->tp_name);\r
-    bytes = RAND_egd(PyString_AS_STRING(arg));\r
-    if (bytes == -1) {\r
-        PyErr_SetString(PySSLErrorObject,\r
-                        "EGD connection failed or EGD did not return "\r
-                        "enough data to seed the PRNG");\r
-        return NULL;\r
-    }\r
-    return PyInt_FromLong(bytes);\r
-}\r
-\r
-PyDoc_STRVAR(PySSL_RAND_egd_doc,\r
-"RAND_egd(path) -> bytes\n\\r
-\n\\r
-Queries the entropy gather daemon (EGD) on the socket named by 'path'.\n\\r
-Returns number of bytes read.  Raises SSLError if connection to EGD\n\\r
-fails or if it does provide enough data to seed PRNG.");\r
-\r
-#endif\r
-\r
-/* List of functions exported by this module. */\r
-\r
-static PyMethodDef PySSL_methods[] = {\r
-    {"sslwrap",             PySSL_sslwrap,\r
-     METH_VARARGS, ssl_doc},\r
-    {"_test_decode_cert",       PySSL_test_decode_certificate,\r
-     METH_VARARGS},\r
-#ifdef HAVE_OPENSSL_RAND\r
-    {"RAND_add",            PySSL_RAND_add, METH_VARARGS,\r
-     PySSL_RAND_add_doc},\r
-    {"RAND_egd",            PySSL_RAND_egd, METH_O,\r
-     PySSL_RAND_egd_doc},\r
-    {"RAND_status",         (PyCFunction)PySSL_RAND_status, METH_NOARGS,\r
-     PySSL_RAND_status_doc},\r
-#endif\r
-    {NULL,                  NULL}            /* Sentinel */\r
-};\r
-\r
-\r
-#ifdef WITH_THREAD\r
-\r
-/* an implementation of OpenSSL threading operations in terms\r
-   of the Python C thread library */\r
-\r
-static PyThread_type_lock *_ssl_locks = NULL;\r
-\r
-static unsigned long _ssl_thread_id_function (void) {\r
-    return PyThread_get_thread_ident();\r
-}\r
-\r
-static void _ssl_thread_locking_function (int mode, int n, const char *file, int line) {\r
-    /* this function is needed to perform locking on shared data\r
-       structures. (Note that OpenSSL uses a number of global data\r
-       structures that will be implicitly shared whenever multiple threads\r
-       use OpenSSL.) Multi-threaded applications will crash at random if\r
-       it is not set.\r
-\r
-       locking_function() must be able to handle up to CRYPTO_num_locks()\r
-       different mutex locks. It sets the n-th lock if mode & CRYPTO_LOCK, and\r
-       releases it otherwise.\r
-\r
-       file and line are the file number of the function setting the\r
-       lock. They can be useful for debugging.\r
-    */\r
-\r
-    if ((_ssl_locks == NULL) ||\r
-        (n < 0) || ((unsigned)n >= _ssl_locks_count))\r
-        return;\r
-\r
-    if (mode & CRYPTO_LOCK) {\r
-        PyThread_acquire_lock(_ssl_locks[n], 1);\r
-    } else {\r
-        PyThread_release_lock(_ssl_locks[n]);\r
-    }\r
-}\r
-\r
-static int _setup_ssl_threads(void) {\r
-\r
-    unsigned int i;\r
-\r
-    if (_ssl_locks == NULL) {\r
-        _ssl_locks_count = CRYPTO_num_locks();\r
-        _ssl_locks = (PyThread_type_lock *)\r
-            malloc(sizeof(PyThread_type_lock) * _ssl_locks_count);\r
-        if (_ssl_locks == NULL)\r
-            return 0;\r
-        memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count);\r
-        for (i = 0;  i < _ssl_locks_count;  i++) {\r
-            _ssl_locks[i] = PyThread_allocate_lock();\r
-            if (_ssl_locks[i] == NULL) {\r
-                unsigned int j;\r
-                for (j = 0;  j < i;  j++) {\r
-                    PyThread_free_lock(_ssl_locks[j]);\r
-                }\r
-                free(_ssl_locks);\r
-                return 0;\r
-            }\r
-        }\r
-        CRYPTO_set_locking_callback(_ssl_thread_locking_function);\r
-        CRYPTO_set_id_callback(_ssl_thread_id_function);\r
-    }\r
-    return 1;\r
-}\r
-\r
-#endif  /* def HAVE_THREAD */\r
-\r
-PyDoc_STRVAR(module_doc,\r
-"Implementation module for SSL socket operations.  See the socket module\n\\r
-for documentation.");\r
-\r
-PyMODINIT_FUNC\r
-init_ssl(void)\r
-{\r
-    PyObject *m, *d, *r;\r
-    unsigned long libver;\r
-    unsigned int major, minor, fix, patch, status;\r
-\r
-    Py_TYPE(&PySSL_Type) = &PyType_Type;\r
-\r
-    m = Py_InitModule3("_ssl", PySSL_methods, module_doc);\r
-    if (m == NULL)\r
-        return;\r
-    d = PyModule_GetDict(m);\r
-\r
-    /* Load _socket module and its C API */\r
-    if (PySocketModule_ImportModuleAndAPI())\r
-        return;\r
-\r
-    /* Init OpenSSL */\r
-    SSL_load_error_strings();\r
-    SSL_library_init();\r
-#ifdef WITH_THREAD\r
-    /* note that this will start threading if not already started */\r
-    if (!_setup_ssl_threads()) {\r
-        return;\r
-    }\r
-#endif\r
-    OpenSSL_add_all_algorithms();\r
-\r
-    /* Add symbols to module dict */\r
-    PySSLErrorObject = PyErr_NewException("ssl.SSLError",\r
-                                          PySocketModule.error,\r
-                                          NULL);\r
-    if (PySSLErrorObject == NULL)\r
-        return;\r
-    if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0)\r
-        return;\r
-    if (PyDict_SetItemString(d, "SSLType",\r
-                             (PyObject *)&PySSL_Type) != 0)\r
-        return;\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",\r
-                            PY_SSL_ERROR_ZERO_RETURN);\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",\r
-                            PY_SSL_ERROR_WANT_READ);\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",\r
-                            PY_SSL_ERROR_WANT_WRITE);\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",\r
-                            PY_SSL_ERROR_WANT_X509_LOOKUP);\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",\r
-                            PY_SSL_ERROR_SYSCALL);\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_SSL",\r
-                            PY_SSL_ERROR_SSL);\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",\r
-                            PY_SSL_ERROR_WANT_CONNECT);\r
-    /* non ssl.h errorcodes */\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_EOF",\r
-                            PY_SSL_ERROR_EOF);\r
-    PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",\r
-                            PY_SSL_ERROR_INVALID_ERROR_CODE);\r
-    /* cert requirements */\r
-    PyModule_AddIntConstant(m, "CERT_NONE",\r
-                            PY_SSL_CERT_NONE);\r
-    PyModule_AddIntConstant(m, "CERT_OPTIONAL",\r
-                            PY_SSL_CERT_OPTIONAL);\r
-    PyModule_AddIntConstant(m, "CERT_REQUIRED",\r
-                            PY_SSL_CERT_REQUIRED);\r
-\r
-    /* protocol versions */\r
-#ifndef OPENSSL_NO_SSL2\r
-    PyModule_AddIntConstant(m, "PROTOCOL_SSLv2",\r
-                            PY_SSL_VERSION_SSL2);\r
-#endif\r
-    PyModule_AddIntConstant(m, "PROTOCOL_SSLv3",\r
-                            PY_SSL_VERSION_SSL3);\r
-    PyModule_AddIntConstant(m, "PROTOCOL_SSLv23",\r
-                            PY_SSL_VERSION_SSL23);\r
-    PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",\r
-                            PY_SSL_VERSION_TLS1);\r
-\r
-    /* OpenSSL version */\r
-    /* SSLeay() gives us the version of the library linked against,\r
-       which could be different from the headers version.\r
-    */\r
-    libver = SSLeay();\r
-    r = PyLong_FromUnsignedLong(libver);\r
-    if (r == NULL)\r
-        return;\r
-    if (PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r))\r
-        return;\r
-    status = libver & 0xF;\r
-    libver >>= 4;\r
-    patch = libver & 0xFF;\r
-    libver >>= 8;\r
-    fix = libver & 0xFF;\r
-    libver >>= 8;\r
-    minor = libver & 0xFF;\r
-    libver >>= 8;\r
-    major = libver & 0xFF;\r
-    r = Py_BuildValue("IIIII", major, minor, fix, patch, status);\r
-    if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r))\r
-        return;\r
-    r = PyString_FromString(SSLeay_version(SSLEAY_VERSION));\r
-    if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r))\r
-        return;\r
-}\r