Browse Source

sha384 added

mom040267 10 years ago
parent
commit
caf63a35de

+ 1 - 0
ChangeLog

@@ -1,6 +1,7 @@
 2/3/2015 Oleg Moskalenko <[email protected]>
 Version 4.4.2.1 'Ardee West':
 	- (HMAC-)SHA-512 algorithms added;
+	- (HMAC-)SHA-384 algorithms added;
 	- TOS (DiffServer) and TTL IP header field handling fixed;
 	- updates according to the new third-party-auth draft (oauth);
 	- peer logging added;

+ 16 - 13
INSTALL

@@ -470,15 +470,15 @@ libevent2 from their web site. It was tested with older *NIXes
 
 NOTE: SQLite must be of version 3.x.
 
-NOTE: For extra security features (DTLS and SHA256 and SHA512) support, OpenSSL 
-version 1.0.0a or newer is recommended. Older versions do not support DTLS,
-reliably, in some cases. For example, the Debian 'Squeeze' Linux supplies
-0.9.8 version of OpenSSL, that does not work correctly with DTLS over IPv6.
-If your system already has an older version of OpenSSL installed (usually
-in directory /usr) then you may want to install your newer OpenSSL "over"
-the old one (because it will most probably will not allow removal of the
-old one). When installing the newer OpenSSL, run the OpenSSL's configure
-command like this:
+NOTE: For extra security features (DTLS and SHA256 and and SHA384 and SHA512)
+support, OpenSSL version 1.0.0a or newer is recommended. Older versions do 
+not support DTLS, reliably, in some cases. For example, the Debian 'Squeeze'
+Linux supplies 0.9.8 version of OpenSSL, that does not work correctly with
+DTLS over IPv6. If your system already has an older version of OpenSSL
+installed (usually in directory /usr) then you may want to install your
+newer OpenSSL "over" the old one (because it will most probably will not allow
+removal of the old one). When installing the newer OpenSSL, run the OpenSSL's
+configure command like this:
 
     $ ./config --prefix=/usr
 
@@ -684,6 +684,7 @@ users, because the realm is used for the HMAC key generation.
 
 The key must be up to 32 characters (HEX representation of 16 bytes) for SHA1,
 or up to 64 characters (HEX representation of 32 bytes) for SHA256,
+or up to 96 characters (HEX representation of 48 bytes) for SHA384,
 or up to 128 characters (HEX representation of 64 bytes) for SHA512:
 
 # Table holding shared secrets for secret-based authorization
@@ -765,9 +766,10 @@ The oauth_key table fields meanings are:
 		is 0 - unlimited lifetime.
 	
 	hkdf_hash_func - (optional) hash function for HKDF procedure; the 
-		valid values are SHA-1, SHA-256 and SHA-512, with SHA-256 as default;
-		The hkdf_hash_func is not needed if the as_rs_key and auth_key 
-		are defined explicitly in the database;
+		valid values are SHA-1, SHA-256, SHA-384 and SHA-512, 
+		with SHA-256 as default. The hkdf_hash_func is not needed
+		if the as_rs_key and auth_key are defined explicitly
+		in the database;
 		
 	as_rs_alg - oAuth token encryption algorithm; the valid values are
 		"AES-128-CBC" and "AES-256-CBC", , "AEAD-AES-128-GCM",
@@ -779,7 +781,8 @@ The oauth_key table fields meanings are:
 		is defined by as_rs_alg.
 		
 	auth_alg - (optional) oAuth token authentication algorithm; the valid values are
-		"HMAC-SHA-256-128", "HMAC-SHA-256", "HMAC-SHA-512" and "HMAC-SHA-1".		  
+		"HMAC-SHA-256-128", "HMAC-SHA-256", "HMAC-SHA-384",
+		"HMAC-SHA-512" and "HMAC-SHA-1".		  
 		The default value is "HMAC-SHA-256-128".
 		
 	auth_key - (optional) base64-encoded AUTH key. If not defined, then 

+ 2 - 3
README.turnadmin

@@ -98,9 +98,8 @@ Options with required values:
 -H, --sha256		Use SHA256 as the keys hash function (a non-standard feature). 
 				By default, MD5 is used for the key storage encryption 
 				(as required by the current STUN/TURNstandards).
