/* * ssl.c * * Copyright (C) AB Strakt * Copyright (C) Jean-Paul Calderone * See LICENSE for details. * * Main file of the SSL sub module. * See the file RATIONALE for a short explanation of why this module was written. * * Reviewed 2001-07-23 */ #include #ifndef MS_WINDOWS # include # include # if !(defined(__BEOS__) || defined(__CYGWIN__)) # include # endif #else # include # include #endif #define SSL_MODULE #include "ssl.h" static char ssl_doc[] = "\n\ Main file of the SSL sub module.\n\ See the file RATIONALE for a short explanation of why this module was written.\n\ "; crypto_X509Obj* (*new_x509)(X509*, int); crypto_X509NameObj* (*new_x509name)(X509_NAME*, int); crypto_X509StoreObj* (*new_x509store)(X509_STORE*, int); #ifndef PY3 void **crypto_API; #endif int _pyOpenSSL_tstate_key; /* Exceptions defined by the SSL submodule */ PyObject *ssl_Error, /* Base class */ *ssl_ZeroReturnError, /* Used with SSL_get_error */ *ssl_WantReadError, /* ... */ *ssl_WantWriteError, /* ... */ *ssl_WantX509LookupError, /* ... */ *ssl_SysCallError; /* Uses (errno,errstr) */ static char ssl_SSLeay_version_doc[] = "\n\ Return a string describing the version of OpenSSL in use.\n\ \n\ :param type: One of the SSLEAY_ constants defined in this module.\n\ "; static PyObject * ssl_SSLeay_version(PyObject *spam, PyObject *args) { int t; const char *version; if (!PyArg_ParseTuple(args, "i:SSLeay_version", &t)) { return NULL; } version = SSLeay_version(t); return PyBytes_FromStringAndSize(version, strlen(version)); } /* Methods in the OpenSSL.SSL module */ static PyMethodDef ssl_methods[] = { { "SSLeay_version", ssl_SSLeay_version, METH_VARARGS, ssl_SSLeay_version_doc }, { NULL, NULL } }; #ifdef PY3 static struct PyModuleDef sslmodule = { PyModuleDef_HEAD_INIT, "SSL", ssl_doc, -1, ssl_methods }; #endif /* * Initialize SSL sub module * * Arguments: None * Returns: None */ PyOpenSSL_MODINIT(SSL) { PyObject *module; #ifndef PY3 static void *ssl_API[ssl_API_pointers]; PyObject *ssl_api_object; import_crypto(); new_x509 = crypto_X509_New; new_x509name = crypto_X509Name_New; new_x509store = crypto_X509Store_New; #else # ifdef _WIN32 HMODULE crypto = GetModuleHandle("crypto.pyd"); if (crypto == NULL) { PyErr_SetString(PyExc_RuntimeError, "Unable to get crypto module"); PyOpenSSL_MODRETURN(NULL); } new_x509 = (crypto_X509Obj* (*)(X509*, int))GetProcAddress(crypto, "crypto_X509_New"); new_x509name = (crypto_X509NameObj* (*)(X509_NAME*, int))GetProcAddress(crypto, "crypto_X509Name_New"); new_x509store = (crypto_X509StoreObj* (*)(X509_STORE*, int))GetProcAddress(crypto, "crypto_X509Store_New"); # else new_x509 = crypto_X509_New; new_x509name = crypto_X509Name_New; new_x509store = crypto_X509Store_New; # endif #endif SSL_library_init(); ERR_load_SSL_strings(); #ifdef PY3 module = PyModule_Create(&sslmodule); #else module = Py_InitModule3("SSL", ssl_methods, ssl_doc); #endif if (module == NULL) { PyOpenSSL_MODRETURN(NULL); } #ifndef PY3 /* Initialize the C API pointer array */ ssl_API[ssl_Context_New_NUM] = (void *)ssl_Context_New; ssl_API[ssl_Connection_New_NUM] = (void *)ssl_Connection_New; ssl_api_object = PyCObject_FromVoidPtr((void *)ssl_API, NULL); if (ssl_api_object != NULL) { /* PyModule_AddObject steals a reference. */ Py_INCREF(ssl_api_object); PyModule_AddObject(module, "_C_API", ssl_api_object); } #endif /* Exceptions */ /* * ADD_EXCEPTION(dict,name,base) expands to a correct Exception declaration, * inserting OpenSSL.SSL.name into dict, derviving the exception from base. */ #define ADD_EXCEPTION(_name, _base) \ do { \ ssl_##_name = PyErr_NewException("OpenSSL.SSL."#_name, _base, NULL);\ if (ssl_##_name == NULL) \ goto error; \ /* PyModule_AddObject steals a reference. */ \ Py_INCREF(ssl_##_name); \ if (PyModule_AddObject(module, #_name, ssl_##_name) != 0) \ goto error; \ } while (0) ssl_Error = PyErr_NewException("OpenSSL.SSL.Error", NULL, NULL); if (ssl_Error == NULL) { goto error; } /* PyModule_AddObject steals a reference. */ Py_INCREF(ssl_Error); if (PyModule_AddObject(module, "Error", ssl_Error) != 0) goto error; ADD_EXCEPTION(ZeroReturnError, ssl_Error); ADD_EXCEPTION(WantReadError, ssl_Error); ADD_EXCEPTION(WantWriteError, ssl_Error); ADD_EXCEPTION(WantX509LookupError, ssl_Error); ADD_EXCEPTION(SysCallError, ssl_Error); #undef ADD_EXCEPTION /* Method constants */ PyModule_AddIntConstant(module, "SSLv2_METHOD", ssl_SSLv2_METHOD); PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD); PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD); PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD); /* Verify constants */ PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE); PyModule_AddIntConstant(module, "VERIFY_PEER", SSL_VERIFY_PEER); PyModule_AddIntConstant(module, "VERIFY_FAIL_IF_NO_PEER_CERT", SSL_VERIFY_FAIL_IF_NO_PEER_CERT); PyModule_AddIntConstant(module, "VERIFY_CLIENT_ONCE", SSL_VERIFY_CLIENT_ONCE); /* File type constants */ PyModule_AddIntConstant(module, "FILETYPE_PEM", SSL_FILETYPE_PEM); PyModule_AddIntConstant(module, "FILETYPE_ASN1", SSL_FILETYPE_ASN1); /* SSL option constants */ PyModule_AddIntConstant(module, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); PyModule_AddIntConstant(module, "OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA); PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); /* More SSL option constants */ PyModule_AddIntConstant(module, "OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG); PyModule_AddIntConstant(module, "OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG); PyModule_AddIntConstant(module, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); PyModule_AddIntConstant(module, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); PyModule_AddIntConstant(module, "OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); PyModule_AddIntConstant(module, "OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING); PyModule_AddIntConstant(module, "OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG); PyModule_AddIntConstant(module, "OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG); PyModule_AddIntConstant(module, "OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG); PyModule_AddIntConstant(module, "OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); PyModule_AddIntConstant(module, "OP_ALL", SSL_OP_ALL); PyModule_AddIntConstant(module, "OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE); PyModule_AddIntConstant(module, "OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG); PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1); PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2); PyModule_AddIntConstant(module, "OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG); PyModule_AddIntConstant(module, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); #ifdef SSL_OP_NO_COMPRESSION PyModule_AddIntConstant(module, "OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION); #endif /* DTLS related options. The first two of these were introduced in * 2005, the third in 2007. To accomodate systems which are still using * older versions, make them optional. */ #ifdef SSL_OP_NO_QUERY_MTU PyModule_AddIntConstant(module, "OP_NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU); #endif #ifdef SSL_OP_COOKIE_EXCHANGE PyModule_AddIntConstant(module, "OP_COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE); #endif #ifdef SSL_OP_NO_TICKET PyModule_AddIntConstant(module, "OP_NO_TICKET", SSL_OP_NO_TICKET); #endif /* For SSL_set_shutdown */ PyModule_AddIntConstant(module, "SENT_SHUTDOWN", SSL_SENT_SHUTDOWN); PyModule_AddIntConstant(module, "RECEIVED_SHUTDOWN", SSL_RECEIVED_SHUTDOWN); /* For set_info_callback */ PyModule_AddIntConstant(module, "SSL_ST_CONNECT", SSL_ST_CONNECT); PyModule_AddIntConstant(module, "SSL_ST_ACCEPT", SSL_ST_ACCEPT); PyModule_AddIntConstant(module, "SSL_ST_MASK", SSL_ST_MASK); PyModule_AddIntConstant(module, "SSL_ST_INIT", SSL_ST_INIT); PyModule_AddIntConstant(module, "SSL_ST_BEFORE", SSL_ST_BEFORE); PyModule_AddIntConstant(module, "SSL_ST_OK", SSL_ST_OK); PyModule_AddIntConstant(module, "SSL_ST_RENEGOTIATE", SSL_ST_RENEGOTIATE); PyModule_AddIntConstant(module, "SSL_CB_LOOP", SSL_CB_LOOP); PyModule_AddIntConstant(module, "SSL_CB_EXIT", SSL_CB_EXIT); PyModule_AddIntConstant(module, "SSL_CB_READ", SSL_CB_READ); PyModule_AddIntConstant(module, "SSL_CB_WRITE", SSL_CB_WRITE); PyModule_AddIntConstant(module, "SSL_CB_ALERT", SSL_CB_ALERT); PyModule_AddIntConstant(module, "SSL_CB_READ_ALERT", SSL_CB_READ_ALERT); PyModule_AddIntConstant(module, "SSL_CB_WRITE_ALERT", SSL_CB_WRITE_ALERT); PyModule_AddIntConstant(module, "SSL_CB_ACCEPT_LOOP", SSL_CB_ACCEPT_LOOP); PyModule_AddIntConstant(module, "SSL_CB_ACCEPT_EXIT", SSL_CB_ACCEPT_EXIT); PyModule_AddIntConstant(module, "SSL_CB_CONNECT_LOOP", SSL_CB_CONNECT_LOOP); PyModule_AddIntConstant(module, "SSL_CB_CONNECT_EXIT", SSL_CB_CONNECT_EXIT); PyModule_AddIntConstant(module, "SSL_CB_HANDSHAKE_START", SSL_CB_HANDSHAKE_START); PyModule_AddIntConstant(module, "SSL_CB_HANDSHAKE_DONE", SSL_CB_HANDSHAKE_DONE); /* Version information indicators, used with SSLeay_version */ PyModule_AddIntConstant(module, "SSLEAY_VERSION", SSLEAY_VERSION); PyModule_AddIntConstant(module, "SSLEAY_CFLAGS", SSLEAY_CFLAGS); PyModule_AddIntConstant(module, "SSLEAY_BUILT_ON", SSLEAY_BUILT_ON); PyModule_AddIntConstant(module, "SSLEAY_PLATFORM", SSLEAY_PLATFORM); PyModule_AddIntConstant(module, "SSLEAY_DIR", SSLEAY_DIR); /* Cache modes */ #define CACHE_MODE(mode) \ PyModule_AddIntConstant(module, "SESS_CACHE_" #mode, SSL_SESS_CACHE_##mode) CACHE_MODE(OFF); CACHE_MODE(CLIENT); CACHE_MODE(SERVER); CACHE_MODE(BOTH); CACHE_MODE(NO_AUTO_CLEAR); CACHE_MODE(NO_INTERNAL_LOOKUP); CACHE_MODE(NO_INTERNAL_STORE); CACHE_MODE(NO_INTERNAL); #undef CACHE_MODE /* Straight up version number */ PyModule_AddIntConstant(module, "OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER); /* SSL modes constants */ #ifdef SSL_MODE_RELEASE_BUFFERS PyModule_AddIntConstant(module, "MODE_RELEASE_BUFFERS", SSL_MODE_RELEASE_BUFFERS); #endif if (!init_ssl_context(module)) goto error; if (!init_ssl_session(module)) goto error; if (!init_ssl_connection(module)) goto error; #ifdef WITH_THREAD /* * Initialize this module's threading support structures. */ _pyOpenSSL_tstate_key = PyThread_create_key(); #endif PyOpenSSL_MODRETURN(module); error: PyOpenSSL_MODRETURN(NULL); ; }