From 6aa1af102c751fc25e2029686a1effd8324619db Mon Sep 17 00:00:00 2001 From: mom040267 Date: Fri, 26 Sep 2014 06:51:04 +0000 Subject: [PATCH] working on oauth --- ChangeLog | 9 +++++- src/apps/uclient/mainuclient.c | 47 ++++++++++++++++++++++++++-- src/apps/uclient/session.h | 3 ++ src/apps/uclient/startuclient.c | 35 +++------------------ src/apps/uclient/uclient.c | 55 ++++++++++++++++++++++++--------- src/apps/uclient/uclient.h | 4 ++- src/client/ns_turn_msg.c | 17 ++++++---- src/client/ns_turn_msg.h | 1 + src/client/ns_turn_msg_defs.h | 1 + 9 files changed, 117 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7bc1dd..34e0a33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,13 @@ 08/22/2014 Oleg Moskalenko Version 4.2.1.1 'Monza': - - oAuth security implementation. (TODO) + - oAuth security implementation: + TODO: + - clients's check_integrity method(); + - security dialog; + - authorization process - test; + - access-token must be cached and included only in ALLOCATE and REFRESH; + - token timeout; + - kid timeout; - TLS renegotiation DoS attack prevention implemented; - FQDN as relay-ip and listener-ip parameters (issue 6) (patch provided by IƱaki Baz Castillo); diff --git a/src/apps/uclient/mainuclient.c b/src/apps/uclient/mainuclient.c index c2bc91b..ddc81de 100644 --- a/src/apps/uclient/mainuclient.c +++ b/src/apps/uclient/mainuclient.c @@ -46,6 +46,7 @@ #include #include +#include /////////////// extern definitions ///////////////////// @@ -98,7 +99,10 @@ band_limit_t bps = 0; int dual_allocation = 0; int oauth = 0; -oauth_key_data_raw okdr = { +oauth_key okey; +oauth_token otoken; + +static oauth_key_data_raw okdr = { "north","Y2FybGVvbg==",0,0,"SHA-256","AES-256-CBC","","HMAC-SHA-256-128","" }; @@ -212,8 +216,26 @@ int main(int argc, char **argv) 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) { switch (c){ - case 'J': + case 'J': { + oauth = 1; + + if(use_short_term) { + fprintf(stderr,"Short-term mechanism cannot be used together with oAuth.\n"); + exit(-1); + } + + oauth_key_data okd; + convert_oauth_key_data_raw(&okdr, &okd); + + char err_msg[1025] = "\0"; + size_t err_msg_size = sizeof(err_msg) - 1; + + if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) { + fprintf(stderr, "%s\n", err_msg); + exit(-1); + } + } break; case 'a': bps = (band_limit_t)atol(optarg); @@ -271,6 +293,10 @@ int main(int argc, char **argv) dual_allocation = 1; break; case 'A': + if(oauth) { + fprintf(stderr,"Short-term mechanism cannot be used together with oAuth.\n"); + exit(-1); + } use_short_term = 1; break; case 'u': @@ -375,6 +401,23 @@ int main(int argc, char **argv) } } + if(oauth) { + + otoken.enc_block.lifetime = 0; + otoken.enc_block.timestamp = 0; + + switch(shatype) { + case SHATYPE_SHA256: + otoken.enc_block.key_length = 32; + break; + default: + otoken.enc_block.key_length = 20; + break; + }; + + RAND_bytes((unsigned char *)(otoken.enc_block.mac_key), otoken.enc_block.key_length); + } + if(g_use_auth_secret_with_timestamp) { if(use_short_term) { diff --git a/src/apps/uclient/session.h b/src/apps/uclient/session.h index 5635c52..b7f98e2 100644 --- a/src/apps/uclient/session.h +++ b/src/apps/uclient/session.h @@ -80,6 +80,9 @@ typedef struct { int broken; u08bits nonce[STUN_MAX_NONCE_SIZE+1]; u08bits realm[STUN_MAX_REALM_SIZE+1]; + /* oAuth */ + int oauth; + u08bits server_name[STUN_MAX_SERVER_NAME_SIZE+1]; /* RFC 6062 */ app_tcp_conn_info **tcp_conn; size_t tcp_conn_number; diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index efb2aca..b725784 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -433,13 +433,8 @@ static int clnet_allocate(int verbose, allocate_finished = 1; if(clnet_info->nonce[0] || use_short_term) { - SHATYPE sht = clnet_info->shatype; - if(stun_check_message_integrity_str(get_turn_credentials_type(), - message.buf, (size_t)(message.len), g_uname, - clnet_info->realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in allocate message received from server\n"); + if(check_integrity(clnet_info, &message)<0) return -1; - } } if (verbose) { @@ -524,13 +519,8 @@ static int clnet_allocate(int verbose, if(err_code == 300) { if(clnet_info->nonce[0] || use_short_term) { - SHATYPE sht = clnet_info->shatype; - if(stun_check_message_integrity_str(get_turn_credentials_type(), - message.buf, (size_t)(message.len), g_uname, - clnet_info->realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in allocate message received from server\n"); + if(check_integrity(clnet_info, &message)<0) return -1; - } } ioa_addr alternate_server; @@ -795,13 +785,8 @@ static int turn_channel_bind(int verbose, uint16_t *chn, cb_received = 1; if(clnet_info->nonce[0] || use_short_term) { - SHATYPE sht = clnet_info->shatype; - if(stun_check_message_integrity_str(get_turn_credentials_type(), - message.buf, (size_t)(message.len), g_uname, - clnet_info->realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in channel bind message received from server\n"); + if(check_integrity(clnet_info, &message)<0) return -1; - } } if (verbose) { @@ -909,13 +894,8 @@ static int turn_create_permission(int verbose, app_ur_conn_info *clnet_info, cp_received = 1; if(clnet_info->nonce[0] || use_short_term) { - SHATYPE sht = clnet_info->shatype; - if(stun_check_message_integrity_str(get_turn_credentials_type(), - message.buf, (size_t)(message.len), g_uname, - clnet_info->realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in create permission message received from server\n"); + if(check_integrity(clnet_info, &message)<0) return -1; - } } if (verbose) { @@ -1495,13 +1475,8 @@ static int turn_tcp_connection_bind(int verbose, app_ur_conn_info *clnet_info, a if (stun_is_success_response(&message)) { if(clnet_info->nonce[0] || use_short_term) { - SHATYPE sht = clnet_info->shatype; - if(stun_check_message_integrity_str(get_turn_credentials_type(), - message.buf, (size_t)(message.len), g_uname, - clnet_info->realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in connect bind message received from server\n"); + if(check_integrity(clnet_info, &message)<0) return -1; - } } if(stun_get_method(&message)!=STUN_METHOD_CONNECTION_BIND) diff --git a/src/apps/uclient/uclient.c b/src/apps/uclient/uclient.c index 77cc57a..7292e55 100644 --- a/src/apps/uclient/uclient.c +++ b/src/apps/uclient/uclient.c @@ -38,6 +38,7 @@ #include #include +#include static int verbose_packets=0; @@ -510,13 +511,9 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info } else if (stun_is_indication(&(elem->in_buffer))) { if(use_short_term) { - SHATYPE sht = elem->pinfo.shatype; - if(stun_check_message_integrity_str(get_turn_credentials_type(), - elem->in_buffer.buf, (size_t)(elem->in_buffer.len), g_uname, - elem->pinfo.realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in indication message 0x%x received from server\n",(unsigned int)stun_get_method(&(elem->in_buffer))); + + if(check_integrity(&(elem->pinfo), &(elem->in_buffer))<0) return -1; - } } uint16_t method = stun_get_method(&elem->in_buffer); @@ -569,13 +566,8 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info } else if (stun_is_success_response(&(elem->in_buffer))) { if(elem->pinfo.nonce[0] || use_short_term) { - SHATYPE sht = elem->pinfo.shatype; - if(stun_check_message_integrity_str(get_turn_credentials_type(), - elem->in_buffer.buf, (size_t)(elem->in_buffer.len), g_uname, - elem->pinfo.realm, g_upwd, sht)<1) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in success message 0x%x received from server\n",(unsigned int)stun_get_method(&(elem->in_buffer))); + if(check_integrity(&(elem->pinfo), &(elem->in_buffer))<0) return -1; - } } if(is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) { @@ -1437,15 +1429,48 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) return -1; } } else if(clnet_info->nonce[0]) { - if(stun_attr_add_integrity_by_user_str(message->buf, (size_t*)&(message->len), g_uname, + + if(oauth && clnet_info->oauth) { + encoded_oauth_token etoken; + u08bits nonce[12]; + RAND_bytes((unsigned char*)nonce,12); + if(encode_oauth_token(clnet_info->server_name, &etoken, &okey, &otoken, nonce)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot encode token\n"); + return -1; + } + stun_attr_add_str(message->buf, (size_t*)&(message->len), STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN, + (const u08bits*)etoken.token, (int)etoken.size); + + hmackey_t key; + ns_bcopy(otoken.enc_block.mac_key,key,otoken.enc_block.key_length); + if(stun_attr_add_integrity_by_key_str(message->buf, (size_t*)&(message->len), g_uname, + clnet_info->realm, key, clnet_info->nonce, clnet_info->shatype)<0) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n"); + return -1; + } + } else { + if(stun_attr_add_integrity_by_user_str(message->buf, (size_t*)&(message->len), g_uname, clnet_info->realm, g_upwd, clnet_info->nonce, clnet_info->shatype)<0) { - TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n"); - return -1; + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n"); + return -1; + } } } return 0; } +int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) +{ + SHATYPE sht = clnet_info->shatype; + if(stun_check_message_integrity_str(get_turn_credentials_type(), + message->buf, (size_t)(message->len), g_uname, + clnet_info->realm, g_upwd, sht)<1) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in a message received from server\n"); + return -1; + } + return 0; +} + /////////////////////////////////////////// diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index fab5920..ffb20cb 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -87,7 +87,8 @@ extern int dual_allocation; extern char origin[STUN_MAX_ORIGIN_SIZE+1]; extern int oauth; -extern oauth_key_data_raw okdr; +extern oauth_key okey; +extern oauth_token otoken; #define is_TCP_relay() (relay_transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) @@ -103,6 +104,7 @@ void client_input_handler(evutil_socket_t fd, short what, void* arg); 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); diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index cdac678..bda8e47 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -1449,13 +1449,8 @@ int stun_attr_add_integrity_str(turn_credential_type ct, u08bits *buf, size_t *l return 0; } -int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, u08bits *upwd, u08bits *nonce, SHATYPE shatype) +int stun_attr_add_integrity_by_key_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, hmackey_t key, u08bits *nonce, SHATYPE shatype) { - hmackey_t key; - - if(stun_produce_integrity_key_str(uname, realm, upwd, key, shatype)<0) - return -1; - if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, strlen((s08bits*)uname))<0) return -1; @@ -1469,6 +1464,16 @@ int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *unam return stun_attr_add_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, len, key, p, shatype); } +int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, u08bits *upwd, u08bits *nonce, SHATYPE shatype) +{ + hmackey_t key; + + if(stun_produce_integrity_key_str(uname, realm, upwd, key, shatype)<0) + return -1; + + return stun_attr_add_integrity_by_key_str(buf, len, uname, realm, key, nonce, shatype); +} + int stun_attr_add_integrity_by_user_short_term_str(u08bits *buf, size_t *len, u08bits *uname, st_password_t pwd, SHATYPE shatype) { if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, strlen((s08bits*)uname))<0) diff --git a/src/client/ns_turn_msg.h b/src/client/ns_turn_msg.h index f54c235..e5f86dc 100644 --- a/src/client/ns_turn_msg.h +++ b/src/client/ns_turn_msg.h @@ -183,6 +183,7 @@ void print_bin_func(const char *name, size_t len, const void *s, const char *fun int stun_check_message_integrity_by_key_str(turn_credential_type ct, u08bits *buf, size_t len, hmackey_t key, st_password_t pwd, SHATYPE shatype, int *too_weak); int stun_check_message_integrity_str(turn_credential_type ct, u08bits *buf, size_t len, u08bits *uname, u08bits *realm, u08bits *upwd, SHATYPE shatype); int stun_attr_add_integrity_str(turn_credential_type ct, u08bits *buf, size_t *len, hmackey_t key, st_password_t pwd, SHATYPE shatype); +int stun_attr_add_integrity_by_key_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, hmackey_t key, u08bits *nonce, SHATYPE shatype); int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, u08bits *upwd, u08bits *nonce, SHATYPE shatype); int stun_attr_add_integrity_by_user_short_term_str(u08bits *buf, size_t *len, u08bits *uname, st_password_t pwd, SHATYPE shatype); size_t get_hmackey_size(SHATYPE shatype); diff --git a/src/client/ns_turn_msg_defs.h b/src/client/ns_turn_msg_defs.h index 1154845..cde11dd 100644 --- a/src/client/ns_turn_msg_defs.h +++ b/src/client/ns_turn_msg_defs.h @@ -43,6 +43,7 @@ #define STUN_MAX_USERNAME_SIZE (513) #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_MAGIC_COOKIE (0x2112A442)