--K, --sha512		Use SHA512 as the keys hash function (a non-standard feature). 
-				By default, MD5 is used for the key storage encryption 
-				(as required by the current STUN/TURNstandards).
+-Y, --sha384		Use SHA384 as the keys hash function (a non-standard feature).
+-K, --sha512		Use SHA512 as the keys hash function (a non-standard feature).
 --max-bps		Set value of realm's max-bps parameter.
 --total-quota	Set value of realm's total-quota parameter.
 --user-quota	Set value of realm's user-quota parameter. 

+ 3 - 0
README.turnserver

@@ -242,6 +242,9 @@ Flags:
 			SHA256 hash function if this option is used. If the server obtains a message 
 			from the client with a weaker (SHA1) hash function then the server returns 
 			error code 426.
+
+--sha384		Require SHA384 digest function to be used for the message integrity.
+
 --sha512		Require SHA512 digest function to be used for the message integrity.
 			
 --mobility		Mobility with ICE (MICE) specs support.

+ 2 - 0
README.turnutils

@@ -95,6 +95,8 @@ Flags:
 -H	SHA256 digest function for message integrity calculation.
 	Without this option, by default, SHA1 is used.
 
+-Y	SHA384 digest function for message integrity calculation.
+
 -K	SHA512 digest function for message integrity calculation.
 		
 -M	Use TURN ICE Mobility.

+ 1 - 1
STATUS

@@ -120,7 +120,7 @@ supported in the client library).
 
 52) Web HTTPS admin interface implemented.
 
-53) SHA512 support added (experimental).
+53) SHA384 and SHA512 support added (experimental).
  
 Things to be implemented in future (the development roadmap) 
 are described in the TODO file.

+ 4 - 3
examples/etc/turnserver.conf

@@ -557,15 +557,16 @@
 #
 #secure-stun
 
-# Require SHA256 or SHA512 digest function to be used for the message
+# Require SHA256, or SHA384, or SHA512 digest function to be used for the message
 # integrity. By default, the server uses SHA1 (as per TURN standard specs). 
-# With this option, the server always requires the stronger SHA256 or SHA512 
-# function. The client application must support SHA256 or SHA512 hash function
+# With this option, the server always requires the stronger SHA256, SHA384 or SHA512 
+# function. The client application must support SHA256, SHA384 or SHA512 hash function
 # if this option is used. If the server obtains 
 # a message from the client with a weaker (SHA1) hash function then the 
 # server returns error code 426.
 #
 #sha256
+#sha384
 #sha512
 
 # Mobility with ICE (MICE) specs support.

+ 6 - 4
man/man1/turnadmin.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
-.TH TURN 1 "04 February 2015" "" ""
+.TH TURN 1 "06 February 2015" "" ""
 .SH GENERAL INFORMATION
 
 \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage 
@@ -179,10 +179,12 @@ By default, MD5 is used for the key storage encryption
 (as required by the current STUN/TURNstandards).
 .TP
 .B
+\fB\-Y\fP, \fB\-\-sha384\fP
+Use SHA384 as the keys hash function (a non\-standard feature).
+.TP
+.B
 \fB\-K\fP, \fB\-\-sha512\fP
-Use SHA512 as the keys hash function (a non\-standard feature). 
-By default, MD5 is used for the key storage encryption 
-(as required by the current STUN/TURNstandards).
+Use SHA512 as the keys hash function (a non\-standard feature).
 .TP
 .B
 \fB\-\-max\-bps\fP

+ 5 - 1
man/man1/turnserver.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
-.TH TURN 1 "04 February 2015" "" ""
+.TH TURN 1 "06 February 2015" "" ""
 .SH GENERAL INFORMATION
 
 The \fBTURN Server\fP project contains the source code of a TURN server and TURN client 
@@ -372,6 +372,10 @@ from the client with a weaker (SHA1) hash function then the server returns
 error code 426.
 .TP
 .B
+\fB\-\-sha384\fP
+Require SHA384 digest function to be used for the message integrity.
+.TP
+.B
 \fB\-\-sha512\fP
 Require SHA512 digest function to be used for the message integrity.
 .TP

