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
0f3d86a4
Commit
0f3d86a4
authored
Sep 05, 2016
by
Christian Heimes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #26470: Port ssl and hashlib module to OpenSSL 1.1.0.
parent
59480444
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
393 additions
and
164 deletions
+393
-164
Doc/library/ssl.rst
Doc/library/ssl.rst
+81
-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 @
0f3d86a4
This diff is collapsed.
Click to expand it.
Lib/ssl.py
View file @
0f3d86a4
...
...
@@ -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
,
...
...
@@ -1056,7 +1058,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
):
...
...
@@ -1125,7 +1127,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 @
0f3d86a4
...
...
@@ -23,6 +23,9 @@ ssl = support.import_module("ssl")
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
)
...
...
@@ -143,8 +146,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
)
...
...
@@ -312,8 +315,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
)),
...
...
@@ -790,7 +793,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
)
...
...
@@ -811,15 +815,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
)
...
...
@@ -1155,6 +1159,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
:
...
...
@@ -1750,13 +1755,13 @@ class NetworkedBIOTests(unittest.TestCase):
sslobj
=
ctx
.
wrap_bio
(
incoming
,
outgoing
,
False
,
REMOTE_HOST
)
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'
))
...
...
@@ -2993,7 +2998,7 @@ else:
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"
)
...
...
@@ -3135,24 +3140,36 @@ else:
([
'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
...
...
@@ -3300,13 +3317,23 @@ else:
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 @
0f3d86a4
...
...
@@ -60,6 +60,8 @@ Core and Builtins
Library
-------
-
Issue
#
26470
:
Port
ssl
and
hashlib
module
to
OpenSSL
1.1.0
.
-
Issue
#
12885
:
Fix
error
when
distutils
encounters
symlink
.
-
Issue
#
27881
:
Fixed
possible
bugs
when
setting
sqlite3
.
Connection
.
isolation_level
.
...
...
Modules/_hashopenssl.c
View file @
0f3d86a4
...
...
@@ -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 @
0f3d86a4
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