@@ -19,8 +19,8 @@ defmodule ExSTUN.Message do
19
19
```
20
20
"""
21
21
import Bitwise
22
- alias ExSTUN.Message.Attribute.Fingerprint
23
- alias ExSTUN.Message.Attribute . { MessageIntegrity , Realm , Username }
22
+
23
+ alias ExSTUN.Message.Attribute . { Fingerprint , MessageIntegrity }
24
24
alias ExSTUN.Message . { RawAttribute , Type }
25
25
26
26
@ magic_cookie 0x2112A442
@@ -221,74 +221,40 @@ defmodule ExSTUN.Message do
221
221
end
222
222
223
223
@ doc """
224
- Authenticates a message long-term mechanism.
225
-
226
- `password` depends on the STUN authentication method and has to
227
- be provided from the outside.
228
-
229
- `key` is a key used for calculating MAC and can be used
230
- for adding message integrity in a response. See `with_integrity/2`.
224
+ Create longe-term authentication key.
231
225
"""
232
- @ spec authenticate_lt ( t ( ) , binary ( ) ) ::
233
- { :ok , key :: binary ( ) }
234
- | { :error ,
235
- :no_message_integrity
236
- | :no_username
237
- | :no_realm
238
- | :no_matching_message_integrity
239
- | atom ( ) }
240
- def authenticate_lt ( msg , password ) do
241
- with { :ok , % MessageIntegrity { } = msg_int } <- get_message_integrity ( msg ) ,
242
- { :ok , % Username { value: username } } <- get_username ( msg ) ,
243
- { :ok , % Realm { value: realm } } <- get_realm ( msg ) do
244
- key = username <> ":" <> realm <> ":" <> password
245
- key = :crypto . hash ( :md5 , key )
246
-
247
- # + 20 for STUN message header
248
- # - 24 for message integrity
249
- len = msg . len_to_int + 20 - 24
250
- << msg_without_integrity :: binary - size ( len ) , _rest :: binary >> = msg . raw
251
- << pre_len :: binary - size ( 2 ) , _len :: 16 , post_len :: binary >> = msg_without_integrity
252
- msg_without_integrity = << pre_len :: binary , msg . len_to_int :: 16 , post_len :: binary >>
253
-
254
- mac = :crypto . mac ( :hmac , :sha , key , msg_without_integrity )
255
-
256
- if mac == msg_int . value do
257
- { :ok , key }
258
- else
259
- { :error , :no_matching_message_integrity }
260
- end
261
- else
262
- { :error , _reason } = err -> err
263
- end
226
+ @ spec lt_key ( binary ( ) , binary ( ) , binary ( ) ) :: binary ( )
227
+ def lt_key ( username , password , realm ) do
228
+ :crypto . hash ( :md5 , username <> ":" <> realm <> ":" <> password )
264
229
end
265
230
266
231
@ doc """
267
- Authenticates a message using short-term mechanism .
232
+ Authenticates a message.
268
233
269
- It is assumed that username attribute of this message is valid.
234
+ `key` depends on the authentication method.
235
+ When authenticating using short-term mechanism, it is simply a password.
236
+ When authenticating using long-term mechanism, use `lt_key/3` to obtain the key.
270
237
271
- `key` is a key used for calculating MAC and can be used
272
- for adding message integrity in a response. See `with_integrity/2`.
238
+ Presence of username, realm and nonce attributes is not checked.
239
+ Depending on the authentication method and its context (client/server side),
240
+ user has to perform those checks on their own.
273
241
"""
274
- @ spec authenticate_st ( t ( ) , binary ( ) ) ::
275
- { :ok , key :: binary ( ) }
276
- | { :error , :no_message_integrity | :no_matching_message_integrity | atom ( ) }
277
- def authenticate_st ( msg , password ) do
242
+ @ spec authenticate ( t ( ) , binary ( ) ) ::
243
+ :ok | { :error , :no_message_integrity , :no_matching_message_integrity | atom ( ) }
244
+ def authenticate ( msg , key ) do
278
245
case get_message_integrity ( msg ) do
279
246
{ :ok , % MessageIntegrity { } = msg_int } ->
280
247
# + 20 for STUN message header
281
248
# - 24 for message integrity
282
- len = msg . len_to_int + 20 - ( 20 + 4 )
249
+ len = msg . len_to_int + 20 - 24
283
250
<< msg_without_integrity :: binary - size ( len ) , _rest :: binary >> = msg . raw
284
251
<< pre_len :: binary - size ( 2 ) , _len :: 16 , post_len :: binary >> = msg_without_integrity
285
252
msg_without_integrity = << pre_len :: binary , msg . len_to_int :: 16 , post_len :: binary >>
286
253
287
- # in short-term authentication key == password
288
- mac = :crypto . mac ( :hmac , :sha , password , msg_without_integrity )
254
+ mac = :crypto . mac ( :hmac , :sha , key , msg_without_integrity )
289
255
290
256
if mac == msg_int . value do
291
- { :ok , password }
257
+ :ok
292
258
else
293
259
{ :error , :no_matching_message_integrity }
294
260
end
@@ -404,18 +370,4 @@ defmodule ExSTUN.Message do
404
370
other -> other
405
371
end
406
372
end
407
-
408
- defp get_username ( msg ) do
409
- case get_attribute ( msg , Username ) do
410
- nil -> { :error , :no_username }
411
- other -> other
412
- end
413
- end
414
-
415
- defp get_realm ( msg ) do
416
- case get_attribute ( msg , Realm ) do
417
- nil -> { :error , :no_realm }
418
- other -> other
419
- end
420
- end
421
373
end
0 commit comments