diff --git a/src/apps/common/ns_turn_utils.h b/src/apps/common/ns_turn_utils.h index f57fea5..72da8e2 100644 --- a/src/apps/common/ns_turn_utils.h +++ b/src/apps/common/ns_turn_utils.h @@ -36,7 +36,6 @@ #endif #include "ns_turn_ioaddr.h" -//#include #ifdef __cplusplus extern "C" { diff --git a/src/apps/rfc5769/rfc5769check.c b/src/apps/rfc5769/rfc5769check.c index a8dc6cf..224449b 100644 --- a/src/apps/rfc5769/rfc5769check.c +++ b/src/apps/rfc5769/rfc5769check.c @@ -39,6 +39,81 @@ #include "apputils.h" #include "stun_buffer.h" +//////////// OAUTH ////////////////// + +static int check_oauth(void) +{ + oauth_key_data_raw okdr = { + "0123456789", + "01234567890123456789012345678901", + 123456789, + 3600, + "SHA1", + "AES-256-CBC", + "", + "HMAC-SHA-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; + oauth_key key; + + if(convert_oauth_key_data(&okd, &key, err_msg, err_msg_size)<0) { + fprintf(stderr,"%s\n",err_msg); + return -1; + } + + oauth_token ot = { + { + 20, + "01234567890123456789", + 123456789, + 3600 + }, + "",0 + }; + + char server_name[33]="herod"; + encoded_oauth_token etoken; + + if(encode_oauth_token((u08bits *)server_name, &etoken, &key, &ot)<0) { + fprintf(stderr,"%s: cannot encode oauth token\n",__FUNCTION__); + return -1; + } + + oauth_token dot; + + if(decode_oauth_token((u08bits *)server_name, &etoken, &key, &dot)<0) { + fprintf(stderr,"%s: cannot decode oauth token\n",__FUNCTION__); + return -1; + } + + if(strcmp((char*)ot.enc_block.mac_key,(char*)dot.enc_block.mac_key)) { + fprintf(stderr,"%s: wrong mac key: %s, must be %s\n",__FUNCTION__,(char*)dot.enc_block.mac_key,(char*)ot.enc_block.mac_key); + return -1; + } + + if(ot.enc_block.key_length != dot.enc_block.key_length) { + fprintf(stderr,"%s: wrong key length: %d, must be %d\n",__FUNCTION__,(int)dot.enc_block.key_length,(int)ot.enc_block.key_length); + return -1; + } + if(ot.enc_block.timestamp != dot.enc_block.timestamp) { + fprintf(stderr,"%s: wrong timestamp: %llu, must be %llu\n",__FUNCTION__,(unsigned long long)dot.enc_block.timestamp,(unsigned long long)ot.enc_block.timestamp); + return -1; + } + if(ot.enc_block.lifetime != dot.enc_block.lifetime) { + fprintf(stderr,"%s: wrong lifetime: %lu, must be %lu\n",__FUNCTION__,(unsigned long)dot.enc_block.lifetime,(unsigned long)ot.enc_block.lifetime); + return -1; + } + + return 0; +} + ////////////////////////////////////////////////// static SHATYPE shatype = SHATYPE_SHA1; @@ -401,5 +476,10 @@ int main(int argc, const char **argv) } } + { + if(check_oauth()<0) + exit(-1); + } + return 0; } diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index 9b08250..8e674b4 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -1931,11 +1931,54 @@ static void update_hmac_len(AUTH_ALG aa, unsigned int *hmac_len) } } +static int my_EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl) +{ + int cycle = 0; + int out_len = 0; + while((out_len>\n",name); + size_t i; + for(i = 0;i",(unsigned int)f[i]); + } + printf("\n<<==field %s\n",name); +} + static int encode_oauth_token_normal(u08bits *server_name, encoded_oauth_token *etoken, oauth_key *key, oauth_token *dtoken) { if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<=128)) { unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + ns_bzero(orig_field,sizeof(orig_field)); size_t len = 0; *((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length); @@ -1960,8 +2003,10 @@ static int encode_oauth_token_normal(u08bits *server_name, encoded_oauth_token * EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit_ex(&ctx, cipher, NULL, (unsigned char *)key->as_rs_key, NULL); int outl=0; - EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len); - EVP_EncryptFinal_ex(&ctx, encoded_field + outl, &outl); + my_EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len); + int tmp_outl = 0; + EVP_EncryptFinal_ex(&ctx, encoded_field + outl, &tmp_outl); + outl += tmp_outl; size_t sn_len = strlen((char*)server_name); ns_bcopy(server_name,encoded_field+outl,sn_len); @@ -1994,9 +2039,9 @@ static int decode_oauth_token_normal(u08bits *server_name, encoded_oauth_token * if(server_name && etoken && key && dtoken) { size_t mac_size = calculate_auth_output_length(key->auth_alg); - size_t min_encoded_field_size = 2+4+8+calculate_auth_output_length(AUTH_ALG_HMAC_SHA_1); + size_t min_encoded_field_size = 2+4+8+1; if(etoken->size < mac_size+min_encoded_field_size) { - OAUTH_ERROR("%s: token size too small: %d\n",__FUNCTION__,(int)etoken->size); + 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); return -1; } @@ -2013,8 +2058,12 @@ static int decode_oauth_token_normal(u08bits *server_name, encoded_oauth_token * OAUTH_ERROR("%s: mac size is wrong: %d, must be %d\n",__FUNCTION__,(int)mac_size,(int)hmac_len); return -1; } + unsigned char efield[MAX_ENCODED_OAUTH_TOKEN_SIZE]; unsigned char check_mac[MAXSHASIZE]; - if (!HMAC(md, key->auth_key, key->auth_key_size, encoded_field, encoded_field_size, check_mac, &hmac_len)) { + ns_bcopy(encoded_field,efield,encoded_field_size); + size_t sn_len = strlen((char*)server_name); + ns_bcopy(server_name,efield+encoded_field_size,sn_len); + if (!HMAC(md, key->auth_key, key->auth_key_size, efield, encoded_field_size+sn_len, check_mac, &hmac_len)) { return -1; } @@ -2037,13 +2086,11 @@ static int decode_oauth_token_normal(u08bits *server_name, encoded_oauth_token * EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit_ex(&ctx, cipher, NULL, (unsigned char *)key->as_rs_key, NULL); int outl=0; - EVP_DecryptUpdate(&ctx, decoded_field, &outl, encoded_field, (int)encoded_field_size); - EVP_DecryptFinal_ex(&ctx, decoded_field + outl, &outl); + my_EVP_DecryptUpdate(&ctx, decoded_field, &outl, encoded_field, (int)encoded_field_size); - if(outl<(int)min_encoded_field_size) { - OAUTH_ERROR("%s: decrypted output has wrong size: %d\n",__FUNCTION__,(int)outl); - return -1; - } + int tmp_outl = 0; + EVP_DecryptFinal_ex(&ctx, decoded_field + outl, &tmp_outl); + outl += tmp_outl; size_t len = 0; @@ -2080,6 +2127,7 @@ static int encode_oauth_token_aead(u08bits *server_name, encoded_oauth_token *et if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<128)) { unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE]; + ns_bzero(orig_field,sizeof(orig_field)); size_t len = 0; *((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length); @@ -2124,10 +2172,10 @@ static int encode_oauth_token_aead(u08bits *server_name, encoded_oauth_token *et /* Provide any AAD data. This can be called zero or more times as * required */ - if(1 != EVP_EncryptUpdate(&ctx, NULL, &outl, server_name, (int)sn_len)) + if(1 != my_EVP_EncryptUpdate(&ctx, NULL, &outl, server_name, (int)sn_len)) return -1; - if(1 != EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len)) + if(1 != my_EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len)) return -1; int tmp_outl = 0; @@ -2151,7 +2199,7 @@ static int decode_oauth_token_aead(u08bits *server_name, encoded_oauth_token *et { if(server_name && etoken && key && dtoken) { - size_t min_encoded_field_size = 2+4+8+OAUTH_AEAD_NONCE_SIZE+OAUTH_AEAD_TAG_SIZE+calculate_auth_output_length(AUTH_ALG_HMAC_SHA_1); + size_t min_encoded_field_size = 2+4+8+OAUTH_AEAD_NONCE_SIZE+OAUTH_AEAD_TAG_SIZE+1; if(etoken->size < min_encoded_field_size) { OAUTH_ERROR("%s: token size too small: %d\n",__FUNCTION__,(int)etoken->size); return -1; @@ -2190,22 +2238,20 @@ static int decode_oauth_token_aead(u08bits *server_name, encoded_oauth_token *et /* Provide any AAD data. This can be called zero or more times as * required */ - if(1 != EVP_DecryptUpdate(&ctx, NULL, &outl, server_name, (int)sn_len)) + if(1 != my_EVP_DecryptUpdate(&ctx, NULL, &outl, server_name, (int)sn_len)) return -1; - if(1 != EVP_DecryptUpdate(&ctx, decoded_field, &outl, encoded_field, (int)encoded_field_size)) + if(1 != my_EVP_DecryptUpdate(&ctx, decoded_field, &outl, encoded_field, (int)encoded_field_size)) return -1; - int tmp_outl = 0; + EVP_CIPHER_CTX_ctrl (&ctx, EVP_CTRL_GCM_SET_TAG, OAUTH_AEAD_TAG_SIZE, tag); + + int tmp_outl = 0; if(EVP_DecryptFinal_ex(&ctx, decoded_field + outl, &tmp_outl)<1) { OAUTH_ERROR("%s: token integrity check failed\n",__FUNCTION__); return -1; } - outl += tmp_outl; - if(outl<(int)min_encoded_field_size) - return -1; - size_t len = 0; dtoken->enc_block.key_length = nswap16(*((uint16_t*)(decoded_field+len)));