|
cwist
Modern C web framework with libttak runtime
|
Minimal STUN/ICE (RFC 5389 / RFC 8445) for the ICE-lite agent. More...
#include "webrtc_internal.h"#include <openssl/evp.h>#include <openssl/hmac.h>#include <openssl/rand.h>#include <string.h>
Go to the source code of this file.
Macros | |
STUN wire-format constants (RFC 5389) | |
| #define | STUN_MAGIC 0x2112A442u |
| #define | STUN_HDR_LEN 20 |
| #define | ATTR_MAPPED_ADDRESS 0x0001 |
| #define | ATTR_USERNAME 0x0006 |
| #define | ATTR_MESSAGE_INTEGRITY 0x0008 |
| #define | ATTR_PRIORITY 0x0024 |
| #define | ATTR_USE_CANDIDATE 0x0025 |
| #define | ATTR_XOR_MAPPED_ADDRESS 0x0020 |
| #define | ATTR_FINGERPRINT 0x8028 |
| #define | ATTR_ICE_CONTROLLED 0x8029 |
| #define | ATTR_ICE_CONTROLLING 0x802A |
Typedefs | |
| typedef bool(* | attr_cb) (uint16_t type, const uint8_t *val, uint16_t val_len, void *arg) |
Functions | |
| int | cwist_ice_stun_is_message (const uint8_t *buf, size_t len) |
| Check whether a datagram looks like a STUN message. | |
| bool | cwist_ice_stun_is_binding_request (const uint8_t *buf, size_t len) |
| Check whether a datagram is a STUN binding request. | |
| bool | cwist_ice_stun_has_use_candidate (const uint8_t *buf, size_t len) |
| Check whether a STUN message carries the USE-CANDIDATE attribute. | |
| int | cwist_ice_stun_validate_request (const uint8_t *buf, size_t len, const char *pwd) |
| Validate the MESSAGE-INTEGRITY of a STUN message against a password. | |
| int | cwist_ice_stun_build_response (uint8_t *out, size_t cap, const uint8_t *req, size_t req_len, const struct sockaddr_in *mapped, const char *pwd) |
| Build a STUN binding response for a received binding request. | |
| int | cwist_ice_stun_build_request (uint8_t *out, size_t cap, const uint8_t txid[12], const char *username) |
| Build an unsigned ICE-controlling STUN binding request. | |
| int | cwist_ice_stun_sign_request (uint8_t *msg, size_t cap, size_t msg_len, const char *pwd) |
| Public wrapper around stun_sign() for signing a built binding request. | |
| int | cwist_ice_stun_parse_response (const uint8_t *buf, size_t len, const uint8_t txid[12], const char *pwd, struct sockaddr_in *mapped) |
| Validate a received STUN binding response. | |
| int | cwist_ice_stun_get_remote_ufrag (const uint8_t *buf, size_t len, char *out, size_t cap) |
| Extract the sender's ufrag from the USERNAME attribute of a STUN message. | |
| void | cwist_ice_random_creds (char *ufrag, size_t ufrag_cap, char *pwd, size_t pwd_cap) |
| Generate random ICE ufrag/pwd credentials. | |
Minimal STUN/ICE (RFC 5389 / RFC 8445) for the ICE-lite agent.
Implements just enough of STUN message parsing, validation, and construction to run an ICE-lite endpoint: binding request/response handling, MESSAGE-INTEGRITY (HMAC-SHA1) and FINGERPRINT (CRC-32) generation and checking, XOR-MAPPED-ADDRESS extraction, and random ICE credential generation. No retransmission or state machine logic lives here; callers in webrtc.c drive timing and nomination.
Definition in file ice.c.
| #define ATTR_FINGERPRINT 0x8028 |
| #define ATTR_ICE_CONTROLLED 0x8029 |
| #define ATTR_ICE_CONTROLLING 0x802A |
| #define ATTR_MAPPED_ADDRESS 0x0001 |
| #define ATTR_MESSAGE_INTEGRITY 0x0008 |
| #define ATTR_PRIORITY 0x0024 |
| #define ATTR_USE_CANDIDATE 0x0025 |
| #define ATTR_USERNAME 0x0006 |
| #define ATTR_XOR_MAPPED_ADDRESS 0x0020 |
| #define STUN_HDR_LEN 20 |
| #define STUN_MAGIC 0x2112A442u |
Callback invoked once per STUN attribute during a walk_attrs() scan.
| type | Attribute type field. |
| val | Pointer to the attribute value inside the message buffer. |
| val_len | Value length in bytes (unpadded). |
| arg | Opaque pointer supplied to walk_attrs(). |
| true | Continue walking. |
| false | Stop walking (walk_attrs() then reports failure to its caller). |
Generate random ICE ufrag/pwd credentials.
Generate random ICE credentials (ice-chars only).
Both strings are drawn from 24 bytes of CSPRNG output encoded with the base64url alphabet (6 bits per character).
| ufrag | Output buffer for the ufrag. |
| ufrag_cap | Capacity of ufrag; up to 8 characters plus NUL are written. |
| pwd | Output buffer for the password. |
| pwd_cap | Capacity of pwd; up to 32 characters plus NUL are written. |
Definition at line 592 of file ice.c.
References cap, and RAND_bytes.
| int cwist_ice_stun_build_request | ( | uint8_t * | out, |
| size_t | cap, | ||
| const uint8_t | txid[12], | ||
| const char * | username | ||
| ) |
Build an unsigned ICE-controlling STUN binding request.
Build an unsigned Binding request (USERNAME, USE-CANDIDATE, ...).
The request carries USERNAME (only if username is non-empty), ICE-CONTROLLING, USE-CANDIDATE, and PRIORITY attributes. MESSAGE-INTEGRITY and FINGERPRINT are intentionally not added here; the MI key (the peer's password) is only known at send time, so the caller signs the built request with cwist_ice_stun_sign_request().
| out | Destination buffer. |
| cap | Capacity of out in bytes. |
| txid | 12-byte transaction ID to copy into the header. |
| username | "remoteufrag:localufrag" string for the USERNAME attribute; skipped when empty. |
cap is too small. Definition at line 361 of file ice.c.
References ATTR_ICE_CONTROLLING, ATTR_PRIORITY, ATTR_USE_CANDIDATE, ATTR_USERNAME, cap, CWIST_STUN_BINDING_REQUEST, STUN_HDR_LEN, and STUN_MAGIC.
| int cwist_ice_stun_build_response | ( | uint8_t * | out, |
| size_t | cap, | ||
| const uint8_t * | req, | ||
| size_t | req_len, | ||
| const struct sockaddr_in * | mapped, | ||
| const char * | pwd | ||
| ) |
Build a STUN binding response for a received binding request.
Build a signed Binding success response with XOR-MAPPED-ADDRESS.
Emits a message containing XOR-MAPPED-ADDRESS (IPv4 only), MESSAGE-INTEGRITY (HMAC-SHA1 keyed with pwd), and FINGERPRINT attributes, reusing the request's transaction ID.
| out | Destination buffer. |
| cap | Capacity of out in bytes. |
| req | The received binding request (used for its transaction ID). |
| req_len | Bytes at req; currently unused. |
| mapped | Address/port to report back (XOR-encoded with the magic cookie). |
| pwd | Short-term credential password for the MI HMAC. |
cap is too small or OpenSSL allocation fails. Definition at line 281 of file ice.c.
References ATTR_FINGERPRINT, ATTR_MESSAGE_INTEGRITY, ATTR_XOR_MAPPED_ADDRESS, cap, CWIST_STUN_BINDING_RESPONSE, HMAC_CTX_free, HMAC_CTX_new, HMAC_Final, HMAC_Init_ex, HMAC_Update, STUN_HDR_LEN, and STUN_MAGIC.
Extract the sender's ufrag from the USERNAME attribute of a STUN message.
Extract the sender's ufrag from USERNAME ("recipient:sender", RFC 8445 section 7.2.2) – the peer's SDP ice-ufrag.
A Binding request's USERNAME is "<recipient ufrag>:<sender ufrag>" (RFC 8445 section 7.2.2), so for a request we received this returns the part after the first ':' – the remote peer's ufrag, as it appears in the peer's SDP.
| buf | Datagram bytes. |
| len | Number of bytes at buf. |
| out | Output buffer for the NUL-terminated ufrag. |
| cap | Capacity of out; output is truncated to cap - 1 characters. |
| 0 | Ufrag extracted (possibly truncated). |
| -1 | Not a STUN message, or no USERNAME attribute present. |
Definition at line 556 of file ice.c.
References ATTR_USERNAME, cap, cwist_ice_stun_is_message(), and STUN_HDR_LEN.
Check whether a STUN message carries the USE-CANDIDATE attribute.
true if the request carries USE-CANDIDATE (nomination).
| buf | Datagram bytes. |
| len | Number of bytes at buf. |
Definition at line 197 of file ice.c.
References ATTR_USE_CANDIDATE.
Check whether a datagram is a STUN binding request.
true if buf is a STUN Binding request.
| buf | Datagram bytes. |
| len | Number of bytes at buf. |
buf is a STUN message with type CWIST_STUN_BINDING_REQUEST. Definition at line 119 of file ice.c.
References cwist_ice_stun_is_message(), and CWIST_STUN_BINDING_REQUEST.
Check whether a datagram looks like a STUN message.
Non-zero if buf looks like a STUN message (magic cookie, length).
| buf | Datagram bytes. |
| len | Number of bytes at buf. |
buf holds at least a STUN header and the magic cookie matches, 0 otherwise. Definition at line 110 of file ice.c.
References STUN_HDR_LEN, and STUN_MAGIC.
Referenced by cwist_ice_stun_get_remote_ufrag(), cwist_ice_stun_is_binding_request(), cwist_ice_stun_parse_response(), and cwist_ice_stun_validate_request().
| int cwist_ice_stun_parse_response | ( | const uint8_t * | buf, |
| size_t | len, | ||
| const uint8_t | txid[12], | ||
| const char * | pwd, | ||
| struct sockaddr_in * | mapped | ||
| ) |
Validate a received STUN binding response.
Validate a response: cookie, txid match, MI with pwd, return mapped address.
Checks, in order: well-formed STUN message of type BINDING-RESPONSE, transaction ID match against txid, MESSAGE-INTEGRITY HMAC with pwd (via cwist_ice_stun_validate_request()), and presence of a MESSAGE-INTEGRITY attribute. If mapped is non-NULL, an IPv4 XOR-MAPPED-ADDRESS must also be present and is decoded into it.
| buf | Datagram bytes. |
| len | Number of bytes at buf. |
| txid | Transaction ID the response must carry (the one we sent). |
| pwd | Local password used as the MI HMAC key. |
| mapped | Optional output for the decoded mapped address. |
| 1 | Valid response. |
| 0 | Any check failed or the message is malformed. |
Definition at line 518 of file ice.c.
References cap, cwist_ice_stun_is_message(), cwist_ice_stun_validate_request(), and CWIST_STUN_BINDING_RESPONSE.
Public wrapper around stun_sign() for signing a built binding request.
Append MESSAGE-INTEGRITY and FINGERPRINT to a request.
| msg | Buffer holding the request; extended in place. |
| cap | Total capacity of msg. |
| msg_len | Current request length. |
| pwd | Peer password used as the MI HMAC key. |
Definition at line 474 of file ice.c.
References cap.
Validate the MESSAGE-INTEGRITY of a STUN message against a password.
Check MESSAGE-INTEGRITY (HMAC-SHA1 keyed with pwd).
| buf | Datagram bytes (any STUN message type; also used for responses). |
| len | Number of bytes at buf. |
| pwd | Short-term credential password used as the HMAC-SHA1 key. |
| 1 | Also when no MESSAGE-INTEGRITY attribute is present: accepted for MVP interoperability (RFC 8445 requires MI, but the agent stays permissive here). |
Definition at line 241 of file ice.c.
References cap, cwist_ice_stun_is_message(), EVP_MAX_MD_SIZE, HMAC_CTX_free, HMAC_CTX_new, HMAC_Final, HMAC_Init_ex, HMAC_Update, and STUN_HDR_LEN.
Referenced by cwist_ice_stun_parse_response().