+ 5 - 1
man/man1/turnutils.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
-.TH TURN 1 "04 February 2015" "" ""
+.TH TURN 1 "06 February 2015" "" ""
 .SH GENERAL INFORMATION
 
 A set of turnutils_* programs provides some utility functionality to be used
@@ -143,6 +143,10 @@ SHA256 digest function for message integrity calculation.
 Without this option, by default, SHA1 is used.
 .TP
 .B
+\fB\-Y\fP
+SHA384 digest function for message integrity calculation.
+.TP
+.B
 \fB\-K\fP
 SHA512 digest function for message integrity calculation.
 .TP

+ 14 - 1
src/apps/relay/mainrelay.c

@@ -569,6 +569,7 @@ static char Usage[] = "Usage: turnserver [options]\n"
 "						support SHA256 hash function if this option is used. If the server obtains\n"
 "						a message from the client with a weaker (SHA1) hash function then the server\n"
 "						returns error code 426.\n"
+" --sha384					Require SHA384 digest function to be used for the message integrity.\n"
 " --sha512					Require SHA512 digest function to be used for the message integrity.\n"
 " --proc-user <user-name>			User name to run the turnserver process.\n"
 "						After the initialization, the turnserver process\n"
@@ -639,6 +640,7 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
 #endif
 	"	-H, --sha256			Use SHA256 digest function to be used for the message integrity.\n"
 	"					By default, the server SHA1 (as per TURN standard specs).\n"
+	"	-Y, --sha384			Use SHA384 digest function to be used for the message integrity.\n"
 	"	-K, --sha512			Use SHA512 digest function to be used for the message integrity.\n"
 	"	--max-bps			Set value of realm's max-bps parameter.\n"
 	"					Setting to zero value means removal of the option.\n"
@@ -650,7 +652,7 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
 
 #define OPTIONS "c:d:p:L:E:X:i:m:l:r:u:b:B:e:M:J:N:O:q:Q:s:C:vVofhznaAS"
   
