Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
2463e5fe
Commit
2463e5fe
authored
Mar 28, 2013
by
Antoine Pitrou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #16692: The ssl module now supports TLS 1.1 and TLS 1.2. Initial patch by Michele Orrù.
parent
f2c64ed9
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
194 additions
and
81 deletions
+194
-81
Doc/library/ssl.rst
Doc/library/ssl.rst
+45
-10
Doc/whatsnew/3.4.rst
Doc/whatsnew/3.4.rst
+1
-0
Lib/ssl.py
Lib/ssl.py
+11
-2
Lib/test/test_ssl.py
Lib/test/test_ssl.py
+53
-20
Misc/NEWS
Misc/NEWS
+5
-0
Modules/_ssl.c
Modules/_ssl.c
+77
-47
setup.py
setup.py
+2
-2
No files found.
Doc/library/ssl.rst
View file @
2463e5fe
...
...
@@ -26,7 +26,8 @@ probably additional platforms, as long as OpenSSL is installed on that platform.
Some behavior may be platform dependent, since calls are made to the
operating system socket APIs. The installed version of OpenSSL may also
cause variations in behavior.
cause variations in behavior. For example, TLSv1.1 and TLSv1.2 come with
openssl version 1.0.1.
This section documents the objects and functions in the ``ssl`` module; for more
general information about TLS, SSL, and certificates, the reader is referred to
...
...
@@ -177,14 +178,16 @@ instead.
.. table::
======================== ========= ========= ========== =========
*client* / **server** **SSLv2** **SSLv3** **SSLv23** **TLSv1**
------------------------ --------- --------- ---------- ---------
*SSLv2* yes no yes no
*SSLv3* no yes yes no
*SSLv23* yes no yes no
*TLSv1* no no yes yes
======================== ========= ========= ========== =========
======================== ========= ========= ========== ========= =========== ===========
*client* / **server** **SSLv2** **SSLv3** **SSLv23** **TLSv1** **TLSv1.1** **TLSv1.2**
------------------------ --------- --------- ---------- --------- ----------- -----------
*SSLv2* yes no yes no no no
*SSLv3* no yes yes no no no
*SSLv23* yes no yes no no no
*TLSv1* no no yes yes no no
*TLSv1.1* no no yes no yes no
*TLSv1.2* no no yes no no yes
======================== ========= ========= ========== ========= =========== ===========
.. note::
...
...
@@ -401,9 +404,25 @@ Constants
.. data:: PROTOCOL_TLSv1
Selects TLS version 1 as the channel encryption protocol. This is the most
Selects TLS version 1.0 as the channel encryption protocol.
.. data:: PROTOCOL_TLSv1_1
Selects TLS version 1.1 as the channel encryption protocol.
Available only with openssl version 1.0.1+.
.. versionadded:: 3.4
.. data:: PROTOCOL_TLSv1_2
Selects TLS version 1.2 as the channel encryption protocol. This is the most
modern version, and probably the best choice for maximum protection, if both
sides can speak it.
Available only with openssl version 1.0.1+.
.. versionadded:: 3.4
.. data:: OP_ALL
...
...
@@ -437,6 +456,22 @@ Constants
.. versionadded:: 3.2
.. data:: OP_NO_TLSv1_1
Prevents a TLSv1.1 connection. This option is only applicable in conjunction
with :const:`PROTOCOL_SSLv23`. It prevents the peers from choosing TLSv1.1 as
the protocol version. Available only with openssl version 1.0.1+.
.. versionadded:: 3.4
.. data:: OP_NO_TLSv1_2
Prevents a TLSv1.2 connection. This option is only applicable in conjunction
with :const:`PROTOCOL_SSLv23`. It prevents the peers from choosing TLSv1.2 as
the protocol version. Available only with openssl version 1.0.1+.
.. versionadded:: 3.4
.. data:: OP_CIPHER_SERVER_PREFERENCE
Use the server's cipher ordering preference, rather than the client's.
...
...
Doc/whatsnew/3.4.rst
View file @
2463e5fe
...
...
@@ -103,6 +103,7 @@ Implementation improvements:
Significantly Improved Library Modules:
* SHA-3 (Keccak) support for :mod:`hashlib`.
* TLSv1.1 and TLSv1.2 support for :mod:`ssl`.
Security improvements:
...
...
Lib/ssl.py
View file @
2463e5fe
...
...
@@ -52,6 +52,8 @@ PROTOCOL_SSLv2
PROTOCOL_SSLv3
PROTOCOL_SSLv23
PROTOCOL_TLSv1
PROTOCOL_TLSv1_1
PROTOCOL_TLSv1_2
The following constants identify various SSL alert message descriptions as per
http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-6
...
...
@@ -110,8 +112,7 @@ _import_symbols('SSL_ERROR_')
from
_ssl
import
HAS_SNI
,
HAS_ECDH
,
HAS_NPN
from
_ssl
import
(
PROTOCOL_SSLv3
,
PROTOCOL_SSLv23
,
PROTOCOL_TLSv1
)
from
_ssl
import
PROTOCOL_SSLv3
,
PROTOCOL_SSLv23
,
PROTOCOL_TLSv1
from
_ssl
import
_OPENSSL_API_VERSION
...
...
@@ -128,6 +129,14 @@ except ImportError:
else
:
_PROTOCOL_NAMES
[
PROTOCOL_SSLv2
]
=
"SSLv2"
try
:
from
_ssl
import
PROTOCOL_TLSv1_1
,
PROTOCOL_TLSv1_2
except
ImportError
:
pass
else
:
_PROTOCOL_NAMES
[
PROTOCOL_TLSv1_1
]
=
"TLSv1.1"
_PROTOCOL_NAMES
[
PROTOCOL_TLSv1_2
]
=
"TLSv1.2"
from
socket
import
getnameinfo
as
_getnameinfo
from
socket
import
socket
,
AF_INET
,
SOCK_STREAM
,
create_connection
import
base64
# for DER-to-PEM translation
...
...
Lib/test/test_ssl.py
View file @
2463e5fe
...
...
@@ -20,13 +20,7 @@ import functools
ssl
=
support
.
import_module
(
"ssl"
)
PROTOCOLS
=
[
ssl
.
PROTOCOL_SSLv3
,
ssl
.
PROTOCOL_SSLv23
,
ssl
.
PROTOCOL_TLSv1
]
if
hasattr
(
ssl
,
'PROTOCOL_SSLv2'
):
PROTOCOLS
.
append
(
ssl
.
PROTOCOL_SSLv2
)
PROTOCOLS
=
sorted
(
ssl
.
_PROTOCOL_NAMES
)
HOST
=
support
.
HOST
data_file
=
lambda
name
:
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
name
)
...
...
@@ -101,10 +95,6 @@ needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
class
BasicSocketTests
(
unittest
.
TestCase
):
def
test_constants
(
self
):
#ssl.PROTOCOL_SSLv2
ssl
.
PROTOCOL_SSLv23
ssl
.
PROTOCOL_SSLv3
ssl
.
PROTOCOL_TLSv1
ssl
.
CERT_NONE
ssl
.
CERT_OPTIONAL
ssl
.
CERT_REQUIRED
...
...
@@ -396,11 +386,8 @@ class ContextTests(unittest.TestCase):
@
skip_if_broken_ubuntu_ssl
def
test_constructor
(
self
):
if
hasattr
(
ssl
,
'PROTOCOL_SSLv2'
):
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_SSLv2
)
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_SSLv23
)
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_SSLv3
)
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
)
for
protocol
in
PROTOCOLS
:
ssl
.
SSLContext
(
protocol
)
self
.
assertRaises
(
TypeError
,
ssl
.
SSLContext
)
self
.
assertRaises
(
ValueError
,
ssl
.
SSLContext
,
-
1
)
self
.
assertRaises
(
ValueError
,
ssl
.
SSLContext
,
42
)
...
...
@@ -1360,12 +1347,15 @@ else:
client_context
.
options
=
ssl
.
OP_ALL
|
client_options
server_context
=
ssl
.
SSLContext
(
server_protocol
)
server_context
.
options
=
ssl
.
OP_ALL
|
server_options
# NOTE: we must enable "ALL" ciphers on the client, otherwise an
# SSLv23 client will send an SSLv3 hello (rather than SSLv2)
# starting from OpenSSL 1.0.0 (see issue #8322).
if
client_context
.
protocol
==
ssl
.
PROTOCOL_SSLv23
:
client_context
.
set_ciphers
(
"ALL"
)
for
ctx
in
(
client_context
,
server_context
):
ctx
.
verify_mode
=
certsreqs
# NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
# will send an SSLv3 hello (rather than SSLv2) starting from
# OpenSSL 1.0.0 (see issue #8322).
ctx
.
set_ciphers
(
"ALL"
)
ctx
.
load_cert_chain
(
CERTFILE
)
ctx
.
load_verify_locations
(
CERTFILE
)
try
:
...
...
@@ -1581,6 +1571,49 @@ else:
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1
,
ssl
.
PROTOCOL_SSLv23
,
False
,
client_options
=
ssl
.
OP_NO_TLSv1
)
@
skip_if_broken_ubuntu_ssl
@
unittest
.
skipUnless
(
hasattr
(
ssl
,
"PROTOCOL_TLSv1_1"
),
"TLS version 1.1 not supported."
)
def
test_protocol_tlsv1_1
(
self
):
"""Connecting to a TLSv1.1 server with various client options.
Testing against older TLS versions."""
if
support
.
verbose
:
sys
.
stdout
.
write
(
"
\
n
"
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_1
,
ssl
.
PROTOCOL_TLSv1_1
,
True
)
if
hasattr
(
ssl
,
'PROTOCOL_SSLv2'
):
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_1
,
ssl
.
PROTOCOL_SSLv2
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_1
,
ssl
.
PROTOCOL_SSLv3
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_1
,
ssl
.
PROTOCOL_SSLv23
,
False
,
client_options
=
ssl
.
OP_NO_TLSv1_1
)
try_protocol_combo
(
ssl
.
PROTOCOL_SSLv23
,
ssl
.
PROTOCOL_TLSv1_1
,
True
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_1
,
ssl
.
PROTOCOL_TLSv1
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1
,
ssl
.
PROTOCOL_TLSv1_1
,
False
)
@
skip_if_broken_ubuntu_ssl
@
unittest
.
skipUnless
(
hasattr
(
ssl
,
"PROTOCOL_TLSv1_2"
),
"TLS version 1.2 not supported."
)
def
test_protocol_tlsv1_2
(
self
):
"""Connecting to a TLSv1.2 server with various client options.
Testing against older TLS versions."""
if
support
.
verbose
:
sys
.
stdout
.
write
(
"
\
n
"
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_2
,
ssl
.
PROTOCOL_TLSv1_2
,
True
,
server_options
=
ssl
.
OP_NO_SSLv3
|
ssl
.
OP_NO_SSLv2
,
client_options
=
ssl
.
OP_NO_SSLv3
|
ssl
.
OP_NO_SSLv2
,)
if
hasattr
(
ssl
,
'PROTOCOL_SSLv2'
):
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_2
,
ssl
.
PROTOCOL_SSLv2
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_2
,
ssl
.
PROTOCOL_SSLv3
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_2
,
ssl
.
PROTOCOL_SSLv23
,
False
,
client_options
=
ssl
.
OP_NO_TLSv1_2
)
try_protocol_combo
(
ssl
.
PROTOCOL_SSLv23
,
ssl
.
PROTOCOL_TLSv1_2
,
True
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_2
,
ssl
.
PROTOCOL_TLSv1
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1
,
ssl
.
PROTOCOL_TLSv1_2
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_2
,
ssl
.
PROTOCOL_TLSv1_1
,
False
)
try_protocol_combo
(
ssl
.
PROTOCOL_TLSv1_1
,
ssl
.
PROTOCOL_TLSv1_2
,
False
)
def
test_starttls
(
self
):
"""Switching from clear text to encrypted and back again."""
msgs
=
(
b"msg 1"
,
b"MSG 2"
,
b"STARTTLS"
,
b"MSG 3"
,
b"msg 4"
,
b"ENDTLS"
,
b"msg 5"
,
b"msg 6"
)
...
...
Misc/NEWS
View file @
2463e5fe
...
...
@@ -297,6 +297,9 @@ Core and Builtins
Library
-------
- Issue #16692: The ssl module now supports TLS 1.1 and TLS 1.2. Initial
patch by Michele Orrù.
- Issue #17025: multiprocessing: Reduce Queue and SimpleQueue contention.
- Issue #17536: Add to webbrowser'
s
browser
list
:
www
-
browser
,
x
-
www
-
browser
,
...
...
@@ -1005,6 +1008,8 @@ _ Issue #17385: Fix quadratic behavior in threading.Condition. The FIFO
- ctypes.call_commethod was removed, since its only usage was in the defunct
samples directory.
- Issue #16692: Added TLSv1.1 and TLSv1.2 support for the ssl modules.
Extension Modules
-----------------
...
...
Modules/_ssl.c
View file @
2463e5fe
...
...
@@ -40,6 +40,61 @@
#endif
/* Include symbols from _socket module */
#include "socketmodule.h"
static
PySocketModule_APIObject
PySocketModule
;
#if defined(HAVE_POLL_H)
#include <poll.h>
#elif defined(HAVE_SYS_POLL_H)
#include <sys/poll.h>
#endif
/* Include OpenSSL header files */
#include "openssl/rsa.h"
#include "openssl/crypto.h"
#include "openssl/x509.h"
#include "openssl/x509v3.h"
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/rand.h"
/* SSL error object */
static
PyObject
*
PySSLErrorObject
;
static
PyObject
*
PySSLZeroReturnErrorObject
;
static
PyObject
*
PySSLWantReadErrorObject
;
static
PyObject
*
PySSLWantWriteErrorObject
;
static
PyObject
*
PySSLSyscallErrorObject
;
static
PyObject
*
PySSLEOFErrorObject
;
/* Error mappings */
static
PyObject
*
err_codes_to_names
;
static
PyObject
*
err_names_to_codes
;
static
PyObject
*
lib_codes_to_names
;
struct
py_ssl_error_code
{
const
char
*
mnemonic
;
int
library
,
reason
;
};
struct
py_ssl_library_code
{
const
char
*
library
;
int
code
;
};
/* Include generated data (error codes) */
#include "_ssl_data.h"
/* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1
http://www.openssl.org/news/changelog.html
*/
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
# define HAVE_TLSv1_2 1
#else
# define HAVE_TLSv1_2 0
#endif
enum
py_ssl_error
{
/* these mirror ssl.h */
PY_SSL_ERROR_NONE
,
...
...
@@ -73,55 +128,14 @@ enum py_ssl_version {
#endif
PY_SSL_VERSION_SSL3
=
1
,
PY_SSL_VERSION_SSL23
,
#if HAVE_TLSv1_2
PY_SSL_VERSION_TLS1
,
PY_SSL_VERSION_TLS1_1
,
PY_SSL_VERSION_TLS1_2
#else
PY_SSL_VERSION_TLS1
};
struct
py_ssl_error_code
{
const
char
*
mnemonic
;
int
library
,
reason
;
};
struct
py_ssl_library_code
{
const
char
*
library
;
int
code
;
};
/* Include symbols from _socket module */
#include "socketmodule.h"
static
PySocketModule_APIObject
PySocketModule
;
#if defined(HAVE_POLL_H)
#include <poll.h>
#elif defined(HAVE_SYS_POLL_H)
#include <sys/poll.h>
#endif
/* Include OpenSSL header files */
#include "openssl/rsa.h"
#include "openssl/crypto.h"
#include "openssl/x509.h"
#include "openssl/x509v3.h"
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/rand.h"
/* Include generated data (error codes) */
#include "_ssl_data.h"
/* SSL error object */
static
PyObject
*
PySSLErrorObject
;
static
PyObject
*
PySSLZeroReturnErrorObject
;
static
PyObject
*
PySSLWantReadErrorObject
;
static
PyObject
*
PySSLWantWriteErrorObject
;
static
PyObject
*
PySSLSyscallErrorObject
;
static
PyObject
*
PySSLEOFErrorObject
;
/* Error mappings */
static
PyObject
*
err_codes_to_names
;
static
PyObject
*
err_names_to_codes
;
static
PyObject
*
lib_codes_to_names
;
};
#ifdef WITH_THREAD
...
...
@@ -1732,6 +1746,12 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PySSL_BEGIN_ALLOW_THREADS
if
(
proto_version
==
PY_SSL_VERSION_TLS1
)
ctx
=
SSL_CTX_new
(
TLSv1_method
());
#if HAVE_TLSv1_2
else
if
(
proto_version
==
PY_SSL_VERSION_TLS1_1
)
ctx
=
SSL_CTX_new
(
TLSv1_1_method
());
else
if
(
proto_version
==
PY_SSL_VERSION_TLS1_2
)
ctx
=
SSL_CTX_new
(
TLSv1_2_method
());
#endif
else
if
(
proto_version
==
PY_SSL_VERSION_SSL3
)
ctx
=
SSL_CTX_new
(
SSLv3_method
());
#ifndef OPENSSL_NO_SSL2
...
...
@@ -3004,6 +3024,12 @@ PyInit__ssl(void)
PY_SSL_VERSION_SSL23
);
PyModule_AddIntConstant
(
m
,
"PROTOCOL_TLSv1"
,
PY_SSL_VERSION_TLS1
);
#if HAVE_TLSv1_2
PyModule_AddIntConstant
(
m
,
"PROTOCOL_TLSv1_1"
,
PY_SSL_VERSION_TLS1_1
);
PyModule_AddIntConstant
(
m
,
"PROTOCOL_TLSv1_2"
,
PY_SSL_VERSION_TLS1_2
);
#endif
/* protocol options */
PyModule_AddIntConstant
(
m
,
"OP_ALL"
,
...
...
@@ -3011,6 +3037,10 @@ PyInit__ssl(void)
PyModule_AddIntConstant
(
m
,
"OP_NO_SSLv2"
,
SSL_OP_NO_SSLv2
);
PyModule_AddIntConstant
(
m
,
"OP_NO_SSLv3"
,
SSL_OP_NO_SSLv3
);
PyModule_AddIntConstant
(
m
,
"OP_NO_TLSv1"
,
SSL_OP_NO_TLSv1
);
#if HAVE_TLSv1_2
PyModule_AddIntConstant
(
m
,
"OP_NO_TLSv1_1"
,
SSL_OP_NO_TLSv1_1
);
PyModule_AddIntConstant
(
m
,
"OP_NO_TLSv1_2"
,
SSL_OP_NO_TLSv1_2
);
#endif
PyModule_AddIntConstant
(
m
,
"OP_CIPHER_SERVER_PREFERENCE"
,
SSL_OP_CIPHER_SERVER_PREFERENCE
);
PyModule_AddIntConstant
(
m
,
"OP_SINGLE_DH_USE"
,
SSL_OP_SINGLE_DH_USE
);
...
...
setup.py
View file @
2463e5fe
...
...
@@ -786,10 +786,10 @@ class PyBuildExt(build_ext):
for
line
in
incfile
:
m
=
openssl_ver_re
.
match
(
line
)
if
m
:
openssl_ver
=
eval
(
m
.
group
(
1
))
openssl_ver
=
int
(
m
.
group
(
1
),
16
)
break
except
IOError
as
msg
:
print
(
"IOError while reading opensshv.h:"
,
msg
)
pass
#print('openssl_ver = 0x%08x' % openssl_ver)
min_openssl_ver
=
0x00907000
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment