Skip to content

Commit 9ab0686

Browse files
[RTC-18] Don't raise in protect and unprotect (#14)
1 parent 35cc769 commit 9ab0686

File tree

5 files changed

+147
-22
lines changed

5 files changed

+147
-22
lines changed

c_src/ex_libsrtp/srtp.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ UNIFEX_TERM protect(UnifexEnv *env, UnifexState *state, char *what,
254254
use_mki, mki_index);
255255
if (serr) {
256256
unifex_payload_free_clone(protected);
257-
return unifex_raise(env, srtp_util_strerror(serr));
257+
return protect_result_error(env, srtp_util_error_to_atom(serr));
258258
}
259259

260260
err = unifex_payload_realloc(protected, len);
@@ -283,19 +283,7 @@ UNIFEX_TERM unprotect(UnifexEnv *env, UnifexState *state, char *what,
283283
use_mki);
284284
if (serr) {
285285
unifex_payload_free_clone(unprotected);
286-
287-
switch (serr) {
288-
case srtp_err_status_auth_fail:
289-
return unprotect_result_error_auth_fail(env);
290-
case srtp_err_status_replay_fail:
291-
return unprotect_result_error_replay_fail(env);
292-
case srtp_err_status_bad_mki:
293-
return unprotect_result_error_bad_mki(env);
294-
case srtp_err_status_replay_old:
295-
return unprotect_result_error_replay_too_old(env);
296-
default:
297-
return unifex_raise(env, srtp_util_strerror(serr));
298-
}
286+
return unprotect_result_error(env, srtp_util_error_to_atom(serr));
299287
}
300288

301289
err = unifex_payload_realloc(unprotected, len);

c_src/ex_libsrtp/srtp.spec.exs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,8 @@ spec update(
3535

3636
spec protect(state, what :: atom, payload, use_mki :: bool, mki_index :: unsigned) ::
3737
{:ok :: label, payload}
38+
| {:error :: label, reason :: atom}
3839

3940
spec unprotect(state, what :: atom, payload, use_mki :: bool) ::
4041
{:ok :: label, payload}
41-
| {:error :: label, :auth_fail :: label}
42-
| {:error :: label, :replay_fail :: label}
43-
| {:error :: label, :bad_mki :: label}
44-
| {:error :: label, :replay_too_old :: label}
42+
| {:error :: label, reason :: atom}

c_src/ex_libsrtp/srtp_util.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,67 @@ const char *srtp_util_strerror(srtp_err_status_t err) {
181181
return "srtp: unknown error";
182182
}
183183
}
184+
185+
const char *srtp_util_error_to_atom(srtp_err_status_t err) {
186+
switch (err) {
187+
case srtp_err_status_ok:
188+
// hardly an error, but let's leave it here for completeness sake
189+
return "ok";
190+
case srtp_err_status_fail:
191+
return "fail";
192+
case srtp_err_status_bad_param:
193+
return "bad_param";
194+
case srtp_err_status_alloc_fail:
195+
return "alloc_fail";
196+
case srtp_err_status_dealloc_fail:
197+
return "dealloc_fail";
198+
case srtp_err_status_init_fail:
199+
return "init_fail";
200+
case srtp_err_status_terminus:
201+
return "terminus";
202+
case srtp_err_status_auth_fail:
203+
return "auth_fail";
204+
case srtp_err_status_cipher_fail:
205+
return "cipher_fail";
206+
case srtp_err_status_replay_fail:
207+
return "replay_fail";
208+
case srtp_err_status_replay_old:
209+
return "replay_old";
210+
case srtp_err_status_algo_fail:
211+
return "algo_fail";
212+
case srtp_err_status_no_such_op:
213+
return "no_such_op";
214+
case srtp_err_status_no_ctx:
215+
return "no_ctx";
216+
case srtp_err_status_cant_check:
217+
return "cant_check";
218+
case srtp_err_status_key_expired:
219+
return "key_expired";
220+
case srtp_err_status_socket_err:
221+
return "socket_err";
222+
case srtp_err_status_signal_err:
223+
return "signal_err";
224+
case srtp_err_status_nonce_bad:
225+
return "nonce_bad";
226+
case srtp_err_status_read_fail:
227+
return "read_fail";
228+
case srtp_err_status_write_fail:
229+
return "write_fail";
230+
case srtp_err_status_parse_err:
231+
return "parse_err";
232+
case srtp_err_status_encode_err:
233+
return "encode_err";
234+
case srtp_err_status_semaphore_err:
235+
return "semaphore_err";
236+
case srtp_err_status_pfkey_err:
237+
return "pfkey_err";
238+
case srtp_err_status_bad_mki:
239+
return "bad_mki";
240+
case srtp_err_status_pkt_idx_old:
241+
return "pkt_idx_old";
242+
case srtp_err_status_pkt_idx_adv:
243+
return "pkt_idx_adv";
244+
default:
245+
return "unknown";
246+
}
247+
}

c_src/ex_libsrtp/srtp_util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
#include <stdbool.h>
55

66
const char *srtp_util_strerror(srtp_err_status_t err);
7+
78
bool srtp_util_unmarshal_ssrc(int ssrc_type, unsigned int ssrc,
89
srtp_ssrc_t *result);
10+
911
bool srtp_util_set_crypto_policy_from_crypto_profile_atom(
1012
char *crypto_profile, srtp_crypto_policy_t *policy);
13+
14+
const char *srtp_util_error_to_atom(srtp_err_status_t err);

