diff --git a/ChangeLog b/ChangeLog index d471ff8c..a7ee0ab1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,8 @@ 2/3/2015 Oleg Moskalenko Version 4.4.2.1 'Ardee West': - - SHA-512 added to oAuth; - - updates according to the new third-party-auth draft (oauth); + - (HMAC-)SHA-512 algorithms added; - TOS (DiffServer) and TTL IP header field handling fixed; + - updates according to the new third-party-auth draft (oauth); 2/1/2015 Oleg Moskalenko Version 4.4.1.2 'Ardee West': diff --git a/INSTALL b/INSTALL index 95c56016..00cd59ec 100644 --- a/INSTALL +++ b/INSTALL @@ -470,14 +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) 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 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 @@ -676,13 +677,14 @@ CREATE TABLE turnusers_lt ( ); The field hmackey contains HEX string representation of the key. -We do not store the user open passwords for long-term credentials, for security reasons. -Storing only the HMAC key has its own implications - if you change the realm, -you will have to update the HMAC keys of all users, because the realm is -used for the HMAC key generation. - -The key must be 32 characters (HEX representation of 16 bytes) for SHA1, -or 64 characters (HEX representation of 32 bytes) for SHA256. +We do not store the user open passwords for long-term credentials, for +security reasons. Storing only the HMAC key has its own implications - +if you change the realm, you will have to update the HMAC keys of all +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 128 characters (HEX representation of 64 bytes) for SHA512: # Table holding shared secrets for secret-based authorization # (REST API). It can only be used together with the long-term diff --git a/README.turnadmin b/README.turnadmin index b10f2379..76112fe6 100644 --- a/README.turnadmin +++ b/README.turnadmin @@ -95,7 +95,10 @@ Options with required values: -r, --realm Realm. -p, --password Password. -o, --origin Origin --H, --sha256 Use SHA256 as the keys hash function (a non-standard feature). +-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). --max-bps Set value of realm's max-bps parameter. diff --git a/README.turnserver b/README.turnserver index 5fb0b495..2eb35408 100644 --- a/README.turnserver +++ b/README.turnserver @@ -242,6 +242,7 @@ 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. +--sha512 Require SHA512 digest function to be used for the message integrity. --mobility Mobility with ICE (MICE) specs support. diff --git a/README.turnutils b/README.turnutils index a39fa889..3f2977e3 100644 --- a/README.turnutils +++ b/README.turnutils @@ -94,6 +94,8 @@ Flags: -H SHA256 digest function for message integrity calculation. Without this option, by default, SHA1 is used. + +-K SHA512 digest function for message integrity calculation. -M Use TURN ICE Mobility. diff --git a/STATUS b/STATUS index c3f1b1b3..405cd8d8 100644 --- a/STATUS +++ b/STATUS @@ -119,6 +119,8 @@ compatibility. supported in the client library). 52) Web HTTPS admin interface implemented. + +53) SHA512 support added (experimental). Things to be implemented in future (the development roadmap) are described in the TODO file. diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index e4209026..bf67d4f6 100644 --- a/examples/etc/turnserver.conf +++ b/examples/etc/turnserver.conf @@ -557,15 +557,16 @@ # #secure-stun -# Require SHA256 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 function. The client application -# must support SHA256 hash function if this option is used. If the server obtains +# Require SHA256 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 +# 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 +#sha512 # Mobility with ICE (MICE) specs support. # diff --git a/examples/var/db/turndb b/examples/var/db/turndb index 1805bfb5..bad666cb 100644 Binary files a/examples/var/db/turndb and b/examples/var/db/turndb differ diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 4f3538f4..23e930d9 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "02 February 2015" "" "" +.TH TURN 1 "04 February 2015" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage @@ -179,6 +179,12 @@ By default, MD5 is used for the key storage encryption (as required by the current STUN/TURNstandards). .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). +.TP +.B \fB\-\-max\-bps\fP Set value of realm's max\-bps parameter. .TP diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 943c7fca..aa7ab86c 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "02 February 2015" "" "" +.TH TURN 1 "04 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\-\-sha512\fP +Require SHA512 digest function to be used for the message integrity. +.TP +.B \fB\-\-mobility\fP Mobility with ICE (MICE) specs support. .TP diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index b72d8b39..e605e40f 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "02 February 2015" "" "" +.TH TURN 1 "04 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\-K\fP +SHA512 digest function for message integrity calculation. +.TP +.B \fB\-M\fP Use TURN ICE Mobility. .TP diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 7dd1e65d..49376be4 100644 --- a/src/apps/relay/mainrelay.c +++ b/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" +" --sha512 Require SHA512 digest function to be used for the message integrity.\n" " --proc-user User name to run the turnserver process.\n" " After the initialization, the turnserver process\n" " will make an attempt to change the current user ID to that user.\n" @@ -638,6 +639,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" + " -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" " --total-quota Set value of realm's total-quota parameter.\n" @@ -648,7 +650,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 "gGORIHlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h" +#define ADMIN_OPTIONS "gGORIHKlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h" enum EXTRA_OPTS { NO_UDP_OPT=256, @@ -688,6 +690,7 @@ enum EXTRA_OPTS { CA_FILE_OPT, DH_FILE_OPT, SHA256_OPT, + SHA512_OPT, NO_STUN_OPT, PROC_USER_OPT, PROC_GROUP_OPT, @@ -811,6 +814,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 }, + { "sha512", optional_argument, NULL, SHA512_OPT }, { "proc-user", required_argument, NULL, PROC_USER_OPT }, { "proc-group", required_argument, NULL, PROC_GROUP_OPT }, { "mobility", optional_argument, NULL, MOBILITY_OPT }, @@ -865,6 +869,7 @@ static const struct myoption admin_long_options[] = { { "realm", required_argument, NULL, 'r' }, { "password", required_argument, NULL, 'p' }, { "sha256", no_argument, NULL, 'H' }, + { "sha512", no_argument, NULL, 'K' }, { "add-origin", no_argument, NULL, 'O' }, { "del-origin", no_argument, NULL, 'R' }, { "list-origins", required_argument, NULL, 'I' }, @@ -1031,8 +1036,10 @@ static void set_option(int c, char *value) case SHA256_OPT: if(get_bool_value(value)) turn_params.shatype = SHATYPE_SHA256; - else - turn_params.shatype = SHATYPE_SHA1; + break; + case SHA512_OPT: + if(get_bool_value(value)) + turn_params.shatype = SHATYPE_SHA512; break; case NO_MULTICAST_PEERS_OPT: turn_params.no_multicast_peers = get_bool_value(value); @@ -1554,8 +1561,10 @@ static int adminmain(int argc, char **argv) case 'H': if(get_bool_value(optarg)) turn_params.shatype = SHATYPE_SHA256; - else - turn_params.shatype = SHATYPE_SHA1; + break; + case 'K': + if(get_bool_value(optarg)) + turn_params.shatype = SHATYPE_SHA512; break; case 'h': printf("\n%s\n", AdminUsage); diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index 26a5b934..1e4e90b4 100644 --- a/src/apps/uclient/mainuclient.c +++ b/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" + " -K SHA512 digest function for message integrity calculation.\n" " -M ICE Mobility engaged.\n" " -I Do not set permissions on TURN relay endpoints\n" " (for testing the non-standard server relay functionality).\n" @@ -162,20 +163,23 @@ static char Usage[] = ////////////////////////////////////////////////// -void recalculate_restapi_hmac(void) { +void recalculate_restapi_hmac(SHATYPE st) { if (g_use_auth_secret_with_timestamp) { u08bits hmac[MAXSHASIZE]; - unsigned int hmac_len; + unsigned int hmac_len = 0; - hmac_len = SHA256SIZEBYTES; + if(st == SHATYPE_SHA256) + hmac_len = SHA256SIZEBYTES; + else if(st == SHATYPE_SHA512) + hmac_len = SHA512SIZEBYTES; hmac[0] = 0; if (stun_calculate_hmac(g_uname, strlen((char*) g_uname), (u08bits*) g_auth_secret, strlen(g_auth_secret), hmac, - &hmac_len, SHATYPE_SHA256) >= 0) { + &hmac_len, st) >= 0) { size_t pwd_length = 0; char *pwd = base64_encode(hmac, hmac_len, &pwd_length); @@ -211,7 +215,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:ZvsyhcxXgtTSAPDNOUHMRIGBJ")) != -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:ZvsyhcxXgtTSAPDNOUHKMRIGBJ")) != -1) { switch (c){ case 'J': { @@ -265,6 +269,9 @@ int main(int argc, char **argv) case 'H': shatype = SHATYPE_SHA256; break; + case 'K': + shatype = SHATYPE_SHA512; + break; case 'E': { char* fn = find_config_file(optarg,1); diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 4dd6a13a..39c6d820 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -526,7 +526,10 @@ static int clnet_allocate(int verbose, clnet_info->server_name, &(clnet_info->oauth))) { if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA1)) { clnet_info->shatype = SHATYPE_SHA256; - recalculate_restapi_hmac(); + recalculate_restapi_hmac(clnet_info->shatype); + } else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) { + clnet_info->shatype = SHATYPE_SHA512; + recalculate_restapi_hmac(clnet_info->shatype); } goto beg_allocate; } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { @@ -724,7 +727,10 @@ static int clnet_allocate(int verbose, clnet_info->server_name, &(clnet_info->oauth))) { if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA1)) { clnet_info->shatype = SHATYPE_SHA256; - recalculate_restapi_hmac(); + recalculate_restapi_hmac(clnet_info->shatype); + } else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) { + clnet_info->shatype = SHATYPE_SHA512; + recalculate_restapi_hmac(clnet_info->shatype); } goto beg_refresh; } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { @@ -822,7 +828,10 @@ static int turn_channel_bind(int verbose, uint16_t *chn, clnet_info->server_name, &(clnet_info->oauth))) { if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA1)) { clnet_info->shatype = SHATYPE_SHA256; - recalculate_restapi_hmac(); + recalculate_restapi_hmac(clnet_info->shatype); + } else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) { + clnet_info->shatype = SHATYPE_SHA512; + recalculate_restapi_hmac(clnet_info->shatype); } goto beg_bind; } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { @@ -930,7 +939,10 @@ static int turn_create_permission(int verbose, app_ur_conn_info *clnet_info, clnet_info->server_name, &(clnet_info->oauth))) { if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA1)) { clnet_info->shatype = SHATYPE_SHA256; - recalculate_restapi_hmac(); + recalculate_restapi_hmac(clnet_info->shatype); + } else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) { + clnet_info->shatype = SHATYPE_SHA512; + recalculate_restapi_hmac(clnet_info->shatype); } goto beg_cp; } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { @@ -1509,7 +1521,10 @@ static int turn_tcp_connection_bind(int verbose, app_ur_conn_info *clnet_info, a clnet_info->server_name, &(clnet_info->oauth))) { if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA1)) { clnet_info->shatype = SHATYPE_SHA256; - recalculate_restapi_hmac(); + recalculate_restapi_hmac(clnet_info->shatype); + } else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (clnet_info->shatype == SHATYPE_SHA256)) { + clnet_info->shatype = SHATYPE_SHA512; + recalculate_restapi_hmac(clnet_info->shatype); } goto beg_cb; } else if (stun_is_error_response(&response_message, &err_code,err_msg,sizeof(err_msg))) { diff --git a/src/apps/uclient/uclient.c b/src/apps/uclient/uclient.c index a75dd0e2..b6c68fc3 100644 --- a/src/apps/uclient/uclient.c +++ b/src/apps/uclient/uclient.c @@ -753,7 +753,10 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info clnet_info->server_name, &(clnet_info->oauth))) { if(err_code == SHA_TOO_WEAK_ERROR_CODE && (elem->pinfo.shatype == SHATYPE_SHA1)) { elem->pinfo.shatype = SHATYPE_SHA256; - recalculate_restapi_hmac(); + recalculate_restapi_hmac(elem->pinfo.shatype); + } else if(err_code == SHA_TOO_WEAK_ERROR_CODE && (elem->pinfo.shatype == SHATYPE_SHA256)) { + elem->pinfo.shatype = SHATYPE_SHA512; + recalculate_restapi_hmac(elem->pinfo.shatype); } if(is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) { diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index 045e53ba..fe930f3f 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -109,7 +109,7 @@ turn_credential_type get_turn_credentials_type(void); int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message); int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message); -void recalculate_restapi_hmac(void); +void recalculate_restapi_hmac(SHATYPE st); //////////////////////////////////////////// diff --git a/src/client/ns_turn_msg_defs.h b/src/client/ns_turn_msg_defs.h index f0a22ee6..78653e05 100644 --- a/src/client/ns_turn_msg_defs.h +++ b/src/client/ns_turn_msg_defs.h @@ -44,7 +44,7 @@ #define STUN_MAX_REALM_SIZE (127) #define STUN_MAX_NONCE_SIZE (127) #define STUN_MAX_SERVER_NAME_SIZE (1025) -#define STUN_MAX_PWD_SIZE (127) +#define STUN_MAX_PWD_SIZE (256) #define AUTH_SECRET_SIZE STUN_MAX_PWD_SIZE #define STUN_MAGIC_COOKIE (0x2112A442) diff --git a/turndb/schema.sql b/turndb/schema.sql index 2b2edd2e..b44f1bec 100644 --- a/turndb/schema.sql +++ b/turndb/schema.sql @@ -8,7 +8,7 @@ CREATE TABLE turnusers_lt ( CREATE TABLE turn_secret ( realm varchar(127) default '', - value varchar(127), + value varchar(256), primary key (realm,value) );