-#define ADMIN_OPTIONS "gGORIHKlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h"
+#define ADMIN_OPTIONS "gGORIHKYlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h"
 
 enum EXTRA_OPTS {
 	NO_UDP_OPT=256,
@@ -690,6 +692,7 @@ enum EXTRA_OPTS {
 	CA_FILE_OPT,
 	DH_FILE_OPT,
 	SHA256_OPT,
+	SHA384_OPT,
 	SHA512_OPT,
 	NO_STUN_OPT,
 	PROC_USER_OPT,
@@ -814,6 +817,7 @@ static const struct myoption long_options[] = {
 				{ "CA-file", required_argument, NULL, CA_FILE_OPT },
 				{ "dh-file", required_argument, NULL, DH_FILE_OPT },
 				{ "sha256", optional_argument, NULL, SHA256_OPT },
+				{ "sha384", optional_argument, NULL, SHA384_OPT },
 				{ "sha512", optional_argument, NULL, SHA512_OPT },
 				{ "proc-user", required_argument, NULL, PROC_USER_OPT },
 				{ "proc-group", required_argument, NULL, PROC_GROUP_OPT },
@@ -869,6 +873,7 @@ static const struct myoption admin_long_options[] = {
 				{ "realm", required_argument, NULL, 'r' },
 				{ "password", required_argument, NULL, 'p' },
 				{ "sha256", no_argument, NULL, 'H' },
+				{ "sha384", no_argument, NULL, 'Y' },
 				{ "sha512", no_argument, NULL, 'K' },
 				{ "add-origin", no_argument, NULL, 'O' },
 				{ "del-origin", no_argument, NULL, 'R' },
@@ -1037,6 +1042,10 @@ static void set_option(int c, char *value)
 		if(get_bool_value(value))
 			turn_params.shatype = SHATYPE_SHA256;
 		break;
+	case SHA384_OPT:
+		if(get_bool_value(value))
+			turn_params.shatype = SHATYPE_SHA384;
+		break;
 	case SHA512_OPT:
 		if(get_bool_value(value))
 			turn_params.shatype = SHATYPE_SHA512;
@@ -1562,6 +1571,10 @@ static int adminmain(int argc, char **argv)
 			if(get_bool_value(optarg))
 				turn_params.shatype = SHATYPE_SHA256;
 			break;
+		case 'Y':
+			if(get_bool_value(optarg))
+				turn_params.shatype = SHATYPE_SHA384;
+			break;
 		case 'K':
 			if(get_bool_value(optarg))
 				turn_params.shatype = SHATYPE_SHA512;

+ 22 - 0
src/apps/relay/turn_admin_server.c

@@ -712,6 +712,8 @@ static void cli_print_configuration(struct cli_session* cs)
 
 		if(turn_params.shatype == SHATYPE_SHA256)
 			cli_print_str(cs,"SHA256","SHA type",0);
+		else if(turn_params.shatype == SHATYPE_SHA384)
+			cli_print_str(cs,"SHA384","SHA type",0);
 		else if(turn_params.shatype == SHATYPE_SHA512)
 			cli_print_str(cs,"SHA512","SHA type",0);
 		else
@@ -1981,6 +1983,8 @@ static void write_pc_page(ioa_socket_handle s)
 
 				if(turn_params.shatype == SHATYPE_SHA256)
 					https_print_str(sb,"SHA256","SHA type",0);
+				else if(turn_params.shatype == SHATYPE_SHA384)
+					https_print_str(sb,"SHA384","SHA type",0);
 				else if(turn_params.shatype == SHATYPE_SHA512)
 					https_print_str(sb,"SHA512","SHA type",0);
 				else
@@ -2512,6 +2516,8 @@ static void write_users_page(ioa_socket_handle s, const u08bits *add_user, const
 
 			if(turn_params.shatype == SHATYPE_SHA256)
 				str_buffer_append(sb,"SHA type: SHA256<br>\r\n");
+			else if(turn_params.shatype == SHATYPE_SHA384)
+				str_buffer_append(sb,"SHA type: SHA384<br>\r\n");
 			else if(turn_params.shatype == SHATYPE_SHA512)
 				str_buffer_append(sb,"SHA type: SHA512<br>\r\n");
 			else
@@ -3054,6 +3060,14 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
 					}
 					str_buffer_append(sb,">SHA-256\r\n<br>\r\n");
 
+					str_buffer_append(sb,"<input type=\"radio\" name=\"");
+					str_buffer_append(sb,HR_ADD_OAUTH_HKDF);
+					str_buffer_append(sb,"\" value=\"SHA-384\" ");
+					if(!strcmp("SHA-384",add_hkdf_hash_func)) {
+						str_buffer_append(sb," checked ");
+					}
+					str_buffer_append(sb,">SHA-384\r\n<br>\r\n");
+
 					str_buffer_append(sb,"<input type=\"radio\" name=\"");
 					str_buffer_append(sb,HR_ADD_OAUTH_HKDF);
 					str_buffer_append(sb,"\" value=\"SHA-512\" ");
@@ -3154,6 +3168,14 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
 					}
 					str_buffer_append(sb,">HMAC-SHA-256\r\n<br>\r\n");
 
+					str_buffer_append(sb,"<input type=\"radio\" name=\"");
+					str_buffer_append(sb,HR_ADD_OAUTH_AA);
+					str_buffer_append(sb,"\" value=\"HMAC-SHA-384\" ");
+					if(!strcmp("HMAC-SHA-384",add_aa)) {
+						str_buffer_append(sb," checked ");
+					}
+					str_buffer_append(sb,">HMAC-SHA-384\r\n<br>\r\n");
+
 					str_buffer_append(sb,"<input type=\"radio\" name=\"");
 					str_buffer_append(sb,HR_ADD_OAUTH_AA);
 					str_buffer_append(sb,"\" value=\"HMAC-SHA-512\" ");

+ 11 - 0
src/apps/relay/userdb.c

@@ -495,6 +495,12 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *u
 							return -1;
 						}
 						break;
+					case SHA384SIZEBYTES:
+						if(turn_params.shatype != SHATYPE_SHA384) {
+							TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(3): %d\n",(int)dot.enc_block.key_length);
+							return -1;
+						}
+						break;
 					case SHA512SIZEBYTES:
 						if(turn_params.shatype != SHATYPE_SHA512) {
 							TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(3): %d\n",(int)dot.enc_block.key_length);
@@ -581,6 +587,11 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *u
 					return -1;
 				hmac_len = SHA256SIZEBYTES;
 				break;
+			case SHA384SIZEBYTES:
+				if(turn_params.shatype != SHATYPE_SHA384)
+					return -1;
+				hmac_len = SHA384SIZEBYTES;
+				break;
 			case SHA512SIZEBYTES:
 				if(turn_params.shatype != SHATYPE_SHA512)
 					return -1;

+ 6 - 0
src/apps/rfc5769/rfc5769check.c

@@ -45,6 +45,9 @@ static const char* shas[]={"SHA1",
 #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
 			   "SHA256",
 #endif
+#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
+			   "SHA384",
+#endif
 #if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
 			   "SHA512",
 #endif
@@ -58,6 +61,9 @@ static const char* hmacs[]={"HMAC-SHA-1",
 #if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
 			    "HMAC-SHA-256","HMAC-SHA-256-128",
 #endif
+#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
+			    "HMAC-SHA-384",
+#endif
 #if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
 			    "HMAC-SHA-512",
 #endif

+ 10 - 1
src/apps/uclient/mainuclient.c

@@ -131,6 +131,7 @@ static char Usage[] =
   "	-O	DOS attack mode (quick connect and exit).\n"
   "	-H	SHA256 digest function for message integrity calculation.\n"
   "		Without this option, by default, SHA1 is used.\n"
+  "	-Y	SHA384 digest function for message integrity calculation.\n"
   "	-K	SHA512 digest function for message integrity calculation.\n"
   "	-M	ICE Mobility engaged.\n"
   "	-I	Do not set permissions on TURN relay endpoints\n"
@@ -172,6 +173,8 @@ void recalculate_restapi_hmac(SHATYPE st) {
 
 		if(st == SHATYPE_SHA256)
 		  hmac_len = SHA256SIZEBYTES;
+		else if(st == SHATYPE_SHA384)
+		  hmac_len = SHA384SIZEBYTES;
 		else if(st == SHATYPE_SHA512)
 		  hmac_len = SHA512SIZEBYTES;
 
@@ -215,7 +218,7 @@ int main(int argc, char **argv)
 
 	ns_bzero(local_addr, sizeof(local_addr));
 
-	while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:ZvsyhcxXgtTSAPDNOUHKMRIGBJ")) != -1) {
+	while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:ZvsyhcxXgtTSAPDNOUHYKMRIGBJ")) != -1) {
 		switch (c){
 		case 'J': {
 
@@ -269,6 +272,9 @@ int main(int argc, char **argv)
 		case 'H':
 			shatype = SHATYPE_SHA256;
 			break;
+		case 'Y':
+			shatype = SHATYPE_SHA384;
+			break;
 		case 'K':
 			shatype = SHATYPE_SHA512;
 			break;
@@ -430,6 +436,9 @@ int main(int argc, char **argv)
 			case SHATYPE_SHA256:
 				hmac_len = SHA256SIZEBYTES;
 				break;
+			case SHATYPE_SHA384:
+				hmac_len = SHA384SIZEBYTES;
+				break;
 			case SHATYPE_SHA512:
 				hmac_len = SHA512SIZEBYTES;
 				break;

+ 15 - 0
src/apps/uclient/startuclient.c

@@ -528,6 +528,9 @@ static int clnet_allocate(int verbose,
 							clnet_info->shatype = SHATYPE_SHA256;
 							recalculate_restapi_hmac(clnet_info->shatype);
 						} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) {
+							clnet_info->shatype = SHATYPE_SHA384;
+							recalculate_restapi_hmac(clnet_info->shatype);
+						} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA384)) {
 							clnet_info->shatype = SHATYPE_SHA512;
 							recalculate_restapi_hmac(clnet_info->shatype);
 						}
@@ -729,6 +732,9 @@ static int clnet_allocate(int verbose,
 							clnet_info->shatype = SHATYPE_SHA256;
 							recalculate_restapi_hmac(clnet_info->shatype);
 						} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) {
+							clnet_info->shatype = SHATYPE_SHA384;
+							recalculate_restapi_hmac(clnet_info->shatype);
+						} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA384)) {
 							clnet_info->shatype = SHATYPE_SHA512;
 							recalculate_restapi_hmac(clnet_info->shatype);
 						}
@@ -830,6 +836,9 @@ static int turn_channel_bind(int verbose, uint16_t *chn,
 						clnet_info->shatype = SHATYPE_SHA256;
 						recalculate_restapi_hmac(clnet_info->shatype);
 					} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) {
+						clnet_info->shatype = SHATYPE_SHA384;
+						recalculate_restapi_hmac(clnet_info->shatype);
+					} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA384)) {
 						clnet_info->shatype = SHATYPE_SHA512;
 						recalculate_restapi_hmac(clnet_info->shatype);
 					}
