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
01113fae
Commit
01113fae
authored
Sep 05, 2016
by
Christian Heimes
Browse files
Options
Browse Files
Download
Plain Diff
Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0.
parents
ae8298bf
598894ff
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
399 additions
and
164 deletions
+399
-164
Doc/library/ssl.rst
Doc/library/ssl.rst
+87
-21
Lib/ssl.py
Lib/ssl.py
+10
-8
Lib/test/test_ssl.py
Lib/test/test_ssl.py
+58
-31
Misc/NEWS
Misc/NEWS
+2
-0
Modules/_hashopenssl.c
Modules/_hashopenssl.c
+106
-59
Modules/_ssl.c
Modules/_ssl.c
+136
-45
No files found.
Doc/library/ssl.rst
View file @
01113fae
This diff is collapsed.
Click to expand it.
Lib/ssl.py
View file @
01113fae
...
...
@@ -51,6 +51,7 @@ The following constants identify various SSL protocol variants:
PROTOCOL_SSLv2
PROTOCOL_SSLv3
PROTOCOL_SSLv23
PROTOCOL_TLS
PROTOCOL_TLSv1
PROTOCOL_TLSv1_1
PROTOCOL_TLSv1_2
...
...
@@ -128,9 +129,10 @@ from _ssl import _OPENSSL_API_VERSION
_IntEnum
.
_convert
(
'_SSLMethod'
,
__name__
,
lambda
name
:
name
.
startswith
(
'PROTOCOL_'
),
lambda
name
:
name
.
startswith
(
'PROTOCOL_'
)
and
name
!=
'PROTOCOL_SSLv23'
,
source
=
_ssl
)
PROTOCOL_SSLv23
=
_SSLMethod
.
PROTOCOL_SSLv23
=
_SSLMethod
.
PROTOCOL_TLS
_PROTOCOL_NAMES
=
{
value
:
name
for
name
,
value
in
_SSLMethod
.
__members__
.
items
()}
try
:
...
...
@@ -357,13 +359,13 @@ class SSLContext(_SSLContext):
__slots__ = ('protocol', '__weakref__')
_windows_cert_stores = ("CA", "ROOT")
def __new__(cls, protocol, *args, **kwargs):
def __new__(cls, protocol
=PROTOCOL_TLS
, *args, **kwargs):
self = _SSLContext.__new__(cls, protocol)
if protocol != _SSLv2_IF_EXISTS:
self.set_ciphers(_DEFAULT_CIPHERS)
return self
def __init__(self, protocol):
def __init__(self, protocol
=PROTOCOL_TLS
):
self.protocol = protocol
def wrap_socket(self, sock, server_side=False,
...
...
@@ -438,7 +440,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
if not isinstance(purpose, _ASN1Object):
raise TypeError(purpose)
context = SSLContext(PROTOCOL_
SSLv23
)
context = SSLContext(PROTOCOL_
TLS
)
# SSLv2 considered harmful.
context.options |= OP_NO_SSLv2
...
...
@@ -475,7 +477,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
context.load_default_certs(purpose)
return context
def _create_unverified_context(protocol=PROTOCOL_
SSLv23
, *, cert_reqs=None,
def _create_unverified_context(protocol=PROTOCOL_
TLS
, *, cert_reqs=None,
check_hostname=False, purpose=Purpose.SERVER_AUTH,
certfile=None, keyfile=None,
cafile=None, capath=None, cadata=None):
...
...
@@ -666,7 +668,7 @@ class SSLSocket(socket):
def
__init__
(
self
,
sock
=
None
,
keyfile
=
None
,
certfile
=
None
,
server_side
=
False
,
cert_reqs
=
CERT_NONE
,
ssl_version
=
PROTOCOL_
SSLv23
,
ca_certs
=
None
,
ssl_version
=
PROTOCOL_
TLS
,
ca_certs
=
None
,
do_handshake_on_connect
=
True
,
family
=
AF_INET
,
type
=
SOCK_STREAM
,
proto
=
0
,
fileno
=
None
,
suppress_ragged_eofs
=
True
,
npn_protocols
=
None
,
ciphers
=
None
,
...
...
@@ -1055,7 +1057,7 @@ class SSLSocket(socket):
def
wrap_socket
(
sock
,
keyfile
=
None
,
certfile
=
None
,
server_side
=
False
,
cert_reqs
=
CERT_NONE
,
ssl_version
=
PROTOCOL_
SSLv23
,
ca_certs
=
None
,
ssl_version
=
PROTOCOL_
TLS
,
ca_certs
=
None
,
do_handshake_on_connect
=
True
,
suppress_ragged_eofs
=
True
,
ciphers
=
None
):
...
...
@@ -1124,7 +1126,7 @@ def PEM_cert_to_DER_cert(pem_cert_string):
d
=
pem_cert_string
.
strip
()[
len
(
PEM_HEADER
):
-
len
(
PEM_FOOTER
)]
return
base64
.
decodebytes
(
d
.
encode
(
'ASCII'
,
'strict'
))
def
get_server_certificate
(
addr
,
ssl_version
=
PROTOCOL_
SSLv23
,
ca_certs
=
None
):
def
get_server_certificate
(
addr
,
ssl_version
=
PROTOCOL_
TLS
,
ca_certs
=
None
):
"""Retrieve the certificate from the server at the specified address,
and return it as a PEM-encoded string.
If 'ca_certs' is specified, validate the server cert against it.
...
...
Lib/test/test_ssl.py
View file @
01113fae
...
...
@@ -30,6 +30,9 @@ else:
PROTOCOLS
=
sorted
(
ssl
.
_PROTOCOL_NAMES
)
HOST
=
support
.
HOST
IS_LIBRESSL
=
ssl
.
OPENSSL_VERSION
.
startswith
(
'LibreSSL'
)
IS_OPENSSL_1_1
=
not
IS_LIBRESSL
and
ssl
.
OPENSSL_VERSION_INFO
>=
(
1
,
1
,
0
)
def
data_file
(
*
name
):
return
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
*
name
)
...
...
@@ -150,8 +153,8 @@ class BasicSocketTests(unittest.TestCase):
def
test_str_for_enums
(
self
):
# Make sure that the PROTOCOL_* constants have enum-like string
# reprs.
proto
=
ssl
.
PROTOCOL_
SSLv23
self
.
assertEqual
(
str
(
proto
),
'_SSLMethod.PROTOCOL_
SSLv23
'
)
proto
=
ssl
.
PROTOCOL_
TLS
self
.
assertEqual
(
str
(
proto
),
'_SSLMethod.PROTOCOL_
TLS
'
)
ctx
=
ssl
.
SSLContext
(
proto
)
self
.
assertIs
(
ctx
.
protocol
,
proto
)
...
...
@@ -319,8 +322,8 @@ class BasicSocketTests(unittest.TestCase):
self
.
assertGreaterEqual
(
status
,
0
)
self
.
assertLessEqual
(
status
,
15
)
# Version string as returned by {Open,Libre}SSL, the format might change
if
"LibreSSL"
in
s
:
self
.
assertTrue
(
s
.
startswith
(
"LibreSSL {:d}
.{:d}"
.
format
(
major
,
min
or
)),
if
IS_LIBRESSL
:
self
.
assertTrue
(
s
.
startswith
(
"LibreSSL {:d}
"
.
format
(
maj
or
)),
(
s
,
t
,
hex
(
n
)))
else
:
self
.
assertTrue
(
s
.
startswith
(
"OpenSSL {:d}.{:d}.{:d}"
.
format
(
major
,
minor
,
fix
)),
...
...
@@ -813,7 +816,8 @@ class ContextTests(unittest.TestCase):
def
test_constructor
(
self
):
for
protocol
in
PROTOCOLS
:
ssl
.
SSLContext
(
protocol
)
self
.
assertRaises
(
TypeError
,
ssl
.
SSLContext
)
ctx
=
ssl
.
SSLContext
()
self
.
assertEqual
(
ctx
.
protocol
,
ssl
.
PROTOCOL_TLS
)
self
.
assertRaises
(
ValueError
,
ssl
.
SSLContext
,
-
1
)
self
.
assertRaises
(
ValueError
,
ssl
.
SSLContext
,
42
)
...
...
@@ -834,15 +838,15 @@ class ContextTests(unittest.TestCase):
def
test_options
(
self
):
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
)
# OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
self
.
assertEqual
(
ssl
.
OP_ALL
|
ssl
.
OP_NO_SSLv2
|
ssl
.
OP_NO_SSLv3
,
ctx
.
options
)
default
=
(
ssl
.
OP_ALL
|
ssl
.
OP_NO_SSLv2
|
ssl
.
OP_NO_SSLv3
)
if
not
IS_LIBRESSL
and
ssl
.
OPENSSL_VERSION_INFO
>=
(
1
,
1
,
0
):
default
|=
ssl
.
OP_NO_COMPRESSION
self
.
assertEqual
(
default
,
ctx
.
options
)
ctx
.
options
|=
ssl
.
OP_NO_TLSv1
self
.
assertEqual
(
ssl
.
OP_ALL
|
ssl
.
OP_NO_SSLv2
|
ssl
.
OP_NO_SSLv3
|
ssl
.
OP_NO_TLSv1
,
ctx
.
options
)
self
.
assertEqual
(
default
|
ssl
.
OP_NO_TLSv1
,
ctx
.
options
)
if
can_clear_options
():
ctx
.
options
=
(
ctx
.
options
&
~
ssl
.
OP_NO_SSLv2
)
|
ssl
.
OP_NO_TLSv1
self
.
assertEqual
(
ssl
.
OP_ALL
|
ssl
.
OP_NO_TLSv1
|
ssl
.
OP_NO_SSLv3
,
ctx
.
options
)
ctx
.
options
=
(
ctx
.
options
&
~
ssl
.
OP_NO_TLSv1
)
self
.
assertEqual
(
default
,
ctx
.
options
)
ctx
.
options
=
0
# Ubuntu has OP_NO_SSLv3 forced on by default
self
.
assertEqual
(
0
,
ctx
.
options
&
~
ssl
.
OP_NO_SSLv3
)
...
...
@@ -1178,6 +1182,7 @@ class ContextTests(unittest.TestCase):
self
.
assertRaises
(
TypeError
,
ctx
.
load_default_certs
,
'SERVER_AUTH'
)
@
unittest
.
skipIf
(
sys
.
platform
==
"win32"
,
"not-Windows specific"
)
@
unittest
.
skipIf
(
IS_LIBRESSL
,
"LibreSSL doesn't support env vars"
)
def
test_load_default_certs_env
(
self
):
ctx
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
)
with
support
.
EnvironmentVarGuard
()
as
env
:
...
...
@@ -1668,13 +1673,13 @@ class SimpleBackgroundTests(unittest.TestCase):
sslobj
=
ctx
.
wrap_bio
(
incoming
,
outgoing
,
False
,
'localhost'
)
self
.
assertIs
(
sslobj
.
_sslobj
.
owner
,
sslobj
)
self
.
assertIsNone
(
sslobj
.
cipher
())
self
.
assertIsNone
(
sslobj
.
shared_ciphers
())
self
.
assertIsNo
tNo
ne
(
sslobj
.
shared_ciphers
())
self
.
assertRaises
(
ValueError
,
sslobj
.
getpeercert
)
if
'tls-unique'
in
ssl
.
CHANNEL_BINDING_TYPES
:
self
.
assertIsNone
(
sslobj
.
get_channel_binding
(
'tls-unique'
))
self
.
ssl_io_loop
(
sock
,
incoming
,
outgoing
,
sslobj
.
do_handshake
)
self
.
assertTrue
(
sslobj
.
cipher
())
self
.
assertIsNone
(
sslobj
.
shared_ciphers
())
self
.
assertIsNo
tNo
ne
(
sslobj
.
shared_ciphers
())
self
.
assertTrue
(
sslobj
.
getpeercert
())
if
'tls-unique'
in
ssl
.
CHANNEL_BINDING_TYPES
:
self
.
assertTrue
(
sslobj
.
get_channel_binding
(
'tls-unique'
))
...
...
@@ -2988,7 +2993,7 @@ if _have_threads:
with
context
.
wrap_socket
(
socket
.
socket
())
as
s
:
self
.
assertIs
(
s
.
version
(),
None
)
s
.
connect
((
HOST
,
server
.
port
))
self
.
assertEqual
(
s
.
version
(),
"TLSv1"
)
self
.
assertEqual
(
s
.
version
(),
'TLSv1'
)
self
.
assertIs
(
s
.
version
(),
None
)
@
unittest
.
skipUnless
(
ssl
.
HAS_ECDH
,
"test requires ECDH-enabled OpenSSL"
)
...
...
@@ -3130,24 +3135,36 @@ if _have_threads:
([
'http/3.0'
,
'http/4.0'
],
None
)
]
for
client_protocols
,
expected
in
protocol_tests
:
server_context
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
)
server_context
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
_2
)
server_context
.
load_cert_chain
(
CERTFILE
)
server_context
.
set_alpn_protocols
(
server_protocols
)
client_context
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
)
client_context
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
_2
)
client_context
.
load_cert_chain
(
CERTFILE
)
client_context
.
set_alpn_protocols
(
client_protocols
)
stats
=
server_params_test
(
client_context
,
server_context
,
chatty
=
True
,
connectionchatty
=
True
)
msg
=
"failed trying %s (s) and %s (c).
\
n
"
\
"was expecting %s, but got %%s from the %%s"
\
%
(
str
(
server_protocols
),
str
(
client_protocols
),
str
(
expected
))
client_result
=
stats
[
'client_alpn_protocol'
]
self
.
assertEqual
(
client_result
,
expected
,
msg
%
(
client_result
,
"client"
))
server_result
=
stats
[
'server_alpn_protocols'
][
-
1
]
\
if
len
(
stats
[
'server_alpn_protocols'
])
else
'nothing'
self
.
assertEqual
(
server_result
,
expected
,
msg
%
(
server_result
,
"server"
))
try
:
stats
=
server_params_test
(
client_context
,
server_context
,
chatty
=
True
,
connectionchatty
=
True
)
except
ssl
.
SSLError
as
e
:
stats
=
e
if
expected
is
None
and
IS_OPENSSL_1_1
:
# OpenSSL 1.1.0 raises handshake error
self
.
assertIsInstance
(
stats
,
ssl
.
SSLError
)
else
:
msg
=
"failed trying %s (s) and %s (c).
\
n
"
\
"was expecting %s, but got %%s from the %%s"
\
%
(
str
(
server_protocols
),
str
(
client_protocols
),
str
(
expected
))
client_result
=
stats
[
'client_alpn_protocol'
]
self
.
assertEqual
(
client_result
,
expected
,
msg
%
(
client_result
,
"client"
))
server_result
=
stats
[
'server_alpn_protocols'
][
-
1
]
\
if
len
(
stats
[
'server_alpn_protocols'
])
else
'nothing'
self
.
assertEqual
(
server_result
,
expected
,
msg
%
(
server_result
,
"server"
))
def
test_selected_npn_protocol
(
self
):
# selected_npn_protocol() is None unless NPN is used
...
...
@@ -3295,13 +3312,23 @@ if _have_threads:
client_context
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_TLSv1
)
client_context
.
verify_mode
=
ssl
.
CERT_REQUIRED
client_context
.
load_verify_locations
(
SIGNING_CA
)
client_context
.
set_ciphers
(
"RC4"
)
server_context
.
set_ciphers
(
"AES:RC4"
)
if
ssl
.
OPENSSL_VERSION_INFO
>=
(
1
,
0
,
2
):
client_context
.
set_ciphers
(
"AES128:AES256"
)
server_context
.
set_ciphers
(
"AES256"
)
alg1
=
"AES256"
alg2
=
"AES-256"
else
:
client_context
.
set_ciphers
(
"AES:3DES"
)
server_context
.
set_ciphers
(
"3DES"
)
alg1
=
"3DES"
alg2
=
"DES-CBC3"
stats
=
server_params_test
(
client_context
,
server_context
)
ciphers
=
stats
[
'server_shared_ciphers'
][
0
]
self
.
assertGreater
(
len
(
ciphers
),
0
)
for
name
,
tls_version
,
bits
in
ciphers
:
self
.
assertIn
(
"RC4"
,
name
.
split
(
"-"
))
if
not
alg1
in
name
.
split
(
"-"
)
and
alg2
not
in
name
:
self
.
fail
(
name
)
def
test_read_write_after_close_raises_valuerror
(
self
):
context
=
ssl
.
SSLContext
(
ssl
.
PROTOCOL_SSLv23
)
...
...
Misc/NEWS
View file @
01113fae
...
...
@@ -75,6 +75,8 @@ Core and Builtins
Library
-------
- Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0.
- Issue #11620: Fix support for SND_MEMORY in winsound.PlaySound. Based on a
patch by Tim Lesher.
...
...
Modules/_hashopenssl.c
View file @
01113fae
...
...
@@ -21,7 +21,6 @@
/* EVP is the preferred interface to hashing in OpenSSL */
#include <openssl/evp.h>
#include <openssl/hmac.h>
/* We use the object interface to discover what hashes OpenSSL supports. */
#include <openssl/objects.h>
#include "openssl/err.h"
...
...
@@ -32,11 +31,22 @@
#define HASH_OBJ_CONSTRUCTOR 0
#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 <openssl/hmac.h>
#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
...
...
@@ -48,7 +58,6 @@ static PyTypeObject EVPtype;
#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
)
...
...
@@ -59,19 +68,57 @@ DEFINE_CONSTS_FOR_NEW(sha384)
DEFINE_CONSTS_FOR_NEW
(
sha512
)
/* LCOV_EXCL_START */
static
PyObject
*
_setException
(
PyObject
*
exc
)
{
unsigned
long
errcode
;
const
char
*
lib
,
*
func
,
*
reason
;
errcode
=
ERR_peek_last_error
();
if
(
!
errcode
)
{
PyErr_SetString
(
exc
,
"unknown reasons"
);
return
NULL
;
}
ERR_clear_error
();
lib
=
ERR_lib_error_string
(
errcode
);
func
=
ERR_func_error_string
(
errcode
);
reason
=
ERR_reason_error_string
(
errcode
);
if
(
lib
&&
func
)
{
PyErr_Format
(
exc
,
"[%s: %s] %s"
,
lib
,
func
,
reason
);
}
else
if
(
lib
)
{
PyErr_Format
(
exc
,
"[%s] %s"
,
lib
,
reason
);
}
else
{
PyErr_SetString
(
exc
,
reason
);
}
return
NULL
;
}
/* LCOV_EXCL_STOP */
static
EVPobject
*
newEVPobject
(
PyObject
*
name
)
{
EVPobject
*
retval
=
(
EVPobject
*
)
PyObject_New
(
EVPobject
,
&
EVPtype
);
if
(
retval
==
NULL
)
{
return
NULL
;
}
retval
->
ctx
=
EVP_MD_CTX_new
();
if
(
retval
->
ctx
==
NULL
)
{
PyErr_NoMemory
();
return
NULL
;
}
/* save the name for .name to return */
if
(
retval
!=
NULL
)
{
Py_INCREF
(
name
);
retval
->
name
=
name
;
Py_INCREF
(
name
);
retval
->
name
=
name
;
#ifdef WITH_THREAD
retval
->
lock
=
NULL
;
retval
->
lock
=
NULL
;
#endif
}
return
retval
;
}
...
...
@@ -86,7 +133,7 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
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
;
}
...
...
@@ -101,16 +148,19 @@ EVP_dealloc(EVPobject *self)
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
);
}
static
void
locked_EVP_MD_CTX_copy
(
EVP_MD_CTX
*
new_ctx_p
,
EVPobject
*
self
)
static
int
locked_EVP_MD_CTX_copy
(
EVP_MD_CTX
*
new_ctx_p
,
EVPobject
*
self
)
{
int
result
;
ENTER_HASHLIB
(
self
);
EVP_MD_CTX_copy
(
new_ctx_p
,
&
self
->
ctx
);
result
=
EVP_MD_CTX_copy
(
new_ctx_p
,
self
->
ctx
);
LEAVE_HASHLIB
(
self
);
return
result
;
}
/* External methods for a hash object */
...
...
@@ -126,7 +176,9 @@ EVP_copy(EVPobject *self, PyObject *unused)
if
(
(
newobj
=
newEVPobject
(
self
->
name
))
==
NULL
)
return
NULL
;
locked_EVP_MD_CTX_copy
(
&
newobj
->
ctx
,
self
);
if
(
!
locked_EVP_MD_CTX_copy
(
newobj
->
ctx
,
self
))
{
return
_setException
(
PyExc_ValueError
);
}
return
(
PyObject
*
)
newobj
;
}
...
...
@@ -137,16 +189,24 @@ static PyObject *
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
);
digest_size
=
EVP_MD_CTX_size
(
&
temp_ctx
);
EVP_DigestFinal
(
&
temp_ctx
,
digest
,
NULL
);
temp_ctx
=
EVP_MD_CTX_new
();
if
(
temp_ctx
==
NULL
)
{
PyErr_NoMemory
();
return
NULL
;
}
if
(
!
locked_EVP_MD_CTX_copy
(
temp_ctx
,
self
))
{
return
_setException
(
PyExc_ValueError
);
}
digest_size
=
EVP_MD_CTX_size
(
temp_ctx
);
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
;
}
...
...
@@ -157,15 +217,23 @@ static PyObject *
EVP_hexdigest
(
EVPobject
*
self
,
PyObject
*
unused
)
{
unsigned
char
digest
[
EVP_MAX_MD_SIZE
];
EVP_MD_CTX
temp_ctx
;
EVP_MD_CTX
*
temp_ctx
;
unsigned
int
digest_size
;
temp_ctx
=
EVP_MD_CTX_new
();
if
(
temp_ctx
==
NULL
)
{
PyErr_NoMemory
();
return
NULL
;
}
/* 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
);
if
(
!
locked_EVP_MD_CTX_copy
(
temp_ctx
,
self
))
{
return
_setException
(
PyExc_ValueError
);
}
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
);
return
_Py_strhex
((
const
char
*
)
digest
,
digest_size
);
}
...
...
@@ -219,7 +287,7 @@ static PyObject *
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
);
}
...
...
@@ -227,7 +295,7 @@ static PyObject *
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
);
}
...
...
@@ -288,7 +356,7 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
PyBuffer_Release
(
&
view
);
return
-
1
;
}
EVP_DigestInit
(
&
self
->
ctx
,
digest
);
EVP_DigestInit
(
self
->
ctx
,
digest
);
self
->
name
=
name_obj
;
Py_INCREF
(
self
->
name
);
...
...
@@ -385,9 +453,9 @@ EVPnew(PyObject *name_obj,
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
)
{
...
...
@@ -453,6 +521,7 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
#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
...
...
@@ -534,37 +603,8 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen,
HMAC_CTX_cleanup
(
&
hctx_tpl
);
return
1
;
}
#endif
/* LCOV_EXCL_START */
static
PyObject
*
_setException
(
PyObject
*
exc
)
{
unsigned
long
errcode
;
const
char
*
lib
,
*
func
,
*
reason
;
errcode
=
ERR_peek_last_error
();
if
(
!
errcode
)
{
PyErr_SetString
(
exc
,
"unknown reasons"
);
return
NULL
;
}
ERR_clear_error
();
lib
=
ERR_lib_error_string
(
errcode
);
func
=
ERR_func_error_string
(
errcode
);
reason
=
ERR_reason_error_string
(
errcode
);
if
(
lib
&&
func
)
{
PyErr_Format
(
exc
,
"[%s: %s] %s"
,
lib
,
func
,
reason
);
}
else
if
(
lib
)
{
PyErr_Format
(
exc
,
"[%s] %s"
,
lib
,
reason
);
}
else
{
PyErr_SetString
(
exc
,
reason
);
}
return
NULL
;
}
/* LCOV_EXCL_STOP */
PyDoc_STRVAR
(
pbkdf2_hmac__doc__
,
"pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key
\n
\
...
...
@@ -646,10 +686,17 @@ pbkdf2_hmac(PyObject *self, PyObject *args, PyObject *kwdict)
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
)
{
...
...
@@ -768,7 +815,7 @@ generate_hash_name_list(void)
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)); \
} \
} \
...
...
Modules/_ssl.c
View file @
01113fae
This diff is collapsed.
Click to expand it.
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