Skip to content

Commit bdb7639

Browse files
reaperhulkalex
authored andcommitted
Export keying material support (#725)
* added method to export keying material from an ssl connection * updated tests to use bytestrings to avoid breaking python3 tests * added additional comments to test * simplify export_keying_material * add changelog * address review feedback
1 parent e738186 commit bdb7639

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-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

2626
- Fixed a potential use-after-free in the verify callback and resolved a memory leak when loading PKCS12 files with ``cacerts``.
2727
`#723 <https://github.com/pyca/pyopenssl/pull/723>`_
28+
- Added ``Connection.export_keying_material`` for RFC 5705 compatible export of keying material.
29+
`#725 <https://github.com/pyca/pyopenssl/pull/725>`_
2830

2931
----
3032

src/OpenSSL/SSL.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,6 +2031,30 @@ def master_key(self):
20312031
_lib.SSL_SESSION_get_master_key(session, outp, length)
20322032
return _ffi.buffer(outp, length)[:]
20332033

2034+
def export_keying_material(self, label, olen, context=None):
2035+
"""
2036+
Obtain keying material for application use.
2037+
2038+
:param label - a disambiguating label string as described in RFC 5705
2039+
:param olen - the length of the exported key material in bytes
2040+
:param context - a per-association context value
2041+
:return the exported key material bytes or None
2042+
"""
2043+
outp = _no_zero_allocator("unsigned char[]", olen)
2044+
context_buf = _ffi.NULL
2045+
context_len = 0
2046+
use_context = 0
2047+
if context is not None:
2048+
context_buf = context
2049+
context_len = len(context)
2050+
use_context = 1
2051+
success = _lib.SSL_export_keying_material(self._ssl, outp, olen,
2052+
label, len(label),
2053+
context_buf, context_len,
2054+
use_context)
2055+
_openssl_assert(success == 1)
2056+
return _ffi.buffer(outp, olen)[:]
2057+
20342058
def sock_shutdown(self, *args, **kwargs):
20352059
"""
20362060
See shutdown(2)

tests/test_ssl.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3379,6 +3379,28 @@ def test_memory_connect(self):
33793379
assert server_conn.client_random() != server_conn.server_random()
33803380
assert client_conn.client_random() != client_conn.server_random()
33813381

3382+
# Export key material for other uses.
3383+
cekm = client_conn.export_keying_material(b'LABEL', 32)
3384+
sekm = server_conn.export_keying_material(b'LABEL', 32)
3385+
assert cekm is not None
3386+
assert sekm is not None
3387+
assert cekm == sekm
3388+
assert len(sekm) == 32
3389+
3390+
# Export key material for other uses with additional context.
3391+
cekmc = client_conn.export_keying_material(b'LABEL', 32, b'CONTEXT')
3392+
sekmc = server_conn.export_keying_material(b'LABEL', 32, b'CONTEXT')
3393+
assert cekmc is not None
3394+
assert sekmc is not None
3395+
assert cekmc == sekmc
3396+
assert cekmc != cekm
3397+
assert sekmc != sekm
3398+
# Export with alternate label
3399+
cekmt = client_conn.export_keying_material(b'test', 32, b'CONTEXT')
3400+
sekmt = server_conn.export_keying_material(b'test', 32, b'CONTEXT')
3401+
assert cekmc != cekmt
3402+
assert sekmc != sekmt
3403+
33823404
# Here are the bytes we'll try to send.
33833405
important_message = b'One if by land, two if by sea.'
33843406

0 commit comments

Comments
 (0)