From d023a40b590cd8bf7cf7c073fbef58af12a14610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Fri, 13 May 2016 13:53:27 +0200 Subject: [PATCH 01/10] oauth token encode and decode utility --- Makefile.in | 7 +- src/apps/oauth/oauth.c | 452 +++++++++++++++++++++++++++++++++++++++++ src/apps/oauth/test.sh | 15 ++ 3 files changed, 473 insertions(+), 1 deletion(-) create mode 100644 src/apps/oauth/oauth.c create mode 100755 src/apps/oauth/test.sh diff --git a/Makefile.in b/Makefile.in index 479df070..6a9956f8 100755 --- a/Makefile.in +++ b/Makefile.in @@ -34,7 +34,7 @@ SERVERAPP_HEADERS = src/apps/relay/userdb.h src/apps/relay/tls_listener.h src/ap SERVERAPP_MODS = src/apps/relay/mainrelay.c src/apps/relay/netengine.c src/apps/relay/libtelnet.c src/apps/relay/turn_admin_server.c src/apps/relay/userdb.c src/apps/relay/tls_listener.c src/apps/relay/dtls_listener.c ${HIREDIS_MODS} ${USERDB_MODS} SERVERAPP_DEPS = ${SERVERTURN_MODS} ${SERVERTURN_DEPS} ${SERVERAPP_MODS} ${SERVERAPP_HEADERS} ${COMMON_DEPS} ${IMPL_DEPS} lib/libturnclient.a -TURN_BUILD_RESULTS = bin/turnutils_natdiscovery bin/turnutils_stunclient bin/turnutils_rfc5769check bin/turnutils_uclient bin/turnserver bin/turnutils_peer lib/libturnclient.a include/turn/ns_turn_defs.h sqlite_empty_db +TURN_BUILD_RESULTS = bin/turnutils_oauth bin/turnutils_natdiscovery bin/turnutils_stunclient bin/turnutils_rfc5769check bin/turnutils_uclient bin/turnserver bin/turnutils_peer lib/libturnclient.a include/turn/ns_turn_defs.h sqlite_empty_db all: ${TURN_BUILD_RESULTS} @@ -59,6 +59,11 @@ bin/turnutils_natdiscovery: ${COMMON_DEPS} lib/libturnclient.a src/apps/natdisco ${MKBUILDDIR} bin ${CC} ${CPPFLAGS} ${CFLAGS} src/apps/natdiscovery/natdiscovery.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS} +bin/turnutils_oauth: ${COMMON_DEPS} lib/libturnclient.a src/apps/oauth/oauth.c + pwd + ${MKBUILDDIR} bin + ${CC} ${CPPFLAGS} ${CFLAGS} src/apps/oauth/oauth.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS} + bin/turnutils_stunclient: ${COMMON_DEPS} lib/libturnclient.a src/apps/stunclient/stunclient.c pwd ${MKBUILDDIR} bin diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c new file mode 100644 index 00000000..9e425978 --- /dev/null +++ b/src/apps/oauth/oauth.c @@ -0,0 +1,452 @@ +/* + * Copyright (C) 2011, 2012, 2013 Citrix Systems + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ns_turn_utils.h" +#include "apputils.h" +#include "stun_buffer.h" + +//////////////////////////////////////////////////// + +#define OAUTH_TOKEN_SIZE 1000 //TODO: find insted of 1000 the real max of encoded token length +#define OAUTH_MAC_KEY_SIZE 32 +#define OAUTH_LTK_ID_SIZE 32 +#define OAUTH_LTK_SIZE 32 +#define OAUTH_LTK_BASE64ENCODED_SIZE 44 +#define OAUTH_TOKEN_LIFETIME 3600 +#define OAUTH_AS_RS_ALG_SIZE 7 +#define OAUTH_SERVER_NAME_SIZE 255 +#define OAUTH_GCM_NONCE_BASE64ENCODED_SIZE 16 +#define OAUTH_HMAC_ALG_SIZE 20 + + +static int setup_ikm_key(const char *kid, + const char *ikm_key, + const turn_time_t key_timestamp, + const turn_time_t key_lifetime, + const char *as_rs_alg, + oauth_key *key) { + + ns_bzero(key,sizeof(*key)); + + oauth_key_data okd; + ns_bzero(&okd,sizeof(okd)); + + { + oauth_key_data_raw okdr; + ns_bzero(&okdr,sizeof(okdr)); + + STRCPY(okdr.kid,kid); + STRCPY(okdr.ikm_key,ikm_key); + STRCPY(okdr.as_rs_alg,as_rs_alg); + okdr.timestamp = key_timestamp; + okdr.lifetime = key_lifetime; + + 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, key, err_msg, err_msg_size) < 0) { + fprintf(stderr, "%s\n", err_msg); + return -1; + } + + return 0; +} + + + +static int encode_token(const char* server_name, + const char* gcm_nonce, + const char* mac_key, + const uint64_t token_timestamp, + const uint32_t token_lifetime, + const oauth_key key, + char* base64encoded_etoken) { + + + oauth_token ot; + ns_bzero(&ot,sizeof(ot)); + + const size_t mac_key_length=strlen(mac_key); + ot.enc_block.key_length = (uint16_t)mac_key_length; + STRCPY(ot.enc_block.mac_key,mac_key); + ot.enc_block.timestamp = token_timestamp; + ot.enc_block.lifetime = token_lifetime; + + encoded_oauth_token etoken; + ns_bzero(&etoken,sizeof(etoken)); + + if (encode_oauth_token((const u08bits *) server_name, &etoken, &key, &ot, (const u08bits*)gcm_nonce) < 0) { + fprintf(stderr, "%s: cannot encode oauth token\n", + __FUNCTION__); + return -1; + } + + size_t base64encoded_etoken_length; + const char *tmp=base64_encode((unsigned char *)(etoken.token), etoken.size, &base64encoded_etoken_length); + STRCPY(base64encoded_etoken,tmp); + + return 0; +} + +static int validate_decode_token(const char* server_name, + const oauth_key key, + const char* base64encoded_etoken, oauth_token* dot) { + + + ns_bzero((dot),sizeof(*dot)); + + encoded_oauth_token etoken; + ns_bzero(&etoken,sizeof(etoken)); + + const size_t base64encoded_etoken_length=strlen(base64encoded_etoken); + const unsigned char *tmp = base64_decode(base64encoded_etoken,base64encoded_etoken_length,&etoken.size); + memcpy(etoken.token,tmp,etoken.size); + + if (decode_oauth_token((const u08bits *) server_name, &etoken, &key, dot) < 0) { + fprintf(stderr, "%s: cannot decode oauth token\n", + __FUNCTION__); + return -1; + } else { + return 0; + }; +} + +static void print_token_body(oauth_token* dot) { + printf("\n"); + printf("Token encrpyted body:\n"); + printf("{\n"); + printf(" mac key: %s\n", (char*) dot->enc_block.mac_key); + printf(" mac key length: %d\n", (int) dot->enc_block.key_length); + time_t time=dot->enc_block.timestamp>>16; + unsigned msec=(dot->enc_block.timestamp & 0xFFFF)*64; + printf(" timestamp:\n"); + printf(" unixtime: %s", ctime(&time)); + printf(" msec:%u\n", msec); + printf(" lifetime: %lu\n", (unsigned long) dot->enc_block.lifetime); + printf("}\n"); +} + +//////////////// local definitions ///////////////// + +const char Usage[] = + "Usage: oauth [ -e / -d ] [options]\n" + "Options:\n" + "\n" + " -h, --help usage\n\n" + " -v, --verbose verbose mode\n\n" + " -e, --encrypt encrypt token\n" + " -d, --decrypt decrypt validate token\n\n" + " -i, --server-name server name (max. 255 char)\n" + " -j, --long-term-key-id long term key id (max. 32 char)\n" + " -k, --long-term-key base64 encoded long term key\n" + " -l --long-term-key-timestamp long term key timestamp (sec since epoch)\n" + " -m, --long-term-key-lifetime long term key lifetime in sec\n" + " -n, --long-term-key-as-rs-alg Authorization Server Resource Server encryption algorithm\n" + " -o, --token-nonce base64 encoded nonce base64(12 octet) = 16 char\n" + " -p, --token-mac-key base64 encoded MAC key base64(32 octet) = 44 char\n" + " -q, --token-timestamp timestamp in sec (sec since epoch, Default: actual gmtime)\n" + " -r, --token-lifetime lifetime in sec (Default: 3600)\n" + " -t, --token base64 encoded encrypted token for validation and decryption\n" + " -u, --hmac-alg stun client hmac algorithm\n"; + +////////////////////////////////////////////////// + + +int main(int argc, char **argv) +{ + + oauth_key key; + + //init vars with default values + char gcm_nonce[OAUTH_GCM_NONCE_SIZE+1]=""; + char mac_key[OAUTH_MAC_KEY_SIZE+1]=""; + uint64_t token_timestamp = (unsigned long long)time(NULL) << 16; + uint32_t token_lifetime = OAUTH_TOKEN_LIFETIME; + + //oauth_key + char kid[OAUTH_LTK_ID_SIZE+1] = ""; + char base64encoded_ltk[OAUTH_LTK_BASE64ENCODED_SIZE+1]=""; + turn_time_t key_timestamp = 0; + turn_time_t key_lifetime = 0; + char as_rs_alg[OAUTH_AS_RS_ALG_SIZE+1]="A256GCM"; + char server_name[OAUTH_SERVER_NAME_SIZE+1] = ""; + + char base64encoded_etoken[OAUTH_TOKEN_SIZE]=""; + + //TODO: replace SHA1 with an option. Actualy both big browser chrome and mozilla supports AFAIU implemented only SHA1. + char hmac_alg[OAUTH_HMAC_ALG_SIZE+1]="HMAC-SHA1"; + + static int verbose_flag=0; + static int encrypt_flag=0; + static int decrypt_flag=0; + + static struct option long_options[] = + { + /* These options set a flag. */ + {"verbose", no_argument, &verbose_flag, 1}, + {"encrypt", no_argument, &encrypt_flag, 1}, + {"decrypt", no_argument, &decrypt_flag, 1}, + {"help", no_argument, 0, 'h'}, + {"server-name", required_argument, 0, 'i'}, + {"long-term-key-id", required_argument, 0, 'j'}, + {"long-term-key", required_argument, 0, 'k'}, + {"long-term-key-timestamp", required_argument, 0, 'l'}, + {"long-term-key-lifetime", required_argument, 0, 'm'}, + {"long-term-key-as-rs-alg", required_argument, 0, 'n'}, + {"token-nonce", required_argument, 0, 'o'}, + {"token-mac-key", required_argument, 0, 'p'}, + {"token-timestamp", required_argument, 0, 'q'}, + {"token-lifetime", required_argument, 0, 'r'}, + {"token", required_argument, 0, 't'}, + {"hmac-alg", required_argument, 0, 'u'}, + {0, 0, 0, 0} + }; + /* getopt_long stores the option index here. */ + int option_index = 0; + + //tmp vars + size_t nonce_size=0; + char *nonce_val; + + size_t mac_key_size; + char *mac_key_val; + + + int i; + int c=0; + + set_logfile("stdout"); + set_system_parameters(0); + + while ((c = getopt_long(argc, argv, "hvedi:j:k:l:m:n:o:p:q:r:t:u:",long_options, &option_index)) != -1) { + switch(c) { + case 'h': + fprintf(stderr, "%s\n", Usage); + exit(1); + break; + case 'v': + verbose_flag=1; + break; + case 'e': + encrypt_flag=1; + break; + case 'd': + decrypt_flag=1; + break; + case 'i': + //server-name + if ( strlen(optarg) <= OAUTH_SERVER_NAME_SIZE ) { + STRCPY(server_name,optarg); + } else { + fprintf(stderr,"Server-name must not exceed %d!\n", OAUTH_LTK_ID_SIZE ); + exit(1); + } + break; + case 'j': + //long-term-key-id + if ( strlen(optarg) <= OAUTH_LTK_ID_SIZE ) { + STRCPY(kid,optarg); + } else { + fprintf(stderr,"Key ID must not exceed %d!\n", OAUTH_LTK_ID_SIZE ); + exit(1); + } + break; + case 'k': + //long-term-key + if ( strlen(optarg) <= OAUTH_LTK_BASE64ENCODED_SIZE ) { + STRCPY(base64encoded_ltk,optarg); + } else { + fprintf(stderr,"Key must not exceed %d!\n", OAUTH_LTK_BASE64ENCODED_SIZE ); + exit(1); + } + break; + case 'l': + //long-term-key-timestamp + key_timestamp = atoi(optarg); + break; + case 'm': + //long-term-key-lifetime + key_lifetime=atoi(optarg); + break; + case 'n': + //long-term-key-as-rs-alg + if ( strlen(optarg) <= OAUTH_AS_RS_ALG_SIZE ) { + STRCPY(as_rs_alg,optarg); + } else { + fprintf(stderr,"AS-RS Alg must not exceed %d!\n", OAUTH_AS_RS_ALG_SIZE ); + exit(1); + } + break; + case 'o': + //token-nonce + nonce_val = (char*)base64_decode(optarg,strlen(optarg),&nonce_size); + if (nonce_size > OAUTH_GCM_NONCE_SIZE){ + nonce_size=OAUTH_GCM_NONCE_SIZE; + } + strncpy(gcm_nonce,nonce_val,nonce_size); + gcm_nonce[ nonce_size + 1 ]='\0'; + break; + case 'p': + //token-mac-key + mac_key_val = (char*)base64_decode(optarg,strlen(optarg),&mac_key_size); + if (mac_key_size > OAUTH_MAC_KEY_SIZE){ + mac_key_size=OAUTH_MAC_KEY_SIZE; + } + strncpy(mac_key,mac_key_val,mac_key_size); + mac_key[mac_key_size+1]='\0'; + break; + case 'q': + //token-timestamp + token_timestamp=strtoull(optarg,0,10); + break; + case 'r': + //token-lifetime + token_lifetime=atoi(optarg); + break; + case 't': + if ( strlen(optarg) <= OAUTH_TOKEN_SIZE ) { + STRCPY(base64encoded_etoken,optarg); + } else { + fprintf(stderr,"base64 encoded encrypted token must not exceed %d!\n", OAUTH_TOKEN_SIZE ); + exit(1); + } + break; + case 'u': + //hmac-alg + if ( strlen(optarg) <= OAUTH_HMAC_ALG_SIZE ) { + STRCPY(hmac_alg,optarg); + } else { + fprintf(stderr,"STUN client HMAC Alg must not exceed %d!\n", OAUTH_HMAC_ALG_SIZE ); + exit(1); + } + break; + default: + fprintf(stderr,"%s\n", Usage); + exit(1); + break; + } + } + + for (i = optind; i < argc; i++) + printf ("Non-option argument %s\n", argv[i]); + + if(optind>argc) { + fprintf(stderr, "%s\n", Usage); + exit(-1); + } + + if (!(encrypt_flag || decrypt_flag)){ + fprintf(stderr, "Hey, encrypt or decrypt?\n"); + exit(-1); + } + + //check if we have required params + //TODO: more compact warnning handling + if (encrypt_flag || decrypt_flag){ + if (strlen(server_name) == 0) { + fprintf(stderr, "For encode/decode --server-name/-i is mandatory \n"); + exit(-1); + } + + if (strlen(kid) == 0){ + fprintf(stderr, "For encode/decode --long-term-key-id/-j is mandatory \n"); + exit(-1); + } + if (strlen(base64encoded_ltk) == 0){ + fprintf(stderr, "For encode/decode --long-term-key/-k is mandatory \n"); + exit(-1); + } + if (key_timestamp == 0){ + fprintf(stderr, "For encode/decode --long-term-key-timestamp/-l is mandatory \n"); + exit(-1); + } + if (key_lifetime == 0){ + fprintf(stderr, "For encode/decode --long-term-key-lifetime/-m is mandatory \n"); + exit(-1); + } + + if (encrypt_flag && strlen(mac_key) == 0) { + fprintf(stderr, "For encode --token-mac-key/-p is mandatory \n"); + exit(-1); + } + + if (!encrypt_flag && decrypt_flag && strlen(base64encoded_etoken) == 0) { + fprintf(stderr, "For decode --token/-t is mandatory \n"); + exit(-1); + } + + + if ( setup_ikm_key(kid, base64encoded_ltk, key_timestamp, key_lifetime, as_rs_alg, &key) == 0 ) { + if(encrypt_flag) { + if (encode_token(server_name, gcm_nonce, mac_key, token_timestamp, token_lifetime, key, base64encoded_etoken) == 0 ) { + printf("{\n"); + printf(" \"access_token\":\"%s\",\n",base64encoded_etoken); + printf(" \"token_type\":\"pop\",\n"); + printf(" \"expires\":%d,\n",token_lifetime); + printf(" \"kid\":\"%s\",\n",kid); + printf(" \"key\":\"%s\",\n",mac_key); + printf(" \"alg\":\%s\n",hmac_alg); + printf("}\n"); + } else { + fprintf(stderr, "Error during token encode\n"); + exit(-1); + } + } + if (decrypt_flag) { + oauth_token dot; + if ( validate_decode_token(server_name, key, base64encoded_etoken,&dot) == 0) { + printf("-=Valid token!=-\n"); + if (verbose_flag) print_token_body(&dot); + } else { + fprintf(stderr, "Error during token validation and decoding\n"); + exit(-1); + } + } + } else { + fprintf(stderr, "Error during key setup\n"); + exit(-1); + } + + } + + return 0; +} diff --git a/src/apps/oauth/test.sh b/src/apps/oauth/test.sh new file mode 100755 index 00000000..cc0e7ac4 --- /dev/null +++ b/src/apps/oauth/test.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +echo "--------------create token---------------" +./bin/turnutils_oauth -e --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 92470300704768 + +echo "---------------create and validate and print out decoded token---------------" +./bin/turnutils_oauth -v -d -e --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 92470300704768 + +echo "---------------validate token---------------" +./bin/turnutils_oauth -d --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token AAwAAAAAAAAAAAAAAABbhGtRHVrDPexC4TQJppr6QNyUwpfB6fS9R3QmwjYvW6YyShKY2fbeUs5lSebE4nYQfA== + +echo "---------------validate and print out decoded token---------------" +./bin/turnutils_oauth -v -d --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token AAwAAAAAAAAAAAAAAABbhGtRHVrDPexC4TQJppr6QNyUwpfB6fS9R3QmwjYvW6YyShKY2fbeUs5lSebE4nYQfA== + + From 9b7256e32f135a428a6655a4187380fc70e80958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 2 Aug 2016 12:09:13 +0200 Subject: [PATCH 02/10] nonce decode and display & fix auto random nonce generation --- src/apps/oauth/oauth.c | 11 ++++++++++- src/client/ns_turn_msg.c | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index 9e425978..10039274 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -114,7 +114,10 @@ static int encode_token(const char* server_name, encoded_oauth_token etoken; ns_bzero(&etoken,sizeof(etoken)); - if (encode_oauth_token((const u08bits *) server_name, &etoken, &key, &ot, (const u08bits*)gcm_nonce) < 0) { + // TODO: avoid this hack + if (!*gcm_nonce) gcm_nonce='\0'; + + if (encode_oauth_token((const u08bits *) server_name, &etoken, &key, &ot,(const u08bits *) gcm_nonce) < 0) { fprintf(stderr, "%s: cannot encode oauth token\n", __FUNCTION__); return -1; @@ -152,6 +155,12 @@ static int validate_decode_token(const char* server_name, static void print_token_body(oauth_token* dot) { printf("\n"); + printf("Token non-encrpyted body:\n"); + printf("{\n"); + size_t base64encoded_nonce_length; + const char *base64encoded_nonce = base64_encode((unsigned char *)dot->enc_block.nonce, dot->enc_block.nonce_length,&base64encoded_nonce_length); + printf(" nonce: %s\n", base64encoded_nonce); + printf(" nonce length: %d\n", (int) dot->enc_block.nonce_length); printf("Token encrpyted body:\n"); printf("{\n"); printf(" mac key: %s\n", (char*) dot->enc_block.mac_key); diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index 1ad98e0c..dde54fba 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -2511,6 +2511,7 @@ static int decode_oauth_token_gcm(const u08bits *server_name, const encoded_oaut const unsigned char *csnl = snl; uint16_t nonce_len = nswap16(*((const uint16_t*)csnl)); + dtoken->enc_block.nonce_length = nonce_len; size_t min_encoded_field_size = 2+4+8+nonce_len+2+OAUTH_GCM_TAG_SIZE+1; if(etoken->size < min_encoded_field_size) { @@ -2521,6 +2522,7 @@ static int decode_oauth_token_gcm(const u08bits *server_name, const encoded_oaut const unsigned char* encoded_field = (const unsigned char*)(etoken->token + nonce_len + 2); unsigned int encoded_field_size = (unsigned int)etoken->size - nonce_len - 2 - OAUTH_GCM_TAG_SIZE; const unsigned char* nonce = ((const unsigned char*)etoken->token + 2); + ns_bcopy(nonce,dtoken->enc_block.nonce,nonce_len); unsigned char tag[OAUTH_GCM_TAG_SIZE]; ns_bcopy(((const unsigned char*)etoken->token) + nonce_len + 2 + encoded_field_size, tag ,sizeof(tag)); From 3d088acd4ec802e765c43dcb577fc7dc15d472bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 2 Aug 2016 12:16:06 +0200 Subject: [PATCH 03/10] Improved timestamp doc and fix the gmt/UTC timestamp issue. --- src/apps/oauth/oauth.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index 10039274..ebf77f8b 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -192,7 +192,9 @@ const char Usage[] = " -n, --long-term-key-as-rs-alg Authorization Server Resource Server encryption algorithm\n" " -o, --token-nonce base64 encoded nonce base64(12 octet) = 16 char\n" " -p, --token-mac-key base64 encoded MAC key base64(32 octet) = 44 char\n" - " -q, --token-timestamp timestamp in sec (sec since epoch, Default: actual gmtime)\n" + " -q, --token-timestamp timestamp in format 64 bit unsigned (Native format - Unix),\n" + " so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a second.\n" + " An example: 16 bit left shift the unixtimestamp. (Default: actual gmtime)\n" " -r, --token-lifetime lifetime in sec (Default: 3600)\n" " -t, --token base64 encoded encrypted token for validation and decryption\n" " -u, --hmac-alg stun client hmac algorithm\n"; @@ -207,8 +209,12 @@ int main(int argc, char **argv) //init vars with default values char gcm_nonce[OAUTH_GCM_NONCE_SIZE+1]=""; + char mac_key[OAUTH_MAC_KEY_SIZE+1]=""; - uint64_t token_timestamp = (unsigned long long)time(NULL) << 16; + + time_t current_time = time(NULL); + struct tm* gmt = gmtime(¤t_time); + uint64_t token_timestamp = (unsigned long long)mktime(gmt) << 16; uint32_t token_lifetime = OAUTH_TOKEN_LIFETIME; //oauth_key From 9c8b4ac71591a95e259a57f2fe1c2e1b3950ec73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 2 Aug 2016 12:18:36 +0200 Subject: [PATCH 04/10] Improved help --- src/apps/oauth/oauth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index ebf77f8b..4a76351a 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -390,7 +390,7 @@ int main(int argc, char **argv) } if (!(encrypt_flag || decrypt_flag)){ - fprintf(stderr, "Hey, encrypt or decrypt?\n"); + fprintf(stderr, "Hey, encrypt or decrypt?\nPlease use -h or --help for the detailed help\n"); exit(-1); } From 3e1f1abcd2184eab88a9a3a524134603cfdb2f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 2 Aug 2016 12:28:43 +0200 Subject: [PATCH 05/10] ouput correction according to rfc7635 Appendix B --- src/apps/oauth/oauth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index 4a76351a..34e6044e 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -436,7 +436,7 @@ int main(int argc, char **argv) printf("{\n"); printf(" \"access_token\":\"%s\",\n",base64encoded_etoken); printf(" \"token_type\":\"pop\",\n"); - printf(" \"expires\":%d,\n",token_lifetime); + printf(" \"expires_in\":%d,\n",token_lifetime); printf(" \"kid\":\"%s\",\n",kid); printf(" \"key\":\"%s\",\n",mac_key); printf(" \"alg\":\%s\n",hmac_alg); From 14754ce43bf15910717ee1e41b66027fe6e3c3a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Tue, 6 Sep 2016 11:19:51 +0200 Subject: [PATCH 06/10] Add turnutils_oauth to README.turnutils --- README.turnutils | 75 +++++++++++++++++++++++ make-man.sh | 7 ++- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 2 +- man/man1/turnutils.1 | 119 ++++++++++++++++++++++++++++++++++++- man/man1/turnutils_oauth.1 | 1 + 6 files changed, 200 insertions(+), 6 deletions(-) create mode 120000 man/man1/turnutils_oauth.1 diff --git a/README.turnutils b/README.turnutils index 6024944b..a5d7bdf7 100644 --- a/README.turnutils +++ b/README.turnutils @@ -37,6 +37,16 @@ according RFC5780. This utility discovers the actual NAT Mapping and Filtering behavior. Be aweare that at least two different listening IP addresses should be configured to be able to work properly! +6. turnutils_oauth: a utility that provides OAuth access_token +generation(AEAD encryption), validation and decryption. This utility inputs +all the keys and lifetimes and any related informations that needed for +creation and validationi of an access_token. It outputs a JSON with all OAuth +PoP parameters that need to pass to the client. Output is generated accoriding +RFC7635 Appendix B, Figure 8. + +For more details, and for the access_token structure, read rfc7635. + + ===================================== NAME @@ -271,6 +281,71 @@ Usage: $ turnutils_natdiscovery -m -f stun.example.com +===================================== + + NAME + +turnutils_oauth - a utility that helps OAuth access_token generation/encryption and validation/decyption + + SYNOPSIS + +$ turnutils_oauth [options] + + DESCRIPTION + +turnutils_oauth utilitiy provides help in OAuth access_token encryption and/or +decryption with AEAD (Atuthenticated Encryption with Associated Data). It helps +for an Auth Server in access_token creation, and also for debuging purposes it +helps the access_token validation and decryption. This utility inputs all the +keys and lifetimes and any related informations that are needed for encryption +or decryption of an access_token. It outputs a JSON with all OAuth PoP +parameters that need to pass to the client. Output is generated accoriding +RFC7635 Appendix B, Figure 8. For more details, and for the access_token +structure, read rfc7635. + +Use either -e and/or -d flag to encrypt or decrypt access_token. + +Flags: + +-h, --help usage + +-v, --verbose verbose mode + +-e, --encrypt encrypt token + +-d, --decrypt decrypt validate token + +Options with required values: + +-i, --server-name server name (max. 255 char) + +-j, --long-term-key-id long term key id (max. 32 char) + +-k, --long-term-key base64 encoded long term key + +-l --long-term-key-timestamp long term key timestamp (sec since epoch) + +-m, --long-term-key-lifetime long term key lifetime in sec + +-n, --long-term-key-as-rs-alg Authorization Server Resource Server encryption algorithm + +-o, --token-nonce base64 encoded nonce base64(12 octet) = 16 char + +-p, --token-mac-key base64 encoded MAC key base64(32 octet) = 44 char + +-q, --token-timestamp timestamp in format 64 bit unsigned (Native format - Unix), + so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a second. + An example: 16 bit left shift the unixtimestamp. (Default: actual gmtime) +-r, --token-lifetime lifetime in sec (Default: 3600) + +-t, --token base64 encoded encrypted token for validation and decryption + +-u, --hmac-alg stun client hmac algorithm + +Usage: + +$ turnutils_natdiscovery + =================================== DOCS diff --git a/make-man.sh b/make-man.sh index 704c19ec..185ae156 100755 --- a/make-man.sh +++ b/make-man.sh @@ -2,15 +2,16 @@ rm -rf man/man1/* -txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -I turnutils_natdiscovery -B "TURN Server" README.turnserver | sed -e 's/-/\\-/g' > man/man1/turnserver.1 +txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -I turnutils_natdiscovery -I turnutils_oauth -B "TURN Server" README.turnserver | sed -e 's/-/\\-/g' > man/man1/turnserver.1 -txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -I turnutils_natdiscovery -B "TURN Server" README.turnadmin | sed -e 's/-/\\-/g'> man/man1/turnadmin.1 +txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -I turnutils_natdiscovery -I turnutils_oauth -B "TURN Server" README.turnadmin | sed -e 's/-/\\-/g'> man/man1/turnadmin.1 -txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -I turnutils_natdiscovery -B "TURN Server" README.turnutils | sed -e 's/-/\\-/g' > man/man1/turnutils.1 +txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -I turnutils_natdiscovery -I turnutils_oauth -B "TURN Server" README.turnutils | sed -e 's/-/\\-/g' > man/man1/turnutils.1 cd man/man1; ln -s turnutils.1 turnutils_uclient.1;cd ../.. cd man/man1; ln -s turnutils.1 turnutils_peer.1;cd ../.. cd man/man1; ln -s turnutils.1 turnutils_stunclient.1;cd ../.. cd man/man1; ln -s turnutils.1 turnutils_natdiscovery.1;cd ../.. +cd man/man1; ln -s turnutils.1 turnutils_oauth.1;cd ../.. cd man/man1; ln -s turnserver.1 coturn.1;cd ../.. diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index f246a0db..746254a3 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "04 September 2016" "" "" +.TH TURN 1 "06 September 2016" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 560a1c8c..bd4d717a 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "04 September 2016" "" "" +.TH TURN 1 "06 September 2016" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index ee7a5580..218a8e30 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "04 September 2016" "" "" +.TH TURN 1 "06 September 2016" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -48,7 +48,21 @@ $ ./scripts/secure_relay.sh according RFC5780. This utility discovers the actual NAT Mapping and Filtering behavior. Be aweare that at least two different listening IP addresses should be configured to be able to work properly! +.TP +.B +6. +\fIturnutils_oauth\fP: a utility that provides OAuth access_token +\fBgeneration\fP(AEAD encryption), validation and decryption. This utility inputs +all the keys and lifetimes and any related informations that needed for +creation and validationi of an access_token. It outputs a JSON with all OAuth +PoP parameters that need to pass to the client. Output is generated accoriding +RFC7635 Appendix B, Figure 8. .PP +For more details, and for the access_token structure, read rfc7635. +.RE +.PP + +.RS ===================================== .SS NAME \fB @@ -414,6 +428,109 @@ Usage: .PP $ \fIturnutils_natdiscovery\fP \fB\-m\fP \fB\-f\fP stun.example.com .PP +===================================== +.SS NAME +\fB +\fBturnutils_oauth \fP\- a utility that helps OAuth access_token generation/encryption and validation/decyption +\fB +.SS SYNOPSIS +.nf +.fam C + +$ \fIturnutils_oauth\fP [\fIoptions\fP] + +.fam T +.fi +.fam T +.fi +.SS DESCRIPTION + +\fIturnutils_oauth\fP utilitiy provides help in OAuth access_token encryption and/or +decryption with AEAD (Atuthenticated Encryption with Associated Data). It helps +for an Auth Server in access_token creation, and also for debuging purposes it +helps the access_token validation and decryption. This utility inputs all the +keys and lifetimes and any related informations that are needed for encryption +or decryption of an access_token. It outputs a JSON with all OAuth PoP +parameters that need to pass to the client. Output is generated accoriding +RFC7635 Appendix B, Figure 8. For more details, and for the access_token +structure, read rfc7635. +.PP +Use either \fB\-e\fP and/or \fB\-d\fP flag to encrypt or decrypt access_token. +.PP +Flags: +.TP +.B +\fB\-h\fP, \fB\-\-help\fP +usage +.TP +.B +\fB\-v\fP, \fB\-\-verbose\fP +verbose mode +.TP +.B +\fB\-e\fP, \fB\-\-encrypt\fP +encrypt token +.TP +.B +\fB\-d\fP, \fB\-\-decrypt\fP +decrypt validate token +.PP +Options with required values: +.TP +.B +\fB\-i\fP, \fB\-\-server\-name\fP +server name (max. 255 char) +.TP +.B +\fB\-j\fP, \fB\-\-long\-term\-key\-id\fP +long term key id (max. 32 char) +.TP +.B +\fB\-k\fP, \fB\-\-long\-term\-key\fP +base64 encoded long term key +.TP +.B +\fB\-l\fP +\fB\-\-long\-term\-key\-timestamp\fP long term key timestamp (sec since epoch) +.TP +.B +\fB\-m\fP, \fB\-\-long\-term\-key\-lifetime\fP +long term key lifetime in sec +.TP +.B +\fB\-n\fP, \fB\-\-long\-term\-key\-as\-rs\-alg\fP +Authorization Server Resource Server encryption algorithm +.TP +.B +\fB\-o\fP, \fB\-\-token\-nonce\fP +base64 encoded nonce \fBbase64\fP(12 octet) = 16 char +.TP +.B +\fB\-p\fP, \fB\-\-token\-mac\-key\fP +base64 encoded MAC key \fBbase64\fP(32 octet) = 44 char +.TP +.B +\fB\-q\fP, \fB\-\-token\-timestamp\fP +timestamp in format 64 bit unsigned (Native format \- Unix), +so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a second. +An example: 16 bit left shift the unixtimestamp. (Default: actual gmtime) +.TP +.B +\fB\-r\fP, \fB\-\-token\-lifetime\fP +lifetime in sec (Default: 3600) +.TP +.B +\fB\-t\fP, \fB\-\-token\fP +base64 encoded encrypted token for validation and decryption +.TP +.B +\fB\-u\fP, \fB\-\-hmac\-alg\fP +stun client hmac algorithm +.PP +Usage: +.PP +$ \fIturnutils_natdiscovery\fP +.PP =================================== .SH DOCS diff --git a/man/man1/turnutils_oauth.1 b/man/man1/turnutils_oauth.1 new file mode 120000 index 00000000..6996d67f --- /dev/null +++ b/man/man1/turnutils_oauth.1 @@ -0,0 +1 @@ +turnutils.1 \ No newline at end of file From d70d0353ec5a24a9a69d67c56fb005a6b6e8ba33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 7 Sep 2016 09:45:58 +0200 Subject: [PATCH 07/10] tidy --- README.turnutils | 9 ++++++--- man/man1/turnadmin.1 | 2 +- man/man1/turnserver.1 | 2 +- man/man1/turnutils.1 | 11 +++++++---- src/apps/oauth/oauth.c | 4 ++-- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/README.turnutils b/README.turnutils index a5d7bdf7..7642070f 100644 --- a/README.turnutils +++ b/README.turnutils @@ -300,8 +300,11 @@ helps the access_token validation and decryption. This utility inputs all the keys and lifetimes and any related informations that are needed for encryption or decryption of an access_token. It outputs a JSON with all OAuth PoP parameters that need to pass to the client. Output is generated accoriding -RFC7635 Appendix B, Figure 8. For more details, and for the access_token -structure, read rfc7635. +RFC7635 Appendix B, Figure 8. This utility could help to build an Auth Server +service, but be awere that this utility does not generate "session key" / +"mac_key" and not verifies lifetime of "session key" / "mac_key" or "Auth key". + +For more details, and for the access_token structure, read rfc7635. Use either -e and/or -d flag to encrypt or decrypt access_token. @@ -335,7 +338,7 @@ Options with required values: -q, --token-timestamp timestamp in format 64 bit unsigned (Native format - Unix), so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a second. - An example: 16 bit left shift the unixtimestamp. (Default: actual gmtime) + e.g.: the actual unixtimestamp 16 bit left shifted. (Default: actual gmtime) -r, --token-lifetime lifetime in sec (Default: 3600) -t, --token base64 encoded encrypted token for validation and decryption diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 746254a3..f2731168 100644 --- a/man/man1/turnadmin.1 +++ b/man/man1/turnadmin.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "06 September 2016" "" "" +.TH TURN 1 "07 September 2016" "" "" .SH GENERAL INFORMATION \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index bd4d717a..eb385cf6 100644 --- a/man/man1/turnserver.1 +++ b/man/man1/turnserver.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "06 September 2016" "" "" +.TH TURN 1 "07 September 2016" "" "" .SH GENERAL INFORMATION The \fBTURN Server\fP project contains the source code of a TURN server and TURN client diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 218a8e30..c32bbf15 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -1,5 +1,5 @@ .\" Text automatically generated by txt2man -.TH TURN 1 "06 September 2016" "" "" +.TH TURN 1 "07 September 2016" "" "" .SH GENERAL INFORMATION A set of turnutils_* programs provides some utility functionality to be used @@ -452,8 +452,11 @@ helps the access_token validation and decryption. This utility inputs all the keys and lifetimes and any related informations that are needed for encryption or decryption of an access_token. It outputs a JSON with all OAuth PoP parameters that need to pass to the client. Output is generated accoriding -RFC7635 Appendix B, Figure 8. For more details, and for the access_token -structure, read rfc7635. +RFC7635 Appendix B, Figure 8. This utility could help to build an Auth Server +service, but be awere that this utility does not generate "session key" / +"mac_key" and not verifies lifetime of "session key" / "mac_key" or "Auth key". +.PP +For more details, and for the access_token structure, read rfc7635. .PP Use either \fB\-e\fP and/or \fB\-d\fP flag to encrypt or decrypt access_token. .PP @@ -513,7 +516,7 @@ base64 encoded MAC key \fBbase64\fP(32 octet) = 44 char \fB\-q\fP, \fB\-\-token\-timestamp\fP timestamp in format 64 bit unsigned (Native format \- Unix), so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a second. -An example: 16 bit left shift the unixtimestamp. (Default: actual gmtime) +e.g.: the actual unixtimestamp 16 bit left shifted. (Default: actual gmtime) .TP .B \fB\-r\fP, \fB\-\-token\-lifetime\fP diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index 34e6044e..457f5722 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -194,7 +194,7 @@ const char Usage[] = " -p, --token-mac-key base64 encoded MAC key base64(32 octet) = 44 char\n" " -q, --token-timestamp timestamp in format 64 bit unsigned (Native format - Unix),\n" " so 48 bit for secs since epoch UTC + 16 bit for 1/64000 fractions of a second.\n" - " An example: 16 bit left shift the unixtimestamp. (Default: actual gmtime)\n" + " e.g.: the actual unixtimestamp 16 bit left shifted. (Default: actual gmtime)\n" " -r, --token-lifetime lifetime in sec (Default: 3600)\n" " -t, --token base64 encoded encrypted token for validation and decryption\n" " -u, --hmac-alg stun client hmac algorithm\n"; @@ -390,7 +390,7 @@ int main(int argc, char **argv) } if (!(encrypt_flag || decrypt_flag)){ - fprintf(stderr, "Hey, encrypt or decrypt?\nPlease use -h or --help for the detailed help\n"); + fprintf(stderr, "Use either encrypt or decrypt.\nPlease use -h or --help for the detailed help\n"); exit(-1); } From 9bd3f0ee9c5ff30fc78dfcf6187a1fcd82fbb0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 7 Sep 2016 10:40:18 +0200 Subject: [PATCH 08/10] tidy example script --- examples/scripts/oauth.sh | 15 +++++++++++++++ src/apps/oauth/test.sh | 15 --------------- 2 files changed, 15 insertions(+), 15 deletions(-) create mode 100755 examples/scripts/oauth.sh delete mode 100755 src/apps/oauth/test.sh diff --git a/examples/scripts/oauth.sh b/examples/scripts/oauth.sh new file mode 100755 index 00000000..ac902b31 --- /dev/null +++ b/examples/scripts/oauth.sh @@ -0,0 +1,15 @@ +#!/bin/bash +OAUTH_UTILITY=../../bin/turnutils_oauth +echo "--------------create an access_token---------------" +$OAUTH_UTILITY -e --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 16332934350000 + +echo "---------------create and validate and print out the decoded access_token---------------" +$OAUTH_UTILITY -v -d -e --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 16332934350000 + +echo -e "\n---------------just validate only the access_token---------------" +$OAUTH_UTILITY -d --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token AAyi1nAiKbhykYXGUzGF9uM/nUu67J4z1ySG3weLavUN6JLQm+HCPvCNkVWWVrOppCSTmYapLx+jDhgZcx0vMA== + +echo -e "\n---------------validate and print out the decoded access_token---------------" +$OAUTH_UTILITY -v -d --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token AAyi1nAiKbhykYXGUzGF9uM/nUu67J4z1ySG3weLavUN6JLQm+HCPvCNkVWWVrOppCSTmYapLx+jDhgZcx0vMA== + + diff --git a/src/apps/oauth/test.sh b/src/apps/oauth/test.sh deleted file mode 100755 index cc0e7ac4..00000000 --- a/src/apps/oauth/test.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -echo "--------------create token---------------" -./bin/turnutils_oauth -e --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 92470300704768 - -echo "---------------create and validate and print out decoded token---------------" -./bin/turnutils_oauth -v -d -e --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 92470300704768 - -echo "---------------validate token---------------" -./bin/turnutils_oauth -d --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token AAwAAAAAAAAAAAAAAABbhGtRHVrDPexC4TQJppr6QNyUwpfB6fS9R3QmwjYvW6YyShKY2fbeUs5lSebE4nYQfA== - -echo "---------------validate and print out decoded token---------------" -./bin/turnutils_oauth -v -d --server-name vvc.niif.hu --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 1464077257 --long-term-key-lifetime 3600 --token AAwAAAAAAAAAAAAAAABbhGtRHVrDPexC4TQJppr6QNyUwpfB6fS9R3QmwjYvW6YyShKY2fbeUs5lSebE4nYQfA== - - From 82ca50ebb247280fd7f5640da185cd45631ec0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 7 Sep 2016 15:03:28 +0200 Subject: [PATCH 09/10] tidy and small improvments * rename long-term-key to auth-key * add warning for auth key and token lifetime expiry or missmatch * tidy sample script --- README.turnutils | 17 ++++++------ examples/scripts/oauth.sh | 12 +++++---- man/man1/turnutils.1 | 25 ++++++++--------- src/apps/oauth/oauth.c | 57 ++++++++++++++++++++++++--------------- 4 files changed, 65 insertions(+), 46 deletions(-) diff --git a/README.turnutils b/README.turnutils index 7642070f..9af7dbeb 100644 --- a/README.turnutils +++ b/README.turnutils @@ -44,7 +44,8 @@ creation and validationi of an access_token. It outputs a JSON with all OAuth PoP parameters that need to pass to the client. Output is generated accoriding RFC7635 Appendix B, Figure 8. -For more details, and for the access_token structure, read rfc7635. +For more details, and for the access_token structure, read rfc7635, and see +script in examples/scripts/oauth.sh. ===================================== @@ -303,8 +304,8 @@ parameters that need to pass to the client. Output is generated accoriding RFC7635 Appendix B, Figure 8. This utility could help to build an Auth Server service, but be awere that this utility does not generate "session key" / "mac_key" and not verifies lifetime of "session key" / "mac_key" or "Auth key". - -For more details, and for the access_token structure, read rfc7635. +For more details, and for the access_token structure, read rfc7635, and see +the example in examples/scripts/oauth.sh. Use either -e and/or -d flag to encrypt or decrypt access_token. @@ -322,15 +323,15 @@ Options with required values: -i, --server-name server name (max. 255 char) --j, --long-term-key-id long term key id (max. 32 char) +-j, --auth-key-id Auth key id (max. 32 char) --k, --long-term-key base64 encoded long term key +-k, --auth-key base64 encoded Auth key --l --long-term-key-timestamp long term key timestamp (sec since epoch) +-l --auth-key-timestamp Auth key timestamp (sec since epoch) --m, --long-term-key-lifetime long term key lifetime in sec +-m, --auth-key-lifetime Auth key lifetime in sec --n, --long-term-key-as-rs-alg Authorization Server Resource Server encryption algorithm +-n, --auth-key-as-rs-alg Authorization Server(AS) - Resource Server(RS) encryption algorithm -o, --token-nonce base64 encoded nonce base64(12 octet) = 16 char diff --git a/examples/scripts/oauth.sh b/examples/scripts/oauth.sh index ac902b31..e869f170 100755 --- a/examples/scripts/oauth.sh +++ b/examples/scripts/oauth.sh @@ -1,15 +1,17 @@ #!/bin/bash -OAUTH_UTILITY=../../bin/turnutils_oauth + +OAUTH_UTILITY=bin/turnutils_oauth + echo "--------------create an access_token---------------" -$OAUTH_UTILITY -e --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 16332934350000 +$OAUTH_UTILITY -e --server-name example.com --auth-key-id 1234 --auth-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --auth-key-timestamp 249213600 --auth-key-lifetime 21600 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 16333642137600 --token-lifetime=3600 echo "---------------create and validate and print out the decoded access_token---------------" -$OAUTH_UTILITY -v -d -e --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 16332934350000 +$OAUTH_UTILITY -v -d -e --server-name example.com --auth-key-id 1234 --auth-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --auth-key-timestamp 249213600 --auth-key-lifetime 21600 --token-mac-key WmtzanB3ZW9peFhtdm42NzUzNG0= --token-timestamp 16333642137600 --token-lifetime=3600 echo -e "\n---------------just validate only the access_token---------------" -$OAUTH_UTILITY -d --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token AAyi1nAiKbhykYXGUzGF9uM/nUu67J4z1ySG3weLavUN6JLQm+HCPvCNkVWWVrOppCSTmYapLx+jDhgZcx0vMA== +$OAUTH_UTILITY -d --server-name example.com --auth-key-id 1234 --auth-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --auth-key-timestamp 249213600 --auth-key-lifetime 21600 --token AAy1JBYVLo16iq9gFdHyyknmx5T/Lq9YlbxgUdLcStOFS0H8xhHceHOL2f49qxp4uBpGuuLeLqk+RcAa5uP2EQ== --token-lifetime=3600 echo -e "\n---------------validate and print out the decoded access_token---------------" -$OAUTH_UTILITY -v -d --server-name example.com --long-term-key-id 1234 --long-term-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --long-term-key-timestamp 249213600 --long-term-key-lifetime 86400 --token AAyi1nAiKbhykYXGUzGF9uM/nUu67J4z1ySG3weLavUN6JLQm+HCPvCNkVWWVrOppCSTmYapLx+jDhgZcx0vMA== +$OAUTH_UTILITY -v -d --server-name example.com --auth-key-id 1234 --auth-key SEdrajMyS0pHaXV5MDk4c2RmYXFiTmpPaWF6NzE5MjM= --auth-key-timestamp 249213600 --auth-key-lifetime 21600 --token AAy1JBYVLo16iq9gFdHyyknmx5T/Lq9YlbxgUdLcStOFS0H8xhHceHOL2f49qxp4uBpGuuLeLqk+RcAa5uP2EQ== --token-lifetime=3600 diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index c32bbf15..07319df6 100644 --- a/man/man1/turnutils.1 +++ b/man/man1/turnutils.1 @@ -58,7 +58,8 @@ creation and validationi of an access_token. It outputs a JSON with all OAuth PoP parameters that need to pass to the client. Output is generated accoriding RFC7635 Appendix B, Figure 8. .PP -For more details, and for the access_token structure, read rfc7635. +For more details, and for the access_token structure, read rfc7635, and see +script in examples/scripts/oauth.sh. .RE .PP @@ -455,8 +456,8 @@ parameters that need to pass to the client. Output is generated accoriding RFC7635 Appendix B, Figure 8. This utility could help to build an Auth Server service, but be awere that this utility does not generate "session key" / "mac_key" and not verifies lifetime of "session key" / "mac_key" or "Auth key". -.PP -For more details, and for the access_token structure, read rfc7635. +For more details, and for the access_token structure, read rfc7635, and see +the example in examples/scripts/oauth.sh. .PP Use either \fB\-e\fP and/or \fB\-d\fP flag to encrypt or decrypt access_token. .PP @@ -485,24 +486,24 @@ Options with required values: server name (max. 255 char) .TP .B -\fB\-j\fP, \fB\-\-long\-term\-key\-id\fP -long term key id (max. 32 char) +\fB\-j\fP, \fB\-\-auth\-key\-id\fP +Auth key id (max. 32 char) .TP .B -\fB\-k\fP, \fB\-\-long\-term\-key\fP -base64 encoded long term key +\fB\-k\fP, \fB\-\-auth\-key\fP +base64 encoded Auth key .TP .B \fB\-l\fP -\fB\-\-long\-term\-key\-timestamp\fP long term key timestamp (sec since epoch) +\fB\-\-auth\-key\-timestamp\fP Auth key timestamp (sec since epoch) .TP .B -\fB\-m\fP, \fB\-\-long\-term\-key\-lifetime\fP -long term key lifetime in sec +\fB\-m\fP, \fB\-\-auth\-key\-lifetime\fP +Auth key lifetime in sec .TP .B -\fB\-n\fP, \fB\-\-long\-term\-key\-as\-rs\-alg\fP -Authorization Server Resource Server encryption algorithm +\fB\-n\fP, \fB\-\-auth\-key\-as\-rs\-alg\fP +Authorization \fBServer\fP(AS) \- Resource \fBServer\fP(RS) encryption algorithm .TP .B \fB\-o\fP, \fB\-\-token\-nonce\fP diff --git a/src/apps/oauth/oauth.c b/src/apps/oauth/oauth.c index 457f5722..c8498040 100644 --- a/src/apps/oauth/oauth.c +++ b/src/apps/oauth/oauth.c @@ -168,7 +168,7 @@ static void print_token_body(oauth_token* dot) { time_t time=dot->enc_block.timestamp>>16; unsigned msec=(dot->enc_block.timestamp & 0xFFFF)*64; printf(" timestamp:\n"); - printf(" unixtime: %s", ctime(&time)); + printf(" unixtime: %u (localtime: %s )", (unsigned int)time, ctime(&time)); printf(" msec:%u\n", msec); printf(" lifetime: %lu\n", (unsigned long) dot->enc_block.lifetime); printf("}\n"); @@ -185,11 +185,11 @@ const char Usage[] = " -e, --encrypt encrypt token\n" " -d, --decrypt decrypt validate token\n\n" " -i, --server-name server name (max. 255 char)\n" - " -j, --long-term-key-id long term key id (max. 32 char)\n" - " -k, --long-term-key base64 encoded long term key\n" - " -l --long-term-key-timestamp long term key timestamp (sec since epoch)\n" - " -m, --long-term-key-lifetime long term key lifetime in sec\n" - " -n, --long-term-key-as-rs-alg Authorization Server Resource Server encryption algorithm\n" + " -j, --auth-key-id Auth key id (max. 32 char)\n" + " -k, --auth-key base64 encoded Auth key\n" + " -l --auth-key-timestamp Auth key timestamp (sec since epoch)\n" + " -m, --auth-key-lifetime Auth key lifetime in sec\n" + " -n, --auth-key-as-rs-alg Authorization Server(AS) - Resource Server (RS) encryption algorithm\n" " -o, --token-nonce base64 encoded nonce base64(12 octet) = 16 char\n" " -p, --token-mac-key base64 encoded MAC key base64(32 octet) = 44 char\n" " -q, --token-timestamp timestamp in format 64 bit unsigned (Native format - Unix),\n" @@ -242,11 +242,11 @@ int main(int argc, char **argv) {"decrypt", no_argument, &decrypt_flag, 1}, {"help", no_argument, 0, 'h'}, {"server-name", required_argument, 0, 'i'}, - {"long-term-key-id", required_argument, 0, 'j'}, - {"long-term-key", required_argument, 0, 'k'}, - {"long-term-key-timestamp", required_argument, 0, 'l'}, - {"long-term-key-lifetime", required_argument, 0, 'm'}, - {"long-term-key-as-rs-alg", required_argument, 0, 'n'}, + {"auth-key-id", required_argument, 0, 'j'}, + {"auth-key", required_argument, 0, 'k'}, + {"auth-key-timestamp", required_argument, 0, 'l'}, + {"auth-key-lifetime", required_argument, 0, 'm'}, + {"auth-key-as-rs-alg", required_argument, 0, 'n'}, {"token-nonce", required_argument, 0, 'o'}, {"token-mac-key", required_argument, 0, 'p'}, {"token-timestamp", required_argument, 0, 'q'}, @@ -297,7 +297,7 @@ int main(int argc, char **argv) } break; case 'j': - //long-term-key-id + //auth-key-id if ( strlen(optarg) <= OAUTH_LTK_ID_SIZE ) { STRCPY(kid,optarg); } else { @@ -306,7 +306,7 @@ int main(int argc, char **argv) } break; case 'k': - //long-term-key + //auth-key if ( strlen(optarg) <= OAUTH_LTK_BASE64ENCODED_SIZE ) { STRCPY(base64encoded_ltk,optarg); } else { @@ -315,15 +315,15 @@ int main(int argc, char **argv) } break; case 'l': - //long-term-key-timestamp + //auth-key-timestamp key_timestamp = atoi(optarg); break; case 'm': - //long-term-key-lifetime + //auth-key-lifetime key_lifetime=atoi(optarg); break; case 'n': - //long-term-key-as-rs-alg + //auth-key-as-rs-alg if ( strlen(optarg) <= OAUTH_AS_RS_ALG_SIZE ) { STRCPY(as_rs_alg,optarg); } else { @@ -403,19 +403,19 @@ int main(int argc, char **argv) } if (strlen(kid) == 0){ - fprintf(stderr, "For encode/decode --long-term-key-id/-j is mandatory \n"); + fprintf(stderr, "For encode/decode --auth-key-id/-j is mandatory \n"); exit(-1); } if (strlen(base64encoded_ltk) == 0){ - fprintf(stderr, "For encode/decode --long-term-key/-k is mandatory \n"); + fprintf(stderr, "For encode/decode --auth-key/-k is mandatory \n"); exit(-1); } if (key_timestamp == 0){ - fprintf(stderr, "For encode/decode --long-term-key-timestamp/-l is mandatory \n"); + fprintf(stderr, "For encode/decode --auth-key-timestamp/-l is mandatory \n"); exit(-1); } if (key_lifetime == 0){ - fprintf(stderr, "For encode/decode --long-term-key-lifetime/-m is mandatory \n"); + fprintf(stderr, "For encode/decode --auth-key-lifetime/-m is mandatory \n"); exit(-1); } @@ -428,7 +428,22 @@ int main(int argc, char **argv) fprintf(stderr, "For decode --token/-t is mandatory \n"); exit(-1); } - + + // Expiry warnings + if ( (unsigned long long)key_timestamp<<16 > token_timestamp +((unsigned long long)token_lifetime << 16) ) { + fprintf(stderr,"\nWARNING: Token expiry is earlear then Auth key life time start timestamp!!\n\n"); + } else { + if( (unsigned long long)key_timestamp<<16 > token_timestamp) { + fprintf(stderr,"\nWARNING: Token life time start timestamp is earlier then Auth key start timestamp!!\n\n"); + } + } + if( (unsigned long long)( key_timestamp + key_lifetime )<<16 < token_timestamp ) { + fprintf(stderr,"\nWARNING: Auth key will expire before token lifetime start timestamp!!\n\n"); + } else { + if( (unsigned long long)( key_timestamp + key_lifetime)<<16 < token_timestamp + ((unsigned long long)token_lifetime << 16) ) { + fprintf(stderr,"\nWARNING: Auth key will expire before token expiry!!\n\n"); + } + } if ( setup_ikm_key(kid, base64encoded_ltk, key_timestamp, key_lifetime, as_rs_alg, &key) == 0 ) { if(encrypt_flag) { From ef7a71c1c5f1167cd7d2185419d440e2f985fe53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Mih=C3=A1ly?= Date: Wed, 7 Sep 2016 15:36:24 +0200 Subject: [PATCH 10/10] update chagelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 6a994a70..e9a4b5b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ Version 4.5.0.5 'dan Eider': - LibreSSL compatibility fixed. - "read_timeout" option support for MySQL. - new NAT behavior discovery utilty. + - new OAuth access_token encrypt/decrypt utilty. 08/20/2016 Oleg Moskalenko Version 4.5.0.4 'dan Eider':