working on oauth

This commit is contained in:
mom040267 2014-09-26 06:51:04 +00:00
parent 064aca0fa7
commit 6aa1af102c
9 changed files with 117 additions and 55 deletions

View File

@ -1,6 +1,13 @@
08/22/2014 Oleg Moskalenko <mom040267@gmail.com>
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);

View File

@ -46,6 +46,7 @@
#include <openssl/ssl.h>
#include <openssl/opensslv.h>
#include <openssl/rand.h>
/////////////// 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) {

View File

@ -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;

View File

@ -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)

View File

@ -38,6 +38,7 @@
#include <time.h>
#include <openssl/err.h>
#include <openssl/rand.h>
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;
}
///////////////////////////////////////////

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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)