1
0
mirror of https://github.com/coturn/coturn.git synced 2025-10-24 20:41:03 +02:00

working on third-party auth

This commit is contained in:
mom040267 2015-04-19 06:18:28 +00:00
parent 676843bf09
commit 86f40b4bd9
23 changed files with 226 additions and 633 deletions

View File

@ -1,7 +1,9 @@
4/9/2015 Oleg Moskalenko <mom040267@gmail.com>
Version 4.4.5.1 'Ardee West':
- dual allocation adjusted according to the new TURN-bis draft;
- options sha256, sha384, sha512 retired as non-standard ones;
- options sha256, sha384, sha512 retired as non-standard;
- third-party authorization (oAuth) updated according to the
version 14 of the draft;
- C++ fixes;
- cosmetic fixes;

25
INSTALL
View File

@ -743,10 +743,8 @@ CREATE TABLE oauth_key (
ikm_key varchar(256) default '',
timestamp bigint default 0,
lifetime integer default 0,
hkdf_hash_func varchar(64) default '',
as_rs_alg varchar(64) default '',
as_rs_key varchar(256) default '',
auth_alg varchar(64) default '',
auth_key varchar(256) default '',
primary key (kid)
);
@ -764,30 +762,17 @@ The oauth_key table fields meanings are:
lifetime - (optional) the key lifetime in seconds; the default value
is 0 - unlimited lifetime.
hkdf_hash_func - (optional) hash function for HKDF procedure; the
valid values are SHA-1, SHA-256, SHA-384 and SHA-512,
with SHA-256 as default. The hkdf_hash_func is not needed
if the as_rs_key and auth_key are defined explicitly
in the database;
as_rs_alg - oAuth token encryption algorithm; the valid values are
"AES-128-CBC" and "AES-256-CBC", , "AEAD-AES-128-GCM",
"AEAD-AES-256-GCM".
The default value is "AES-256-CBC";
"A256GCMKW", "A128GCMKW" (see
http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-4.1).
The default value is "A256GCMKW";
as_rs_key - (optional) base64-encoded AS-RS key. If not defined, then
calculated with ikm_key and hkdf_hash_func. The as_rs_key length
is defined by as_rs_alg.
auth_alg - (optional) oAuth token authentication algorithm; the valid values are
"HMAC-SHA-256-128", "HMAC-SHA-256", "HMAC-SHA-384",
"HMAC-SHA-512" and "HMAC-SHA-1".
The default value is "HMAC-SHA-256-128".
calculated with ikm_key.
auth_key - (optional) base64-encoded AUTH key. If not defined, then
calculated with ikm_key and hkdf_hash_func. The auth_key length
is defined by auth_alg.
calculated with ikm_key. Not used for AEAD algorithms.
# Https access admin users.
# Leave this table empty if you do not want

Binary file not shown.

View File

@ -1125,8 +1125,6 @@ void convert_oauth_key_data_raw(const oauth_key_data_raw *raw, oauth_key_data *o
oakd->lifetime = raw->lifetime;
ns_bcopy(raw->as_rs_alg,oakd->as_rs_alg,sizeof(oakd->as_rs_alg));
ns_bcopy(raw->auth_alg,oakd->auth_alg,sizeof(oakd->auth_alg));
ns_bcopy(raw->hkdf_hash_func,oakd->hkdf_hash_func,sizeof(oakd->hkdf_hash_func));
ns_bcopy(raw->kid,oakd->kid,sizeof(oakd->kid));
if(raw->ikm_key[0]) {

View File

@ -141,10 +141,8 @@ struct _oauth_key_data_raw {
char ikm_key[OAUTH_KEY_SIZE+1];
u64bits timestamp;
u32bits lifetime;
char hkdf_hash_func[OAUTH_HASH_FUNC_SIZE+1];
char as_rs_alg[OAUTH_ALG_SIZE+1];
char as_rs_key[OAUTH_KEY_SIZE+1];
char auth_alg[OAUTH_ALG_SIZE+1];
char auth_key[OAUTH_KEY_SIZE+1];
};

View File

@ -256,9 +256,7 @@ static int mongo_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
BSON_APPEND_INT32(&fields, "timestamp", 1);
BSON_APPEND_INT32(&fields, "as_rs_alg", 1);
BSON_APPEND_INT32(&fields, "as_rs_key", 1);
BSON_APPEND_INT32(&fields, "auth_alg", 1);
BSON_APPEND_INT32(&fields, "auth_key", 1);
BSON_APPEND_INT32(&fields, "hkdf_hash_func", 1);
BSON_APPEND_INT32(&fields, "ikm_key", 1);
mongoc_cursor_t * cursor;
@ -284,18 +282,12 @@ static int mongo_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->as_rs_key,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "auth_alg") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->auth_alg,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "auth_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->auth_key,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "hkdf_hash_func") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->hkdf_hash_func,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) {
key->timestamp = (u64bits)bson_iter_int64(&iter);
}
@ -358,9 +350,7 @@ static int mongo_set_oauth_key(oauth_key_data_raw *key) {
BSON_APPEND_UTF8(&doc, "kid", (const char *)key->kid);
BSON_APPEND_UTF8(&doc, "as_rs_alg", (const char *)key->as_rs_alg);
BSON_APPEND_UTF8(&doc, "as_rs_key", (const char *)key->as_rs_key);
BSON_APPEND_UTF8(&doc, "auth_alg", (const char *)key->auth_alg);
BSON_APPEND_UTF8(&doc, "auth_key", (const char *)key->auth_key);
BSON_APPEND_UTF8(&doc, "hkdf_hash_func", (const char *)key->hkdf_hash_func);
BSON_APPEND_UTF8(&doc, "ikm_key", (const char *)key->ikm_key);
BSON_APPEND_INT64(&doc, "timestamp", (int64_t)key->timestamp);
BSON_APPEND_INT32(&doc, "lifetime", (int32_t)key->lifetime);
@ -497,7 +487,7 @@ static int mongo_list_users(u08bits *realm, secrets_list_t *users, secrets_list_
return ret;
}
static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secrets_list_t *teas,secrets_list_t *aas,secrets_list_t *tss,secrets_list_t *lts) {
static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
const char * collection_name = "oauth_key";
mongoc_collection_t * collection = mongo_get_collection(collection_name);
@ -522,9 +512,7 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
BSON_APPEND_INT32(&fields, "timestamp", 1);
BSON_APPEND_INT32(&fields, "as_rs_alg", 1);
BSON_APPEND_INT32(&fields, "as_rs_key", 1);
BSON_APPEND_INT32(&fields, "auth_alg", 1);
BSON_APPEND_INT32(&fields, "auth_key", 1);
BSON_APPEND_INT32(&fields, "hkdf_hash_func", 1);
BSON_APPEND_INT32(&fields, "ikm_key", 1);
mongoc_cursor_t * cursor;
@ -552,18 +540,12 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "as_rs_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->as_rs_key,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "auth_alg") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->auth_alg,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "auth_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->auth_key,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "ikm_key") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->ikm_key,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "hkdf_hash_func") && BSON_ITER_HOLDS_UTF8(&iter)) {
STRCPY(key->hkdf_hash_func,bson_iter_utf8(&iter, &length));
}
if (bson_iter_init(&iter, item) && bson_iter_find(&iter, "timestamp") && BSON_ITER_HOLDS_INT64(&iter)) {
key->timestamp = (u64bits)bson_iter_int64(&iter);
}
@ -572,9 +554,7 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
}
if(kids) {
add_to_secrets_list(kids,key->kid);
add_to_secrets_list(hkdfs,key->hkdf_hash_func);
add_to_secrets_list(teas,key->as_rs_alg);
add_to_secrets_list(aas,key->auth_alg);
{
char ts[256];
snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@ -586,9 +566,9 @@ static int mongo_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
add_to_secrets_list(lts,lt);
}
} else {
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
key->as_rs_alg, key->as_rs_key, key->auth_key);
}
}
mongoc_cursor_destroy(cursor);

View File

