1 /*
2  * Copyright (C) 2011, 2012, 2013 Citrix Systems
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the project nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include "ns_turn_msg.h"
32 #include "ns_turn_msg_addr.h"
33 
34 ///////////// Security functions implementation from ns_turn_msg.h ///////////
35 
36 #include "ns_turn_openssl.h"
37 
38 ///////////
39 
40 #include <stdlib.h>
41 
42 ///////////
43 
44 static void generate_random_nonce(unsigned char *nonce, size_t sz);
45 
46 ///////////
47 
stun_method_str(uint16_t method,char * smethod)48 int stun_method_str(uint16_t method, char *smethod)
49 {
50 	int ret = 0;
51 
52 	const char* s = "UNKNOWN";
53 
54 	switch(method) {
55 	case STUN_METHOD_BINDING:
56 		s = "BINDING";
57 		break;
58 	case STUN_METHOD_ALLOCATE:
59 		s = "ALLOCATE";
60 		break;
61 	case STUN_METHOD_REFRESH:
62 		s = "REFRESH";
63 		break;
64 	case STUN_METHOD_SEND:
65 		s = "SEND";
66 		break;
67 	case STUN_METHOD_DATA:
68 		s = "DATA";
69 		break;
70 	case STUN_METHOD_CREATE_PERMISSION:
71 		s = "CREATE_PERMISSION";
72 		break;
73 	case STUN_METHOD_CHANNEL_BIND:
74 		s = "CHANNEL_BIND";
75 		break;
76 	case STUN_METHOD_CONNECT:
77 		s = "CONNECT";
78 		break;
79 	case STUN_METHOD_CONNECTION_BIND:
80 		s = "CONNECTION_BIND";
81 		break;
82 	case STUN_METHOD_CONNECTION_ATTEMPT:
83 		s = "CONNECTION_ATTEMPT";
84 		break;
85 	default:
86 		ret = -1;
87 	};
88 
89 	if(smethod) {
90 		bcopy(s,smethod,strlen(s)+1);
91 	}
92 
93 	return ret;
94 }
95 
turn_random(void)96 long turn_random(void)
97 {
98 	long ret = 0;
99 	if(!RAND_bytes((unsigned char *)&ret,sizeof(ret)))
100 		ret = random();
101 	return ret;
102 }
103 
turn_random_tid_size(void * id)104 static void turn_random_tid_size(void *id)
105 {
106 	uint32_t *ar=(uint32_t*)id;
107 	if(!RAND_pseudo_bytes((unsigned char *)ar,12)) {
108 		size_t i;
109 		for(i=0;i<3;++i) {
110 			ar[i] = (uint32_t)random();
111 		}
112 	}
113 }
114 
stun_calculate_hmac(const uint8_t * buf,size_t len,const uint8_t * key,size_t keylen,uint8_t * hmac,unsigned int * hmac_len,SHATYPE shatype)115 int stun_calculate_hmac(const uint8_t *buf, size_t len, const uint8_t *key, size_t keylen, uint8_t *hmac, unsigned int *hmac_len, SHATYPE shatype)
116 {
117 	ERR_clear_error();
118 	UNUSED_ARG(shatype);
119 
120 	if(shatype == SHATYPE_SHA256) {
121 #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
122 	  if (!HMAC(EVP_sha256(), key, (int)keylen, buf, len, hmac, hmac_len)) {
123 	    return -1;
124 	  }
125 #else
126 	  fprintf(stderr,"SHA256 is not supported\n");
127 	  return -1;
128 #endif
129 	} else if(shatype == SHATYPE_SHA384) {
130 #if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
131 	  if (!HMAC(EVP_sha384(), key, (int)keylen, buf, len, hmac, hmac_len)) {
132 	    return -1;
133 	  }
134 #else
135 	  fprintf(stderr,"SHA384 is not supported\n");
136 	  return -1;
137 #endif
138 	} else if(shatype == SHATYPE_SHA512) {
139 #if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
140 	  if (!HMAC(EVP_sha512(), key, (int)keylen, buf, len, hmac, hmac_len)) {
141 	    return -1;
142 	  }
143 #else
144 	  fprintf(stderr,"SHA512 is not supported\n");
145 	  return -1;
146 #endif
147 	} else
148 	  if (!HMAC(EVP_sha1(), key, (int)keylen, buf, len, hmac, hmac_len)) {
149 	    return -1;
150 	  }
151 
152 	return 0;
153 }
154 
stun_produce_integrity_key_str(const uint8_t * uname,const uint8_t * realm,const uint8_t * upwd,hmackey_t key,SHATYPE shatype)155 int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, hmackey_t key, SHATYPE shatype)
156 {
157 	int ret;
158 
159 	ERR_clear_error();
160 	UNUSED_ARG(shatype);
161 
162 	size_t ulen = strlen((const char*)uname);
163 	size_t rlen = strlen((const char*)realm);
164 	size_t plen = strlen((const char*)upwd);
165 	size_t sz = ulen+1+rlen+1+plen+1+10;
166 	size_t strl = ulen+1+rlen+1+plen;
167 	uint8_t *str = (uint8_t*)malloc(sz+1);
168 
169 	strncpy((char*)str,(const char*)uname,sz);
170 	str[ulen]=':';
171 	strncpy((char*)str+ulen+1,(const char*)realm,sz-ulen-1);
172 	str[ulen+1+rlen]=':';
173 	strncpy((char*)str+ulen+1+rlen+1,(const char*)upwd,sz-ulen-1-rlen-1);
174 	str[strl]=0;
175 
176 	if(shatype == SHATYPE_SHA256) {
177 #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
178 #if OPENSSL_VERSION_NUMBER < 0x10100000L
179 		unsigned int keylen = 0;
180 		EVP_MD_CTX ctx;
181 		EVP_DigestInit(&ctx,EVP_sha256());
182 		EVP_DigestUpdate(&ctx,str,strl);
183 		EVP_DigestFinal(&ctx,key,&keylen);
184 		EVP_MD_CTX_cleanup(&ctx);
185 #else
186 		unsigned int keylen = 0;
187 		EVP_MD_CTX *ctx = EVP_MD_CTX_new();
188 		EVP_DigestInit(ctx,EVP_sha256());
189 		EVP_DigestUpdate(ctx,str,strl);
190 		EVP_DigestFinal(ctx,key,&keylen);
191 		EVP_MD_CTX_free(ctx);
192 #endif
193 		ret = 0;
194 #else
195 		fprintf(stderr,"SHA256 is not supported\n");
196 		ret = -1;
197 #endif
198 	} else if(shatype == SHATYPE_SHA384) {
199 #if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
200 #if OPENSSL_VERSION_NUMBER < 0x10100000L
201 		unsigned int keylen = 0;
202 		EVP_MD_CTX ctx;
203 		EVP_DigestInit(&ctx,EVP_sha384());
204 		EVP_DigestUpdate(&ctx,str,strl);
205 		EVP_DigestFinal(&ctx,key,&keylen);
206 		EVP_MD_CTX_cleanup(&ctx);
207 #else
208 		unsigned int keylen = 0;
209 		EVP_MD_CTX *ctx = EVP_MD_CTX_new();
210 		EVP_DigestInit(ctx,EVP_sha384());
211 		EVP_DigestUpdate(ctx,str,strl);
212 		EVP_DigestFinal(ctx,key,&keylen);
213 		EVP_MD_CTX_free(ctx);
214 #endif
215 		ret = 0;
216 #else
217 		fprintf(stderr,"SHA384 is not supported\n");
218 		ret = -1;
219 #endif
220 	} else if(shatype == SHATYPE_SHA512) {
221 #if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
222 #if OPENSSL_VERSION_NUMBER < 0x10100000L
223 		unsigned int keylen = 0;
224 		EVP_MD_CTX ctx;
225 		EVP_DigestInit(&ctx,EVP_sha512());
226 		EVP_DigestUpdate(&ctx,str,strl);
227 		EVP_DigestFinal(&ctx,key,&keylen);
228 		EVP_MD_CTX_cleanup(&ctx);
229 #else
230 		unsigned int keylen = 0;
231 		EVP_MD_CTX *ctx = EVP_MD_CTX_new();
232 		EVP_DigestInit(ctx,EVP_sha512());
233 		EVP_DigestUpdate(ctx,str,strl);
234 		EVP_DigestFinal(ctx,key,&keylen);
235 		EVP_MD_CTX_free(ctx);
236 #endif
237 		ret = 0;
238 #else
239 		fprintf(stderr,"SHA512 is not supported\n");
240 		ret = -1;
241 #endif
242 	} else {
243 #if OPENSSL_VERSION_NUMBER < 0x10100000L
244 		unsigned int keylen = 0;
245 		EVP_MD_CTX ctx;
246 		EVP_MD_CTX_init(&ctx);
247 #if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && !defined(LIBRESSL_VERSION_NUMBER)
248 		if (FIPS_mode()) {
249 			EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
250 		}
251 #endif
252 		EVP_DigestInit_ex(&ctx,EVP_md5(), NULL);
253 		EVP_DigestUpdate(&ctx,str,strl);
254 		EVP_DigestFinal(&ctx,key,&keylen);
255 		EVP_MD_CTX_cleanup(&ctx);
256 #else
257 		unsigned int keylen = 0;
258 		EVP_MD_CTX *ctx = EVP_MD_CTX_new();
259 #if defined EVP_MD_CTX_FLAG_NON_FIPS_ALLOW && ! defined(LIBRESSL_VERSION_NUMBER)
260 		if (FIPS_mode()) {
261 			EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
262 		}
263 #endif
264 		EVP_DigestInit_ex(ctx,EVP_md5(), NULL);
265 		EVP_DigestUpdate(ctx,str,strl);
266 		EVP_DigestFinal(ctx,key,&keylen);
267 		EVP_MD_CTX_free(ctx);
268 #endif
269 		ret = 0;
270 	}
271 
272 	free(str);
273 
274 	return ret;
275 }
276 
277 #define PWD_SALT_SIZE (8)
278 
readable_string(unsigned char * orig,unsigned char * out,size_t sz)279 static void readable_string(unsigned char *orig, unsigned char *out, size_t sz)
280 {
281     size_t i = 0;
282     out[0]=0;
283 
284     for(i = 0; i < sz; ++i) {
285       snprintf((char*)(out + (i * 2)), 4, "%02x", (unsigned int)orig[i]);
286     }
287 }
288 
generate_enc_password(const char * pwd,char * result,const unsigned char * orig_salt)289 static void generate_enc_password(const char* pwd, char *result, const unsigned char *orig_salt)
290 {
291 	unsigned char salt[PWD_SALT_SIZE+1];
292 	if(!orig_salt) {
293 		generate_random_nonce(salt, PWD_SALT_SIZE);
294 	} else {
295 		bcopy(orig_salt,salt,PWD_SALT_SIZE);
296 		salt[PWD_SALT_SIZE]=0;
297 	}
298 	unsigned char rsalt[PWD_SALT_SIZE*2+1];
299 	readable_string(salt,rsalt,PWD_SALT_SIZE);
300 	result[0]='$';
301 	result[1]='5';
302 	result[2]='$';
303 	bcopy((char*)rsalt,result+3,PWD_SALT_SIZE+PWD_SALT_SIZE);
304 	result[3+PWD_SALT_SIZE+PWD_SALT_SIZE]='$';
305 	unsigned char* out = (unsigned char*)(result+3+PWD_SALT_SIZE+PWD_SALT_SIZE+1);
306 	{
307 #if OPENSSL_VERSION_NUMBER < 0x10100000L
308 		EVP_MD_CTX ctx;
309 #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
310 		EVP_DigestInit(&ctx,EVP_sha256());
311 #else
312 		EVP_DigestInit(&ctx,EVP_sha1());
313 #endif
314 		EVP_DigestUpdate(&ctx,salt,PWD_SALT_SIZE);
315 		EVP_DigestUpdate(&ctx,pwd,strlen(pwd));
316 		{
317 			unsigned char hash[129];
318 			unsigned int keylen = 0;
319 			EVP_DigestFinal(&ctx,hash,&keylen);
320 			readable_string(hash,out,keylen);
321 		}
322 		EVP_MD_CTX_cleanup(&ctx);
323 #else
324 		EVP_MD_CTX *ctx = EVP_MD_CTX_new();
325 #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
326 		EVP_DigestInit(ctx,EVP_sha256());
327 #else
328 		EVP_DigestInit(ctx,EVP_sha1());
329 #endif
330 		EVP_DigestUpdate(ctx,salt,PWD_SALT_SIZE);
331 		EVP_DigestUpdate(ctx,pwd,strlen(pwd));
332 		{
333 			unsigned char hash[129];
334 			unsigned int keylen = 0;
335 			EVP_DigestFinal(ctx,hash,&keylen);
336 			readable_string(hash,out,keylen);
337 		}
338 		EVP_MD_CTX_free(ctx);
339 #endif
340 	}
341 }
342 
generate_new_enc_password(const char * pwd,char * result)343 void generate_new_enc_password(const char* pwd, char *result)
344 {
345 	generate_enc_password(pwd, result, NULL);
346 }
347 
encrypted_password(const char * pin,unsigned char * salt)348 static int encrypted_password(const char* pin, unsigned char* salt)
349 {
350 	size_t min_len = 3+PWD_SALT_SIZE+PWD_SALT_SIZE+1+32;
351 	if(strlen(pin)>=min_len) {
352 		if((pin[0]=='$') && (pin[1]=='5') && (pin[2]=='$') && (pin[3+PWD_SALT_SIZE+PWD_SALT_SIZE]=='$')) {
353 			size_t i = 0;
354 			for(i=0;i<PWD_SALT_SIZE;++i) {
355 				const char* c = pin+3+i+i;
356 				char sc[3];
357 				sc[0]=c[0];
358 				sc[1]=c[1];
359 				sc[2]=0;
360 				salt[i] = (unsigned char)strtoul(sc,NULL,16);
361 			}
362 			return 1;
363 		}
364 	}
365 	return 0;
366 }
367 
check_password(const char * pin,const char * pwd)368 int check_password(const char* pin, const char* pwd)
369 {
370 	unsigned char salt[PWD_SALT_SIZE];
371 	if(!encrypted_password(pwd,salt)) {
372 		return strcmp(pin,pwd);
373 	}
374 	char enc_pin[257];
375 	generate_enc_password(pin, enc_pin, salt);
376 	return strcmp(enc_pin,pwd);
377 }
378 
379 /////////////////////////////////////////////////////////////////
380 
381 static uint32_t ns_crc32(const uint8_t *buffer, uint32_t len);
382 
383 void print_hmac(const char *name, const void *s, size_t len);
384 
385 /////////////////////////////////////////////////////////////////
386 
stun_get_command_message_len_str(const uint8_t * buf,size_t len)387 int stun_get_command_message_len_str(const uint8_t* buf, size_t len)
388 {
389 	if (len < STUN_HEADER_LENGTH)
390 		return -1;
391 
392 	/* Validate the size the buffer claims to be */
393 	size_t bufLen = (size_t) (nswap16(((const uint16_t*)(buf))[1]) + STUN_HEADER_LENGTH);
394 	if (bufLen > len) {
395 		return -1;
396 	}
397 
398 	return bufLen;
399 }
400 
stun_set_command_message_len_str(uint8_t * buf,int len)401 static int stun_set_command_message_len_str(uint8_t* buf, int len) {
402   if(len<STUN_HEADER_LENGTH) return -1;
403   ((uint16_t*)buf)[1]=nswap16((uint16_t)(len-STUN_HEADER_LENGTH));
404   return 0;
405 }
406 
407 ///////////  Low-level binary //////////////////////////////////////////////
408 
stun_make_type(uint16_t method)409 uint16_t stun_make_type(uint16_t method) {
410   method = method & 0x0FFF;
411   return ((method & 0x000F) | ((method & 0x0070)<<1) |
412 	  ((method & 0x0380)<<2) | ((method & 0x0C00)<<2));
413 }
414 
stun_get_method_str(const uint8_t * buf,size_t len)415 uint16_t stun_get_method_str(const uint8_t *buf, size_t len) {
416   if(!buf || len<2) return (uint16_t)-1;
417 
418   uint16_t tt = nswap16(((const uint16_t*)buf)[0]);
419 
420   return (tt & 0x000F) | ((tt & 0x00E0)>>1) |
421     ((tt & 0x0E00)>>2) | ((tt & 0x3000)>>2);
422 }
423 
stun_get_msg_type_str(const uint8_t * buf,size_t len)424 uint16_t stun_get_msg_type_str(const uint8_t *buf, size_t len) {
425   if(!buf || len<2) return (uint16_t)-1;
426   return ((nswap16(((const uint16_t*)buf)[0])) & 0x3FFF);
427 }
428 
is_channel_msg_str(const uint8_t * buf,size_t blen)429 int is_channel_msg_str(const uint8_t* buf, size_t blen) {
430   return (buf && blen>=4 && STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0])));
431 }
432 
433 /////////////// message types /////////////////////////////////
434 
stun_is_command_message_str(const uint8_t * buf,size_t blen)435 int stun_is_command_message_str(const uint8_t* buf, size_t blen)
436 {
437 	if (buf && blen >= STUN_HEADER_LENGTH) {
438 		if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0]))) {
439 			if ((((uint8_t) buf[0]) & ((uint8_t) (0xC0))) == 0) {
440 				if (nswap32(((const uint32_t*)(buf))[1])
441 						== STUN_MAGIC_COOKIE) {
442 					uint16_t len = nswap16(((const uint16_t*)(buf))[1]);
443 					if ((len & 0x0003) == 0) {
444 						if ((size_t) (len + STUN_HEADER_LENGTH) == blen) {
445 							return 1;
446 						}
447 					}
448 				}
449 			}
450 		}
451 	}
452 	return 0;
453 }
454 
old_stun_is_command_message_str(const uint8_t * buf,size_t blen,uint32_t * cookie)455 int old_stun_is_command_message_str(const uint8_t* buf, size_t blen, uint32_t *cookie)
456 {
457 	if (buf && blen >= STUN_HEADER_LENGTH) {
458 		if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0]))) {
459 			if ((((uint8_t) buf[0]) & ((uint8_t) (0xC0))) == 0) {
460 				if (nswap32(((const uint32_t*)(buf))[1])
461 						!= STUN_MAGIC_COOKIE) {
462 					uint16_t len = nswap16(((const uint16_t*)(buf))[1]);
463 					if ((len & 0x0003) == 0) {
464 						if ((size_t) (len + STUN_HEADER_LENGTH) == blen) {
465 							*cookie = nswap32(((const uint32_t*)(buf))[1]);
466 							return 1;
467 						}
468 					}
469 				}
470 			}
471 		}
472 	}
473 	return 0;
474 }
475 
stun_is_command_message_full_check_str(const uint8_t * buf,size_t blen,int must_check_fingerprint,int * fingerprint_present)476 int stun_is_command_message_full_check_str(const uint8_t* buf, size_t blen, int must_check_fingerprint, int *fingerprint_present) {
477 	if(!stun_is_command_message_str(buf,blen))
478 		return 0;
479 	stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, blen, STUN_ATTRIBUTE_FINGERPRINT);
480 	if(!sar) {
481 		if(fingerprint_present)
482 			*fingerprint_present = 0;
483 		if(stun_get_method_str(buf,blen) == STUN_METHOD_BINDING) {
484 			return 1;
485 		}
486 		return !must_check_fingerprint;
487 	}
488 	if(stun_attr_get_len(sar) != 4)
489 		return 0;
490 	const uint32_t* fingerprint = (const uint32_t*)stun_attr_get_value(sar);
491 	if(!fingerprint)
492 		return !must_check_fingerprint;
493 	uint32_t crc32len = (uint32_t)((((const uint8_t*)fingerprint)-buf)-4);
494 	int ret = (*fingerprint == nswap32(ns_crc32(buf,crc32len) ^ ((uint32_t)0x5354554e)));
495 	if(ret && fingerprint_present)
496 		*fingerprint_present = ret;
497 	return ret;
498 }
499 
stun_is_command_message_offset_str(const uint8_t * buf,size_t blen,int offset)500 int stun_is_command_message_offset_str(const uint8_t* buf, size_t blen, int offset) {
501   return stun_is_command_message_str(buf + offset, blen);
502 }
503 
stun_is_request_str(const uint8_t * buf,size_t len)504 int stun_is_request_str(const uint8_t* buf, size_t len) {
505   if(is_channel_msg_str(buf,len)) return 0;
506   return IS_STUN_REQUEST(stun_get_msg_type_str(buf,len));
507 }
508 
stun_is_success_response_str(const uint8_t * buf,size_t len)509 int stun_is_success_response_str(const uint8_t* buf, size_t len) {
510   if(is_channel_msg_str(buf,len)) return 0;
511   return IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf,len));
512 }
513 
stun_is_error_response_str(const uint8_t * buf,size_t len,int * err_code,uint8_t * err_msg,size_t err_msg_size)514 int stun_is_error_response_str(const uint8_t* buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size) {
515   if(is_channel_msg_str(buf,len)) return 0;
516   if(IS_STUN_ERR_RESP(stun_get_msg_type_str(buf,len))) {
517     if(err_code) {
518       stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_ERROR_CODE);
519       if(sar) {
520     	  if(stun_attr_get_len(sar)>=4) {
521     		  const uint8_t* val = (const uint8_t*)stun_attr_get_value(sar);
522     		  *err_code=(int)(val[2]*100 + val[3]);
523     		  if(err_msg && err_msg_size>0) {
524     			  err_msg[0]=0;
525     			  if(stun_attr_get_len(sar)>4) {
526     				  size_t msg_len = stun_attr_get_len(sar) - 4;
527     				  if(msg_len>(err_msg_size-1))
528     					  msg_len=err_msg_size - 1;
529     				  bcopy(val+4, err_msg, msg_len);
530     				  err_msg[msg_len]=0;
531     			  }
532     		  }
533     	  }
534       }
535     }
536     return 1;
537   }
538   return 0;
539 }
540 
stun_is_challenge_response_str(const uint8_t * buf,size_t len,int * err_code,uint8_t * err_msg,size_t err_msg_size,uint8_t * realm,uint8_t * nonce,uint8_t * server_name,int * oauth)541 int stun_is_challenge_response_str(const uint8_t* buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size,
542 				uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth)
543 {
544 	int ret = stun_is_error_response_str(buf, len, err_code, err_msg, err_msg_size);
545 
546 	if(ret && (((*err_code) == 401) || ((*err_code) == 438) )) {
547 
548 		stun_attr_ref sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_REALM);
549 		if(sar) {
550 
551 			int found_oauth = 0;
552 
553 			const uint8_t *value = stun_attr_get_value(sar);
554 			if(value) {
555 				size_t vlen = (size_t)stun_attr_get_len(sar);
556 				bcopy(value,realm,vlen);
557 				realm[vlen]=0;
558 
559 				{
560 					sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_THIRD_PARTY_AUTHORIZATION);
561 					if(sar) {
562 						value = stun_attr_get_value(sar);
563 						if(value) {
564 							vlen = (size_t)stun_attr_get_len(sar);
565 							if(vlen>0) {
566 								if(server_name) {
567 									bcopy(value,server_name,vlen);
568 								}
569 								found_oauth = 1;
570 							}
571 						}
572 					}
573 				}
574 
575 				sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_NONCE);
576 				if(sar) {
577 					value = stun_attr_get_value(sar);
578 					if(value) {
579 						vlen = (size_t)stun_attr_get_len(sar);
580 						bcopy(value,nonce,vlen);
581 						nonce[vlen]=0;
582 						if(oauth) {
583 							*oauth = found_oauth;
584 						}
585 						return 1;
586 					}
587 				}
588 			}
589 		}
590 	}
591 
592 	return 0;
593 }
594 
stun_is_response_str(const uint8_t * buf,size_t len)595 int stun_is_response_str(const uint8_t* buf, size_t len) {
596   if(is_channel_msg_str(buf,len)) return 0;
597   if(IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf,len))) return 1;
598   if(IS_STUN_ERR_RESP(stun_get_msg_type_str(buf,len))) return 1;
599   return 0;
600 }
601 
stun_is_indication_str(const uint8_t * buf,size_t len)602 int stun_is_indication_str(const uint8_t* buf, size_t len) {
603   if(is_channel_msg_str(buf,len)) return 0;
604   return IS_STUN_INDICATION(stun_get_msg_type_str(buf,len));
605 }
606 
stun_make_request(uint16_t method)607 uint16_t stun_make_request(uint16_t method) {
608   return GET_STUN_REQUEST(stun_make_type(method));
609 }
610 
stun_make_indication(uint16_t method)611 uint16_t stun_make_indication(uint16_t method) {
612   return GET_STUN_INDICATION(stun_make_type(method));
613 }
614 
stun_make_success_response(uint16_t method)615 uint16_t stun_make_success_response(uint16_t method) {
616   return GET_STUN_SUCCESS_RESP(stun_make_type(method));
617 }
618 
stun_make_error_response(uint16_t method)619 uint16_t stun_make_error_response(uint16_t method) {
620   return GET_STUN_ERR_RESP(stun_make_type(method));
621 }
622 
623 //////////////// INIT ////////////////////////////////////////////
624 
stun_init_buffer_str(uint8_t * buf,size_t * len)625 void stun_init_buffer_str(uint8_t *buf, size_t *len) {
626   *len=STUN_HEADER_LENGTH;
627   bzero(buf,*len);
628 }
629 
stun_init_command_str(uint16_t message_type,uint8_t * buf,size_t * len)630 void stun_init_command_str(uint16_t message_type, uint8_t* buf, size_t *len) {
631   stun_init_buffer_str(buf,len);
632   message_type &= (uint16_t)(0x3FFF);
633   ((uint16_t*)buf)[0]=nswap16(message_type);
634   ((uint16_t*)buf)[1]=0;
635   ((uint32_t*)buf)[1]=nswap32(STUN_MAGIC_COOKIE);
636   stun_tid_generate_in_message_str(buf,NULL);
637 }
638 
old_stun_init_command_str(uint16_t message_type,uint8_t * buf,size_t * len,uint32_t cookie)639 void old_stun_init_command_str(uint16_t message_type, uint8_t* buf, size_t *len, uint32_t cookie) {
640   stun_init_buffer_str(buf,len);
641   message_type &= (uint16_t)(0x3FFF);
642   ((uint16_t*)buf)[0]=nswap16(message_type);
643   ((uint16_t*)buf)[1]=0;
644   ((uint32_t*)buf)[1]=nswap32(cookie);
645   stun_tid_generate_in_message_str(buf,NULL);
646 }
647 
stun_init_request_str(uint16_t method,uint8_t * buf,size_t * len)648 void stun_init_request_str(uint16_t method, uint8_t* buf, size_t *len) {
649   stun_init_command_str(stun_make_request(method), buf, len);
650 }
651 
stun_init_indication_str(uint16_t method,uint8_t * buf,size_t * len)652 void stun_init_indication_str(uint16_t method, uint8_t* buf, size_t *len) {
653   stun_init_command_str(stun_make_indication(method), buf, len);
654 }
655 
stun_init_success_response_str(uint16_t method,uint8_t * buf,size_t * len,stun_tid * id)656 void stun_init_success_response_str(uint16_t method, uint8_t* buf, size_t *len, stun_tid* id) {
657   stun_init_command_str(stun_make_success_response(method), buf, len);
658   if(id) {
659     stun_tid_message_cpy(buf, id);
660   }
661 }
662 
old_stun_init_success_response_str(uint16_t method,uint8_t * buf,size_t * len,stun_tid * id,uint32_t cookie)663 void old_stun_init_success_response_str(uint16_t method, uint8_t* buf, size_t *len, stun_tid* id, uint32_t cookie) {
664   old_stun_init_command_str(stun_make_success_response(method), buf, len, cookie);
665   if(id) {
666     stun_tid_message_cpy(buf, id);
667   }
668 }
669 
get_default_reason(int error_code)670 const uint8_t* get_default_reason(int error_code)
671 {
672 	const uint8_t* reason = (const uint8_t *) "Unknown error";
673 
674 	switch (error_code){
675 	case 300:
676 		reason = (const uint8_t *) "Try Alternate";
677 		break;
678 	case 400:
679 		reason = (const uint8_t *) "Bad Request";
680 		break;
681 	case 401:
682 		reason = (const uint8_t *) "Unauthorized";
683 		break;
684 	case 403:
685 		reason = (const uint8_t *) "Forbidden";
686 		break;
687 	case 404:
688 		reason = (const uint8_t *) "Not Found";
689 		break;
690 	case 420:
691 		reason = (const uint8_t *) "Unknown Attribute";
692 		break;
693 	case 437:
694 		reason = (const uint8_t *) "Allocation Mismatch";
695 		break;
696 	case 438:
697 		reason = (const uint8_t *) "Stale Nonce";
698 		break;
699 	case 440:
700 		reason = (const uint8_t *) "Address Family not Supported";
701 		break;
702 	case 441:
703 		reason = (const uint8_t *) "Wrong Credentials";
704 		break;
705 	case 442:
706 		reason = (const uint8_t *) "Unsupported Transport Protocol";
707 		break;
708 	case 443:
709 		reason = (const uint8_t *) "Peer Address Family Mismatch";
710 		break;
711 	case 446:
712 		reason = (const uint8_t *) "Connection Already Exists";
713 		break;
714 	case 447:
715 		reason = (const uint8_t *) "Connection Timeout or Failure";
716 		break;
717 	case 486:
718 		reason = (const uint8_t *) "Allocation Quota Reached";
719 		break;
720 	case 487:
721 		reason = (const uint8_t *) "Role Conflict";
722 		break;
723 	case 500:
724 		reason = (const uint8_t *) "Server Error";
725 		break;
726 	case 508:
727 		reason = (const uint8_t *) "Insufficient Capacity";
728 		break;
729 	default:
730 		;
731 	};
732 
733 	return reason;
734 }
735 
stun_init_error_response_common_str(uint8_t * buf,size_t * len,uint16_t error_code,const uint8_t * reason,stun_tid * id)736 static void stun_init_error_response_common_str(uint8_t* buf, size_t *len,
737 				uint16_t error_code, const uint8_t *reason,
738 				stun_tid* id)
739 {
740 
741 	if (!reason || !strcmp((const char*)reason,"Unknown error")) {
742 		reason = get_default_reason(error_code);
743 	}
744 
745 	uint8_t avalue[513];
746 	avalue[0] = 0;
747 	avalue[1] = 0;
748 	avalue[2] = (uint8_t) (error_code / 100);
749 	avalue[3] = (uint8_t) (error_code % 100);
750 	strncpy((char*) (avalue + 4), (const char*) reason, sizeof(avalue)-4);
751 	avalue[sizeof(avalue)-1]=0;
752 	int alen = 4 + (int)strlen((const char*) (avalue+4));
753 
754 	//"Manual" padding for compatibility with classic old stun:
755 	{
756 		int rem = alen % 4;
757 		if(rem) {
758 			alen +=(4-rem);
759 		}
760 	}
761 
762 	stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ERROR_CODE, (uint8_t*) avalue, alen);
763 	if (id) {
764 		stun_tid_message_cpy(buf, id);
765 	}
766 }
767 
old_stun_init_error_response_str(uint16_t method,uint8_t * buf,size_t * len,uint16_t error_code,const uint8_t * reason,stun_tid * id,uint32_t cookie)768 void old_stun_init_error_response_str(uint16_t method, uint8_t* buf, size_t *len,
769 				uint16_t error_code, const uint8_t *reason,
770 				stun_tid* id, uint32_t cookie)
771 {
772 
773 	old_stun_init_command_str(stun_make_error_response(method), buf, len, cookie);
774 
775 	stun_init_error_response_common_str(buf, len,
776 					error_code, reason,
777 					id);
778 }
779 
stun_init_error_response_str(uint16_t method,uint8_t * buf,size_t * len,uint16_t error_code,const uint8_t * reason,stun_tid * id)780 void stun_init_error_response_str(uint16_t method, uint8_t* buf, size_t *len,
781 				uint16_t error_code, const uint8_t *reason,
782 				stun_tid* id)
783 {
784 
785 	stun_init_command_str(stun_make_error_response(method), buf, len);
786 
787 	stun_init_error_response_common_str(buf, len,
788 					error_code, reason,
789 					id);
790 }
791 
792 /////////// CHANNEL ////////////////////////////////////////////////
793 
stun_init_channel_message_str(uint16_t chnumber,uint8_t * buf,size_t * len,int length,int do_padding)794 int stun_init_channel_message_str(uint16_t chnumber, uint8_t* buf, size_t *len, int length, int do_padding)
795 {
796 	uint16_t rlen = (uint16_t)length;
797 
798 	if(length<0 || (MAX_STUN_MESSAGE_SIZE<(4+length))) return -1;
799 	((uint16_t*)(buf))[0]=nswap16(chnumber);
800 	((uint16_t*)(buf))[1]=nswap16((uint16_t)length);
801 
802 	if(do_padding && (rlen & 0x0003))
803 		rlen = ((rlen>>2)+1)<<2;
804 
805 	*len=4+rlen;
806 
807 	return 0;
808 }
809 
stun_is_channel_message_str(const uint8_t * buf,size_t * blen,uint16_t * chnumber,int mandatory_padding)810 int stun_is_channel_message_str(const uint8_t *buf, size_t *blen, uint16_t* chnumber, int mandatory_padding)
811 {
812 	uint16_t datalen_header;
813 	uint16_t datalen_actual;
814 
815 	if (!blen || (*blen < 4))
816 		return 0;
817 
818 	uint16_t chn = nswap16(((const uint16_t*)(buf))[0]);
819 	if (!STUN_VALID_CHANNEL(chn))
820 		return 0;
821 
822 	if(*blen>(uint16_t)-1)
823 		*blen=(uint16_t)-1;
824 
825 	datalen_actual = (uint16_t)(*blen) - 4;
826 	datalen_header = ((const uint16_t*)buf)[1];
827 	datalen_header = nswap16(datalen_header);
828 
829 	if (datalen_header > datalen_actual)
830 		return 0;
831 
832 	if (datalen_header != datalen_actual) {
833 
834 		/* maybe there are padding bytes for 32-bit alignment. Mandatory for TCP. Optional for UDP */
835 
836 		if(datalen_actual & 0x0003) {
837 
838 			if(mandatory_padding) {
839 				return 0;
840 			} else if ((datalen_actual < datalen_header) || (datalen_header == 0)) {
841 				return 0;
842 			} else {
843 				uint16_t diff = datalen_actual - datalen_header;
844 				if (diff > 3)
845 					return 0;
846 			}
847 		}
848 	}
849 
850 	*blen = datalen_header + 4;
851 
852 	if (chnumber)
853 		*chnumber = chn;
854 
855 	return 1;
856 }
857 
858 ////////// STUN message ///////////////////////////////
859 
sheadof(const char * head,const char * full,int ignore_case)860 static inline int sheadof(const char *head, const char* full, int ignore_case)
861 {
862 	while(*head) {
863 		if(*head != *full) {
864 		  if(ignore_case && (tolower((int)*head)==tolower((int)*full))) {
865 				//OK
866 			} else {
867 				return 0;
868 			}
869 		}
870 		++head;++full;
871 	}
872 	return 1;
873 }
874 
findstr(const char * hay,size_t slen,const char * needle,int ignore_case)875 static inline const char* findstr(const char *hay, size_t slen, const char *needle, int ignore_case)
876 {
877 	const char *ret = NULL;
878 
879 	if(hay && slen && needle) {
880 		size_t nlen=strlen(needle);
881 		if(nlen<=slen) {
882 			size_t smax = slen-nlen+1;
883 			size_t i;
884 			const char *sp = hay;
885 			for(i=0;i<smax;++i) {
886 				if(sheadof(needle,sp+i,ignore_case)) {
887 					ret = sp+i;
888 					break;
889 				}
890 			}
891 		}
892 	}
893 
894 	return ret;
895 }
896 
is_http_inline(const char * s,size_t blen)897 static inline int is_http_inline(const char *s, size_t blen) {
898 	if(s && blen>=12) {
899 		if((strstr(s,"GET ")==s) ||(strstr(s,"POST ")==s) || (strstr(s,"DELETE ")==s) || (strstr(s,"PUT ")==s)) {
900 			const char *sp=findstr(s+4,blen-4," HTTP/",0);
901 			if(sp) {
902 				sp += 6;
903 				size_t diff_blen = sp-s;
904 				if(diff_blen+4 <= blen) {
905 					sp=findstr(sp,blen-diff_blen,"\r\n\r\n",0);
906 					if(sp) {
907 						int ret_len = (int)(sp-s+4);
908 						const char* clheader = "content-length: ";
909 						const char* cl = findstr(s,sp-s,clheader,1);
910 						if(cl) {
911 							unsigned long clen = strtoul(cl+strlen(clheader),NULL,10);
912 							if(clen>0 && clen<(0x0FFFFFFF)) {
913 								ret_len += (int)clen;
914 							}
915 						}
916 						return ret_len;
917 					}
918 				}
919 			}
920 		}
921 	}
922 	return 0;
923 }
924 
is_http(const char * s,size_t blen)925 int is_http(const char *s, size_t blen) {
926 	return is_http_inline(s, blen);
927 }
928 
stun_get_message_len_str(uint8_t * buf,size_t blen,int padding,size_t * app_len)929 int stun_get_message_len_str(uint8_t *buf, size_t blen, int padding, size_t *app_len) {
930 	if (buf && blen) {
931 		/* STUN request/response ? */
932 		if (buf && blen >= STUN_HEADER_LENGTH) {
933 			if (!STUN_VALID_CHANNEL(nswap16(((const uint16_t*)buf)[0]))) {
934 				if ((((uint8_t) buf[0]) & ((uint8_t) (0xC0))) == 0) {
935 					if (nswap32(((const uint32_t*)(buf))[1])
936 							== STUN_MAGIC_COOKIE) {
937 						uint16_t len = nswap16(((const uint16_t*)(buf))[1]);
938 						if ((len & 0x0003) == 0) {
939 							len += STUN_HEADER_LENGTH;
940 							if ((size_t) len <= blen) {
941 								*app_len = (size_t)len;
942 								return (int)len;
943 							}
944 						}
945 					}
946 				}
947 			}
948 		}
949 
950 		//HTTP request ?
951 		{
952 			int http_len = is_http_inline(((char*)buf), blen);
953 			if((http_len>0) && ((size_t)http_len<=blen)) {
954 				*app_len = (size_t)http_len;
955 				return http_len;
956 			}
957 		}
958 
959 		/* STUN channel ? */
960 		if(blen>=4) {
961 			uint16_t chn=nswap16(((const uint16_t*)(buf))[0]);
962 			if(STUN_VALID_CHANNEL(chn)) {
963 
964 				uint16_t bret = (4+(nswap16(((const uint16_t*)(buf))[1])));
965 
966 				*app_len = bret;
967 
968 				if(padding && (bret & 0x0003)) {
969 					bret = ((bret>>2)+1)<<2;
970 				}
971 
972 				if(bret<=blen) {
973 					return bret;
974 				}
975 			}
976 		}
977 
978 	}
979 
980 	return -1;
981 }
982 
983 ////////// ALLOCATE ///////////////////////////////////
984 
stun_set_allocate_request_str(uint8_t * buf,size_t * len,uint32_t lifetime,int af4,int af6,uint8_t transport,int mobile,const char * rt,int ep)985 int stun_set_allocate_request_str(uint8_t* buf, size_t *len, uint32_t lifetime, int af4, int af6,
986 				uint8_t transport, int mobile, const char* rt, int ep) {
987 
988   stun_init_request_str(STUN_METHOD_ALLOCATE, buf, len);
989 
990   //REQUESTED-TRANSPORT
991   {
992     uint8_t field[4];
993     field[0]=transport;
994     field[1]=0;
995     field[2]=0;
996     field[3]=0;
997     if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_TRANSPORT,field,sizeof(field))<0) return -1;
998   }
999 
1000   //LIFETIME
1001   {
1002     if(lifetime<1) lifetime=STUN_DEFAULT_ALLOCATE_LIFETIME;
1003     uint32_t field=nswap32(lifetime);
1004     if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_LIFETIME,(uint8_t*)(&field),sizeof(field))<0) return -1;
1005   }
1006 
1007   //MICE
1008   if(mobile) {
1009 	  if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(const uint8_t*)"",0)<0) return -1;
1010   }
1011 
1012   if(ep>-1) {
1013 	  uint8_t value = ep ? 0x80 : 0x00;
1014 	  if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_EVEN_PORT,(const uint8_t*)&value,1)<0) return -1;
1015   }
1016 
1017   //RESERVATION-TOKEN, EVEN-PORT and DUAL-ALLOCATION are mutually exclusive:
1018   if(rt) {
1019 
1020 	  stun_attr_add_str(buf,len, STUN_ATTRIBUTE_RESERVATION_TOKEN, (const uint8_t*) rt, 8);
1021 
1022   } else {
1023 
1024 	  //ADRESS-FAMILY
1025 	  if (af4 && !af6) {
1026 		  uint8_t field[4];
1027 		  field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4;
1028 		  field[1]=0;
1029 		  field[2]=0;
1030 		  field[3]=0;
1031 		  if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY,field,sizeof(field))<0) return -1;
1032 	  }
1033 
1034 	  if (af6 && !af4) {
1035 		  uint8_t field[4];
1036 		  field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6;
1037 		  field[1]=0;
1038 		  field[2]=0;
1039 		  field[3]=0;
1040 		  if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY,field,sizeof(field))<0) return -1;
1041 	  }
1042 
1043 	  if (af4 && af6) {
1044 	  	uint8_t field[4];
1045 	  	field[0] = (uint8_t)STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6;
1046 	  	field[1]=0;
1047 	  	field[2]=0;
1048 	  	field[3]=0;
1049 	  	if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_ADDITIONAL_ADDRESS_FAMILY,field,sizeof(field))<0) return -1;
1050 	  }
1051   }
1052 
1053   return 0;
1054 }
1055 
stun_set_allocate_response_str(uint8_t * buf,size_t * len,stun_tid * tid,const ioa_addr * relayed_addr1,const ioa_addr * relayed_addr2,const ioa_addr * reflexive_addr,uint32_t lifetime,uint32_t max_lifetime,int error_code,const uint8_t * reason,uint64_t reservation_token,char * mobile_id)1056 int stun_set_allocate_response_str(uint8_t* buf, size_t *len, stun_tid* tid,
1057 				   const ioa_addr *relayed_addr1, const ioa_addr *relayed_addr2,
1058 				   const ioa_addr *reflexive_addr,
1059 				   uint32_t lifetime, uint32_t max_lifetime, int error_code, const uint8_t *reason,
1060 				   uint64_t reservation_token, char* mobile_id) {
1061 
1062   if(!error_code) {
1063 
1064     stun_init_success_response_str(STUN_METHOD_ALLOCATE, buf, len, tid);
1065 
1066     if(relayed_addr1) {
1067       if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr1)<0) return -1;
1068     }
1069 
1070     if(relayed_addr2) {
1071       if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr2)<0) return -1;
1072     }
1073 
1074     if(reflexive_addr) {
1075       if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,reflexive_addr)<0) return -1;
1076     }
1077 
1078     if(reservation_token) {
1079       reservation_token=nswap64(reservation_token);
1080       stun_attr_add_str(buf,len,STUN_ATTRIBUTE_RESERVATION_TOKEN,(uint8_t*)(&reservation_token),8);
1081     }
1082 
1083     {
1084       if(lifetime<1) lifetime=STUN_DEFAULT_ALLOCATE_LIFETIME;
1085       else if(lifetime>max_lifetime) lifetime = max_lifetime;
1086 
1087       uint32_t field=nswap32(lifetime);
1088       if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_LIFETIME,(uint8_t*)(&field),sizeof(field))<0) return -1;
1089     }
1090 
1091     if(mobile_id && *mobile_id) {
1092 	    if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(uint8_t*)mobile_id,(int)strlen(mobile_id))<0) return -1;
1093     }
1094 
1095   } else {
1096     stun_init_error_response_str(STUN_METHOD_ALLOCATE, buf, len, error_code, reason, tid);
1097   }
1098 
1099   return 0;
1100 }
1101 
1102 /////////////// CHANNEL BIND ///////////////////////////////////////
1103 
stun_set_channel_bind_request_str(uint8_t * buf,size_t * len,const ioa_addr * peer_addr,uint16_t channel_number)1104 uint16_t stun_set_channel_bind_request_str(uint8_t* buf, size_t *len,
1105 					   const ioa_addr* peer_addr, uint16_t channel_number) {
1106 
1107   if(!STUN_VALID_CHANNEL(channel_number)) {
1108     channel_number = 0x4000 + ((uint16_t)(((uint32_t)turn_random())%(0x7FFF-0x4000+1)));
1109   }
1110 
1111   stun_init_request_str(STUN_METHOD_CHANNEL_BIND, buf, len);
1112 
1113   if(stun_attr_add_channel_number_str(buf, len, channel_number)<0) return 0;
1114 
1115   if(!peer_addr) {
1116     ioa_addr ca;
1117     bzero(&ca,sizeof(ioa_addr));
1118 
1119     if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &ca)<0) return 0;
1120   } else {
1121     if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr)<0) return 0;
1122   }
1123 
1124   return channel_number;
1125 }
1126 
stun_set_channel_bind_response_str(uint8_t * buf,size_t * len,stun_tid * tid,int error_code,const uint8_t * reason)1127 void stun_set_channel_bind_response_str(uint8_t* buf, size_t *len, stun_tid* tid, int error_code, const uint8_t *reason) {
1128   if(!error_code) {
1129     stun_init_success_response_str(STUN_METHOD_CHANNEL_BIND, buf, len, tid);
1130   } else {
1131     stun_init_error_response_str(STUN_METHOD_CHANNEL_BIND, buf, len, error_code, reason, tid);
1132   }
1133 }
1134 
1135 /////////////// BINDING ///////////////////////////////////////
1136 
stun_set_binding_request_str(uint8_t * buf,size_t * len)1137 void stun_set_binding_request_str(uint8_t* buf, size_t *len) {
1138   stun_init_request_str(STUN_METHOD_BINDING, buf, len);
1139 }
1140 
stun_set_binding_response_str(uint8_t * buf,size_t * len,stun_tid * tid,const ioa_addr * reflexive_addr,int error_code,const uint8_t * reason,uint32_t cookie,int old_stun)1141 int stun_set_binding_response_str(uint8_t* buf, size_t *len, stun_tid* tid,
1142 				  const ioa_addr *reflexive_addr, int error_code, const uint8_t *reason,
1143 				  uint32_t cookie, int old_stun)
1144 
1145 {
1146 	if (!error_code) {
1147 		if (!old_stun) {
1148 			stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid);
1149 		} else {
1150 			old_stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid, cookie);
1151 		}
1152 		if(!old_stun && reflexive_addr) {
1153 			if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr) < 0)
1154 				return -1;
1155 		}
1156 		if(reflexive_addr) {
1157 			if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_MAPPED_ADDRESS, reflexive_addr) < 0)
1158 				return -1;
1159 		}
1160 	} else if (!old_stun) {
1161 		stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid);
1162 	} else {
1163 		old_stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid, cookie);
1164 	}
1165 
1166 	return 0;
1167 }
1168 
stun_is_binding_request_str(const uint8_t * buf,size_t len,size_t offset)1169 int stun_is_binding_request_str(const uint8_t* buf, size_t len, size_t offset)
1170 {
1171   if(offset < len) {
1172     buf += offset;
1173     len -= offset;
1174     if (stun_is_command_message_str(buf, len)) {
1175       if (stun_is_request_str(buf, len) && (stun_get_method_str(buf, len) == STUN_METHOD_BINDING)) {
1176 	return 1;
1177       }
1178     }
1179   }
1180   return 0;
1181 }
1182 
stun_is_binding_response_str(const uint8_t * buf,size_t len)1183 int stun_is_binding_response_str(const uint8_t* buf, size_t len) {
1184   if(stun_is_command_message_str(buf,len) &&
1185      (stun_get_method_str(buf,len)==STUN_METHOD_BINDING)) {
1186     if(stun_is_response_str(buf,len)) {
1187       return 1;
1188     }
1189   }
1190   return 0;
1191 }
1192 
1193 /////////////////////////////// TID ///////////////////////////////
1194 
1195 
stun_tid_equals(const stun_tid * id1,const stun_tid * id2)1196 int stun_tid_equals(const stun_tid *id1, const stun_tid *id2) {
1197   if(id1==id2) return 1;
1198   if(!id1) return 0;
1199   if(!id2) return 0;
1200   {
1201     unsigned int i=0;
1202     for(i=0;i<STUN_TID_SIZE;++i) {
1203       if(id1->tsx_id[i]!=id2->tsx_id[i]) return 0;
1204     }
1205   }
1206   return 1;
1207 }
1208 
stun_tid_cpy(stun_tid * id1,const stun_tid * id2)1209 void stun_tid_cpy(stun_tid *id1, const stun_tid *id2) {
1210   if(!id1) return;
1211   if(!id2) return;
1212   bcopy((const void*)(id2->tsx_id),(void*)(id1->tsx_id),STUN_TID_SIZE);
1213 }
1214 
stun_tid_string_cpy(uint8_t * s,const stun_tid * id)1215 static void stun_tid_string_cpy(uint8_t* s, const stun_tid* id) {
1216   if(s && id) {
1217     bcopy((const void*)(id->tsx_id),s,STUN_TID_SIZE);
1218   }
1219 }
1220 
stun_tid_from_string(const uint8_t * s,stun_tid * id)1221 static void stun_tid_from_string(const uint8_t* s, stun_tid* id) {
1222   if(s && id) {
1223     bcopy(s,(void*)(id->tsx_id),STUN_TID_SIZE);
1224   }
1225 }
1226 
stun_tid_from_message_str(const uint8_t * buf,size_t len,stun_tid * id)1227 void stun_tid_from_message_str(const uint8_t* buf, size_t len, stun_tid* id) {
1228 	UNUSED_ARG(len);
1229 	stun_tid_from_string(buf+8, id);
1230 }
1231 
stun_tid_message_cpy(uint8_t * buf,const stun_tid * id)1232 void stun_tid_message_cpy(uint8_t* buf, const stun_tid* id) {
1233   if(buf && id) {
1234     stun_tid_string_cpy(buf+8, id);
1235   }
1236 }
1237 
stun_tid_generate(stun_tid * id)1238 void stun_tid_generate(stun_tid* id) {
1239   if(id) {
1240     turn_random_tid_size(id->tsx_id);
1241   }
1242 }
1243 
stun_tid_generate_in_message_str(uint8_t * buf,stun_tid * id)1244 void stun_tid_generate_in_message_str(uint8_t* buf, stun_tid* id) {
1245   stun_tid tmp;
1246   if(!id) id=&tmp;
1247   stun_tid_generate(id);
1248   stun_tid_message_cpy(buf, id);
1249 }
1250 
1251 /////////////////// TIME ////////////////////////////////////////////////////////
1252 
stun_adjust_allocate_lifetime(turn_time_t lifetime,turn_time_t max_allowed_lifetime,turn_time_t max_lifetime)1253 turn_time_t stun_adjust_allocate_lifetime(turn_time_t lifetime, turn_time_t max_allowed_lifetime, turn_time_t max_lifetime) {
1254 
1255   if(!lifetime) lifetime = STUN_DEFAULT_ALLOCATE_LIFETIME;
1256   else if(lifetime<STUN_MIN_ALLOCATE_LIFETIME) lifetime = STUN_MIN_ALLOCATE_LIFETIME;
1257   else if(lifetime>max_allowed_lifetime) lifetime = max_allowed_lifetime;
1258 
1259   if(max_lifetime && (max_lifetime < lifetime)) {
1260   	lifetime = max_lifetime;
1261   }
1262 
1263   return lifetime;
1264 }
1265 
1266 ////////////// ATTR /////////////////////////////////////////////////////////////
1267 
stun_attr_get_type(stun_attr_ref attr)1268 int stun_attr_get_type(stun_attr_ref attr) {
1269   if(attr)
1270     return (int)(nswap16(((const uint16_t*)attr)[0]));
1271   return -1;
1272 }
1273 
stun_attr_get_len(stun_attr_ref attr)1274 int stun_attr_get_len(stun_attr_ref attr) {
1275   if(attr)
1276     return (int)(nswap16(((const uint16_t*)attr)[1]));
1277   return -1;
1278 }
1279 
stun_attr_get_value(stun_attr_ref attr)1280 const uint8_t* stun_attr_get_value(stun_attr_ref attr) {
1281   if(attr) {
1282     int len = (int)(nswap16(((const uint16_t*)attr)[1]));
1283     if(len<1) return NULL;
1284     return ((const uint8_t*)attr)+4;
1285   }
1286   return NULL;
1287 }
1288 
stun_get_requested_address_family(stun_attr_ref attr)1289 int stun_get_requested_address_family(stun_attr_ref attr)
1290 {
1291 	if (attr) {
1292 		int len = (int) (nswap16(((const uint16_t*)attr)[1]));
1293 		if (len != 4)
1294 			return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID;
1295 		int val = ((const uint8_t*) attr)[4];
1296 		switch (val){
1297 		case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4:
1298 			return val;
1299 		case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6:
1300 			return val;
1301 		default:
1302 			return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID;
1303 		};
1304 	}
1305 	return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT;
1306 }
1307 
stun_attr_get_channel_number(stun_attr_ref attr)1308 uint16_t stun_attr_get_channel_number(stun_attr_ref attr) {
1309   if(attr) {
1310     const uint8_t* value = stun_attr_get_value(attr);
1311     if(value && (stun_attr_get_len(attr) >= 2)) {
1312       uint16_t cn=nswap16(((const uint16_t*)value)[0]);
1313       if(STUN_VALID_CHANNEL(cn)) return cn;
1314     }
1315   }
1316   return 0;
1317 }
1318 
stun_attr_get_bandwidth(stun_attr_ref attr)1319 band_limit_t stun_attr_get_bandwidth(stun_attr_ref attr) {
1320   if(attr) {
1321     const uint8_t* value = stun_attr_get_value(attr);
1322     if(value && (stun_attr_get_len(attr) >= 4)) {
1323       uint32_t bps=nswap32(((const uint32_t*)value)[0]);
1324       return (band_limit_t)(bps << 7);
1325     }
1326   }
1327   return 0;
1328 }
1329 
stun_attr_get_reservation_token_value(stun_attr_ref attr)1330 uint64_t stun_attr_get_reservation_token_value(stun_attr_ref attr)  {
1331   if(attr) {
1332     const uint8_t* value = stun_attr_get_value(attr);
1333     if(value && (stun_attr_get_len(attr) == 8)) {
1334       uint64_t token;
1335       bcopy(value, &token, sizeof(uint64_t));
1336       return nswap64(token);
1337     }
1338   }
1339   return 0;
1340 }
1341 
stun_attr_is_addr(stun_attr_ref attr)1342 int stun_attr_is_addr(stun_attr_ref attr) {
1343 
1344   if(attr) {
1345     switch(stun_attr_get_type(attr)) {
1346     case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS:
1347     case STUN_ATTRIBUTE_XOR_PEER_ADDRESS:
1348     case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS:
1349     case STUN_ATTRIBUTE_MAPPED_ADDRESS:
1350     case STUN_ATTRIBUTE_ALTERNATE_SERVER:
1351     case OLD_STUN_ATTRIBUTE_RESPONSE_ADDRESS:
1352     case OLD_STUN_ATTRIBUTE_SOURCE_ADDRESS:
1353     case OLD_STUN_ATTRIBUTE_CHANGED_ADDRESS:
1354     case OLD_STUN_ATTRIBUTE_REFLECTED_FROM:
1355     case STUN_ATTRIBUTE_RESPONSE_ORIGIN:
1356     case STUN_ATTRIBUTE_OTHER_ADDRESS:
1357       return 1;
1358       break;
1359     default:
1360       ;
1361     };
1362   }
1363   return 0;
1364 }
1365 
stun_attr_get_even_port(stun_attr_ref attr)1366 uint8_t stun_attr_get_even_port(stun_attr_ref attr) {
1367   if(attr) {
1368     const uint8_t* value=stun_attr_get_value(attr);
1369     if(value) {
1370       if((uint8_t)(value[0]) > 0x7F) return 1;
1371     }
1372   }
1373   return 0;
1374 }
1375 
stun_attr_get_first_by_type_str(const uint8_t * buf,size_t len,uint16_t attr_type)1376 stun_attr_ref stun_attr_get_first_by_type_str(const uint8_t* buf, size_t len, uint16_t attr_type) {
1377 
1378   stun_attr_ref attr=stun_attr_get_first_str(buf,len);
1379   while(attr) {
1380     if(stun_attr_get_type(attr) == attr_type) {
1381       return attr;
1382     }
1383     attr=stun_attr_get_next_str(buf,len,attr);
1384   }
1385 
1386   return NULL;
1387 }
1388 
stun_attr_check_valid(stun_attr_ref attr,size_t remaining)1389 static stun_attr_ref stun_attr_check_valid(stun_attr_ref attr, size_t remaining) {
1390 
1391   if(remaining >= 4) {
1392     /* Read the size of the attribute */
1393     size_t attrlen = stun_attr_get_len(attr);
1394     remaining -= 4;
1395 
1396     /* Round to boundary */
1397     uint16_t rem4 = ((uint16_t)attrlen) & 0x0003;
1398     if(rem4) {
1399       attrlen = attrlen+4-(int)rem4;
1400     }
1401 
1402     /* Check that there's enough space remaining */
1403     if(attrlen <= remaining) {
1404       return attr;
1405     }
1406   }
1407 
1408   return NULL;
1409 }
1410 
stun_attr_get_first_str(const uint8_t * buf,size_t len)1411 stun_attr_ref stun_attr_get_first_str(const uint8_t* buf, size_t len) {
1412 
1413   int bufLen = stun_get_command_message_len_str(buf,len);
1414   if(bufLen > STUN_HEADER_LENGTH) {
1415     stun_attr_ref attr = (stun_attr_ref)(buf+STUN_HEADER_LENGTH);
1416     return stun_attr_check_valid(attr, bufLen - STUN_HEADER_LENGTH);
1417   }
1418 
1419   return NULL;
1420 }
1421 
stun_attr_get_next_str(const uint8_t * buf,size_t len,stun_attr_ref prev)1422 stun_attr_ref stun_attr_get_next_str(const uint8_t* buf, size_t len, stun_attr_ref prev) {
1423 
1424   if(!prev) return stun_attr_get_first_str(buf,len);
1425   else {
1426     const uint8_t* end = buf + stun_get_command_message_len_str(buf,len);
1427     int attrlen=stun_attr_get_len(prev);
1428     uint16_t rem4 = ((uint16_t)attrlen) & 0x0003;
1429     if(rem4) {
1430       attrlen = attrlen+4-(int)rem4;
1431     }
1432     /* Note the order here: operations on attrlen are untrusted as they may overflow */
1433     if(attrlen < end - (const uint8_t*)prev - 4) {
1434       const uint8_t* attr_end=(const uint8_t*)prev+4+attrlen;
1435       return stun_attr_check_valid(attr_end, end - attr_end);
1436     }
1437     return NULL;
1438   }
1439 }
1440 
stun_attr_add_str(uint8_t * buf,size_t * len,uint16_t attr,const uint8_t * avalue,int alen)1441 int stun_attr_add_str(uint8_t* buf, size_t *len, uint16_t attr, const uint8_t* avalue, int alen) {
1442   if(alen<0) alen=0;
1443   uint8_t tmp[1];
1444   if(!avalue) {
1445     alen=0;
1446     avalue=tmp;
1447   }
1448   int clen = stun_get_command_message_len_str(buf,*len);
1449   int newlen = clen + 4 + alen;
1450   int newlenrem4=newlen & 0x00000003;
1451   if(newlenrem4) {
1452     newlen=newlen+(4-newlenrem4);
1453   }
1454   if(newlen>=MAX_STUN_MESSAGE_SIZE) return -1;
1455   else {
1456     uint8_t* attr_start=buf+clen;
1457 
1458     uint16_t *attr_start_16t=(uint16_t*)attr_start;
1459 
1460     stun_set_command_message_len_str(buf,newlen);
1461     *len = newlen;
1462 
1463     attr_start_16t[0]=nswap16(attr);
1464     attr_start_16t[1]=nswap16(alen);
1465     if(alen>0) bcopy(avalue,attr_start+4,alen);
1466     return 0;
1467   }
1468 }
1469 
stun_attr_add_addr_str(uint8_t * buf,size_t * len,uint16_t attr_type,const ioa_addr * ca)1470 int stun_attr_add_addr_str(uint8_t *buf, size_t *len, uint16_t attr_type, const ioa_addr* ca) {
1471 
1472   stun_tid tid;
1473   stun_tid_from_message_str(buf, *len, &tid);
1474 
1475   int xor_ed=0;
1476   switch(attr_type) {
1477   case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS:
1478   case STUN_ATTRIBUTE_XOR_PEER_ADDRESS:
1479   case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS:
1480     xor_ed=1;
1481     break;
1482   default:
1483     ;
1484   };
1485 
1486   ioa_addr public_addr;
1487   map_addr_from_private_to_public(ca,&public_addr);
1488 
1489   uint8_t cfield[64];
1490   int clen=0;
1491   if(stun_addr_encode(&public_addr, cfield, &clen, xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id)<0) {
1492     return -1;
1493   }
1494 
1495   if(stun_attr_add_str(buf,len,attr_type,(uint8_t*)(&cfield),clen)<0) return -1;
1496 
1497   return 0;
1498 }
1499 
stun_attr_get_addr_str(const uint8_t * buf,size_t len,stun_attr_ref attr,ioa_addr * ca,const ioa_addr * default_addr)1500 int stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, ioa_addr* ca, const ioa_addr *default_addr) {
1501 
1502   stun_tid tid;
1503   stun_tid_from_message_str(buf, len, &tid);
1504   ioa_addr public_addr;
1505 
1506   addr_set_any(ca);
1507   addr_set_any(&public_addr);
1508 
1509   int attr_type = stun_attr_get_type(attr);
1510   if(attr_type<0) return -1;
1511 
1512   int xor_ed=0;
1513   switch(attr_type) {
1514   case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS:
1515   case STUN_ATTRIBUTE_XOR_PEER_ADDRESS:
1516   case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS:
1517     xor_ed=1;
1518     break;
1519   default:
1520     ;
1521   };
1522 
1523   const uint8_t *cfield=stun_attr_get_value(attr);
1524   if(!cfield) return -1;
1525 
1526   if(stun_addr_decode(&public_addr, cfield, stun_attr_get_len(attr), xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id)<0) {
1527     return -1;
1528   }
1529 
1530   map_addr_from_public_to_private(&public_addr, ca);
1531 
1532   if(default_addr && addr_any_no_port(ca) && !addr_any_no_port(default_addr)) {
1533     int port = addr_get_port(ca);
1534     addr_cpy(ca,default_addr);
1535     addr_set_port(ca,port);
1536   }
1537 
1538   return 0;
1539 }
1540 
stun_attr_get_first_addr_str(const uint8_t * buf,size_t len,uint16_t attr_type,ioa_addr * ca,const ioa_addr * default_addr)1541 int stun_attr_get_first_addr_str(const uint8_t *buf, size_t len, uint16_t attr_type, ioa_addr* ca, const ioa_addr *default_addr) {
1542 
1543   stun_attr_ref attr=stun_attr_get_first_str(buf,len);
1544 
1545   while(attr) {
1546     if(stun_attr_is_addr(attr) && (attr_type == stun_attr_get_type(attr))) {
1547       if(stun_attr_get_addr_str(buf,len,attr,ca,default_addr)==0) {
1548     	  return 0;
1549       }
1550     }
1551     attr=stun_attr_get_next_str(buf,len,attr);
1552   }
1553 
1554   return -1;
1555 }
1556 
stun_attr_add_channel_number_str(uint8_t * buf,size_t * len,uint16_t chnumber)1557 int stun_attr_add_channel_number_str(uint8_t* buf, size_t *len, uint16_t chnumber) {
1558 
1559   uint16_t field[2];
1560   field[0]=nswap16(chnumber);
1561   field[1]=0;
1562 
1563   return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_CHANNEL_NUMBER,(uint8_t*)(field),sizeof(field));
1564 }
1565 
stun_attr_add_bandwidth_str(uint8_t * buf,size_t * len,band_limit_t bps0)1566 int stun_attr_add_bandwidth_str(uint8_t* buf, size_t *len, band_limit_t bps0) {
1567 
1568 	uint32_t bps = (uint32_t)(band_limit_t)(bps0 >> 7);
1569 
1570 	uint32_t field=nswap32(bps);
1571 
1572 	return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_NEW_BANDWIDTH,(uint8_t*)(&field),sizeof(field));
1573 }
1574 
stun_attr_add_address_error_code(uint8_t * buf,size_t * len,int requested_address_family,int error_code)1575 int stun_attr_add_address_error_code(uint8_t* buf, size_t *len, int requested_address_family, int error_code)
1576 {
1577 	const uint8_t *reason = get_default_reason(error_code);
1578 
1579 	uint8_t avalue[513];
1580 	avalue[0] = (uint8_t)requested_address_family;
1581 	avalue[1] = 0;
1582 	avalue[2] = (uint8_t) (error_code / 100);
1583 	avalue[3] = (uint8_t) (error_code % 100);
1584 	strncpy((char*) (avalue + 4), (const char*) reason, sizeof(avalue)-4);
1585 	avalue[sizeof(avalue)-1]=0;
1586 	int alen = 4 + (int)strlen((const char*) (avalue+4));
1587 
1588 	//"Manual" padding for compatibility with classic old stun:
1589 	{
1590 		int rem = alen % 4;
1591 		if(rem) {
1592 			alen +=(4-rem);
1593 		}
1594 	}
1595 
1596 	stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ADDRESS_ERROR_CODE, (uint8_t*) avalue, alen);
1597 
1598 	return 0;
1599 }
1600 
stun_attr_get_address_error_code(uint8_t * buf,size_t len,int * requested_address_family,int * error_code)1601 int stun_attr_get_address_error_code(uint8_t* buf, size_t len, int *requested_address_family, int *error_code)
1602 {
1603 	if(requested_address_family) {
1604 		*requested_address_family = 0;
1605 	}
1606 	if(error_code) {
1607 		*error_code = 0;
1608 	}
1609 	if(buf && len) {
1610 		stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_ADDRESS_ERROR_CODE);
1611 		if(sar) {
1612 			const uint8_t* value = stun_attr_get_value(sar);
1613 			if(!value) {
1614 				return -1;
1615 			} else {
1616 				int alen = stun_attr_get_len(sar);
1617 				if(alen != 4) {
1618 					return -1;
1619 				}
1620 				if(requested_address_family) {
1621 					*requested_address_family = value[0];
1622 				}
1623 				if(error_code) {
1624 					*error_code = (int)(value[2]*100+value[3]);
1625 				}
1626 				return 0;
1627 			}
1628 		}
1629 	}
1630 	return 0;
1631 }
1632 
stun_attr_get_first_channel_number_str(const uint8_t * buf,size_t len)1633 uint16_t stun_attr_get_first_channel_number_str(const uint8_t *buf, size_t len) {
1634 
1635   stun_attr_ref attr=stun_attr_get_first_str(buf,len);
1636   while(attr) {
1637     if(stun_attr_get_type(attr) == STUN_ATTRIBUTE_CHANNEL_NUMBER) {
1638       uint16_t ret = stun_attr_get_channel_number(attr);
1639       if(STUN_VALID_CHANNEL(ret)) {
1640     	  return ret;
1641       }
1642     }
1643     attr=stun_attr_get_next_str(buf,len,attr);
1644   }
1645 
1646   return 0;
1647 }
1648 
1649 ////////////// FINGERPRINT ////////////////////////////
1650 
stun_attr_add_fingerprint_str(uint8_t * buf,size_t * len)1651 int stun_attr_add_fingerprint_str(uint8_t *buf, size_t *len)
1652 {
1653 	uint32_t crc32 = 0;
1654 	stun_attr_add_str(buf, len, STUN_ATTRIBUTE_FINGERPRINT, (uint8_t*)&crc32, 4);
1655 	crc32 = ns_crc32(buf,(int)*len-8);
1656 	*((uint32_t*)(buf+*len-4)) = nswap32(crc32 ^ ((uint32_t)0x5354554e));
1657 	return 0;
1658 }
1659 ////////////// CRC ///////////////////////////////////////////////
1660 
1661 #define CRC_MASK    0xFFFFFFFFUL
1662 
1663 #define UPDATE_CRC(crc, c)  crc = crctable[(uint8_t)crc ^ (uint8_t)(c)] ^ (crc >> 8)
1664 
1665 static const uint32_t crctable[256] = {
1666   0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
1667   0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
1668   0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
1669   0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
1670   0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
1671   0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
1672   0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
1673   0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
1674   0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
1675   0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
1676   0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
1677   0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
1678   0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
1679   0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
1680   0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
1681   0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
1682   0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
1683   0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
1684   0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
1685   0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
1686   0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
1687   0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
1688   0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
1689   0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
1690   0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
1691   0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
1692   0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
1693   0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
1694   0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
1695   0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
1696   0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
1697   0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
1698   0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
1699   0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
1700   0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
1701   0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
1702   0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
1703   0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
1704   0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
1705   0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
1706   0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
1707   0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
1708   0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
1709   0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
1710   0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
1711   0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
1712   0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
1713   0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
1714   0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
1715   0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
1716   0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
1717   0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
1718   0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
1719   0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
1720   0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
1721   0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
1722   0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
1723   0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
1724   0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
1725   0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
1726   0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
1727   0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
1728   0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
1729   0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
1730 };
1731 
1732 /*
1733 
1734 #define CRCPOLY     0xEDB88320UL
1735 reversed 0x04C11DB7
1736 1110 1101 1001 1000 1000 0011 0010 0000
1737 
1738 static void make_crctable(void)
1739 {
1740 	uint i, j;
1741 	uint32_t r;
1742 
1743 	for (i = 0; i < 256; ++i) {
1744 		r = i;
1745 		for (j = 8; j > 0; --j) {
1746 			if (r & 1)
1747 				r = (r >> 1) ^ CRCPOLY;
1748 			else
1749 				r >>= 1;
1750 		}
1751 		crctable[i] = r;
1752 	}
1753 }
1754 */
1755 
ns_crc32(const uint8_t * buffer,uint32_t len)1756 static uint32_t ns_crc32(const uint8_t *buffer, uint32_t len)
1757 {
1758 	uint32_t crc = CRC_MASK;
1759 	while ( len-- ) UPDATE_CRC( crc, *buffer++ );
1760 	return (~crc);
1761 }
1762 
1763 //////////// SASLprep RFC 4013 /////////////////////////////////////////
1764 
1765 /* We support only basic ASCII table */
1766 
SASLprep(uint8_t * s)1767 int SASLprep(uint8_t *s)
1768 {
1769 	if(s) {
1770 		uint8_t *strin = s;
1771 		uint8_t *strout = s;
1772 		for(;;) {
1773 			uint8_t c = *strin;
1774 			if(!c) {
1775 				*strout=0;
1776 				break;
1777 			}
1778 
1779 			switch(c) {
1780 			case 0xAD:
1781 				++strin;
1782 				break;
1783 			case 0xA0:
1784 			case 0x20:
1785 				*strout=0x20;
1786 				++strout;
1787 				++strin;
1788 				break;
1789 			case 0x7F:
1790 				return -1;
1791 			default:
1792 				if(c<0x1F)
1793 					return -1;
1794 				if(c>=0x80 && c<=0x9F)
1795 					return -1;
1796 				*strout=c;
1797 				++strout;
1798 				++strin;
1799 			};
1800 		}
1801 	}
1802 
1803 	return 0;
1804 }
1805 
1806 //////////////// Message Integrity ////////////////////////////
1807 
get_hmackey_size(SHATYPE shatype)1808 size_t get_hmackey_size(SHATYPE shatype)
1809 {
1810 	if(shatype == SHATYPE_SHA256)
1811 		return 32;
1812 	if(shatype == SHATYPE_SHA384)
1813 		return 48;
1814 	if(shatype == SHATYPE_SHA512)
1815 		return 64;
1816 	return 16;
1817 }
1818 
print_bin_func(const char * name,size_t len,const void * s,const char * func)1819 void print_bin_func(const char *name, size_t len, const void *s, const char *func)
1820 {
1821 	printf("<%s>:<%s>:len=%d:[",func,name,(int)len);
1822 	size_t i;
1823 	for(i=0;i<len;i++) {
1824 		printf("%02x",(int)((const uint8_t*)s)[i]);
1825 	}
1826 	printf("]\n");
1827 }
1828 
stun_attr_add_integrity_str(turn_credential_type ct,uint8_t * buf,size_t * len,hmackey_t key,password_t pwd,SHATYPE shatype)1829 int stun_attr_add_integrity_str(turn_credential_type ct, uint8_t *buf, size_t *len, hmackey_t key, password_t pwd, SHATYPE shatype)
1830 {
1831 	uint8_t hmac[MAXSHASIZE];
1832 
1833 	unsigned int shasize;
1834 
1835 	switch(shatype) {
1836 	case SHATYPE_SHA256:
1837 		shasize = SHA256SIZEBYTES;
1838 		break;
1839 	case SHATYPE_SHA384:
1840 		shasize = SHA384SIZEBYTES;
1841 		break;
1842 	case SHATYPE_SHA512:
1843 		shasize = SHA512SIZEBYTES;
1844 		break;
1845 	default:
1846 		shasize = SHA1SIZEBYTES;
1847 	};
1848 
1849 	if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, hmac, shasize)<0)
1850 		return -1;
1851 
1852 	if(ct == TURN_CREDENTIALS_SHORT_TERM) {
1853 		if(stun_calculate_hmac(buf, *len-4-shasize, pwd, strlen((char*)pwd), buf+*len-shasize, &shasize, shatype)<0)
1854 				return -1;
1855 	} else {
1856 		if(stun_calculate_hmac(buf, *len-4-shasize, key, get_hmackey_size(shatype), buf+*len-shasize, &shasize, shatype)<0)
1857 			return -1;
1858 	}
1859 
1860 	return 0;
1861 }
1862 
stun_attr_add_integrity_by_key_str(uint8_t * buf,size_t * len,const uint8_t * uname,const uint8_t * realm,hmackey_t key,const uint8_t * nonce,SHATYPE shatype)1863 int stun_attr_add_integrity_by_key_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, hmackey_t key, const uint8_t *nonce, SHATYPE shatype)
1864 {
1865 	if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, (int)strlen((const char*)uname))<0)
1866 			return -1;
1867 
1868 	if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_NONCE, nonce, (int)strlen((const char*)nonce))<0)
1869 		return -1;
1870 
1871 	if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_REALM, realm, (int)strlen((const char*)realm))<0)
1872 			return -1;
1873 
1874 	password_t p;
1875 	return stun_attr_add_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, len, key, p, shatype);
1876 }
1877 
stun_attr_add_integrity_by_user_str(uint8_t * buf,size_t * len,const uint8_t * uname,const uint8_t * realm,const uint8_t * upwd,const uint8_t * nonce,SHATYPE shatype)1878 int stun_attr_add_integrity_by_user_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, const uint8_t *nonce, SHATYPE shatype)
1879 {
1880 	hmackey_t key;
1881 
1882 	if(stun_produce_integrity_key_str(uname, realm, upwd, key, shatype)<0)
1883 		return -1;
1884 
1885 	return stun_attr_add_integrity_by_key_str(buf, len, uname, realm, key, nonce, shatype);
1886 }
1887 
stun_attr_add_integrity_by_user_short_term_str(uint8_t * buf,size_t * len,const uint8_t * uname,password_t pwd,SHATYPE shatype)1888 int stun_attr_add_integrity_by_user_short_term_str(uint8_t *buf, size_t *len, const uint8_t *uname, password_t pwd, SHATYPE shatype)
1889 {
1890 	if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, (int)strlen((const char*)uname))<0)
1891 			return -1;
1892 
1893 	hmackey_t key;
1894 	return stun_attr_add_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, len, key, pwd, shatype);
1895 }
1896 
print_hmac(const char * name,const void * s,size_t len)1897 void print_hmac(const char *name, const void *s, size_t len)
1898 {
1899 	printf("%s:len=%d:[",name,(int)len);
1900 	size_t i;
1901 	for(i=0;i<len;i++) {
1902 		printf("%02x",(int)((const uint8_t*)s)[i]);
1903 	}
1904 	printf("]\n");
1905 }
1906 
1907 /*
1908  * Return -1 if failure, 0 if the integrity is not correct, 1 if OK
1909  */
stun_check_message_integrity_by_key_str(turn_credential_type ct,uint8_t * buf,size_t len,hmackey_t key,password_t pwd,SHATYPE shatype)1910 int stun_check_message_integrity_by_key_str(turn_credential_type ct, uint8_t *buf, size_t len, hmackey_t key, password_t pwd, SHATYPE shatype)
1911 {
1912 	int res = 0;
1913 	uint8_t new_hmac[MAXSHASIZE];
1914 	unsigned int shasize;
1915 	const uint8_t *old_hmac = NULL;
1916 
1917 	stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_MESSAGE_INTEGRITY);
1918 	if (!sar)
1919 		return -1;
1920 
1921 	int sarlen = stun_attr_get_len(sar);
1922 
1923 	switch(sarlen) {
1924 	case SHA256SIZEBYTES:
1925 		shasize = SHA256SIZEBYTES;
1926 		if(shatype != SHATYPE_SHA256)
1927 			return -1;
1928 		break;
1929 	case SHA384SIZEBYTES:
1930 		shasize = SHA384SIZEBYTES;
1931 		if(shatype != SHATYPE_SHA384)
1932 			return -1;
1933 		break;
1934 	case SHA512SIZEBYTES:
1935 		shasize = SHA512SIZEBYTES;
1936 		if(shatype != SHATYPE_SHA512)
1937 			return -1;
1938 		break;
1939 	case SHA1SIZEBYTES:
1940 		shasize = SHA1SIZEBYTES;
1941 		if(shatype != SHATYPE_SHA1)
1942 			return -1;
1943 		break;
1944 	default:
1945 		return -1;
1946 	};
1947 
1948 	int orig_len = stun_get_command_message_len_str(buf, len);
1949 	if (orig_len < 0)
1950 		return -1;
1951 
1952 	int new_len = (int)((const uint8_t*) sar - buf) + 4 + shasize;
1953 	if (new_len > orig_len)
1954 		return -1;
1955 
1956 	if (stun_set_command_message_len_str(buf, new_len) < 0)
1957 		return -1;
1958 
1959 	if(ct == TURN_CREDENTIALS_SHORT_TERM) {
1960 		res = stun_calculate_hmac(buf, (size_t) new_len - 4 - shasize, pwd, strlen((char*)pwd), new_hmac, &shasize, shatype);
1961 	} else {
1962 		res = stun_calculate_hmac(buf, (size_t) new_len - 4 - shasize, key, get_hmackey_size(shatype), new_hmac, &shasize, shatype);
1963 	}
1964 
1965 	stun_set_command_message_len_str(buf, orig_len);
1966 	if(res<0)
1967 		return -1;
1968 
1969 	old_hmac = stun_attr_get_value(sar);
1970 	if(!old_hmac)
1971 		return -1;
1972 
1973 	if(bcmp(old_hmac,new_hmac,shasize))
1974 		return 0;
1975 
1976 	return +1;
1977 }
1978 
1979 /*
1980  * Return -1 if failure, 0 if the integrity is not correct, 1 if OK
1981  */
stun_check_message_integrity_str(turn_credential_type ct,uint8_t * buf,size_t len,const uint8_t * uname,const uint8_t * realm,const uint8_t * upwd,SHATYPE shatype)1982 int stun_check_message_integrity_str(turn_credential_type ct, uint8_t *buf, size_t len, const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, SHATYPE shatype)
1983 {
1984 	hmackey_t key;
1985 	password_t pwd;
1986 
1987 	if(ct == TURN_CREDENTIALS_SHORT_TERM)
1988 		strncpy((char*)pwd,(const char*)upwd,sizeof(password_t));
1989 	else if (stun_produce_integrity_key_str(uname, realm, upwd, key, shatype) < 0)
1990 		return -1;
1991 
1992 	return stun_check_message_integrity_by_key_str(ct, buf, len, key, pwd, shatype);
1993 }
1994 
1995 /* RFC 5780 */
1996 
stun_attr_get_change_request_str(stun_attr_ref attr,int * change_ip,int * change_port)1997 int stun_attr_get_change_request_str(stun_attr_ref attr, int *change_ip, int *change_port)
1998 {
1999 	if(stun_attr_get_len(attr) == 4) {
2000 		const uint8_t* value = stun_attr_get_value(attr);
2001 		if(value) {
2002 			*change_ip = (value[3] & (uint8_t)0x04);
2003 			*change_port = (value[3] & (uint8_t)0x02);
2004 			return 0;
2005 		}
2006 	}
2007 	return -1;
2008 }
2009 
stun_attr_add_change_request_str(uint8_t * buf,size_t * len,int change_ip,int change_port)2010 int stun_attr_add_change_request_str(uint8_t *buf, size_t *len, int change_ip, int change_port)
2011 {
2012 	uint8_t avalue[4]={0,0,0,0};
2013 
2014 	if(change_ip) {
2015 		if(change_port) {
2016 			avalue[3] = 0x06;
2017 		} else {
2018 			avalue[3] = 0x04;
2019 		}
2020 	} else if(change_port) {
2021 		avalue[3]=0x02;
2022 	}
2023 
2024 	return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_CHANGE_REQUEST, avalue, 4);
2025 }
2026 
stun_attr_get_response_port_str(stun_attr_ref attr)2027 int stun_attr_get_response_port_str(stun_attr_ref attr)
2028 {
2029 	if(stun_attr_get_len(attr) >= 2) {
2030 		const uint8_t* value = stun_attr_get_value(attr);
2031 		if(value) {
2032 			return nswap16(((const uint16_t*)value)[0]);
2033 		}
2034 	}
2035 	return -1;
2036 }
2037 
stun_attr_add_response_port_str(uint8_t * buf,size_t * len,uint16_t port)2038 int stun_attr_add_response_port_str(uint8_t *buf, size_t *len, uint16_t port)
2039 {
2040 	uint8_t avalue[4]={0,0,0,0};
2041 	uint16_t *port_ptr = (uint16_t*)avalue;
2042 
2043 	*port_ptr = nswap16(port);
2044 
2045 	return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_RESPONSE_PORT, avalue, 4);
2046 }
2047 
stun_attr_get_padding_len_str(stun_attr_ref attr)2048 int stun_attr_get_padding_len_str(stun_attr_ref attr) {
2049 	int len = stun_attr_get_len(attr);
2050 	if(len<0)
2051 		return -1;
2052 	return (uint16_t)len;
2053 }
2054 
stun_attr_add_padding_str(uint8_t * buf,size_t * len,uint16_t padding_len)2055 int stun_attr_add_padding_str(uint8_t *buf, size_t *len, uint16_t padding_len)
2056 {
2057 	uint8_t avalue[0xFFFF];
2058 	bzero(avalue,padding_len);
2059 
2060 	return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_PADDING, avalue, padding_len);
2061 }
2062 
2063 /* OAUTH */
2064 
2065 #define OAUTH_ERROR(...) fprintf(stderr,__VA_ARGS__)
2066 
remove_spaces(char * s)2067 static void remove_spaces(char *s)
2068 {
2069 	char *sfns = s;
2070 	while(*sfns) {
2071 		if(*sfns != ' ')
2072 			break;
2073 		++sfns;
2074 	}
2075 	if(*sfns) {
2076 		if(sfns != s) {
2077 			while(*sfns && (*sfns != ' ')) {
2078 				*s = *sfns;
2079 				++s;
2080 				++sfns;
2081 			};
2082 			*s = 0;
2083 		} else {
2084 			while(*s) {
2085 				if(*s == ' ') {
2086 					*s = 0;
2087 					break;
2088 				}
2089 				++s;
2090 			}
2091 		}
2092 	}
2093 }
2094 
normalize_algorithm(char * s)2095 static void normalize_algorithm(char *s)
2096 {
2097 	char c = *s;
2098 	while(c) {
2099 		if(c=='_') *s='-';
2100 		else if((c>='a')&&(c<='z')) {
2101 			*s = c - 'a' + 'A';
2102 		}
2103 		++s;
2104 		c = *s;
2105 	}
2106 }
2107 
2108 size_t calculate_enc_key_length(ENC_ALG a);
calculate_enc_key_length(ENC_ALG a)2109 size_t calculate_enc_key_length(ENC_ALG a)
2110 {
2111 	switch(a) {
2112 #if !defined(TURN_NO_GCM)
2113 	case A128GCM:
2114 		return 16;
2115 #endif
2116 	default:
2117 		break;
2118 	};
2119 
2120 	return 32;
2121 }
2122 
2123 size_t calculate_auth_key_length(ENC_ALG a);
calculate_auth_key_length(ENC_ALG a)2124 size_t calculate_auth_key_length(ENC_ALG a)
2125 {
2126 	switch(a) {
2127 #if !defined(TURN_NO_GCM)
2128 	case A256GCM:
2129 	case A128GCM:
2130 		return 0;
2131 #endif
2132 	default:
2133 		break;
2134 	};
2135 
2136 	return 0;
2137 }
2138 
2139 int calculate_key(char *key, size_t key_size,
2140 		char *new_key, size_t new_key_size);
calculate_key(char * key,size_t key_size,char * new_key,size_t new_key_size)2141 int calculate_key(char *key, size_t key_size,
2142 		char *new_key, size_t new_key_size)
2143 {
2144 	UNUSED_ARG(key_size);
2145 
2146 	bcopy(key,new_key,new_key_size);
2147 
2148 	return 0;
2149 }
2150 
convert_oauth_key_data(const oauth_key_data * oakd0,oauth_key * key,char * err_msg,size_t err_msg_size)2151 int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *err_msg, size_t err_msg_size)
2152 {
2153 	if(oakd0 && key) {
2154 
2155 		oauth_key_data oakd_obj;
2156 		bcopy(oakd0,&oakd_obj,sizeof(oauth_key_data));
2157 		oauth_key_data *oakd = &oakd_obj;
2158 
2159 		if(!(oakd->ikm_key_size)) {
2160 			if(err_msg) {
2161 				snprintf(err_msg,err_msg_size,"key is not defined");
2162 			}
2163 		}
2164 
2165 		remove_spaces(oakd->kid);
2166 
2167 		remove_spaces(oakd->as_rs_alg);
2168 
2169 		normalize_algorithm(oakd->as_rs_alg);
2170 
2171 		if(!(oakd->kid[0])) {
2172 			if(err_msg) {
2173 				snprintf(err_msg,err_msg_size,"KID is not defined");
2174 			}
2175 			OAUTH_ERROR("KID is not defined\n");
2176 			return -1;
2177 		}
2178 
2179 		bzero(key,sizeof(oauth_key));
2180 
2181 		STRCPY(key->kid,oakd->kid);
2182 
2183 		bcopy(oakd->ikm_key,key->ikm_key,sizeof(key->ikm_key));
2184 		key->ikm_key_size = oakd->ikm_key_size;
2185 
2186 		key->timestamp = oakd->timestamp;
2187 		key->lifetime = oakd->lifetime;
2188 
2189 		if(!(key->timestamp)) key->timestamp = OAUTH_DEFAULT_TIMESTAMP;
2190 		if(!(key->lifetime)) key->lifetime = OAUTH_DEFAULT_LIFETIME;
2191 
2192 		key->as_rs_alg = ENC_ALG_ERROR;
2193 #if !defined(TURN_NO_GCM)
2194 		key->as_rs_alg = ENC_ALG_DEFAULT;
2195 		if(!strcmp(oakd->as_rs_alg,"A128GCM")) {
2196 			key->as_rs_alg = A128GCM;
2197 			key->auth_key_size = 0;
2198 			key->auth_key[0] = 0;
2199 		} else if(!strcmp(oakd->as_rs_alg,"A256GCM")) {
2200 			key->as_rs_alg = A256GCM;
2201 			key->auth_key_size = 0;
2202 			key->auth_key[0] = 0;
2203 		} else
2204 #endif
2205 		{
2206 			if(err_msg) {
2207 				snprintf(err_msg,err_msg_size,"Wrong oAuth token encryption algorithm: %s (2)\n",oakd->as_rs_alg);
2208 			}
2209 			OAUTH_ERROR("Wrong oAuth token encryption algorithm: %s (3)\n",oakd->as_rs_alg);
2210 			return -1;
2211 		}
2212 
2213 #if !defined(TURN_NO_GCM)
2214 
2215 		key->auth_key_size = calculate_auth_key_length(key->as_rs_alg);
2216 		if(key->auth_key_size) {
2217 			if(calculate_key(key->ikm_key,key->ikm_key_size,key->auth_key,key->auth_key_size)<0) {
2218 				return -1;
2219 			}
2220 		}
2221 
2222 		key->as_rs_key_size = calculate_enc_key_length(key->as_rs_alg);
2223 		if(calculate_key(key->ikm_key,key->ikm_key_size,key->as_rs_key,key->as_rs_key_size)<0) {
2224 			return -1;
2225 		}
2226 #endif
2227 	}
2228 
2229 	return 0;
2230 }
2231 
2232 const EVP_CIPHER *get_cipher_type(ENC_ALG enc_alg);
get_cipher_type(ENC_ALG enc_alg)2233 const EVP_CIPHER *get_cipher_type(ENC_ALG enc_alg)
2234 {
2235 	switch(enc_alg) {
2236 #if !defined(TURN_NO_GCM)
2237 	case A128GCM:
2238 		return EVP_aes_128_gcm();
2239 	case A256GCM:
2240 		return EVP_aes_256_gcm();
2241 #endif
2242 	default:
2243 		break;
2244 	}
2245 	OAUTH_ERROR("%s: Unsupported enc algorithm: %d\n",__FUNCTION__,(int)enc_alg);
2246 	return NULL;
2247 }
2248 
2249 int my_EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
2250 			 int *outl, const unsigned char *in, int inl);
my_EVP_EncryptUpdate(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl,const unsigned char * in,int inl)2251 int my_EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
2252 		int *outl, const unsigned char *in, int inl)
2253 {
2254 	int cycle = 0;
2255 	int out_len = 0;
2256 	while((out_len<inl)&&(++cycle<128)) {
2257 		int tmp_outl=0;
2258 		unsigned char *ptr = NULL;
2259 		if(out)
2260 			ptr = out+out_len;
2261 		int ret = EVP_EncryptUpdate(ctx, ptr, &tmp_outl, in+out_len, inl-out_len);
2262 		out_len += tmp_outl;
2263 		if(ret<1)
2264 			return ret;
2265 	}
2266 	*outl = out_len;
2267 	return 1;
2268 }
2269 
2270 int my_EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
2271 			 int *outl, const unsigned char *in, int inl);
my_EVP_DecryptUpdate(EVP_CIPHER_CTX * ctx,unsigned char * out,int * outl,const unsigned char * in,int inl)2272 int my_EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
2273 		int *outl, const unsigned char *in, int inl)
2274 {
2275 	int cycle = 0;
2276 	int out_len = 0;
2277 	while((out_len<inl)&&(++cycle<128)) {
2278 		int tmp_outl=0;
2279 		unsigned char *ptr = NULL;
2280 		if(out)
2281 			ptr = out+out_len;
2282 		int ret = EVP_DecryptUpdate(ctx, ptr, &tmp_outl, in+out_len, inl-out_len);
2283 		out_len += tmp_outl;
2284 		if(ret<1)
2285 			return ret;
2286 	}
2287 	*outl = out_len;
2288 	return 1;
2289 }
2290 
2291 void print_field(const char* name, const unsigned char* f, size_t len);
print_field(const char * name,const unsigned char * f,size_t len)2292 void print_field(const char* name, const unsigned char* f, size_t len) {
2293 	printf("\nfield %s==>>\n",name);
2294 	size_t i;
2295 	for(i = 0;i<len;++i) {
2296 		printf("<0x%x>",(unsigned int)f[i]);
2297 	}
2298 	printf("\n<<==field %s\n",name);
2299 }
2300 
2301 int encode_oauth_token_normal(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken);
encode_oauth_token_normal(const uint8_t * server_name,encoded_oauth_token * etoken,const oauth_key * key,const oauth_token * dtoken)2302 int encode_oauth_token_normal(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken)
2303 {
2304 	UNUSED_ARG(server_name);
2305 	UNUSED_ARG(etoken);
2306 	UNUSED_ARG(key);
2307 	UNUSED_ARG(dtoken);
2308 
2309 	/*
2310 	if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<=128)) {
2311 
2312 		unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
2313 		bzero(orig_field,sizeof(orig_field));
2314 
2315 		size_t len = 0;
2316 		*((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length);
2317 		len +=2;
2318 
2319 		bcopy(dtoken->enc_block.mac_key,orig_field+len,dtoken->enc_block.key_length);
2320 		len += dtoken->enc_block.key_length;
2321 
2322 		*((uint64_t*)(orig_field+len)) = nswap64(dtoken->enc_block.timestamp);
2323 		len += 8;
2324 
2325 		*((uint32_t*)(orig_field+len)) = nswap32(dtoken->enc_block.lifetime);
2326 		len += 4;
2327 
2328 		const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg);
2329 		if(!cipher)
2330 			return -1;
2331 
2332 		unsigned char *encoded_field = (unsigned char*)etoken->token;
2333 
2334 		EVP_CIPHER_CTX ctx;
2335 		EVP_CIPHER_CTX_init(&ctx);
2336 		EVP_EncryptInit_ex(&ctx, cipher, NULL, (const unsigned char *)key->as_rs_key, NULL);
2337 		EVP_CIPHER_CTX_set_padding(&ctx,1);
2338 		int outl=0;
2339 		my_EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len);
2340 		if(outl % OAUTH_ENC_ALG_BLOCK_SIZE) {
2341 			int tmp_outl = 0;
2342 			EVP_EncryptFinal_ex(&ctx, encoded_field + outl, &tmp_outl);
2343 			outl += tmp_outl;
2344 		}
2345 
2346 		EVP_CIPHER_CTX_cleanup(&ctx);
2347 
2348 		size_t sn_len = strlen((const char*)server_name);
2349 		bcopy(server_name,encoded_field+outl,sn_len);
2350 		outl += sn_len;
2351 
2352 		const EVP_MD *md = get_auth_type(key->auth_alg);
2353 		if(!md)
2354 			return -1;
2355 
2356 		unsigned int hmac_len = EVP_MD_size(md);
2357 		if (!HMAC(md, key->auth_key, key->auth_key_size, encoded_field, outl, encoded_field + outl, &hmac_len)) {
2358 		    return -1;
2359 		}
2360 
2361 		update_hmac_len(key->auth_alg, &hmac_len);
2362 
2363 		bcopy(encoded_field + outl, encoded_field + outl - sn_len, hmac_len);
2364 		outl -= sn_len;
2365 		outl += hmac_len; //encoded+hmac
2366 
2367 		etoken->size = outl;
2368 
2369 		return 0;
2370 	}
2371 	*/
2372 	return -1;
2373 }
2374 
2375 int decode_oauth_token_normal(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken);
decode_oauth_token_normal(const uint8_t * server_name,const encoded_oauth_token * etoken,const oauth_key * key,oauth_token * dtoken)2376 int decode_oauth_token_normal(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken)
2377 {
2378 	UNUSED_ARG(server_name);
2379 	UNUSED_ARG(etoken);
2380 	UNUSED_ARG(key);
2381 	UNUSED_ARG(dtoken);
2382 
2383 	/*
2384 	if(server_name && etoken && key && dtoken) {
2385 
2386 		size_t mac_size = calculate_auth_output_length(key->auth_alg);
2387 		size_t min_encoded_field_size = 2+4+8+1;
2388 		if(etoken->size < mac_size+min_encoded_field_size) {
2389 			OAUTH_ERROR("%s: token size too small: %d, mac_size=%d, min_encoded_field_size=%d\n",__FUNCTION__,(int)etoken->size,(int)mac_size,(int)min_encoded_field_size);
2390 			return -1;
2391 		}
2392 
2393 		const unsigned char* encoded_field = (const unsigned char*)etoken->token;
2394 		unsigned int encoded_field_size = (unsigned int)etoken->size-mac_size;
2395 		const unsigned char* mac = ((const unsigned char*)etoken->token) + etoken->size - mac_size;
2396 
2397 		{
2398 			const EVP_MD *md = get_auth_type(key->auth_alg);
2399 			if(!md)
2400 				return -1;
2401        		unsigned int hmac_len = EVP_MD_size(md);
2402        		update_hmac_len(key->auth_alg,&hmac_len);
2403        		if(hmac_len != mac_size) {
2404        			OAUTH_ERROR("%s: mac size is wrong: %d, must be %d\n",__FUNCTION__,(int)mac_size,(int)hmac_len);
2405        			return -1;
2406        		}
2407        		unsigned char efield[MAX_ENCODED_OAUTH_TOKEN_SIZE];
2408        		unsigned char check_mac[MAXSHASIZE];
2409        		bcopy(encoded_field,efield,encoded_field_size);
2410        		size_t sn_len = strlen((const char*)server_name);
2411        		bcopy(server_name,efield+encoded_field_size,sn_len);
2412 		    if (!HMAC(md, key->auth_key, key->auth_key_size, efield, encoded_field_size+sn_len, check_mac, &hmac_len)) {
2413 		    	return -1;
2414 		    }
2415 
2416 		    if(bcmp(check_mac,mac,mac_size)) {
2417 		    	OAUTH_ERROR("%s: token integrity check failed\n",__FUNCTION__);
2418 		    	return -1;
2419 		    }
2420 		}
2421 
2422 		unsigned char decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
2423 
2424 		const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg);
2425 		if(!cipher)
2426 			return -1;
2427 
2428 		EVP_CIPHER_CTX ctx;
2429 		EVP_CIPHER_CTX_init(&ctx);
2430 		EVP_DecryptInit_ex(&ctx, cipher, NULL, (const unsigned char *)key->as_rs_key, NULL);
2431 		EVP_CIPHER_CTX_set_padding(&ctx,1);
2432 		int outl=0;
2433 		my_EVP_DecryptUpdate(&ctx, decoded_field, &outl, encoded_field, (int)encoded_field_size);
2434 
2435 		int tmp_outl = 0;
2436 		EVP_DecryptFinal_ex(&ctx, decoded_field + outl, &tmp_outl);
2437 		outl += tmp_outl;
2438 
2439 		EVP_CIPHER_CTX_cleanup(&ctx);
2440 
2441 		size_t len = 0;
2442 
2443 		dtoken->enc_block.key_length = nswap16(*((uint16_t*)(decoded_field+len)));
2444 		len += 2;
2445 
2446 		bcopy(decoded_field+len,dtoken->enc_block.mac_key,dtoken->enc_block.key_length);
2447 		len += dtoken->enc_block.key_length;
2448 
2449 		dtoken->enc_block.timestamp = nswap64(*((uint64_t*)(decoded_field+len)));
2450 		len += 8;
2451 
2452 		dtoken->enc_block.lifetime = nswap32(*((uint32_t*)(decoded_field+len)));
2453 		len += 4;
2454 
2455 		return 0;
2456 	}
2457 	*/
2458 	return -1;
2459 }
2460 
generate_random_nonce(unsigned char * nonce,size_t sz)2461 static void generate_random_nonce(unsigned char *nonce, size_t sz) {
2462 	if(!RAND_bytes(nonce, (int)sz)) {
2463 		size_t i;
2464 		for(i=0;i<sz;++i) {
2465 			nonce[i] = (unsigned char)random();
2466 		}
2467 	}
2468 }
2469 
2470 #if !defined(TURN_NO_GCM)
2471 
encode_oauth_token_gcm(const uint8_t * server_name,encoded_oauth_token * etoken,const oauth_key * key,const oauth_token * dtoken,const uint8_t * nonce0)2472 static int encode_oauth_token_gcm(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken, const uint8_t* nonce0) {
2473 	if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<=MAXSHASIZE)) {
2474 
2475 		unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
2476 		bzero(orig_field,sizeof(orig_field));
2477 
2478 		unsigned char nonce[OAUTH_GCM_NONCE_SIZE];
2479 		if(nonce0) {
2480 			bcopy(nonce0,nonce,sizeof(nonce));
2481 		} else {
2482 			generate_random_nonce(nonce, sizeof(nonce));
2483 		}
2484 
2485 		size_t len = 0;
2486 
2487 		*((uint16_t*)(orig_field+len)) = nswap16(OAUTH_GCM_NONCE_SIZE);
2488 		len +=2;
2489 
2490 		bcopy(nonce,orig_field+len,OAUTH_GCM_NONCE_SIZE);
2491 		len += OAUTH_GCM_NONCE_SIZE;
2492 
2493 		*((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length);
2494 		len +=2;
2495 
2496 		bcopy(dtoken->enc_block.mac_key,orig_field+len,dtoken->enc_block.key_length);
2497 		len += dtoken->enc_block.key_length;
2498 
2499 		uint64_t ts = nswap64(dtoken->enc_block.timestamp);
2500 		bcopy( &ts, (orig_field+len), sizeof(ts));
2501 		len += sizeof(ts);
2502 
2503 		*((uint32_t*)(orig_field+len)) = nswap32(dtoken->enc_block.lifetime);
2504 		len += 4;
2505 
2506 		const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg);
2507 		if(!cipher)
2508 			return -1;
2509 
2510 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2511 		EVP_CIPHER_CTX ctx;
2512 		EVP_CIPHER_CTX *ctxp = &ctx;
2513 #else
2514 		EVP_CIPHER_CTX *ctxp = EVP_CIPHER_CTX_new();
2515 #endif
2516 		EVP_CIPHER_CTX_init(ctxp);
2517 
2518 		/* Initialize the encryption operation. */
2519 		if(1 != EVP_EncryptInit_ex(ctxp, cipher, NULL, NULL, NULL))
2520 			return -1;
2521 
2522 		EVP_CIPHER_CTX_set_padding(ctxp,1);
2523 
2524 		/* Set IV length if default 12 bytes (96 bits) is not appropriate */
2525 		if(1 != EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_SET_IVLEN, OAUTH_GCM_NONCE_SIZE, NULL))
2526 			return -1;
2527 
2528 		/* Initialize key and IV */
2529 		if(1 != EVP_EncryptInit_ex(ctxp, NULL, NULL, (const unsigned char *)key->as_rs_key, nonce))
2530 			return -1;
2531 
2532 		int outl=0;
2533 		size_t sn_len = strlen((const char*)server_name);
2534 
2535 		/* Provide any AAD data. This can be called zero or more times as
2536 		 * required
2537 		 */
2538 		if(1 != my_EVP_EncryptUpdate(ctxp, NULL, &outl, server_name, (int)sn_len))
2539 			return -1;
2540 
2541 		outl=0;
2542 		unsigned char *encoded_field = (unsigned char*)etoken->token;
2543 		bcopy(orig_field,encoded_field,OAUTH_GCM_NONCE_SIZE + 2);
2544 		encoded_field += OAUTH_GCM_NONCE_SIZE + 2;
2545 		unsigned char *start_field = orig_field + OAUTH_GCM_NONCE_SIZE + 2;
2546 		len -= OAUTH_GCM_NONCE_SIZE + 2;
2547 
2548 		if(1 != my_EVP_EncryptUpdate(ctxp, encoded_field, &outl, start_field, (int)len))
2549 			return -1;
2550 
2551 		int tmp_outl = 0;
2552 		EVP_EncryptFinal_ex(ctxp, encoded_field + outl, &tmp_outl);
2553 		outl += tmp_outl;
2554 
2555 		EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_GET_TAG, OAUTH_GCM_TAG_SIZE, encoded_field + outl);
2556 		outl += OAUTH_GCM_TAG_SIZE;
2557 
2558 		etoken->size = 2 + OAUTH_GCM_NONCE_SIZE + outl;
2559 
2560 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2561 		EVP_CIPHER_CTX_cleanup(ctxp);
2562 #else
2563 		EVP_CIPHER_CTX_free(ctxp);
2564 #endif
2565 
2566 		return 0;
2567 	}
2568 	return -1;
2569 }
2570 
decode_oauth_token_gcm(const uint8_t * server_name,const encoded_oauth_token * etoken,const oauth_key * key,oauth_token * dtoken)2571 static int decode_oauth_token_gcm(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken)
2572 {
2573 	if(server_name && etoken && key && dtoken) {
2574 
2575 		unsigned char snl[2];
2576 		bcopy((const unsigned char*)(etoken->token),snl,2);
2577 		const unsigned char *csnl = snl;
2578 
2579 		uint16_t nonce_len = nswap16(*((const uint16_t*)csnl));
2580                 dtoken->enc_block.nonce_length = nonce_len;
2581 
2582 		size_t min_encoded_field_size = 2+4+8+nonce_len+2+OAUTH_GCM_TAG_SIZE+1;
2583 		if(etoken->size < min_encoded_field_size) {
2584 			OAUTH_ERROR("%s: token size too small: %d\n",__FUNCTION__,(int)etoken->size);
2585 			return -1;
2586 		}
2587 
2588 		const unsigned char* encoded_field = (const unsigned char*)(etoken->token + nonce_len + 2);
2589 		unsigned int encoded_field_size = (unsigned int)etoken->size - nonce_len - 2 - OAUTH_GCM_TAG_SIZE;
2590 		const unsigned char* nonce = ((const unsigned char*)etoken->token + 2);
2591                 bcopy(nonce,dtoken->enc_block.nonce,nonce_len);
2592 
2593 		unsigned char tag[OAUTH_GCM_TAG_SIZE];
2594 		bcopy(((const unsigned char*)etoken->token) + nonce_len + 2 + encoded_field_size, tag ,sizeof(tag));
2595 
2596 		unsigned char decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
2597 
2598 		const EVP_CIPHER * cipher = get_cipher_type(key->as_rs_alg);
2599 		if(!cipher) {
2600 			OAUTH_ERROR("%s: Cannot find cipher for algorithm: %d\n",__FUNCTION__,(int)key->as_rs_alg);
2601 			return -1;
2602 		}
2603 
2604 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2605 		EVP_CIPHER_CTX ctx;
2606 		EVP_CIPHER_CTX *ctxp = &ctx;
2607 #else
2608 		EVP_CIPHER_CTX *ctxp = EVP_CIPHER_CTX_new();
2609 #endif
2610 		EVP_CIPHER_CTX_init(ctxp);
2611 		/* Initialize the decryption operation. */
2612 		if(1 != EVP_DecryptInit_ex(ctxp, cipher, NULL, NULL, NULL)) {
2613 			OAUTH_ERROR("%s: Cannot initialize decryption\n",__FUNCTION__);
2614 			return -1;
2615 		}
2616 
2617 		//EVP_CIPHER_CTX_set_padding(&ctx,1);
2618 
2619 		/* Set IV length if default 12 bytes (96 bits) is not appropriate */
2620 		if(1 != EVP_CIPHER_CTX_ctrl(ctxp, EVP_CTRL_GCM_SET_IVLEN, nonce_len, NULL)) {
2621 			OAUTH_ERROR("%s: Cannot set nonce length\n",__FUNCTION__);
2622 			return -1;
2623 		}
2624 
2625 		/* Initialize key and IV */
2626 		if(1 != EVP_DecryptInit_ex(ctxp, NULL, NULL, (const unsigned char *)key->as_rs_key, nonce)) {
2627 			OAUTH_ERROR("%s: Cannot set nonce\n",__FUNCTION__);
2628 			return -1;
2629 		}
2630 
2631 		/* Set expected tag value. A restriction in OpenSSL 1.0.1c and earlier
2632 		  +         * required the tag before any AAD or ciphertext */
2633 		EVP_CIPHER_CTX_ctrl (ctxp, EVP_CTRL_GCM_SET_TAG, OAUTH_GCM_TAG_SIZE, tag);
2634 
2635 		int outl=0;
2636 		size_t sn_len = strlen((const char*)server_name);
2637 
2638 		/* Provide any AAD data. This can be called zero or more times as
2639 		 * required
2640 		 */
2641 		if(1 != my_EVP_DecryptUpdate(ctxp, NULL, &outl, server_name, (int)sn_len)) {
2642 			OAUTH_ERROR("%s: Cannot decrypt update server_name: %s, len=%d\n",__FUNCTION__,server_name,(int)sn_len);
2643 			return -1;
2644 		}
2645 		if(1 != my_EVP_DecryptUpdate(ctxp, decoded_field, &outl, encoded_field, (int)encoded_field_size)) {
2646 			OAUTH_ERROR("%s: Cannot decrypt update\n",__FUNCTION__);
2647 			return -1;
2648 		}
2649 
2650 		int tmp_outl = 0;
2651 		if(EVP_DecryptFinal_ex(ctxp, decoded_field + outl, &tmp_outl)<1) {
2652 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2653 			EVP_CIPHER_CTX_cleanup(ctxp);
2654 #else
2655 			EVP_CIPHER_CTX_free(ctxp);
2656 #endif
2657 			OAUTH_ERROR("%s: token integrity check failed\n",__FUNCTION__);
2658 			return -1;
2659 		}
2660 		outl += tmp_outl;
2661 
2662 #if OPENSSL_VERSION_NUMBER < 0x10100000L
2663 			EVP_CIPHER_CTX_cleanup(ctxp);
2664 #else
2665 			EVP_CIPHER_CTX_free(ctxp);
2666 #endif
2667 
2668 		size_t len = 0;
2669 
2670 		dtoken->enc_block.key_length = nswap16(*((uint16_t*)(decoded_field+len)));
2671 		len += 2;
2672 
2673 		bcopy(decoded_field+len,dtoken->enc_block.mac_key,dtoken->enc_block.key_length);
2674 		len += dtoken->enc_block.key_length;
2675 
2676 		uint64_t ts;
2677 		bcopy((decoded_field+len),&ts,sizeof(ts));
2678 		dtoken->enc_block.timestamp = nswap64(ts);
2679 		len += sizeof(ts);
2680 
2681 		uint32_t lt;
2682 		bcopy((decoded_field+len),&lt,sizeof(lt));
2683 		dtoken->enc_block.lifetime = nswap32(lt);
2684 		len += sizeof(lt);
2685 
2686 		return 0;
2687 	}
2688 	return -1;
2689 }
2690 
2691 #endif
2692 
encode_oauth_token(const uint8_t * server_name,encoded_oauth_token * etoken,const oauth_key * key,const oauth_token * dtoken,const uint8_t * nonce)2693 int encode_oauth_token(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken, const uint8_t *nonce)
2694 {
2695 	UNUSED_ARG(nonce);
2696 	if(server_name && etoken && key && dtoken) {
2697 		switch(key->as_rs_alg) {
2698 #if !defined(TURN_NO_GCM)
2699 		case A256GCM:
2700 		case A128GCM:
2701 			return encode_oauth_token_gcm(server_name, etoken,key,dtoken,nonce);
2702 #endif
2703 		default:
2704 			fprintf(stderr,"Unsupported AS_RS algorithm: %d\n",(int)key->as_rs_alg);
2705 			break;
2706 		};
2707 	}
2708 	return -1;
2709 }
2710 
decode_oauth_token(const uint8_t * server_name,const encoded_oauth_token * etoken,const oauth_key * key,oauth_token * dtoken)2711 int decode_oauth_token(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken)
2712 {
2713 	if(server_name && etoken && key && dtoken) {
2714 		switch(key->as_rs_alg) {
2715 #if !defined(TURN_NO_GCM)
2716 		case A256GCM:
2717 		case A128GCM:
2718 			return decode_oauth_token_gcm(server_name, etoken,key,dtoken);
2719 #endif
2720 		default:
2721 			fprintf(stderr,"Unsupported AS_RS algorithm: %d\n",(int)key->as_rs_alg);
2722 			break;
2723 		};
2724 	}
2725 	return -1;
2726 }
2727 
2728 ///////////////////////////////////////////////////////////////
2729