Skip to content

Commit d62d7fc

Browse files
committed
Add Connection.get_selected_srtp_profile (#1278)
If an SRTP profile was negotiated as part of the handshake, make it possible to retrieve the name of the profile. This is needed to determine which profiles were offered using `Context.set_tlsext_use_srtp` was actually selected.
1 parent abf91d7 commit d62d7fc

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

CHANGELOG.rst

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Changes:
3535
to the now deprecated ``OpenSSL.crypto.CRL`` arguments.
3636
- Fixed ``test_set_default_verify_paths`` test so that it is skipped if no
3737
network connection is available.
38+
- Added ``OpenSSL.SSL.Connection.get_selected_srtp_profile`` to determine which SRTP profile was negotiated.
39+
`#1279 <https://github.com/pyca/pyopenssl/pull/1279>`_.
3840

3941
23.2.0 (2023-05-30)
4042
-------------------

src/OpenSSL/SSL.py

+13
Original file line numberDiff line numberDiff line change
@@ -2858,6 +2858,19 @@ def get_alpn_proto_negotiated(self):
28582858

28592859
return _ffi.buffer(data[0], data_len[0])[:]
28602860

2861+
def get_selected_srtp_profile(self):
2862+
"""
2863+
Get the SRTP protocol which was negotiated.
2864+
2865+
:returns: A bytestring of the SRTP profile name. If no profile has been
2866+
negotiated yet, returns an empty bytestring.
2867+
"""
2868+
profile = _lib.SSL_get_selected_srtp_profile(self._ssl)
2869+
if not profile:
2870+
return b""
2871+
2872+
return _ffi.string(profile.name)
2873+
28612874
def request_ocsp(self):
28622875
"""
28632876
Called to request that the server sends stapled OCSP data, if

tests/test_ssl.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -4380,7 +4380,7 @@ class TestDTLS:
43804380
# Arbitrary number larger than any conceivable handshake volley.
43814381
LARGE_BUFFER = 65536
43824382

4383-
def test_it_works_at_all(self):
4383+
def _test_handshake_and_data(self, srtp_profile):
43844384
s_ctx = Context(DTLS_METHOD)
43854385

43864386
def generate_cookie(ssl):
@@ -4394,11 +4394,15 @@ def verify_cookie(ssl, cookie):
43944394
s_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
43954395
s_ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
43964396
s_ctx.set_options(OP_NO_QUERY_MTU)
4397+
if srtp_profile is not None:
4398+
s_ctx.set_tlsext_use_srtp(srtp_profile)
43974399
s = Connection(s_ctx)
43984400
s.set_accept_state()
43994401

44004402
c_ctx = Context(DTLS_METHOD)
44014403
c_ctx.set_options(OP_NO_QUERY_MTU)
4404+
if srtp_profile is not None:
4405+
c_ctx.set_tlsext_use_srtp(srtp_profile)
44024406
c = Connection(c_ctx)
44034407
c.set_connect_state()
44044408

@@ -4480,6 +4484,14 @@ def pump():
44804484
pump()
44814485
assert s.read(100) == b"goodbye"
44824486

4487+
# Check whether SRTP was negotiated
4488+
if srtp_profile is not None:
4489+
assert s.get_selected_srtp_profile() == srtp_profile
4490+
assert c.get_selected_srtp_profile() == srtp_profile
4491+
else:
4492+
assert s.get_selected_srtp_profile() == b""
4493+
assert c.get_selected_srtp_profile() == b""
4494+
44834495
# Check that the MTU set/query functions are doing *something*
44844496
c.set_ciphertext_mtu(1000)
44854497
try:
@@ -4492,6 +4504,12 @@ def pump():
44924504
except NotImplementedError: # OpenSSL 1.1.0 and earlier
44934505
pass
44944506

4507+
def test_it_works_at_all(self):
4508+
self._test_handshake_and_data(srtp_profile=None)
4509+
4510+
def test_it_works_with_srtp(self):
4511+
self._test_handshake_and_data(srtp_profile=b"SRTP_AES128_CM_SHA1_80")
4512+
44954513
def test_timeout(self, monkeypatch):
44964514
c_ctx = Context(DTLS_METHOD)
44974515
c = Connection(c_ctx)

0 commit comments

Comments
 (0)