--- Python-3.4.6-orig/Modules/_ssl.c 2017-01-17 18:57:45.000000000 +1100 +++ Python-3.4.6/Modules/_ssl.c 2017-10-10 00:06:29.805949585 +1100 @@ -90,6 +90,10 @@ /* Include generated data (error codes) */ #include "_ssl_data.h" +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) +# define OPENSSL_VERSION_1_1 1 +#endif + /* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1 http://www.openssl.org/news/changelog.html */ @@ -203,6 +207,27 @@ # define HAVE_OPENSSL_VERIFY_PARAM #endif +#ifndef OPENSSL_VERSION_1_1 +/* OpenSSL 1.1.0+ */ +#ifndef OPENSSL_NO_SSL2 +#define OPENSSL_NO_SSL2 +#endif +#if defined(WITH_THREAD) +#define HAVE_OPENSSL_CRYPTO_LOCK +#endif +#endif + +#ifndef OPENSSL_VERSION_1_1 +#define TLS_method SSLv23_method +#define TLS_client_method SSLv23_client_method +#define TLS_server_method SSLv23_server_method +#define X509_get0_notBefore X509_get_notBefore +#define X509_get0_notAfter X509_get_notAfter +#define ASN1_STRING_get0_data ASN1_STRING_data +#define OpenSSL_version_num SSLeay +#define OpenSSL_version SSLeay_version +#define OPENSSL_VERSION SSLEAY_VERSION +#endif typedef struct { PyObject_HEAD @@ -691,7 +716,7 @@ /* check to see if we've gotten to a new RDN */ if (rdn_level >= 0) { - if (rdn_level != entry->set) { + if (rdn_level != X509_NAME_ENTRY_set(entry)) { /* yes, new RDN */ /* add old RDN to DN */ rdnt = PyList_AsTuple(rdn); @@ -708,7 +733,7 @@ goto fail0; } } - rdn_level = entry->set; + rdn_level = X509_NAME_ENTRY_set(entry); /* now add this attribute to the current RDN */ name = X509_NAME_ENTRY_get_object(entry); @@ -811,18 +836,18 @@ goto fail; } - p = ext->value->data; + p = X509_EXTENSION_get_data(ext)->data; if (method->it) names = (GENERAL_NAMES*) (ASN1_item_d2i(NULL, &p, - ext->value->length, + X509_EXTENSION_get_data(ext)->length, ASN1_ITEM_ptr(method->it))); else names = (GENERAL_NAMES*) (method->d2i(NULL, &p, - ext->value->length)); + X509_EXTENSION_get_data(ext)->length)); for(j = 0; j < sk_GENERAL_NAME_num(names); j++) { /* get a rendering of each name in the set of names */ @@ -883,7 +908,7 @@ goto fail; } PyTuple_SET_ITEM(t, 0, v); - v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_data(as), + v = PyUnicode_FromStringAndSize((char *)ASN1_STRING_get0_data(as), ASN1_STRING_length(as)); if (v == NULL) { Py_DECREF(t); @@ -1033,13 +1058,7 @@ int i, j; PyObject *lst, *res = NULL; -#if OPENSSL_VERSION_NUMBER < 0x10001000L dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); -#else - /* Calls x509v3_cache_extensions and sets up crldp */ - X509_check_ca(certificate); - dps = certificate->crldp; -#endif if (dps == NULL) return Py_None; @@ -1161,7 +1180,7 @@ Py_DECREF(sn_obj); (void) BIO_reset(biobuf); - notBefore = X509_get_notBefore(certificate); + notBefore = X509_get0_notBefore(certificate); ASN1_TIME_print(biobuf, notBefore); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -1178,7 +1197,7 @@ Py_DECREF(pnotBefore); (void) BIO_reset(biobuf); - notAfter = X509_get_notAfter(certificate); + notAfter = X509_get0_notAfter(certificate); ASN1_TIME_print(biobuf, notAfter); len = BIO_gets(biobuf, buf, sizeof(buf)-1); if (len < 0) { @@ -1427,9 +1446,9 @@ if (self->ssl == NULL) Py_RETURN_NONE; comp_method = SSL_get_current_compression(self->ssl); - if (comp_method == NULL || comp_method->type == NID_undef) + if (comp_method == NULL || COMP_get_type(comp_method) == NID_undef) Py_RETURN_NONE; - short_name = OBJ_nid2sn(comp_method->type); + short_name = OBJ_nid2sn(COMP_get_type(comp_method)); if (short_name == NULL) Py_RETURN_NONE; return PyUnicode_DecodeFSDefault(short_name); @@ -1987,24 +2006,54 @@ return NULL; PySSL_BEGIN_ALLOW_THREADS - if (proto_version == PY_SSL_VERSION_TLS1) + if (proto_version == PY_SSL_VERSION_TLS1) { +#ifdef OPENSSL_VERSION_1_1 + ctx = SSL_CTX_new(TLS_method()); + SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); +#else ctx = SSL_CTX_new(TLSv1_method()); +#endif + } #if HAVE_TLSv1_2 - else if (proto_version == PY_SSL_VERSION_TLS1_1) + else if (proto_version == PY_SSL_VERSION_TLS1_1) { +#ifdef OPENSSL_VERSION_1_1 + ctx = SSL_CTX_new(TLS_method()); + SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION); +#else ctx = SSL_CTX_new(TLSv1_1_method()); - else if (proto_version == PY_SSL_VERSION_TLS1_2) +#endif + } + else if (proto_version == PY_SSL_VERSION_TLS1_2) { +#ifdef OPENSSL_VERSION_1_1 + ctx = SSL_CTX_new(TLS_method()); + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); +#else ctx = SSL_CTX_new(TLSv1_2_method()); #endif + } +#endif #ifndef OPENSSL_NO_SSL3 - else if (proto_version == PY_SSL_VERSION_SSL3) + else if (proto_version == PY_SSL_VERSION_SSL3) { +#ifdef OPENSSL_VERSION_1_1 + ctx = SSL_CTX_new(TLS_method()); + SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION); +#else ctx = SSL_CTX_new(SSLv3_method()); #endif + } +#endif #ifndef OPENSSL_NO_SSL2 - else if (proto_version == PY_SSL_VERSION_SSL2) + else if (proto_version == PY_SSL_VERSION_SSL2) { +#ifdef OPENSSL_VERSION_1_1 + ctx = SSL_CTX_new(TLS_method()); + SSL_CTX_set_min_proto_version(ctx, SSL2_VERSION); +#else ctx = SSL_CTX_new(SSLv2_method()); #endif + } +#endif else if (proto_version == PY_SSL_VERSION_SSL23) - ctx = SSL_CTX_new(SSLv23_method()); + ctx = SSL_CTX_new(TLS_method()); else proto_version = -1; PySSL_END_ALLOW_THREADS @@ -2259,10 +2308,12 @@ get_verify_flags(PySSLContext *self, void *c) { X509_STORE *store; + X509_VERIFY_PARAM *param; unsigned long flags; store = SSL_CTX_get_cert_store(self->ctx); - flags = X509_VERIFY_PARAM_get_flags(store->param); + param = X509_STORE_get0_param(store); + flags = X509_VERIFY_PARAM_get_flags(param); return PyLong_FromUnsignedLong(flags); } @@ -2270,22 +2321,24 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) { X509_STORE *store; + X509_VERIFY_PARAM *param; unsigned long new_flags, flags, set, clear; if (!PyArg_Parse(arg, "k", &new_flags)) return -1; store = SSL_CTX_get_cert_store(self->ctx); - flags = X509_VERIFY_PARAM_get_flags(store->param); + param = X509_STORE_get0_param(store); + flags = X509_VERIFY_PARAM_get_flags(param); clear = flags & ~new_flags; set = ~flags & new_flags; if (clear) { - if (!X509_VERIFY_PARAM_clear_flags(store->param, clear)) { + if (!X509_VERIFY_PARAM_clear_flags(param, clear)) { _setSSLError(NULL, 0, __FILE__, __LINE__); return -1; } } if (set) { - if (!X509_VERIFY_PARAM_set_flags(store->param, set)) { + if (!X509_VERIFY_PARAM_set_flags(param, set)) { _setSSLError(NULL, 0, __FILE__, __LINE__); return -1; } @@ -2455,8 +2508,8 @@ char *kwlist[] = {"certfile", "keyfile", "password", NULL}; PyObject *certfile, *keyfile = NULL, *password = NULL; PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; - pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback; - void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata; + pem_password_cb *orig_passwd_cb = SSL_CTX_get_default_passwd_cb(self->ctx); + void *orig_passwd_userdata = SSL_CTX_get_default_passwd_cb_userdata(self->ctx); _PySSLPasswordInfo pw_info = { NULL, NULL, NULL, 0, 0 }; int r; @@ -2587,8 +2640,9 @@ cert = d2i_X509_bio(biobuf, NULL); } else { cert = PEM_read_bio_X509(biobuf, NULL, - self->ctx->default_passwd_callback, - self->ctx->default_passwd_callback_userdata); + SSL_CTX_get_default_passwd_cb(self->ctx), + SSL_CTX_get_default_passwd_cb_userdata(self->ctx) + ); } if (cert == NULL) { break; @@ -3036,25 +3090,24 @@ cert_store_stats(PySSLContext *self) { X509_STORE *store; + STACK_OF(X509_OBJECT) *objs; X509_OBJECT *obj; - int x509 = 0, crl = 0, pkey = 0, ca = 0, i; + int x509 = 0, crl = 0, ca = 0, i; store = SSL_CTX_get_cert_store(self->ctx); - for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) { - obj = sk_X509_OBJECT_value(store->objs, i); - switch (obj->type) { + objs = X509_STORE_get0_objects(store); + for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { + obj = sk_X509_OBJECT_value(objs, i); + switch (X509_OBJECT_get_type(obj)) { case X509_LU_X509: x509++; - if (X509_check_ca(obj->data.x509)) { + if (X509_check_ca(X509_OBJECT_get0_X509(obj))) { ca++; } break; case X509_LU_CRL: crl++; break; - case X509_LU_PKEY: - pkey++; - break; default: /* Ignore X509_LU_FAIL, X509_LU_RETRY, X509_LU_PKEY. * As far as I can tell they are internal states and never @@ -3079,6 +3132,7 @@ { char *kwlist[] = {"binary_form", NULL}; X509_STORE *store; + STACK_OF(X509_OBJECT) *objs; PyObject *ci = NULL, *rlist = NULL; int i; int binary_mode = 0; @@ -3093,17 +3147,18 @@ } store = SSL_CTX_get_cert_store(self->ctx); - for (i = 0; i < sk_X509_OBJECT_num(store->objs); i++) { + objs = X509_STORE_get0_objects(store); + for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { X509_OBJECT *obj; X509 *cert; - obj = sk_X509_OBJECT_value(store->objs, i); - if (obj->type != X509_LU_X509) { + obj = sk_X509_OBJECT_value(objs, i); + if (X509_OBJECT_get_type(obj) != X509_LU_X509) { /* not a x509 cert */ continue; } /* CA for any purpose */ - cert = obj->data.x509; + cert = X509_OBJECT_get0_X509(obj); if (!X509_check_ca(cert)) { continue; } @@ -3262,7 +3317,11 @@ if (bytes == NULL) return NULL; if (pseudo) { +#ifdef OPENSSL_VERSION_1_1 + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#else ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); +#endif if (ok == 0 || ok == 1) return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); } @@ -3776,7 +3835,7 @@ }; -#ifdef WITH_THREAD +#ifdef HAVE_OPENSSL_CRYPTO_LOCK /* an implementation of OpenSSL threading operations in terms of the Python C thread library */ @@ -3860,7 +3919,7 @@ return 1; } -#endif /* def HAVE_THREAD */ +#endif /* HAVE_OPENSSL_CRYPTO_LOCK for WITH_THREAD && OpenSSL < 1.1.0 */ PyDoc_STRVAR(module_doc, "Implementation module for SSL socket operations. See the socket module\n\ @@ -3924,16 +3983,26 @@ PySocketModule = *socket_api; /* Init OpenSSL */ +#ifdef OPENSSL_VERSION_1_1 + OPENSSL_init_ssl(0, NULL); +#else SSL_load_error_strings(); SSL_library_init(); +#endif #ifdef WITH_THREAD +#ifdef HAVE_OPENSSL_CRYPTO_LOCK /* note that this will start threading if not already started */ if (!_setup_ssl_threads()) { return NULL; } +#elif OPENSSL_VERSION_1_1 && defined(OPENSSL_THREADS) + /* OpenSSL 1.1.0 builtin thread support is enabled */ + _ssl_locks_count++; #endif +#endif /* WITH_THREAD */ +#ifndef OPENSSL_VERSION_1_1 OpenSSL_add_all_algorithms(); - +#endif /* Add symbols to module dict */ sslerror_type_slots[0].pfunc = PyExc_OSError; PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec); @@ -4183,10 +4252,10 @@ return NULL; /* OpenSSL version */ - /* SSLeay() gives us the version of the library linked against, + /* OpenSSL_version_num() gives us the version of the library linked against, which could be different from the headers version. */ - libver = SSLeay(); + libver = OpenSSL_version_num(); r = PyLong_FromUnsignedLong(libver); if (r == NULL) return NULL; @@ -4196,7 +4265,7 @@ r = Py_BuildValue("IIIII", major, minor, fix, patch, status); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) return NULL; - r = PyUnicode_FromString(SSLeay_version(SSLEAY_VERSION)); + r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) return NULL; --- Python-3.4.6-orig/Modules/_hashopenssl.c 2017-01-17 18:57:45.000000000 +1100 +++ Python-3.4.6/Modules/_hashopenssl.c 2017-10-09 23:55:14.881930759 +1100 @@ -20,7 +20,6 @@ /* EVP is the preferred interface to hashing in OpenSSL */ #include -#include /* We use the object interface to discover what hashes OpenSSL supports. */ #include #include "openssl/err.h" @@ -36,10 +35,21 @@ #define _OPENSSL_SUPPORTS_SHA2 #endif +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +/* OpenSSL < 1.1.0 */ +#define EVP_MD_CTX_new EVP_MD_CTX_create +#define EVP_MD_CTX_free EVP_MD_CTX_destroy +#define HAS_FAST_PKCS5_PBKDF2_HMAC 0 +#include +#else +/* OpenSSL >= 1.1.0 */ +#define HAS_FAST_PKCS5_PBKDF2_HMAC 1 +#endif + typedef struct { PyObject_HEAD PyObject *name; /* name of this hash algorithm */ - EVP_MD_CTX ctx; /* OpenSSL message digest context */ + EVP_MD_CTX *ctx; /* OpenSSL message digest context */ #ifdef WITH_THREAD PyThread_type_lock lock; /* OpenSSL context lock */ #endif @@ -51,7 +61,6 @@ #define DEFINE_CONSTS_FOR_NEW(Name) \ static PyObject *CONST_ ## Name ## _name_obj = NULL; \ - static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \ static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL; DEFINE_CONSTS_FOR_NEW(md5) @@ -91,7 +100,7 @@ process = MUNCH_SIZE; else process = Py_SAFE_DOWNCAST(len, Py_ssize_t, unsigned int); - EVP_DigestUpdate(&self->ctx, (const void*)cp, process); + EVP_DigestUpdate(self->ctx, (const void*)cp, process); len -= process; cp += process; } @@ -106,7 +115,7 @@ if (self->lock != NULL) PyThread_free_lock(self->lock); #endif - EVP_MD_CTX_cleanup(&self->ctx); + EVP_MD_CTX_free(self->ctx); Py_XDECREF(self->name); PyObject_Del(self); } @@ -114,7 +123,7 @@ static void locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) { ENTER_HASHLIB(self); - EVP_MD_CTX_copy(new_ctx_p, &self->ctx); + EVP_MD_CTX_copy(new_ctx_p, self->ctx); LEAVE_HASHLIB(self); } @@ -131,7 +140,7 @@ if ( (newobj = newEVPobject(self->name))==NULL) return NULL; - locked_EVP_MD_CTX_copy(&newobj->ctx, self); + locked_EVP_MD_CTX_copy(newobj->ctx, self); return (PyObject *)newobj; } @@ -142,16 +151,22 @@ EVP_digest(EVPobject *self, PyObject *unused) { unsigned char digest[EVP_MAX_MD_SIZE]; - EVP_MD_CTX temp_ctx; + EVP_MD_CTX *temp_ctx; PyObject *retval; unsigned int digest_size; - locked_EVP_MD_CTX_copy(&temp_ctx, self); + temp_ctx = EVP_MD_CTX_new(); + if (temp_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + locked_EVP_MD_CTX_copy(temp_ctx, self); digest_size = EVP_MD_CTX_size(&temp_ctx); - EVP_DigestFinal(&temp_ctx, digest, NULL); + EVP_DigestFinal(temp_ctx, digest, NULL); retval = PyBytes_FromStringAndSize((const char *)digest, digest_size); - EVP_MD_CTX_cleanup(&temp_ctx); + EVP_MD_CTX_free(temp_ctx); return retval; } @@ -162,17 +177,17 @@ EVP_hexdigest(EVPobject *self, PyObject *unused) { unsigned char digest[EVP_MAX_MD_SIZE]; - EVP_MD_CTX temp_ctx; + EVP_MD_CTX *temp_ctx; PyObject *retval; char *hex_digest; unsigned int i, j, digest_size; /* Get the raw (binary) digest value */ - locked_EVP_MD_CTX_copy(&temp_ctx, self); - digest_size = EVP_MD_CTX_size(&temp_ctx); - EVP_DigestFinal(&temp_ctx, digest, NULL); + locked_EVP_MD_CTX_copy(temp_ctx, self); + digest_size = EVP_MD_CTX_size(temp_ctx); + EVP_DigestFinal(temp_ctx, digest, NULL); - EVP_MD_CTX_cleanup(&temp_ctx); + EVP_MD_CTX_free(temp_ctx); /* Allocate a new buffer */ hex_digest = PyMem_Malloc(digest_size * 2 + 1); @@ -241,7 +256,7 @@ EVP_get_block_size(EVPobject *self, void *closure) { long block_size; - block_size = EVP_MD_CTX_block_size(&self->ctx); + block_size = EVP_MD_CTX_block_size(self->ctx); return PyLong_FromLong(block_size); } @@ -249,7 +264,7 @@ EVP_get_digest_size(EVPobject *self, void *closure) { long size; - size = EVP_MD_CTX_size(&self->ctx); + size = EVP_MD_CTX_size(self->ctx); return PyLong_FromLong(size); } @@ -310,7 +325,7 @@ PyBuffer_Release(&view); return -1; } - EVP_DigestInit(&self->ctx, digest); + EVP_DigestInit(self->ctx, digest); self->name = name_obj; Py_INCREF(self->name); @@ -407,9 +422,9 @@ return NULL; if (initial_ctx) { - EVP_MD_CTX_copy(&self->ctx, initial_ctx); + EVP_MD_CTX_copy(self->ctx, initial_ctx); } else { - EVP_DigestInit(&self->ctx, digest); + EVP_DigestInit(self->ctx, digest); } if (cp && len) { @@ -475,6 +490,7 @@ #define PY_PBKDF2_HMAC 1 +#if !HAS_FAST_PKCS5_PBKDF2_HMAC /* Improved implementation of PKCS5_PBKDF2_HMAC() * * PKCS5_PBKDF2_HMAC_fast() hashes the password exactly one time instead of @@ -556,6 +572,7 @@ HMAC_CTX_cleanup(&hctx_tpl); return 1; } +#endif /* LCOV_EXCL_START */ static PyObject * @@ -668,10 +685,17 @@ key = PyBytes_AS_STRING(key_obj); Py_BEGIN_ALLOW_THREADS +#if HAS_FAST_PKCS5_PBKDF2_HMAC + retval = PKCS5_PBKDF2_HMAC((char*)password.buf, (int)password.len, + (unsigned char *)salt.buf, (int)salt.len, + iterations, digest, dklen, + (unsigned char *)key); +#else retval = PKCS5_PBKDF2_HMAC_fast((char*)password.buf, (int)password.len, (unsigned char *)salt.buf, (int)salt.len, iterations, digest, dklen, (unsigned char *)key); +#endif Py_END_ALLOW_THREADS if (!retval) { @@ -790,7 +814,7 @@ if (CONST_ ## NAME ## _name_obj == NULL) { \ CONST_ ## NAME ## _name_obj = PyUnicode_FromString(#NAME); \ if (EVP_get_digestbyname(#NAME)) { \ - CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \ + CONST_new_ ## NAME ## _ctx_p = EVP_MD_CTX_new(); \ EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \ } \ } \ @@ -845,8 +869,10 @@ { PyObject *m, *openssl_md_meth_names; +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) OpenSSL_add_all_digests(); ERR_load_crypto_strings(); +#endif /* TODO build EVP_functions openssl_* entries dynamically based * on what hashes are supported rather than listing many