@ -343,7 +343,7 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
int ret = -1;
char statement[TURN_LONG_STRING_SIZE];
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key from oauth_key where kid='%s'",(const char*)kid);
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key from oauth_key where kid='%s'",(const char*)kid);
MYSQL * myc = get_mydb_connection();
if(myc) {
@ -354,7 +354,7 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
MYSQL_RES *mres = mysql_store_result(myc);
if(!mres) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
} else if(mysql_field_count(myc)!=8) {
} else if(mysql_field_count(myc)!=6) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
} else {
MYSQL_ROW row = mysql_fetch_row(mres);
@ -375,20 +375,14 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
slifetime[lengths[2]]=0;
key->lifetime = (u32bits)strtoul(slifetime,NULL,10);
ns_bcopy(row[3],key->hkdf_hash_func,lengths[3]);
key->hkdf_hash_func[lengths[3]]=0;
ns_bcopy(row[3],key->as_rs_alg,lengths[3]);
key->as_rs_alg[lengths[3]]=0;
ns_bcopy(row[4],key->as_rs_alg,lengths[4]);
key->as_rs_alg[lengths[4]]=0;
ns_bcopy(row[4],key->as_rs_key,lengths[4]);
key->as_rs_key[lengths[4]]=0;
ns_bcopy(row[5],key->as_rs_key,lengths[5]);
key->as_rs_key[lengths[5]]=0;
ns_bcopy(row[6],key->auth_alg,lengths[6]);
key->auth_alg[lengths[6]]=0;
ns_bcopy(row[7],key->auth_key,lengths[7]);
key->auth_key[lengths[7]]=0;
ns_bcopy(row[5],key->auth_key,lengths[5]);
key->auth_key[lengths[5]]=0;
ret = 0;
}
@ -402,13 +396,13 @@ static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
return ret;
}
static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secrets_list_t *teas,secrets_list_t *aas,secrets_list_t *tss,secrets_list_t *lts) {
static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
oauth_key_data_raw key_;
oauth_key_data_raw *key=&key_;
int ret = -1;
char statement[TURN_LONG_STRING_SIZE];
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key,kid from oauth_key order by kid");
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key,kid from oauth_key order by kid");
MYSQL * myc = get_mydb_connection();
if(myc) {
@ -419,7 +413,7 @@ static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
MYSQL_RES *mres = mysql_store_result(myc);
if(!mres) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
} else if(mysql_field_count(myc)!=9) {
} else if(mysql_field_count(myc)!=7) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
} else {
MYSQL_ROW row = mysql_fetch_row(mres);
@ -440,28 +434,21 @@ static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
slifetime[lengths[2]]=0;
key->lifetime = (u32bits)strtoul(slifetime,NULL,10);
ns_bcopy(row[3],key->hkdf_hash_func,lengths[3]);
key->hkdf_hash_func[lengths[3]]=0;
ns_bcopy(row[4],key->as_rs_alg,lengths[4]);
key->as_rs_alg[lengths[4]]=0;
ns_bcopy(row[3],key->as_rs_alg,lengths[3]);
key->as_rs_alg[lengths[3]]=0;
ns_bcopy(row[5],key->as_rs_key,lengths[5]);
key->as_rs_key[lengths[5]]=0;
ns_bcopy(row[4],key->as_rs_key,lengths[4]);
key->as_rs_key[lengths[4]]=0;
ns_bcopy(row[6],key->auth_alg,lengths[6]);
key->auth_alg[lengths[6]]=0;
ns_bcopy(row[5],key->auth_key,lengths[5]);
key->auth_key[lengths[5]]=0;
ns_bcopy(row[7],key->auth_key,lengths[7]);
key->auth_key[lengths[7]]=0;
ns_bcopy(row[8],key->kid,lengths[8]);
key->kid[lengths[8]]=0;
ns_bcopy(row[6],key->kid,lengths[6]);
key->kid[lengths[6]]=0;
if(kids) {
add_to_secrets_list(kids,key->kid);
add_to_secrets_list(hkdfs,key->hkdf_hash_func);
add_to_secrets_list(teas,key->as_rs_alg);
add_to_secrets_list(aas,key->auth_alg);
{
char ts[256];
snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@ -473,9 +460,9 @@ static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
add_to_secrets_list(lts,lt);
}
} else {
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
key->as_rs_alg, key->as_rs_key, key->auth_key);
}
}
row = mysql_fetch_row(mres);
@ -519,13 +506,13 @@ static int mysql_set_oauth_key(oauth_key_data_raw *key)
char statement[TURN_LONG_STRING_SIZE];
MYSQL * myc = get_mydb_connection();
if(myc) {
snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s','%s','%s')",
snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s')",
key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,
key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key);
key->as_rs_alg,key->as_rs_key,key->auth_key);
int res = mysql_query(myc, statement);
if(res) {
snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, hkdf_hash_func = '%s', as_rs_alg='%s',as_rs_key='%s',auth_alg='%s',auth_key='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key,key->kid);
snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s',as_rs_key='%s',auth_key='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
key->as_rs_alg,key->as_rs_key,key->auth_key,key->kid);
res = mysql_query(myc, statement);
if(res) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth key information: %s\n",mysql_error(myc));

View File