@@ -941,6 +950,9 @@ static int turn_create_permission(int verbose, app_ur_conn_info *clnet_info,
 						clnet_info->shatype = SHATYPE_SHA256;
 						recalculate_restapi_hmac(clnet_info->shatype);
 					} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) {
+						clnet_info->shatype = SHATYPE_SHA384;
+						recalculate_restapi_hmac(clnet_info->shatype);
+					} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA384)) {
 						clnet_info->shatype = SHATYPE_SHA512;
 						recalculate_restapi_hmac(clnet_info->shatype);
 					}
@@ -1523,6 +1535,9 @@ static int turn_tcp_connection_bind(int verbose, app_ur_conn_info *clnet_info, a
 						clnet_info->shatype = SHATYPE_SHA256;
 						recalculate_restapi_hmac(clnet_info->shatype);
 					} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) {
+						clnet_info->shatype = SHATYPE_SHA384;
+						recalculate_restapi_hmac(clnet_info->shatype);
+					} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA384)) {
 						clnet_info->shatype = SHATYPE_SHA512;
 						recalculate_restapi_hmac(clnet_info->shatype);
 					}

+ 5 - 0
src/apps/uclient/uclient.c

@@ -755,6 +755,9 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
 				elem->pinfo.shatype = SHATYPE_SHA256;
 				recalculate_restapi_hmac(elem->pinfo.shatype);
 			} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (elem->pinfo.shatype == SHATYPE_SHA256)) {
+				elem->pinfo.shatype = SHATYPE_SHA384;
+				recalculate_restapi_hmac(elem->pinfo.shatype);
+			} else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (elem->pinfo.shatype == SHATYPE_SHA384)) {
 				elem->pinfo.shatype = SHATYPE_SHA512;
 				recalculate_restapi_hmac(elem->pinfo.shatype);
 			}
