Skip to content

Commit d3c13ac

Browse files
committed
add Connection.use_(certificate|privatekey)
1 parent a145fc3 commit d3c13ac

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Changes:
2525
- Add ``OpenSSL.SSL.Connection.set_verify`` and ``OpenSSL.SSL.Connection.get_verify_mode``
2626
to override the context object's verification flags.
2727
`#1073 <https://github.com/pyca/pyopenssl/pull/1073>`_
28+
- Add ``OpenSSL.SSL.Connection.use_certificate`` and ``OpenSSL.SSL.Connection.use_privatekey``
29+
to set a certificate per connection (and not just per context) `#1121 <https://github.com/pyca/pyopenssl/pull/1121>`_.
2830

2931
22.0.0 (2022-01-29)
3032
-------------------

src/OpenSSL/SSL.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ def use_certificate(self, cert):
954954
:param cert: The X509 object
955955
:return: None
956956
"""
957+
# Mirrored at Connection.use_certificate
957958
if not isinstance(cert, X509):
958959
raise TypeError("cert must be an X509 instance")
959960

@@ -1015,6 +1016,7 @@ def use_privatekey(self, pkey):
10151016
:param pkey: The PKey object
10161017
:return: None
10171018
"""
1019+
# Mirrored at Connection.use_privatekey
10181020
if not isinstance(pkey, PKey):
10191021
raise TypeError("pkey must be a PKey instance")
10201022

@@ -1780,6 +1782,36 @@ def get_verify_mode(self):
17801782
"""
17811783
return _lib.SSL_get_verify_mode(self._ssl)
17821784

1785+
def use_certificate(self, cert):
1786+
"""
1787+
Load a certificate from a X509 object
1788+
1789+
:param cert: The X509 object
1790+
:return: None
1791+
"""
1792+
# Mirrored from Context.use_certificate
1793+
if not isinstance(cert, X509):
1794+
raise TypeError("cert must be an X509 instance")
1795+
1796+
use_result = _lib.SSL_use_certificate(self._ssl, cert._x509)
1797+
if not use_result:
1798+
_raise_current_error()
1799+
1800+
def use_privatekey(self, pkey):
1801+
"""
1802+
Load a private key from a PKey object
1803+
1804+
:param pkey: The PKey object
1805+
:return: None
1806+
"""
1807+
# Mirrored from Context.use_privatekey
1808+
if not isinstance(pkey, PKey):
1809+
raise TypeError("pkey must be a PKey instance")
1810+
1811+
use_result = _lib.SSL_use_PrivateKey(self._ssl, pkey._pkey)
1812+
if not use_result:
1813+
self._context._raise_passphrase_exception()
1814+
17831815
def set_ciphertext_mtu(self, mtu):
17841816
"""
17851817
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)