lib/ex_libsrtp.ex

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,42 @@ defmodule ExLibSRTP do
1212

1313
alias ExLibSRTP.{Native, Policy}
1414

15+
@typedoc """
16+
Type describing possible errors that might be returned by ExLibSRTP functions.
17+
18+
Meaning of these might vary depending on the function. For explanation, please refer to
19+
appropriate documentation.
20+
21+
This type is based on [`srtp_err_status_t` enum](https://github.com/cisco/libsrtp/blob/004b7bb85caf4f52a7cc8a7aad94d9d1706e8b6d/include/srtp.h#L164).
22+
"""
23+
@type libsrtp_error_t() ::
24+
:fail
25+
| :bad_param
26+
| :alloc_fail
27+
| :dealloc_fail
28+
| :init_fail
29+
| :terminus
30+
| :auth_fail
31+
| :cipher_fail
32+
| :replay_fail
33+
| :replay_old
34+
| :algo_fail
35+
| :no_such_op
36+
| :no_ctx
37+
| :cant_check
38+
| :key_expired
39+
| :socket_err
40+
| :signal_err
41+
| :nonce_bad
42+
| :read_fail
43+
| :write_fail
44+
| :parse_err
45+
| :encode_err
46+
| :semaphore_err
47+
| :pfkey_err
48+
| :bad_mki
49+
| :pkt_idx_old
50+
1551
@opaque t :: {__MODULE__, native :: reference}
1652

1753
@type ssrc_t :: 0..4_294_967_295
@@ -72,8 +108,18 @@ defmodule ExLibSRTP do
72108
)
73109
end
74110

111+
@doc """
112+
Protect RTP packet.
113+
114+
Most common errors:
115+
- `:replay_fail` - packet has either a duplicate sequence number or its sequence number has an old rollover counter (roc)
116+
- `:replay_old` - packet has a sequence number with current roc, but it is older than the beginning of the encryption window.
117+
- `:bad_mki` - provided MKI is not a known MKI id
118+
119+
Other errors indicate a failure in cryptographic mechanisms, please refer to [libsrtp documentation](https://github.com/cisco/libsrtp)
120+
"""
75121
@spec protect(t(), unprotected :: binary(), mki_index :: pos_integer() | nil) ::
76-
{:ok, protected :: binary()}
122+
{:ok, protected :: binary()} | {:error, libsrtp_error_t()}
77123
def protect(srtp, unprotected, mki_index \\ nil)
78124

79125
def protect(ref(native), unprotected, nil) do
@@ -84,8 +130,13 @@ defmodule ExLibSRTP do
84130
Native.protect(native, :rtp, unprotected, true, mki_index)
85131
end
86132

133+
@doc """
134+
Protect RTCP packet.
135+
136+
All errors indicate an error in the cryptographic mechanisms.
137+
"""
87138
@spec protect_rtcp(t(), unprotected :: binary(), mki_index :: pos_integer() | nil) ::
88-
{:ok, protected :: binary()}
139+
{:ok, protected :: binary()} | {:error, libsrtp_error_t()}
89140
def protect_rtcp(srtp, unprotected, mki_index \\ nil)
90141

91142
def protect_rtcp(ref(native), unprotected, nil) do
@@ -96,14 +147,34 @@ defmodule ExLibSRTP do
96147
Native.protect(native, :rtcp, unprotected, true, mki_index)
97148
end
98149

150+
@doc """
151+
Unprotect RTP packet.
152+
153+
Most common errors:
154+
- `:replay_fail` - packet has either a duplicate sequence number or its sequence number has an old rollover counter (roc)
155+
- `:replay_old` - packet has a sequence number with current roc, but it is older than the beginning of the decryption window.
156+
- `:auth_fail` - packet has failed the message authentication check
157+
158+
Other errors indicate a failure in cryptographic mechanisms, please refer to [libsrtp documentation](https://github.com/cisco/libsrtp)
159+
"""
99160
@spec unprotect(t(), protected :: binary(), use_mki :: boolean()) ::
100-
{:ok, unprotected :: binary()} | {:error, :auth_fail | :reply_fail | :bad_mki}
161+
{:ok, unprotected :: binary()} | {:error, libsrtp_error_t()}
101162
def unprotect(ref(native) = _srtp, protected, use_mki \\ false) do
102163
Native.unprotect(native, :rtp, protected, use_mki)
103164
end
104165

166+
@doc """
167+
Unprotect RTCP packet.
168+
169+
Expected errors:
170+
- `:auth_fail` - SRTCP message has failed the message authentication check.
171+
- `:replay_fail` - SRTCP message is a duplicate
172+
- `:bad_mki` - provided MKI is not a known MKI id
173+
174+
Other errors indicate issues in the cryptographic mechanisms.
175+
"""
105176
@spec unprotect_rtcp(t(), protected :: binary(), use_mki :: boolean()) ::
106-
{:ok, unprotected :: binary()} | {:error, :auth_fail | :reply_fail | :bad_mki}
177+
{:ok, unprotected :: binary()} | {:error, libsrtp_error_t()}
107178
def unprotect_rtcp(ref(native) = _srtp, protected, use_mki \\ false) do
108179
Native.unprotect(native, :rtcp, protected, use_mki)
109180
end

0 commit comments

Comments
 (0)