20#define STUN_MAGIC 0x2112A442u
21#define STUN_HDR_LEN 20
22#define ATTR_MAPPED_ADDRESS 0x0001
23#define ATTR_USERNAME 0x0006
24#define ATTR_MESSAGE_INTEGRITY 0x0008
25#define ATTR_PRIORITY 0x0024
26#define ATTR_USE_CANDIDATE 0x0025
27#define ATTR_XOR_MAPPED_ADDRESS 0x0020
28#define ATTR_FINGERPRINT 0x8028
29#define ATTR_ICE_CONTROLLED 0x8029
30#define ATTR_ICE_CONTROLLING 0x802A
36static bool crc32_ready =
false;
42static void crc32_init(
void) {
47 for (
int k = 0;
k < 8;
k++)
48 c = (
c & 1) ? 0xEDB88320u ^ (
c >> 1) :
c >> 1;
63 for (
size_t i = 0;
i < len;
i++)
64 c = crc32_table[(
c ^ data[
i]) & 0xFF] ^ (
c >> 8);
147 while (off + 4 <=
end) {
153 if (!cb(type,
msg + off,
alen, arg))
155 off += (
alen + 3) & ~3u;
172 attr_find_arg *
a = arg;
173 if (type ==
a->type_wanted) {
175 a->val_len = val_len;
188 attr_find_arg
a = { .type_wanted = type };
189 walk_attrs(
msg, len, attr_find_cb, &
a);
216 while (off + 4 <=
end) {
223 off += 4 + ((
alen + 3) & ~3u);
248 if (!find_mi(buf, len, &
mi_off))
289 wr16(body +
blen + 2, 8);
308 memcpy(hdr + 8, req + 8, 12);
321 wr16(body +
blen + 2, 20);
332 c = crc32_update(
c, body,
blen);
335 wr16(body +
blen + 2, 4);
336 wr32(body +
blen + 4,
c ^ 0x5354554Eu);
385 wr16(body +
blen + 2, 8);
390 wr16(body +
blen + 2, 0);
394 wr16(body +
blen + 2, 4);
395 wr32(body +
blen + 4, 0x7EFFFFFFu);
442 wr16(body +
blen + 2, 20);
453 c = crc32_update(
c, body,
blen);
456 wr16(body +
blen + 2, 4);
457 wr32(body +
blen + 4,
c ^ 0x5354554Eu);
489 parse_resp_arg *
a = arg;
497 a->has_mapped =
true;
526 parse_resp_arg
a = { 0 };
527 if (!walk_attrs(buf, len, parse_resp_cb, &
a))
540static const char b64url_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
562 while (off + 4 <=
end) {
566 if (off + 4 +
alen >
end)
return -1;
567 const uint8_t *name = buf + off + 4;
576 off += 4 + ((
alen + 3) & ~3u);
596 for (
size_t i = 0;
i <
n;
i++)
597 ufrag[
i] = b64url_chars[raw[
i] & 63];
600 for (
size_t i = 0;
i <
m;
i++)
601 pwd[
i] = b64url_chars[raw[8 + (
i % 16)] & 63];
mbedTLS TLS backend: EVP subset (HMAC digest tags, AES-256-CBC).
mbedTLS TLS backend: HMAC subset (HMAC-SHA256, one-shot + streaming).
struct cwist_mtls_hmac_ctx HMAC_CTX
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_is_message(const uint8_t *buf, size_t len)
Check whether a datagram looks like a STUN message.
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_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_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_request(uint8_t *out, size_t cap, const uint8_t txid[12], const char *username)
Build an unsigned ICE-controlling STUN binding request.
#define ATTR_MESSAGE_INTEGRITY
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.
bool cwist_ice_stun_is_binding_request(const uint8_t *buf, size_t len)
Check whether a datagram is a STUN binding request.
void cwist_ice_random_creds(char *ufrag, size_t ufrag_cap, char *pwd, size_t pwd_cap)
Generate random ICE ufrag/pwd credentials.
bool(* attr_cb)(uint16_t type, const uint8_t *val, uint16_t val_len, void *arg)
#define ATTR_XOR_MAPPED_ADDRESS
#define ATTR_ICE_CONTROLLING
#define ATTR_USE_CANDIDATE
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.
mbedTLS TLS backend: RAND_bytes over mbedTLS CTR-DRBG.
Internal types and cross-file helpers for the WebRTC DataChannel module (ICE-lite + DTLS + SCTP over ...
#define CWIST_STUN_BINDING_RESPONSE
#define CWIST_STUN_BINDING_REQUEST