@ -158,7 +158,7 @@ static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
int ret = -1;
char statement[TURN_LONG_STRING_SIZE];
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key from oauth_key where kid='%s'",(const char*)kid);
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key from oauth_key where kid='%s'",(const char*)kid);
PGconn * pqc = get_pqdb_connection();
if(pqc) {
@ -170,11 +170,9 @@ static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
STRCPY(key->ikm_key,PQgetvalue(res,0,0));
key->timestamp = (u64bits)strtoll(PQgetvalue(res,0,1),NULL,10);
key->lifetime = (u32bits)strtol(PQgetvalue(res,0,2),NULL,10);
STRCPY(key->hkdf_hash_func,PQgetvalue(res,0,3));
STRCPY(key->as_rs_alg,PQgetvalue(res,0,4));
STRCPY(key->as_rs_key,PQgetvalue(res,0,5));
STRCPY(key->auth_alg,PQgetvalue(res,0,6));
STRCPY(key->auth_key,PQgetvalue(res,0,7));
STRCPY(key->as_rs_alg,PQgetvalue(res,0,3));
STRCPY(key->as_rs_key,PQgetvalue(res,0,4));
STRCPY(key->auth_key,PQgetvalue(res,0,5));
STRCPY(key->kid,kid);
ret = 0;
}
@ -187,7 +185,7 @@ static int pgsql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
return ret;
}
static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secrets_list_t *teas,secrets_list_t *aas,secrets_list_t *tss,secrets_list_t *lts) {
static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
oauth_key_data_raw key_;
oauth_key_data_raw *key=&key_;
@ -195,7 +193,7 @@ static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
int ret = -1;
char statement[TURN_LONG_STRING_SIZE];
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key,kid from oauth_key order by kid");
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key,kid from oauth_key order by kid");
PGconn * pqc = get_pqdb_connection();
if(pqc) {
@ -210,18 +208,14 @@ static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
STRCPY(key->ikm_key,PQgetvalue(res,i,0));
key->timestamp = (u64bits)strtoll(PQgetvalue(res,i,1),NULL,10);
key->lifetime = (u32bits)strtol(PQgetvalue(res,i,2),NULL,10);
STRCPY(key->hkdf_hash_func,PQgetvalue(res,i,3));
STRCPY(key->as_rs_alg,PQgetvalue(res,i,4));
STRCPY(key->as_rs_key,PQgetvalue(res,i,5));
STRCPY(key->auth_alg,PQgetvalue(res,i,6));
STRCPY(key->auth_key,PQgetvalue(res,i,7));
STRCPY(key->kid,PQgetvalue(res,i,8));
STRCPY(key->as_rs_alg,PQgetvalue(res,i,3));
STRCPY(key->as_rs_key,PQgetvalue(res,i,4));
STRCPY(key->auth_key,PQgetvalue(res,i,5));
STRCPY(key->kid,PQgetvalue(res,i,6));
if(kids) {
add_to_secrets_list(kids,key->kid);
add_to_secrets_list(hkdfs,key->hkdf_hash_func);
add_to_secrets_list(teas,key->as_rs_alg);
add_to_secrets_list(aas,key->auth_alg);
{
char ts[256];
snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@ -233,9 +227,9 @@ static int pgsql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
add_to_secrets_list(lts,lt);
}
} else {
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
key->as_rs_alg, key->as_rs_key, key->auth_key);
}
ret = 0;
@ -283,17 +277,17 @@ static int pgsql_set_oauth_key(oauth_key_data_raw *key) {
char statement[TURN_LONG_STRING_SIZE];
PGconn *pqc = get_pqdb_connection();
if(pqc) {
snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s','%s','%s')",
snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s')",
key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,
key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key);
key->as_rs_alg,key->as_rs_key,key->auth_key);
PGresult *res = PQexec(pqc, statement);
if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
if(res) {
PQclear(res);
}
snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, hkdf_hash_func = '%s', as_rs_alg='%s',as_rs_key='%s',auth_alg='%s',auth_key='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key,key->kid);
snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, as_rs_alg='%s',as_rs_key='%s',auth_key='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
key->as_rs_alg,key->as_rs_key,key->auth_key,key->kid);
res = PQexec(pqc, statement);
if(!res || (PQresultStatus(res) != PGRES_COMMAND_OK)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth_key information: %s\n",PQerrorMessage(pqc));

View File

@ -481,12 +481,8 @@ static int redis_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
STRCPY(key->as_rs_key,val);
} else if(!strcmp(kw,"auth_key")) {
STRCPY(key->auth_key,val);
} else if(!strcmp(kw,"auth_alg")) {
STRCPY(key->auth_alg,val);
} else if(!strcmp(kw,"ikm_key")) {
STRCPY(key->ikm_key,val);
} else if(!strcmp(kw,"hkdf_hash_func")) {
STRCPY(key->hkdf_hash_func,val);
} else if(!strcmp(kw,"timestamp")) {
key->timestamp = (u64bits)strtoull(val,NULL,10);
} else if(!strcmp(kw,"lifetime")) {
@ -520,8 +516,8 @@ static int redis_set_oauth_key(oauth_key_data_raw *key) {
redisContext *rc = get_redis_connection();
if(rc) {
char statement[TURN_LONG_STRING_SIZE];
snprintf(statement,sizeof(statement),"hmset turn/oauth/kid/%s ikm_key %s hkdf_hash_func %s as_rs_alg %s as_rs_key %s auth_alg %s auth_key %s timestamp %llu lifetime %lu",
key->kid,key->ikm_key,key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime);
snprintf(statement,sizeof(statement),"hmset turn/oauth/kid/%s ikm_key %s as_rs_alg %s as_rs_key %s auth_key %s timestamp %llu lifetime %lu",
key->kid,key->ikm_key,key->as_rs_alg,key->as_rs_key,key->auth_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime);
turnFreeRedisReply(redisCommand(rc, statement));
turnFreeRedisReply(redisCommand(rc, "save"));
ret = 0;
@ -637,7 +633,7 @@ static int redis_list_users(u08bits *realm, secrets_list_t *users, secrets_list_
return ret;
}
static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secrets_list_t *teas,secrets_list_t *aas,secrets_list_t *tss,secrets_list_t *lts) {
static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
int ret = -1;
redisContext *rc = get_redis_connection();
secrets_list_t keys;
@ -675,9 +671,7 @@ static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
if(redis_get_oauth_key((const u08bits*)s,key) == 0) {
if(kids) {
add_to_secrets_list(kids,key->kid);
add_to_secrets_list(hkdfs,key->hkdf_hash_func);
add_to_secrets_list(teas,key->as_rs_alg);
add_to_secrets_list(aas,key->auth_alg);
{
char ts[256];
snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@ -689,9 +683,9 @@ static int redis_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secr
add_to_secrets_list(lts,lt);
}
} else {
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
key->as_rs_alg, key->as_rs_key, key->auth_key);
}
}
}

View File

@ -154,7 +154,7 @@ static void init_sqlite_database(sqlite3 *sqliteconnection) {
"CREATE TABLE denied_peer_ip (realm varchar(127) default '', ip_range varchar(256), primary key (realm,ip_range))",
"CREATE TABLE turn_origin_to_realm (origin varchar(127),realm varchar(127),primary key (origin))",
"CREATE TABLE turn_realm_option (realm varchar(127) default '', opt varchar(32), value varchar(128), primary key (realm,opt))",
"CREATE TABLE oauth_key (kid varchar(128),ikm_key varchar(256) default '',timestamp bigint default 0,lifetime integer default 0,hkdf_hash_func varchar(64) default '',as_rs_alg varchar(64) default '',as_rs_key varchar(256) default '',auth_alg varchar(64) default '',auth_key varchar(256) default '',primary key (kid))",
"CREATE TABLE oauth_key (kid varchar(128),ikm_key varchar(256) default '',timestamp bigint default 0,lifetime integer default 0,as_rs_alg varchar(64) default '',as_rs_key varchar(256) default '',auth_key varchar(256) default '',primary key (kid))",
"CREATE TABLE admin_user (name varchar(32), realm varchar(127), password varchar(127), primary key (name))",
NULL
};
@ -293,7 +293,7 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
char statement[TURN_LONG_STRING_SIZE];
sqlite3_stmt *st = NULL;
int rc = 0;
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key from oauth_key where kid='%s'",(const char*)kid);
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key from oauth_key where kid='%s'",(const char*)kid);
sqlite3 *sqliteconnection = get_sqlite_connection();
if(sqliteconnection) {
@ -308,11 +308,9 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
STRCPY(key->ikm_key,sqlite3_column_text(st, 0));
key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10);
key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10);
STRCPY(key->hkdf_hash_func,sqlite3_column_text(st, 3));
STRCPY(key->as_rs_alg,sqlite3_column_text(st, 4));
STRCPY(key->as_rs_key,sqlite3_column_text(st, 5));
STRCPY(key->auth_alg,sqlite3_column_text(st, 6));
STRCPY(key->auth_key,sqlite3_column_text(st, 7));
STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3));
STRCPY(key->as_rs_key,sqlite3_column_text(st, 4));
STRCPY(key->auth_key,sqlite3_column_text(st, 5));
STRCPY(key->kid,kid);
ret = 0;
}
@ -329,7 +327,7 @@ static int sqlite_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
return ret;
}
static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secrets_list_t *teas,secrets_list_t *aas,secrets_list_t *tss,secrets_list_t *lts) {
static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts) {
oauth_key_data_raw key_;
oauth_key_data_raw *key=&key_;
@ -341,7 +339,7 @@ static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,sec
char statement[TURN_LONG_STRING_SIZE];
sqlite3_stmt *st = NULL;
int rc = 0;
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key,kid from oauth_key order by kid");
snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key,kid from oauth_key order by kid");
sqlite3 *sqliteconnection = get_sqlite_connection();
if(sqliteconnection) {
@ -358,18 +356,14 @@ static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,sec
STRCPY(key->ikm_key,sqlite3_column_text(st, 0));
key->timestamp = (u64bits)strtoll((const char*)sqlite3_column_text(st, 1),NULL,10);
key->lifetime = (u32bits)strtol((const char*)sqlite3_column_text(st, 2),NULL,10);
STRCPY(key->hkdf_hash_func,sqlite3_column_text(st, 3));
STRCPY(key->as_rs_alg,sqlite3_column_text(st, 4));
STRCPY(key->as_rs_key,sqlite3_column_text(st, 5));
STRCPY(key->auth_alg,sqlite3_column_text(st, 6));
STRCPY(key->auth_key,sqlite3_column_text(st, 7));
STRCPY(key->kid,sqlite3_column_text(st, 8));
STRCPY(key->as_rs_alg,sqlite3_column_text(st, 3));
STRCPY(key->as_rs_key,sqlite3_column_text(st, 4));
STRCPY(key->auth_key,sqlite3_column_text(st, 5));
STRCPY(key->kid,sqlite3_column_text(st, 6));
if(kids) {
add_to_secrets_list(kids,key->kid);
add_to_secrets_list(hkdfs,key->hkdf_hash_func);
add_to_secrets_list(teas,key->as_rs_alg);
add_to_secrets_list(aas,key->auth_alg);
{
char ts[256];
snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
@ -381,9 +375,9 @@ static int sqlite_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,sec
add_to_secrets_list(lts,lt);
}
} else {
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
key->as_rs_alg, key->as_rs_key, key->auth_key);
}
} else if (res == SQLITE_DONE) {
@ -453,8 +447,8 @@ static int sqlite_set_oauth_key(oauth_key_data_raw *key)
snprintf(
statement,
sizeof(statement),
"insert or replace into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s','%s','%s')",
key->kid, key->ikm_key, (unsigned long long) key->timestamp, (unsigned long) key->lifetime, key->hkdf_hash_func, key->as_rs_alg, key->as_rs_key, key->auth_alg,
"insert or replace into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s')",
key->kid, key->ikm_key, (unsigned long long) key->timestamp, (unsigned long) key->lifetime, key->as_rs_alg, key->as_rs_key,
key->auth_key);
sqlite_lock(1);

View File

@ -68,7 +68,7 @@ typedef struct _turn_dbdriver_t {
int (*set_oauth_key)(oauth_key_data_raw *key);
int (*get_oauth_key)(const u08bits *kid, oauth_key_data_raw *key);
int (*del_oauth_key)(const u08bits *kid);
int (*list_oauth_keys)(secrets_list_t *kids,secrets_list_t *hkdfs,secrets_list_t *teas,secrets_list_t *aas,secrets_list_t *tss,secrets_list_t *lts);
int (*list_oauth_keys)(secrets_list_t *kids,secrets_list_t *teas,secrets_list_t *tss,secrets_list_t *lts);
int (*get_admin_user)(const u08bits *usname, u08bits *realm, password_t pwd);
int (*set_admin_user)(const u08bits *usname, const u08bits *realm, const password_t pwd);
int (*del_admin_user)(const u08bits *usname);

View File

@ -1374,9 +1374,7 @@ typedef enum _AS_FORM AS_FORM;
#define HR_ADD_OAUTH_IKM "oauth_ikm"
#define HR_ADD_OAUTH_RS_KEY "oauth_rs_key"
#define HR_ADD_OAUTH_AUTH_KEY "oauth_auth_key"
#define HR_ADD_OAUTH_HKDF "oauth_hkdf"
#define HR_ADD_OAUTH_TEA "oauth_tea"
#define HR_ADD_OAUTH_AA "oauth_aa"
#define HR_DELETE_OAUTH_KID "oauth_kid_del"
#define HR_OAUTH_KID "kid"
@ -2775,14 +2773,12 @@ static size_t https_print_oauth_keys(struct str_buffer* sb)
size_t ret = 0;
const turn_dbdriver_t * dbd = get_dbdriver();
if (dbd && dbd->list_oauth_keys) {
secrets_list_t kids,hkdfs,teas,aas,tss,lts;
secrets_list_t kids,teas,tss,lts;
init_secrets_list(&kids);
init_secrets_list(&hkdfs);
init_secrets_list(&teas);
init_secrets_list(&aas);
init_secrets_list(&tss);
init_secrets_list(&lts);
dbd->list_oauth_keys(&kids,&hkdfs,&teas,&aas,&tss,&lts);
dbd->list_oauth_keys(&kids,&teas,&tss,&lts);
size_t sz = get_secrets_list_size(&kids);
size_t i;
@ -2809,14 +2805,8 @@ static size_t https_print_oauth_keys(struct str_buffer* sb)
str_buffer_append(sb,get_secrets_list_elem(&lts,i));
str_buffer_append(sb,"</td>");
str_buffer_append(sb,"<td>");
str_buffer_append(sb,get_secrets_list_elem(&hkdfs,i));
str_buffer_append(sb,"</td>");
str_buffer_append(sb,"<td>");
str_buffer_append(sb,get_secrets_list_elem(&teas,i));
str_buffer_append(sb,"</td>");
str_buffer_append(sb,"<td>");
str_buffer_append(sb,get_secrets_list_elem(&aas,i));
str_buffer_append(sb,"</td>");
{
str_buffer_append(sb,"<td> <a href=\"");
@ -2833,9 +2823,7 @@ static size_t https_print_oauth_keys(struct str_buffer* sb)
}
clean_secrets_list(&kids);
clean_secrets_list(&hkdfs);
clean_secrets_list(&teas);
clean_secrets_list(&aas);
}
return ret;
@ -2924,7 +2912,7 @@ static void write_https_oauth_show_keys(ioa_socket_handle s, const char* kid)
}
static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, const char* add_ikm,
const char* add_hkdf_hash_func, const char* add_tea, const char* add_aa,
const char* add_tea,
const char *add_ts, const char* add_lt,
const char *add_rs_key, const char *add_auth_key,
const char* msg)
@ -2989,48 +2977,9 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
str_buffer_append(sb,"\"><br>\r\n");
}
str_buffer_append(sb,"</td></tr><tr><td>");
str_buffer_append(sb,"</td></tr>\r\n");
{
str_buffer_append(sb,"<br>Hash key derivation function (optional):<br>\r\n");
if(!add_hkdf_hash_func || !add_hkdf_hash_func[0])
add_hkdf_hash_func = "SHA-256";
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_HKDF);
str_buffer_append(sb,"\" value=\"SHA-1\" ");
if(!strcmp("SHA-1",add_hkdf_hash_func)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">SHA-1\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_HKDF);
str_buffer_append(sb,"\" value=\"SHA-256\" ");
if(!strcmp("SHA-256",add_hkdf_hash_func)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">SHA-256\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_HKDF);
str_buffer_append(sb,"\" value=\"SHA-384\" ");
if(!strcmp("SHA-384",add_hkdf_hash_func)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">SHA-384\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_HKDF);
str_buffer_append(sb,"\" value=\"SHA-512\" ");
if(!strcmp("SHA-512",add_hkdf_hash_func)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">SHA-512\r\n<br>\r\n");
}
str_buffer_append(sb,"</td><td colspan=\"2\">");
str_buffer_append(sb,"<tr><td colspan=\"2\">");
{
if(!add_ikm) add_ikm = "";
@ -3049,39 +2998,23 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
str_buffer_append(sb,"<br>Token encryption algorithm (required):<br>\r\n");
if(!add_tea || !add_tea[0])
add_tea = "AES-256-CBC";
add_tea = "A256GCMKW";
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_TEA);
str_buffer_append(sb,"\" value=\"AES-128-CBC\" ");
if(!strcmp("AES-128-CBC",add_tea)) {
str_buffer_append(sb,"\" value=\"A128GCMKW\" ");
if(!strcmp("A128GCMKW",add_tea)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">AES-128-CBC\r\n<br>\r\n");
str_buffer_append(sb,">A128GCMKW\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_TEA);
str_buffer_append(sb,"\" value=\"AES-256-CBC\" ");
if(!strcmp("AES-256-CBC",add_tea)) {
str_buffer_append(sb,"\" value=\"A256GCMKW\" ");
if(!strcmp("A256GCMKW",add_tea)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">AES-256-CBC\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_TEA);
str_buffer_append(sb,"\" value=\"AEAD-AES-128-GCM\" ");
if(!strcmp("AEAD-AES-128-GCM",add_tea)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">AEAD-AES-128-GCM\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_TEA);
str_buffer_append(sb,"\" value=\"AEAD-AES-256-GCM\" ");
if(!strcmp("AEAD-AES-256-GCM",add_tea)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">AEAD-AES-256-GCM\r\n<br>\r\n");
str_buffer_append(sb,">A256GCMKW\r\n<br>\r\n");
}
str_buffer_append(sb,"</td><td colspan=\"2\">");
@ -3097,56 +3030,9 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
str_buffer_append(sb,"<br>\r\n");
}
str_buffer_append(sb,"</td></tr>\r\n<tr><td>");
str_buffer_append(sb,"</td></tr>\r\n");
{
str_buffer_append(sb,"<br>Token authentication algorithm (required if no AEAD used):<br>\r\n");
if(!add_aa || !add_aa[0])
add_aa = "HMAC-SHA-256-128";
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_AA);
str_buffer_append(sb,"\" value=\"HMAC-SHA-256-128\" ");
if(!strcmp("HMAC-SHA-256-128",add_aa)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">HMAC-SHA-256-128\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_AA);
str_buffer_append(sb,"\" value=\"HMAC-SHA-256\" ");
if(!strcmp("HMAC-SHA-256",add_aa)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">HMAC-SHA-256\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_AA);
str_buffer_append(sb,"\" value=\"HMAC-SHA-384\" ");
if(!strcmp("HMAC-SHA-384",add_aa)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">HMAC-SHA-384\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_AA);
str_buffer_append(sb,"\" value=\"HMAC-SHA-512\" ");
if(!strcmp("HMAC-SHA-512",add_aa)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">HMAC-SHA-512\r\n<br>\r\n");
str_buffer_append(sb,"<input type=\"radio\" name=\"");
str_buffer_append(sb,HR_ADD_OAUTH_AA);
str_buffer_append(sb,"\" value=\"HMAC-SHA-1\" ");
if(!strcmp("HMAC-SHA-1",add_aa)) {
str_buffer_append(sb," checked ");
}
str_buffer_append(sb,">HMAC-SHA-1\r\n<br>\r\n");
}
str_buffer_append(sb,"</td><td colspan=\"2\">");
str_buffer_append(sb,"<tr><td colspan=\"2\">");
{
if(!add_auth_key) add_auth_key = "";
@ -3172,9 +3058,7 @@ static void write_https_oauth_page(ioa_socket_handle s, const char* add_kid, con
str_buffer_append(sb,"<tr><th>N</th><th>KID</th><th>keys</th>");
str_buffer_append(sb,"<th>Timestamp, secs</th>");
str_buffer_append(sb,"<th>Lifetime,secs</th>");
str_buffer_append(sb,"<th>Hash key derivation function</th>");
str_buffer_append(sb,"<th>Token encryption algorithm</th>");
str_buffer_append(sb,"<th>Token authentication algorithm</th>");
str_buffer_append(sb,"<th> </th>");
str_buffer_append(sb,"</tr>\r\n");
@ -3663,9 +3547,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
const char* add_ikm = "";
const char *add_rs_key = "";
const char *add_auth_key = "";
const char* add_hkdf_hash_func = "";
const char* add_tea = "";
const char* add_aa = "";
const char* msg = "";
add_kid = get_http_header_value(hr,HR_ADD_OAUTH_KID,"");
@ -3675,16 +3557,12 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
add_auth_key = get_http_header_value(hr,HR_ADD_OAUTH_AUTH_KEY,"");
add_ts = get_http_header_value(hr,HR_ADD_OAUTH_TS,"");
add_lt = get_http_header_value(hr,HR_ADD_OAUTH_LT,"");
add_hkdf_hash_func = get_http_header_value(hr,HR_ADD_OAUTH_HKDF,"");
add_tea = get_http_header_value(hr,HR_ADD_OAUTH_TEA,"");
add_aa = get_http_header_value(hr,HR_ADD_OAUTH_AA,"");
int keys_ok = 0;
if(add_ikm[0] && add_hkdf_hash_func[0]) {
if(add_rs_key[0] && add_auth_key[0]) {
keys_ok = 1;
} else if(add_rs_key[0] && add_auth_key[0]) {
keys_ok = 1;
} else if(strstr(add_tea,"AEAD") && add_rs_key[0]) {
} else if(strstr(add_tea,"GCM") && add_rs_key[0]) {
keys_ok = 1;
}
if(!keys_ok) {
@ -3709,14 +3587,10 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
}
STRCPY(key.ikm_key,add_ikm);
STRCPY(key.hkdf_hash_func,add_hkdf_hash_func);
STRCPY(key.as_rs_alg,add_tea);
STRCPY(key.auth_alg,add_aa);
STRCPY(key.as_rs_key,add_rs_key);
STRCPY(key.auth_key,add_auth_key);
if(strstr(key.as_rs_alg,"AEAD")) key.auth_alg[0]=0;
const turn_dbdriver_t * dbd = get_dbdriver();
if (dbd && dbd->set_oauth_key) {
if((*dbd->set_oauth_key)(&key)<0) {
@ -3726,9 +3600,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
add_ts = "0";
add_lt = "0";
add_ikm = "";
add_hkdf_hash_func = "";
add_tea = "";
add_aa = "";
add_rs_key = "";
add_auth_key = "";
}
@ -3736,7 +3608,7 @@ static void handle_https(ioa_socket_handle s, ioa_network_buffer_handle nbh)
}
}
write_https_oauth_page(s,add_kid,add_ikm,add_hkdf_hash_func,add_tea,add_aa,add_ts,add_lt,add_rs_key,add_auth_key,msg);
write_https_oauth_page(s,add_kid,add_ikm,add_tea,add_ts,add_lt,add_rs_key,add_auth_key,msg);
}
break;
}

View File

@ -1018,17 +1018,15 @@ void run_db_test(void)
oauth_key_data_raw key_;
oauth_key_data_raw *key=&key_;
dbd->get_oauth_key((const u08bits*)"north",key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
key->as_rs_alg, key->as_rs_key, key->auth_key);
printf("DB TEST 3:\n");
STRCPY(key->as_rs_alg,"as_rs_alg");
STRCPY(key->as_rs_key,"as_rs_key");
STRCPY(key->auth_alg,"auth_alg");
STRCPY(key->auth_key,"auth_key");
STRCPY(key->hkdf_hash_func,"hkdf");
STRCPY(key->ikm_key,"ikm_key");
STRCPY(key->kid,"kid");
key->timestamp = 123;
@ -1039,9 +1037,9 @@ void run_db_test(void)
printf("DB TEST 4:\n");
dbd->get_oauth_key((const u08bits*)"kid",key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key=%s, auth_key=%s\n",
key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime,
key->as_rs_alg, key->as_rs_key, key->auth_key);
printf("DB TEST 5:\n");
dbd->del_oauth_key((const u08bits*)"kid");
@ -1053,9 +1051,9 @@ void run_db_test(void)
oauth_key_data oakd;
convert_oauth_key_data_raw(key, &oakd);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key_size=%d, auth_alg=%s, auth_key_size=%d\n",
oakd.kid, oakd.ikm_key, (unsigned long long)oakd.timestamp, (unsigned long)oakd.lifetime, oakd.hkdf_hash_func,
oakd.as_rs_alg, (int)oakd.as_rs_key_size, oakd.auth_alg, (int)oakd.auth_key_size);
printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s, as_rs_key_size=%d, auth_key_size=%d\n",
oakd.kid, oakd.ikm_key, (unsigned long long)oakd.timestamp, (unsigned long)oakd.lifetime,
oakd.as_rs_alg, (int)oakd.as_rs_key_size, (int)oakd.auth_key_size);
oauth_key oak;
char err_msg[1025];

View File

@ -41,33 +41,11 @@
//////////// OAUTH //////////////////
static const char* shas[]={"SHA1",
#if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
"SHA256",
#endif
#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
"SHA384",
#endif
#if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
"SHA512",
#endif
NULL};
static const char* encs[]={"AES-256-CBC","AES-128-CBC",
static const char* encs[]={
#if !defined(TURN_NO_GCM)
"AEAD_AES_128_GCM", "AEAD_AES_256_GCM",
"A128GCMKW", "A256GCMKW",
#endif
NULL};
static const char* hmacs[]={"HMAC-SHA-1",
#if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
"HMAC-SHA-256","HMAC-SHA-256-128",
#endif
#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
"HMAC-SHA-384",
#endif
#if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
"HMAC-SHA-512",
#endif
NULL};
static int print_extra = 0;
@ -86,7 +64,7 @@ static int check_oauth(void) {
const char server_name[33] = "blackdow.carleon.gov";
size_t i_hmacs,i_shas,i_encs;
size_t i_encs;
const char long_term_key[33] = "HGkj32KJGiuy098sdfaqbNjOiaz71923";
@ -107,18 +85,18 @@ static int check_oauth(void) {
const char aead_nonce[OAUTH_AEAD_NONCE_SIZE+1] = "h4j3k2l2n4b5";
for (i_hmacs = 0; hmacs[i_hmacs]; ++i_hmacs) {
for (i_shas = 0; shas[i_shas]; ++i_shas) {
{
{
for (i_encs = 0; encs[i_encs]; ++i_encs) {
printf("oauth token %s:%s:%s:",hmacs[i_hmacs],shas[i_shas],encs[i_encs]);
printf("oauth token %s:",encs[i_encs]);
if(print_extra)
printf("\n");
oauth_token ot;
ns_bzero(&ot,sizeof(ot));
ot.enc_block.key_length = (uint16_t)mac_key_length;
STRCPY(ot.enc_block.mac_key,mac_key);
ot.enc_block.timestamp = token_timestamp;
@ -140,8 +118,6 @@ static int check_oauth(void) {
STRCPY(okdr.kid,kid);
STRCPY(okdr.ikm_key,base64encoded_ltp);
STRCPY(okdr.as_rs_alg, encs[i_encs]);
STRCPY(okdr.auth_alg, hmacs[i_hmacs]);
STRCPY(okdr.hkdf_hash_func, shas[i_shas]);
okdr.timestamp = key_timestamp;
okdr.lifetime = key_lifetime;

View File

@ -102,9 +102,9 @@ int oauth = 0;
oauth_key okey_array[3];
static oauth_key_data_raw okdr_array[3] = {
{"north","Y2FybGVvbg==",0,0,"SHA-256","AES-256-CBC","","HMAC-SHA-256-128",""},
{"union","aGVyb2Q=",0,0,"SHA-256","AES-256-CBC","","HMAC-SHA-512",""},
{"oldempire","YXVsY3Vz",0,0,"SHA-256","AEAD-AES-256-GCM","","",""}
{"north","Y2FybGVvbg==",0,0,"A256GCMKW","",""},
{"union","aGVyb2Q=",0,0,"A128GCMKW","",""},
{"oldempire","YXVsY3Vz",0,0,"A256GCMKW","",""}
};
//////////////// local definitions /////////////////

View File

@ -662,7 +662,7 @@ static void stun_init_error_response_common_str(u08bits* buf, size_t *len,
stun_tid* id)
{
if (!reason) {
if (!reason || !strcmp((const char*)reason,"Unknown error")) {
reason = get_default_reason(error_code);
}
@ -2002,8 +2002,7 @@ static void normalize_algorithm(char *s)
static size_t calculate_enc_key_length(ENC_ALG a)
{
switch(a) {
case AES_128_CBC:
case AEAD_AES_128_GCM:
case A128GCMKW:
return 16;
default:
break;
@ -2012,105 +2011,27 @@ static size_t calculate_enc_key_length(ENC_ALG a)
return 32;
}
static size_t calculate_auth_key_length(AUTH_ALG a)
static size_t calculate_auth_key_length(ENC_ALG a)
{
switch(a) {
case AUTH_ALG_HMAC_SHA_1:
return 20;
case AUTH_ALG_HMAC_SHA_256_128:
return 32;
case AUTH_ALG_HMAC_SHA_256:
return 32;
case AUTH_ALG_HMAC_SHA_384:
return 48;
case AUTH_ALG_HMAC_SHA_512:
return 64;
#if !defined(TURN_NO_GCM)
case A256GCMKW:
case A128GCMKW:
return 0;
#endif
default:
break;
};
return 32;
}
static size_t calculate_auth_output_length(AUTH_ALG a)
{
switch(a) {
case AUTH_ALG_HMAC_SHA_1:
return 20;
case AUTH_ALG_HMAC_SHA_256_128:
return 16;
case AUTH_ALG_HMAC_SHA_256:
return 32;
case AUTH_ALG_HMAC_SHA_384:
return 48;
case AUTH_ALG_HMAC_SHA_512:
return 64;
default:
break;
};
return 32;
return 0;
}
static int calculate_key(char *key, size_t key_size,
char *new_key, size_t new_key_size,
SHATYPE shatype,
char *err_msg, size_t err_msg_size,
const char *info)
char *new_key, size_t new_key_size)
{
//Extract:
u08bits prk[128];
unsigned int prk_len = 0;
stun_calculate_hmac((const u08bits *)key, key_size, (const u08bits *)"", 0, prk, &prk_len, shatype);
UNUSED_ARG(key_size);
//Expand:
size_t info_len = strlen(info);
u08bits buf[256];
ns_bcopy(info,buf,info_len);
buf[info_len]=0x01;
u08bits hmac1[128];
unsigned int hmac1_len = 0;
stun_calculate_hmac((const u08bits *)buf, info_len+1, prk, prk_len, hmac1, &hmac1_len, shatype);
ns_bcopy(hmac1,new_key,hmac1_len);
//Check
if(new_key_size>hmac1_len) {
ns_bcopy(hmac1,buf,hmac1_len);
ns_bcopy(info,buf+hmac1_len,info_len);
buf[hmac1_len+info_len]=0x02;
u08bits hmac2[128];
unsigned int hmac2_len = 0;
stun_calculate_hmac((const u08bits *)buf, hmac1_len+info_len+1, prk, prk_len, hmac2, &hmac2_len, shatype);
ns_bcopy(hmac2,new_key+hmac1_len,hmac2_len);
if(new_key_size > (hmac1_len + hmac2_len)) {
ns_bcopy(hmac2,buf,hmac2_len);
ns_bcopy(info,buf+hmac2_len,info_len);
buf[hmac2_len+info_len]=0x03;
u08bits hmac3[128];
unsigned int hmac3_len = 0;
stun_calculate_hmac((const u08bits *)buf, hmac2_len+info_len+1, prk, prk_len, hmac3, &hmac3_len, shatype);
ns_bcopy(hmac3,new_key+hmac1_len+hmac2_len,hmac3_len);
if(new_key_size > (hmac1_len + hmac2_len + hmac3_len)) {
ns_bcopy(hmac3,buf,hmac3_len);
ns_bcopy(info,buf+hmac3_len,info_len);
buf[hmac3_len+info_len]=0x04;
u08bits hmac4[128];
unsigned int hmac4_len = 0;
stun_calculate_hmac((const u08bits *)buf, hmac3_len+info_len+1, prk, prk_len, hmac4, &hmac4_len, shatype);
ns_bcopy(hmac4,new_key+hmac1_len+hmac2_len+hmac3_len,hmac4_len);
if(new_key_size > (hmac1_len + hmac2_len + hmac3_len + hmac4_len)) {
if(err_msg) {
snprintf(err_msg,err_msg_size,"Wrong HKDF procedure (key sizes): output.sz=%lu, hmac(1)=%lu, hmac(2)=%lu",(unsigned long)new_key_size,(unsigned long)hmac1_len,(unsigned long)hmac2_len);
}
OAUTH_ERROR("Wrong HKDF procedure (key sizes): output.sz=%lu, hmac(1)=%lu, hmac(2)=%lu",(unsigned long)new_key_size,(unsigned long)hmac1_len,(unsigned long)hmac2_len);
return -1;
}
}
}
}
ns_bcopy(key,new_key,new_key_size);
return 0;
}
@ -2138,13 +2059,9 @@ int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *er
remove_spaces(oakd->kid);
remove_spaces(oakd->hkdf_hash_func);
remove_spaces(oakd->as_rs_alg);
remove_spaces(oakd->auth_alg);
normalize_algorithm(oakd->hkdf_hash_func);
normalize_algorithm(oakd->as_rs_alg);
normalize_algorithm(oakd->auth_alg);
if(!(oakd->kid[0])) {
if(err_msg) {
@ -2171,57 +2088,19 @@ int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *er
if(!(key->timestamp)) key->timestamp = OAUTH_DEFAULT_TIMESTAMP;
if(!(key->lifetime)) key->lifetime = OAUTH_DEFAULT_LIFETIME;
key->hkdf_hash_func = SHATYPE_SHA256;
if(!strcmp(oakd->hkdf_hash_func,"SHA1") || !strcmp(oakd->hkdf_hash_func,"SHA-1")) {
key->hkdf_hash_func = SHATYPE_SHA1;
} else if(!strcmp(oakd->hkdf_hash_func,"SHA256") || !strcmp(oakd->hkdf_hash_func,"SHA-256")) {
key->hkdf_hash_func = SHATYPE_SHA256;
} else if(!strcmp(oakd->hkdf_hash_func,"SHA384") || !strcmp(oakd->hkdf_hash_func,"SHA-384")) {
key->hkdf_hash_func = SHATYPE_SHA384;
} else if(!strcmp(oakd->hkdf_hash_func,"SHA512") || !strcmp(oakd->hkdf_hash_func,"SHA-512")) {
key->hkdf_hash_func = SHATYPE_SHA512;
} else if(oakd->hkdf_hash_func[0]) {
if(err_msg) {
snprintf(err_msg,err_msg_size,"Wrong HKDF hash function algorithm: %s",oakd->hkdf_hash_func);
}
OAUTH_ERROR("Wrong HKDF hash function algorithm: %s\n",oakd->hkdf_hash_func);
return -1;
}
key->auth_alg = AUTH_ALG_DEFAULT;
if(!strcmp(oakd->auth_alg,"HMAC-SHA-1") || !strcmp(oakd->auth_alg,"HMAC-SHA1")) {
key->auth_alg = AUTH_ALG_HMAC_SHA_1;
} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-256")) {
key->auth_alg = AUTH_ALG_HMAC_SHA_256;
} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-384")) {
key->auth_alg = AUTH_ALG_HMAC_SHA_384;
} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-512")) {
key->auth_alg = AUTH_ALG_HMAC_SHA_512;
} else if(!strcmp(oakd->auth_alg,"HMAC-SHA-256-128")) {
key->auth_alg = AUTH_ALG_HMAC_SHA_256_128;
} else if(oakd->auth_alg[0]) {
if(err_msg) {
snprintf(err_msg,err_msg_size,"Wrong oAuth token hash algorithm: %s (1)\n",oakd->auth_alg);
}
key->auth_alg = AUTH_ALG_ERROR;
OAUTH_ERROR("Wrong oAuth token hash algorithm: %s (2)\n",oakd->auth_alg);
return -1;
} else {
key->auth_alg = AUTH_ALG_UNDEFINED;
}
key->as_rs_alg = ENC_ALG_DEFAULT;
if(!strcmp(oakd->as_rs_alg,"AES-128-CBC")) {
key->as_rs_alg = AES_128_CBC;
} else if(!strcmp(oakd->as_rs_alg,"AES-256-CBC")) {
key->as_rs_alg = AES_256_CBC;
} else if(!strcmp(oakd->as_rs_alg,"AEAD-AES-128-GCM")) {
key->as_rs_alg = AEAD_AES_128_GCM;
key->auth_alg = AUTH_ALG_UNDEFINED;
} else if(!strcmp(oakd->as_rs_alg,"AEAD-AES-256-GCM")) {
key->as_rs_alg = AEAD_AES_256_GCM;
key->auth_alg = AUTH_ALG_UNDEFINED;
} else if(oakd->as_rs_alg[0]) {
#if !defined(TURN_NO_GCM)
if(!strcmp(oakd->as_rs_alg,"A128GCMKW")) {
key->as_rs_alg = A128GCMKW;
key->auth_key_size = 0;
key->auth_key[0] = 0;
} else if(!strcmp(oakd->as_rs_alg,"A256GCMKW")) {
key->as_rs_alg = A256GCMKW;
key->auth_key_size = 0;
key->auth_key[0] = 0;
} else if(oakd->as_rs_alg[0])
#endif
{
if(err_msg) {
snprintf(err_msg,err_msg_size,"Wrong oAuth token encryption algorithm: %s (2)\n",oakd->as_rs_alg);
}
@ -2229,20 +2108,18 @@ int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *er
return -1;
}
if(key->auth_alg == AUTH_ALG_UNDEFINED) {
//AEAD
key->auth_key_size = 0;
key->auth_key[0] = 0;
} else if(!(key->auth_key_size)) {
key->auth_key_size = calculate_auth_key_length(key->auth_alg);
if(calculate_key(key->ikm_key,key->ikm_key_size,key->auth_key,key->auth_key_size,key->hkdf_hash_func,err_msg,err_msg_size,"AUTH key")<0) {
return -1;
if(!(key->auth_key_size)) {
key->auth_key_size = calculate_auth_key_length(key->as_rs_alg);
if(key->auth_key_size) {
if(calculate_key(key->ikm_key,key->ikm_key_size,key->auth_key,key->auth_key_size)<0) {
return -1;
}
}
}
if(!(key->as_rs_key_size)) {
key->as_rs_key_size = calculate_enc_key_length(key->as_rs_alg);
if(calculate_key(key->ikm_key,key->ikm_key_size,key->as_rs_key,key->as_rs_key_size,key->hkdf_hash_func,err_msg,err_msg_size,"AS-RS key")<0) {
if(calculate_key(key->ikm_key,key->ikm_key_size,key->as_rs_key,key->as_rs_key_size)<0) {
return -1;
}
}
@ -2254,14 +2131,10 @@ int convert_oauth_key_data(const oauth_key_data *oakd0, oauth_key *key, char *er
static const EVP_CIPHER *get_cipher_type(ENC_ALG enc_alg)
{
switch(enc_alg) {
case AES_256_CBC:
return EVP_aes_256_cbc();
case AES_128_CBC:
return EVP_aes_128_cbc();
#if !defined(TURN_NO_GCM)
case AEAD_AES_128_GCM:
case A128GCMKW:
return EVP_aes_128_gcm();
case AEAD_AES_256_GCM:
case A256GCMKW:
return EVP_aes_256_gcm();
#endif
default:
@ -2271,44 +2144,6 @@ static const EVP_CIPHER *get_cipher_type(ENC_ALG enc_alg)
return NULL;
}
static const EVP_MD *get_auth_type(AUTH_ALG aa)
{
switch(aa) {
case AUTH_ALG_HMAC_SHA_1:
return EVP_sha1();
#if !defined(OPENSSL_NO_SHA256) && defined(SHA256_DIGEST_LENGTH)
case AUTH_ALG_HMAC_SHA_256_128:
case AUTH_ALG_HMAC_SHA_256:
return EVP_sha256();
#endif
#if !defined(OPENSSL_NO_SHA384) && defined(SHA384_DIGEST_LENGTH)
case AUTH_ALG_HMAC_SHA_384:
return EVP_sha384();
#endif
#if !defined(OPENSSL_NO_SHA512) && defined(SHA512_DIGEST_LENGTH)
case AUTH_ALG_HMAC_SHA_512:
return EVP_sha512();
#endif
default:
break;
};
OAUTH_ERROR("%s: Unknown auth algorithm: %d\n",__FUNCTION__,(int)aa);
return NULL;
}
static void update_hmac_len(AUTH_ALG aa, unsigned int *hmac_len)
{
if(hmac_len) {
switch(aa) {
case AUTH_ALG_HMAC_SHA_256_128:
*hmac_len = 16;
break;
default:
break;
};
}
}
static int my_EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
int *outl, const unsigned char *in, int inl)
{
@ -2357,8 +2192,15 @@ void print_field(const char* name, const unsigned char* f, size_t len) {
printf("\n<<==field %s\n",name);
}
static int encode_oauth_token_normal(const u08bits *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken)
int encode_oauth_token_normal(const u08bits *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken);
int encode_oauth_token_normal(const u08bits *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken)
{
UNUSED_ARG(server_name);
UNUSED_ARG(etoken);
UNUSED_ARG(key);
UNUSED_ARG(dtoken);
/*
if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<=128)) {
unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
@ -2420,11 +2262,19 @@ static int encode_oauth_token_normal(const u08bits *server_name, encoded_oauth_t
return 0;
}
*/
return -1;
}
static int decode_oauth_token_normal(const u08bits *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken)
int decode_oauth_token_normal(const u08bits *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken);
int decode_oauth_token_normal(const u08bits *server_name, const encoded_oauth_token *etoken, const oauth_key *key, oauth_token *dtoken)
{
UNUSED_ARG(server_name);
UNUSED_ARG(etoken);
UNUSED_ARG(key);
UNUSED_ARG(dtoken);
/*
if(server_name && etoken && key && dtoken) {
size_t mac_size = calculate_auth_output_length(key->auth_alg);
@ -2498,6 +2348,7 @@ static int decode_oauth_token_normal(const u08bits *server_name, const encoded_o
return 0;
}
*/
return -1;
}
@ -2512,14 +2363,27 @@ static void generate_random_nonce(unsigned char *nonce, size_t sz) {
#if !defined(TURN_NO_GCM)
static int encode_oauth_token_aead(const u08bits *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken, const u08bits* nonce0)
{
if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<128)) {
static int encode_oauth_token_aead(const u08bits *server_name, encoded_oauth_token *etoken, const oauth_key *key, const oauth_token *dtoken, const u08bits* nonce0) {
if(server_name && etoken && key && dtoken && (dtoken->enc_block.key_length<=MAXSHASIZE)) {
unsigned char orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
ns_bzero(orig_field,sizeof(orig_field));
unsigned char nonce[OAUTH_AEAD_NONCE_SIZE];
if(nonce0) {
ns_bcopy(nonce0,nonce,sizeof(nonce));
} else {
generate_random_nonce(nonce, sizeof(nonce));
}
size_t len = 0;
*((uint16_t*)(orig_field+len)) = nswap16(OAUTH_AEAD_NONCE_SIZE);
len +=2;
ns_bcopy(nonce,orig_field+len,OAUTH_AEAD_NONCE_SIZE);
len += OAUTH_AEAD_NONCE_SIZE;
*((uint16_t*)(orig_field+len)) = nswap16(dtoken->enc_block.key_length);
len +=2;
@ -2536,15 +2400,6 @@ static int encode_oauth_token_aead(const u08bits *server_name, encoded_oauth_tok
if(!cipher)
return -1;
unsigned char *encoded_field = (unsigned char*)etoken->token;
unsigned char nonce[OAUTH_AEAD_NONCE_SIZE];
if(nonce0) {
ns_bcopy(nonce0,nonce,sizeof(nonce));
} else {
generate_random_nonce(nonce, sizeof(nonce));
}
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
@ -2572,8 +2427,13 @@ static int encode_oauth_token_aead(const u08bits *server_name, encoded_oauth_tok
return -1;
outl=0;
unsigned char *encoded_field = (unsigned char*)etoken->token;
ns_bcopy(orig_field,encoded_field,OAUTH_AEAD_NONCE_SIZE + 2);
encoded_field += OAUTH_AEAD_NONCE_SIZE + 2;
unsigned char *start_field = orig_field + OAUTH_AEAD_NONCE_SIZE + 2;
len -= OAUTH_AEAD_NONCE_SIZE + 2;
if(1 != my_EVP_EncryptUpdate(&ctx, encoded_field, &outl, orig_field, (int)len))
if(1 != my_EVP_EncryptUpdate(&ctx, encoded_field, &outl, start_field, (int)len))
return -1;
int tmp_outl = 0;
@ -2583,10 +2443,7 @@ static int encode_oauth_token_aead(const u08bits *server_name, encoded_oauth_tok
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, OAUTH_AEAD_TAG_SIZE, encoded_field + outl);
outl += OAUTH_AEAD_TAG_SIZE;
ns_bcopy(nonce, encoded_field + outl, OAUTH_AEAD_NONCE_SIZE);
outl += OAUTH_AEAD_NONCE_SIZE; //encoded+tag+hmac
etoken->size = outl;
etoken->size = 2 + OAUTH_AEAD_NONCE_SIZE + outl;
EVP_CIPHER_CTX_cleanup(&ctx);
@ -2599,18 +2456,24 @@ static int decode_oauth_token_aead(const u08bits *server_name, const encoded_oau
{
if(server_name && etoken && key && dtoken) {
size_t min_encoded_field_size = 2+4+8+OAUTH_AEAD_NONCE_SIZE+OAUTH_AEAD_TAG_SIZE+1;
unsigned char snl[2];
ns_bcopy((const unsigned char*)(etoken->token),snl,2);
const unsigned char *csnl = snl;
uint16_t nonce_len = nswap16(*((const uint16_t*)csnl));
size_t min_encoded_field_size = 2+4+8+nonce_len+2+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;
}
const unsigned char* encoded_field = (const unsigned char*)etoken->token;
unsigned int encoded_field_size = (unsigned int)etoken->size-OAUTH_AEAD_NONCE_SIZE - OAUTH_AEAD_TAG_SIZE;
const unsigned char* nonce = ((const unsigned char*)etoken->token) + encoded_field_size + OAUTH_AEAD_TAG_SIZE;
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_AEAD_TAG_SIZE;
const unsigned char* nonce = ((const unsigned char*)etoken->token + 2);
unsigned char tag[OAUTH_AEAD_TAG_SIZE];
ns_bcopy(((const unsigned char*)etoken->token) + encoded_field_size, tag ,sizeof(tag));
ns_bcopy(((const unsigned char*)etoken->token) + nonce_len + 2 + encoded_field_size, tag ,sizeof(tag));
unsigned char decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
@ -2631,7 +2494,7 @@ static int decode_oauth_token_aead(const u08bits *server_name, const encoded_oau
//EVP_CIPHER_CTX_set_padding(&ctx,1);
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if(1 != EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, OAUTH_AEAD_NONCE_SIZE, NULL)) {
if(1 != EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, nonce_len, NULL)) {
OAUTH_ERROR("%s: Cannot set nonce length\n",__FUNCTION__);
return -1;
}
@ -2697,12 +2560,9 @@ int encode_oauth_token(const u08bits *server_name, encoded_oauth_token *etoken,
UNUSED_ARG(nonce);
if(server_name && etoken && key && dtoken) {
switch(key->as_rs_alg) {
case AES_256_CBC:
case AES_128_CBC:
return encode_oauth_token_normal(server_name, etoken,key,dtoken);
#if !defined(TURN_NO_GCM)
case AEAD_AES_128_GCM:
case AEAD_AES_256_GCM:
case A256GCMKW:
case A128GCMKW:
return encode_oauth_token_aead(server_name, etoken,key,dtoken,nonce);
#endif
default:
@ -2717,12 +2577,9 @@ int decode_oauth_token(const u08bits *server_name, const encoded_oauth_token *et
{
if(server_name && etoken && key && dtoken) {
switch(key->as_rs_alg) {
case AES_256_CBC:
case AES_128_CBC:
return decode_oauth_token_normal(server_name, etoken,key,dtoken);
#if !defined(TURN_NO_GCM)
case AEAD_AES_128_GCM:
case AEAD_AES_256_GCM:
case A256GCMKW:
case A128GCMKW:
return decode_oauth_token_aead(server_name, etoken,key,dtoken);
#endif
default:

View File

@ -73,10 +73,10 @@ typedef enum _SHATYPE SHATYPE;
enum _ENC_ALG {
ENC_ALG_ERROR=-1,
ENC_ALG_DEFAULT=0,
AES_256_CBC=ENC_ALG_DEFAULT,
AES_128_CBC,
AEAD_AES_128_GCM,
AEAD_AES_256_GCM,
#if !defined(TURN_NO_GCM)
A256GCMKW=ENC_ALG_DEFAULT,
A128GCMKW,
#endif
ENG_ALG_NUM
};
@ -84,23 +84,6 @@ typedef enum _ENC_ALG ENC_ALG;
/* <<== OAUTH TOKEN ENC ALG */
/* OAUTH TOKEN AUTH ALG ==> */
enum _AUTH_ALG {
AUTH_ALG_ERROR = -1,
AUTH_ALG_UNDEFINED = 0,
AUTH_ALG_DEFAULT = 1,
AUTH_ALG_HMAC_SHA_256_128 = AUTH_ALG_DEFAULT,
AUTH_ALG_HMAC_SHA_1,
AUTH_ALG_HMAC_SHA_256,
AUTH_ALG_HMAC_SHA_384,
AUTH_ALG_HMAC_SHA_512
};
typedef enum _AUTH_ALG AUTH_ALG;
/* <<== OAUTH TOKEN AUTH ALG */
/**
* oAuth struct
*/
@ -113,6 +96,7 @@ typedef enum _AUTH_ALG AUTH_ALG;
#define OAUTH_ALG_SIZE (64)
#define OAUTH_KEY_SIZE (256)
#define OAUTH_AEAD_NONCE_SIZE (12)
#define OAUTH_MAX_NONCE_SIZE (256)
#define OAUTH_AEAD_TAG_SIZE (16)
#define OAUTH_ENC_ALG_BLOCK_SIZE (16)
@ -127,11 +111,9 @@ struct _oauth_key_data {
size_t ikm_key_size;
turn_time_t timestamp;
turn_time_t lifetime;
char hkdf_hash_func[OAUTH_HASH_FUNC_SIZE+1];
char as_rs_alg[OAUTH_ALG_SIZE+1];
char as_rs_key[OAUTH_KEY_SIZE+1];
size_t as_rs_key_size;
char auth_alg[OAUTH_ALG_SIZE+1];
char auth_key[OAUTH_KEY_SIZE+1];
size_t auth_key_size;
};
@ -144,11 +126,9 @@ struct _oauth_key {
size_t ikm_key_size;
turn_time_t timestamp;
turn_time_t lifetime;
SHATYPE hkdf_hash_func;
ENC_ALG as_rs_alg;
char as_rs_key[OAUTH_KEY_SIZE+1];
size_t as_rs_key_size;
AUTH_ALG auth_alg;
char auth_key[OAUTH_KEY_SIZE+1];
size_t auth_key_size;
};
@ -156,6 +136,8 @@ struct _oauth_key {
typedef struct _oauth_key oauth_key;
struct _oauth_encrypted_block {
uint16_t nonce_length;
uint8_t nonce[OAUTH_MAX_NONCE_SIZE];
uint16_t key_length;
uint8_t mac_key[MAXSHASIZE];
uint64_t timestamp;

View File

@ -3398,7 +3398,6 @@ static int check_stun_auth(turn_turnserver *server,
}
}
/* direct user pattern is supported only for long-term credentials */
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"%s: Cannot find credentials of user <%s>\n",
__FUNCTION__, (char*)usname);

View File

@ -42,10 +42,8 @@ CREATE TABLE oauth_key (
ikm_key varchar(256) default '',
timestamp bigint default 0,
lifetime integer default 0,
hkdf_hash_func varchar(64) default '',
as_rs_alg varchar(64) default '',
as_rs_key varchar(256) default '',
auth_alg varchar(64) default '',
auth_key varchar(256) default '',
primary key (kid)
);

View File

@ -43,30 +43,18 @@ and they will be almost immediately "seen" by the turnserver process.
lifetime - (optional) the key lifetime in seconds; the default value
is 0 - unlimited lifetime.
hkdf_hash_func - (optional) hash function for HKDF procedure; the
valid values are SHA-1, SHA-256, SHA-384 and SHA-512,
with SHA-256 as default. The hkdf_hash_func is not needed
if the as_rs_key and auth_key are defined explicitly
in the database;
as_rs_alg - oAuth token encryption algorithm; the valid values are
"AES-128-CBC" and "AES-256-CBC", , "AEAD-AES-128-GCM",
"AEAD-AES-256-GCM".
The default value is "AES-256-CBC";
"A256GCMKW", "A128GCMKW" (see
http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-4.1).
The default value is "A256GCMKW";
as_rs_key - (optional) base64-encoded AS-RS key. If not defined, then
calculated with ikm_key and hkdf_hash_func. The as_rs_key length
calculated with ikm_key. The as_rs_key length
is defined by as_rs_alg.
auth_alg - (optional) oAuth token authentication algorithm; the valid values are
"HMAC-SHA-256-128", "HMAC-SHA-256", "HMAC-SHA-384",
"HMAC-SHA-512" and "HMAC-SHA-1".
The default value is "HMAC-SHA-256-128".
auth_key - (optional) base64-encoded AUTH key. If not defined, then
calculated with ikm_key and hkdf_hash_func. The auth_key length
is defined by auth_alg.
calculated with ikm_key. Not used with AEAD algorithms.
5) admin users (over https interface) are maintained as keys of form:
"turn/admin_user/<username> with hash members "password" and,
@ -137,8 +125,7 @@ sadd turn/realm/crinna.org/allowed-peer-ip "172.17.13.202"
sadd turn/realm/north.gov/denied-peer-ip "172.17.13.133-172.17.14.56" "172.17.17.133-172.17.19.56" "123::45"
sadd turn/realm/crinna.org/denied-peer-ip "123::77"
hmset turn/oauth/kid/north ikm_key 'Y2FybGVvbg==' hkdf_hash_func 'SHA-256' as_rs_alg 'AES-128-CBC' auth_alg 'HMAC-SHA-256-128'
hmset turn/oauth/kid/oldempire ikm_key 'YXVsY3Vz' hkdf_hash_func 'SHA-256' as_rs_alg 'AEAD-AES-256-GCM'
hmset turn/oauth/kid/oldempire ikm_key 'YXVsY3Vz' as_rs_alg 'A256GCMKW'
hmset turn/admin_user/skarling realm 'north.gov' password 'hoodless'
hmset turn/admin_user/bayaz password 'magi'

View File

@ -56,21 +56,13 @@ db.realm.insert({
db.oauth_key.insert({ kid: 'north',
ikm_key: 'Y2FybGVvbg==',
hkdf_hash_func: 'SHA-256',
as_rs_alg: 'AES-256-CBC',
auth_alg: 'HMAC-SHA-256-128' });
as_rs_alg: 'A256GCMKW'});
db.oauth_key.insert({ kid: 'union',
ikm_key: 'aGVyb2Q=',
hkdf_hash_func: 'SHA-256',
as_rs_alg: 'AES-256-CBC',
auth_alg: 'HMAC-SHA-512' });
as_rs_alg: 'A128GCMKW'});
db.oauth_key.insert({ kid: 'oldempire',
ikm_key: 'YXVsY3Vz',
hkdf_hash_func: 'SHA-256',
as_rs_alg: 'AEAD-AES-256-GCM',
auth_alg: '' });
as_rs_alg: 'A256GCMKW'});
exit

View File

@ -38,9 +38,9 @@ sadd turn/realm/crinna.org/allowed-peer-ip "172.17.13.202"
sadd turn/realm/north.gov/denied-peer-ip "172.17.13.133-172.17.14.56" "172.17.17.133-172.17.19.56" "123::45"
sadd turn/realm/crinna.org/denied-peer-ip "123::77"
hmset turn/oauth/kid/north ikm_key 'Y2FybGVvbg==' hkdf_hash_func 'SHA-256' as_rs_alg 'AES-256-CBC' auth_alg 'HMAC-SHA-256-128'
hmset turn/oauth/kid/union ikm_key 'aGVyb2Q=' hkdf_hash_func 'SHA-256' as_rs_alg 'AES-256-CBC' auth_alg 'HMAC-SHA-512'
hmset turn/oauth/kid/oldempire ikm_key 'YXVsY3Vz' hkdf_hash_func 'SHA-256' as_rs_alg 'AEAD-AES-256-GCM'
hmset turn/oauth/kid/north ikm_key 'Y2FybGVvbg==' as_rs_alg 'A256GCMKW'
hmset turn/oauth/kid/union ikm_key 'aGVyb2Q=' as_rs_alg 'A128GCMKW'
hmset turn/oauth/kid/oldempire ikm_key 'YXVsY3Vz' as_rs_alg 'A256GCMKW'
hmset turn/admin_user/skarling realm 'north.gov' password '\$5\$6fc35c3b0c7d4633\$27fca7574f9b79d0cb93ae03e45379470cbbdfcacdd6401f97ebc620f31f54f2'
hmset turn/admin_user/bayaz password '\$5\$e018513e9de69e73\$5cbdd2e29e04ca46aeb022268a7460d3a3468de193dcb2b95f064901769f455f'

View File

@ -31,6 +31,6 @@ insert into denied_peer_ip (ip_range) values('123::45');
insert into denied_peer_ip (realm,ip_range) values('north.gov','172.17.17.133-172.17.19.56');
insert into denied_peer_ip (realm,ip_range) values('crinna.org','123::77');
insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('north','Y2FybGVvbg==',0,0,'SHA-256','AES-256-CBC','','HMAC-SHA-256-128','');
insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('union','aGVyb2Q=',0,0,'SHA-256','AES-256-CBC','','HMAC-SHA-512','');
insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('oldempire','YXVsY3Vz',0,0,'SHA-256','AEAD-AES-256-GCM','','','');
insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key) values('north','Y2FybGVvbg==',0,0,'A256GCMKW','','');
insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key) values('union','aGVyb2Q=',0,0,'A128GCMKW','','');
insert into oauth_key (kid,ikm_key,timestamp,lifetime,as_rs_alg,as_rs_key,auth_key) values('oldempire','YXVsY3Vz',0,0,'A256GCMKW','','');