}
static int oauth2_lookup_hmac_key(const struct oauth2_settings *set,
- const char *key_id, const buffer_t **hmac_key_r,
+ const char *algo, const char *key_id,
+ const buffer_t **hmac_key_r,
const char **error_r)
{
const char *base64_key;
- if (oauth2_validation_key_cache_lookup_hmac_key(set->key_cache, key_id,
+ const char *cache_key_id = t_strconcat(key_id, ".", algo, NULL);
+ if (oauth2_validation_key_cache_lookup_hmac_key(set->key_cache, cache_key_id,
hmac_key_r) == 0)
return 0;
int ret;
- const char *lookup_key = t_strconcat(DICT_PATH_SHARED, key_id, NULL);
+ const char *lookup_key = t_strconcat(DICT_PATH_SHARED, algo, "/", key_id, NULL);
/* do a synchronous dict lookup */
if ((ret = dict_lookup(set->key_dict, pool_datastack_create(),
lookup_key, &base64_key, error_r)) < 0) {
return -1;
} else if (ret == 0) {
- *error_r = t_strdup_printf("Key '%s' not found", key_id);
+ *error_r = t_strdup_printf("%s key '%s' not found", algo, key_id);
return -1;
}
*error_r = "Invalid base64 encoded key";
return -1;
}
- oauth2_validation_key_cache_insert_hmac_key(set->key_cache, key_id, key);
+ oauth2_validation_key_cache_insert_hmac_key(set->key_cache, cache_key_id, key);
*hmac_key_r = key;
return 0;
}
}
const buffer_t *key;
- if (oauth2_lookup_hmac_key(set, key_id, &key, error_r) < 0)
+ if (oauth2_lookup_hmac_key(set, algo, key_id, &key, error_r) < 0)
return -1;
struct hmac_context ctx;
hmac_init(&ctx, key->data, key->used, method);
}
static int oauth2_lookup_pubkey(const struct oauth2_settings *set,
- const char *key_id, struct dcrypt_public_key **key_r,
+ const char *algo, const char *key_id,
+ struct dcrypt_public_key **key_r,
const char **error_r)
{
const char *key_str;
- if (oauth2_validation_key_cache_lookup_pubkey(set->key_cache, key_id, key_r) == 0)
+ const char *cache_key_id = t_strconcat(key_id, ".", algo, NULL);
+ if (oauth2_validation_key_cache_lookup_pubkey(set->key_cache, cache_key_id, key_r) == 0)
return 0;
int ret;
- const char *lookup_key = t_strconcat(DICT_PATH_SHARED, key_id, NULL);
+ const char *lookup_key = t_strconcat(DICT_PATH_SHARED, algo, "/", key_id, NULL);
/* do a synchronous dict lookup */
if ((ret = dict_lookup(set->key_dict, pool_datastack_create(),
lookup_key, &key_str, error_r)) < 0) {
return -1;
} else if (ret == 0) {
- *error_r = t_strdup_printf("Key '%s' not found", key_id);
+ *error_r = t_strdup_printf("%s key '%s' not found", algo, key_id);
return -1;
}
}
/* cache key */
- oauth2_validation_key_cache_insert_pubkey(set->key_cache, key_id, pubkey);
+ oauth2_validation_key_cache_insert_pubkey(set->key_cache, cache_key_id, pubkey);
*key_r = pubkey;
return 0;
}
t_base64url_decode_str(BASE64_DECODE_FLAG_NO_PADDING, blobs[2]);
struct dcrypt_public_key *pubkey;
- if (oauth2_lookup_pubkey(set, key_id, &pubkey, error_r) < 0)
+ if (oauth2_lookup_pubkey(set, algo, key_id, &pubkey, error_r) < 0)
return -1;
/* data to verify */
return tokenbuf;
}
-#define save_key(key) save_key_to("default", (key))
-static void save_key_to(const char *name, const char *keydata)
+#define save_key(algo, key) save_key_to(algo, "default", (key))
+static void save_key_to(const char *algo, const char *name, const char *keydata)
{
const char *error;
struct dict_transaction_context *ctx = dict_transaction_begin(keys_dict);
- dict_set(ctx, t_strconcat(DICT_PATH_SHARED, name, NULL), keydata);
+ dict_set(ctx, t_strconcat(DICT_PATH_SHARED, algo, "/", name, NULL), keydata);
if (dict_transaction_commit(&ctx, &error) < 0)
i_error("dict_set(%s) failed: %s", name, error);
}
void *ptr = buffer_append_space_unsafe(secret, 32);
random_fill(ptr, 32);
buffer_t *b64_key = t_base64_encode(0, (size_t)-1, secret->data, secret->used);
- save_key_to("first", str_c(b64_key));
+ save_key_to("HS256", "first", str_c(b64_key));
buffer_t *secret2 = t_buffer_create(32);
ptr = buffer_append_space_unsafe(secret2, 32);
random_fill(ptr, 32);
b64_key = t_base64_encode(0, (size_t)-1, secret2->data, secret2->used);
- save_key_to("second", str_c(b64_key));
+ save_key_to("HS256", "second", str_c(b64_key));
/* create and sign token */
buffer_t *token_1 = create_jwt_token_kid("HS256", "first");
test_assert(parse_jwt_token(&req, str_c(token_3), &is_jwt, &error) != 0);
test_assert(is_jwt == TRUE);
- test_assert_strcmp(error, "Key 'missing' not found");
+ test_assert_strcmp(error, "HS256 key 'missing' not found");
test_assert(parse_jwt_token(&req, str_c(token_4), &is_jwt, &error) != 0);
test_assert(is_jwt == TRUE);
test_assert_strcmp(error, "'kid' field is empty");
test_begin("JWT RSA token");
/* write public key to file */
oauth2_validation_key_cache_evict(key_cache, "default");
- save_key(rsa_public_key);
+ save_key("RS256", rsa_public_key);
buffer_t *tokenbuf = create_jwt_token("RS256");
/* sign token */
test_begin("JWT RSAPSS token");
/* write public key to file */
oauth2_validation_key_cache_evict(key_cache, "default");
- save_key(rsa_public_key);
+ save_key("PS256", rsa_public_key);
buffer_t *tokenbuf = create_jwt_token("PS256");
/* sign token */
exit(1);
}
oauth2_validation_key_cache_evict(key_cache, "default");
- save_key(str_c(keybuf));
+ save_key("ES256", str_c(keybuf));
buffer_t *tokenbuf = create_jwt_token("ES256");
/* sign token */
random_fill(ptr, 32);
buffer_t *b64_key = t_base64_encode(0, (size_t)-1,
hs_sign_key->data, hs_sign_key->used);
- save_key(str_c(b64_key));
+ save_key("HS256", str_c(b64_key));
}
static void test_do_deinit(void)