Skip to content

Commit e05eac4

Browse files
committed
add Connection.use_(certificate|privatekey)
1 parent 8e9f0c2 commit e05eac4

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ Deprecations:
1919
Changes:
2020
^^^^^^^^
2121

22+
- Add ``OpenSSL.SSL.Connection.use_certificate`` and ``OpenSSL.SSL.Connection.use_privatekey``
23+
to set a certificate per connection (and not just per context) `#1121 <https://github.com/pyca/pyopenssl/pull/1121>`_.
24+
2225
22.0.0 (2022-01-29)
2326
-------------------
2427

src/OpenSSL/SSL.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,7 @@ def use_certificate(self, cert):
948948
:param cert: The X509 object
949949
:return: None
950950
"""
951+
# Mirrored at Connection.use_certificate
951952
if not isinstance(cert, X509):
952953
raise TypeError("cert must be an X509 instance")
953954

@@ -1009,6 +1010,7 @@ def use_privatekey(self, pkey):
10091010
:param pkey: The PKey object
10101011
:return: None
10111012
"""
1013+
# Mirrored at Connection.use_privatekey
10121014
if not isinstance(pkey, PKey):
10131015
raise TypeError("pkey must be a PKey instance")
10141016

@@ -1745,6 +1747,36 @@ def get_servername(self):
17451747

17461748
return _ffi.string(name)
17471749

1750+
def use_certificate(self, cert):
1751+
"""
1752+
Load a certificate from a X509 object
1753+
1754+
:param cert: The X509 object
1755+
:return: None
1756+
"""
1757+
# Mirrored from Context.use_certificate
1758+
if not isinstance(cert, X509):
1759+
raise TypeError("cert must be an X509 instance")
1760+
1761+
use_result = _lib.SSL_use_certificate(self._ssl, cert._x509)
1762+
if not use_result:
1763+
_raise_current_error()
1764+
1765+
def use_privatekey(self, pkey):
1766+
"""
1767+
Load a private key from a PKey object
1768+
1769+
:param pkey: The PKey object
1770+
:return: None
1771+
"""
1772+
# Mirrored from Context.use_privatekey
1773+
if not isinstance(pkey, PKey):
1774+
raise TypeError("pkey must be a PKey instance")
1775+
1776+
use_result = _lib.SSL_use_PrivateKey(self._ssl, pkey._pkey)
1777+
if not use_result:
1778+
self._context._raise_passphrase_exception()
1779+
17481780
def set_ciphertext_mtu(self, mtu):
17491781
"""
17501782
For DTLS, set the maximum UDP payload size (*not* including IP/UDP

tests/test_ssl.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ def test_use_privatekey(self):
625625
"""
626626
`Context.use_privatekey` takes an `OpenSSL.crypto.PKey` instance.
627627
"""
628+
# Mirrored at TestConnection.test_use_privatekey
628629
key = PKey()
629630
key.generate_key(TYPE_RSA, 1024)
630631
ctx = Context(SSLv23_METHOD)
@@ -709,6 +710,7 @@ def test_use_certificate(self):
709710
`Context.use_certificate` sets the certificate which will be
710711
used to identify connections created using the context.
711712
"""
713+
# Mirrored at TestConnection.test_use_certificate
712714
# TODO
713715
# Hard to assert anything. But we could set a privatekey then ask
714716
# OpenSSL if the cert and key agree using check_privatekey. Then as
@@ -2206,6 +2208,31 @@ def test_type(self):
22062208
ctx = Context(SSLv23_METHOD)
22072209
assert is_consistent_type(Connection, "Connection", ctx, None)
22082210

2211+
def test_use_privatekey(self):
2212+
"""
2213+
`Connection.use_privatekey` takes an `OpenSSL.crypto.PKey` instance.
2214+
"""
2215+
# Mirrored from TestContext.test_use_privatekey
2216+
key = PKey()
2217+
key.generate_key(TYPE_RSA, 1024)
2218+
ctx = Context(SSLv23_METHOD)
2219+
connection = Connection(ctx, None)
2220+
connection.use_privatekey(key)
2221+
with pytest.raises(TypeError):
2222+
connection.use_privatekey("")
2223+
2224+
def test_use_certificate(self):
2225+
"""
2226+
`Connection.use_certificate` sets the certificate which will be
2227+
used to identify connections created using the context.
2228+
"""
2229+
# Mirrored from TestContext.test_use_certificate
2230+
ctx = Context(SSLv23_METHOD)
2231+
connection = Connection(ctx, None)
2232+
connection.use_certificate(
2233+
load_certificate(FILETYPE_PEM, root_cert_pem)
2234+
)
2235+
22092236
@pytest.mark.parametrize("bad_context", [object(), "context", None, 1])
22102237
def test_wrong_args(self, bad_context):
22112238
"""

0 commit comments

Comments
 (0)