@@ -1629,6 +1632,8 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message)
 				otoken.enc_block.timestamp = ((uint64_t)turn_time()) << 16;
 				if(shatype == SHATYPE_SHA256) {
 					otoken.enc_block.key_length = 32;
+				} else if(shatype == SHATYPE_SHA384) {
+					otoken.enc_block.key_length = 48;
 				} else if(shatype == SHATYPE_SHA512) {
 					otoken.enc_block.key_length = 64;
 				} else {

+ 49 - 1
src/client/ns_turn_msg.c

@@ -125,6 +125,15 @@ int stun_calculate_hmac(const u08bits *buf, size_t len, const u08bits *key, size
 #else
 	  fprintf(stderr,"SHA256 is not supported\n");
 	  return -1;
+#endif
+	} else if(shatype == SHATYPE_SHA384) {
+#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
+	  if (!HMAC(EVP_sha384(), key, keylen, buf, len, hmac, hmac_len)) {
+	    return -1;
+	  }
+#else
+	  fprintf(stderr,"SHA384 is not supported\n");
+	  return -1;
 #endif
 	} else if(shatype == SHATYPE_SHA512) {
 #if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
@@ -173,6 +182,18 @@ int stun_produce_integrity_key_str(u08bits *uname, u08bits *realm, u08bits *upwd
 #else
 		fprintf(stderr,"SHA256 is not supported\n");
 		return -1;
+#endif
+	} else if(shatype == SHATYPE_SHA384) {
+#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
+		unsigned int keylen = 0;
+		EVP_MD_CTX ctx;
+		EVP_DigestInit(&ctx,EVP_sha384());
+		EVP_DigestUpdate(&ctx,str,strl);
+		EVP_DigestFinal(&ctx,key,&keylen);
+		EVP_MD_CTX_cleanup(&ctx);
+#else
+		fprintf(stderr,"SHA384 is not supported\n");
+		return -1;
 #endif
 	} else if(shatype == SHATYPE_SHA512) {
 #if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
@@ -1538,6 +1559,8 @@ size_t get_hmackey_size(SHATYPE shatype)
 {
 	if(shatype == SHATYPE_SHA256)
 		return 32;
+	if(shatype == SHATYPE_SHA384)
+		return 48;
 	if(shatype == SHATYPE_SHA512)
 		return 64;
 	return 16;
@@ -1563,6 +1586,9 @@ int stun_attr_add_integrity_str(turn_credential_type ct, u08bits *buf, size_t *l
 	case SHATYPE_SHA256:
 		shasize = SHA256SIZEBYTES;
 		break;
+	case SHATYPE_SHA384:
+		shasize = SHA384SIZEBYTES;
+		break;
 	case SHATYPE_SHA512:
 		shasize = SHA512SIZEBYTES;
 		break;
@@ -1655,6 +1681,16 @@ int stun_check_message_integrity_by_key_str(turn_credential_type ct, u08bits *bu
 		if(shatype != SHATYPE_SHA256)
 			return -1;
 		break;
+	case SHA384SIZEBYTES:
+		shasize = SHA384SIZEBYTES;
+		if(shatype > SHATYPE_SHA384) {
+			if(too_weak)
+				*too_weak = 1;
+				return -1;
+		}
+		if(shatype != SHATYPE_SHA384)
+			return -1;
+		break;
 	case SHA512SIZEBYTES:
 		shasize = SHA512SIZEBYTES;
 		if(shatype > SHATYPE_SHA512) {
@@ -1861,6 +1897,8 @@ static size_t calculate_auth_key_length(AUTH_ALG a)
 		return 32;
 	case AUTH_ALG_HMAC_SHA_256:
 		return 32;
+	case AUTH_ALG_HMAC_SHA_384:
+		return 48;
 	case AUTH_ALG_HMAC_SHA_512:
 		return 64;
 	default:
@@ -1879,6 +1917,8 @@ static size_t calculate_auth_output_length(AUTH_ALG a)
 		return 16;
 	case AUTH_ALG_HMAC_SHA_256:
 		return 32;
+	case AUTH_ALG_HMAC_SHA_384:
+		return 48;
 	case AUTH_ALG_HMAC_SHA_512:
 		return 64;
 	default:
@@ -2004,6 +2044,8 @@ int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *er
 			key->hkdf_hash_func = SHATYPE_SHA1;
 		} else if(!strcmp(oakd->hkdf_hash_func,"SHA256") || !strcmp(oakd->hkdf_hash_func,"SHA-256")) {
 			key->hkdf_hash_func = SHATYPE_SHA256;
+		} else if(!strcmp(oakd->hkdf_hash_func,"SHA384") || !strcmp(oakd->hkdf_hash_func,"SHA-384")) {
+			key->hkdf_hash_func = SHATYPE_SHA384;
 		} else if(!strcmp(oakd->hkdf_hash_func,"SHA512") || !strcmp(oakd->hkdf_hash_func,"SHA-512")) {
 			key->hkdf_hash_func = SHATYPE_SHA512;
 		} else if(oakd->hkdf_hash_func[0]) {
@@ -2019,6 +2061,8 @@ int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *er
 			key->auth_alg = AUTH_ALG_HMAC_SHA_1;
 		} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-256")) {
 			key->auth_alg = AUTH_ALG_HMAC_SHA_256;
+		} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-384")) {
+			key->auth_alg = AUTH_ALG_HMAC_SHA_384;
 		} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-512")) {
 			key->auth_alg = AUTH_ALG_HMAC_SHA_512;
 		} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-256-128")) {
@@ -2104,10 +2148,14 @@ static const EVP_MD *get_auth_type(AUTH_ALG aa)
 	case AUTH_ALG_HMAC_SHA_256_128:
 	case AUTH_ALG_HMAC_SHA_256:
 		return EVP_sha256();
+#endif
+#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
+	case AUTH_ALG_HMAC_SHA_384:
+		return EVP_sha384();
+#endif
 #if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
 	case AUTH_ALG_HMAC_SHA_512:
 		return EVP_sha512();
-#endif
 #endif
 	default:
 		break;

+ 4 - 1
src/client/ns_turn_msg_defs_new.h

@@ -48,6 +48,7 @@
 
 #define SHA1SIZEBYTES (20)
 #define SHA256SIZEBYTES (32)
+#define SHA384SIZEBYTES (48)
 #define SHA512SIZEBYTES (64)
 
 #define MAXSHASIZE (128)
@@ -57,12 +58,13 @@ enum _SHATYPE {
 	SHATYPE_DEFAULT=0,
 	SHATYPE_SHA1=SHATYPE_DEFAULT,
 	SHATYPE_SHA256,
+	SHATYPE_SHA384,
 	SHATYPE_SHA512
 };
 
 typedef enum _SHATYPE SHATYPE;
 
-#define shatype_name(sht) ((sht == SHATYPE_SHA1) ? "SHA1" : ((sht == SHATYPE_SHA256) ? "SHA256" : ((sht == SHATYPE_SHA512) ? "SHA512" : "SHA UNKNOWN")))
+#define shatype_name(sht) ((sht == SHATYPE_SHA1) ? "SHA1" : ((sht == SHATYPE_SHA256) ? "SHA256" : ((sht == SHATYPE_SHA384) ? "SHA384" : "SHA512")))
 
 #define SHA_TOO_WEAK_ERROR_CODE (426)
 #define SHA_TOO_WEAK_ERROR_REASON ((const u08bits*)("credentials too weak"))
@@ -94,6 +96,7 @@ enum _AUTH_ALG {
 	AUTH_ALG_HMAC_SHA_256_128 = AUTH_ALG_DEFAULT,
 	AUTH_ALG_HMAC_SHA_1,
 	AUTH_ALG_HMAC_SHA_256,
+	AUTH_ALG_HMAC_SHA_384,
 	AUTH_ALG_HMAC_SHA_512
 };
 

+ 11 - 0
src/server/ns_turn_server.c

@@ -3316,6 +3316,17 @@ static int check_stun_auth(turn_turnserver *server,
 				return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method);
 			}
 			break;
+		case SHA384SIZEBYTES:
+			if(server->shatype > SHATYPE_SHA384) {
+				*err_code = SHA_TOO_WEAK_ERROR_CODE;
+				*reason = SHA_TOO_WEAK_ERROR_REASON;
+				return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method);
+			}
+			if(server->shatype != SHATYPE_SHA384) {
+				*err_code = 401;
+				return create_challenge_response(ss,tid,resp_constructed,err_code,reason,nbh,method);
+			}
+			break;
 		case SHA512SIZEBYTES:
 			if(server->shatype > SHATYPE_SHA512) {
 				*err_code = SHA_TOO_WEAK_ERROR_CODE;

+ 6 - 4
turndb/schema.userdb.redis

@@ -45,9 +45,10 @@ and they will be almost immediately "seen" by the turnserver process.
 		is 0 - unlimited lifetime.
 	
 	hkdf_hash_func - (optional) hash function for HKDF procedure; the 
-		valid values are SHA-1, SHA-256 and SHA-512, with SHA-256 as default;
-		The hkdf_hash_func is not needed if the as_rs_key and auth_key 
-		are defined explicitly in the database;
+		valid values are SHA-1, SHA-256, SHA-384 and SHA-512,
+		with SHA-256 as default. The hkdf_hash_func is not needed
+		if the as_rs_key and auth_key are defined explicitly
+		in the database;
 		
 	as_rs_alg - oAuth token encryption algorithm; the valid values are
 		"AES-128-CBC" and "AES-256-CBC", , "AEAD-AES-128-GCM",
@@ -59,7 +60,8 @@ and they will be almost immediately "seen" by the turnserver process.
 		is defined by as_rs_alg.
 		
 	auth_alg - (optional) oAuth token authentication algorithm; the valid values are
-		"HMAC-SHA-256-128", "HMAC-SHA-256", "HMAC-SHA-512" and "HMAC-SHA-1".		  
+		"HMAC-SHA-256-128", "HMAC-SHA-256", "HMAC-SHA-384",
+		"HMAC-SHA-512" and "HMAC-SHA-1".		  
 		The default value is "HMAC-SHA-256-128".
 		
 	auth_key - (optional) base64-encoded AUTH key. If not defined, then