From: Stephan Bosch Date: Fri, 5 Jun 2020 18:51:19 +0000 (+0200) Subject: lib-oauth2: Reformat oauth2-jwt.c. X-Git-Tag: 2.3.14.rc1~250 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=19dd87200817a2ec6ec7cc699da8ee267e53650d;p=thirdparty%2Fdovecot%2Fcore.git lib-oauth2: Reformat oauth2-jwt.c. --- diff --git a/src/lib-oauth2/oauth2-jwt.c b/src/lib-oauth2/oauth2-jwt.c index a68875e57f..83b241c558 100644 --- a/src/lib-oauth2/oauth2-jwt.c +++ b/src/lib-oauth2/oauth2-jwt.c @@ -30,8 +30,8 @@ static const char *get_field(const struct json_tree *tree, const char *key) return json_tree_get_value_str(value_node); } -static int get_time_field(const struct json_tree *tree, const char *key, - long *value_r) +static int +get_time_field(const struct json_tree *tree, const char *key, long *value_r) { const char *value = get_field(tree, key); int tz_offset ATTR_UNUSED; @@ -45,24 +45,30 @@ static int get_time_field(const struct json_tree *tree, const char *key, return 1; } -static int oauth2_lookup_hmac_key(const struct oauth2_settings *set, - const char *azp, const char *alg, const char *key_id, - const buffer_t **hmac_key_r, - const char **error_r) +static int +oauth2_lookup_hmac_key(const struct oauth2_settings *set, const char *azp, + const char *alg, const char *key_id, + const buffer_t **hmac_key_r, const char **error_r) { const char *base64_key; - const char *cache_key_id = t_strconcat(azp, ".", alg, ".", key_id, NULL); - if (oauth2_validation_key_cache_lookup_hmac_key(set->key_cache, cache_key_id, - hmac_key_r) == 0) - return 0; + const char *cache_key_id, *lookup_key; int ret; - const char *lookup_key = t_strconcat(DICT_PATH_SHARED, azp, "/", alg, "/", key_id, NULL); + + cache_key_id = t_strconcat(azp, ".", alg, ".", key_id, NULL); + if (oauth2_validation_key_cache_lookup_hmac_key( + set->key_cache, cache_key_id, hmac_key_r) == 0) + return 0; + + /* do a synchronous dict lookup */ + lookup_key = t_strconcat(DICT_PATH_SHARED, azp, "/", alg, "/", key_id, + NULL); 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("%s key '%s' not found", alg, key_id); + *error_r = t_strdup_printf("%s key '%s' not found", + alg, key_id); return -1; } @@ -72,16 +78,19 @@ static int oauth2_lookup_hmac_key(const struct oauth2_settings *set, *error_r = "Invalid base64 encoded key"; return -1; } - oauth2_validation_key_cache_insert_hmac_key(set->key_cache, cache_key_id, key); + oauth2_validation_key_cache_insert_hmac_key(set->key_cache, + cache_key_id, key); *hmac_key_r = key; return 0; } -static int oauth2_validate_hmac(const struct oauth2_settings *set, - const char *azp, const char *alg, const char *key_id, - const char *const *blobs, const char **error_r) +static int +oauth2_validate_hmac(const struct oauth2_settings *set, const char *azp, + const char *alg, const char *key_id, + const char *const *blobs, const char **error_r) { const struct hash_method *method; + if (strcmp(alg, "HS256") == 0) method = hash_method_lookup("sha256"); else if (strcmp(alg, "HS384") == 0) @@ -96,6 +105,7 @@ static int oauth2_validate_hmac(const struct oauth2_settings *set, const buffer_t *key; if (oauth2_lookup_hmac_key(set, azp, alg, key_id, &key, error_r) < 0) return -1; + struct hmac_context ctx; hmac_init(&ctx, key->data, key->used, method); hmac_update(&ctx, blobs[0], strlen(blobs[0])); @@ -108,30 +118,37 @@ static int oauth2_validate_hmac(const struct oauth2_settings *set, buffer_t *their_digest = t_base64url_decode_str(BASE64_DECODE_FLAG_NO_PADDING, blobs[2]); if (method->digest_size != their_digest->used || - !mem_equals_timing_safe(digest, their_digest->data, method->digest_size)) { + !mem_equals_timing_safe(digest, their_digest->data, + method->digest_size)) { *error_r = "Incorrect JWT signature"; return -1; } return 0; } -static int oauth2_lookup_pubkey(const struct oauth2_settings *set, - const char *azp, const char *alg, const char *key_id, - struct dcrypt_public_key **key_r, - const char **error_r) +static int +oauth2_lookup_pubkey(const struct oauth2_settings *set, const char *azp, + const char *alg, const char *key_id, + struct dcrypt_public_key **key_r, const char **error_r) { const char *key_str; - const char *cache_key_id = t_strconcat(azp, ".", alg, ".", key_id, NULL); - if (oauth2_validation_key_cache_lookup_pubkey(set->key_cache, cache_key_id, key_r) == 0) - return 0; + const char *cache_key_id, *lookup_key; int ret; - const char *lookup_key = t_strconcat(DICT_PATH_SHARED, azp, "/", alg, "/", key_id, NULL); + + cache_key_id = t_strconcat(azp, ".", alg, ".", key_id, NULL); + if (oauth2_validation_key_cache_lookup_pubkey( + set->key_cache, cache_key_id, key_r) == 0) + return 0; + /* do a synchronous dict lookup */ + lookup_key = t_strconcat(DICT_PATH_SHARED, azp, "/", alg, "/", key_id, + NULL); 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("%s key '%s' not found", alg, key_id); + *error_r = t_strdup_printf("%s key '%s' not found", + alg, key_id); return -1; } @@ -144,18 +161,21 @@ static int oauth2_lookup_pubkey(const struct oauth2_settings *set, } /* cache key */ - oauth2_validation_key_cache_insert_pubkey(set->key_cache, cache_key_id, pubkey); + oauth2_validation_key_cache_insert_pubkey(set->key_cache, cache_key_id, + pubkey); *key_r = pubkey; return 0; } -static int oauth2_validate_rsa_ecdsa(const struct oauth2_settings *set, - const char *azp, const char *alg, const char *key_id, - const char *const *blobs, const char **error_r) +static int +oauth2_validate_rsa_ecdsa(const struct oauth2_settings *set, + const char *azp, const char *alg, const char *key_id, + const char *const *blobs, const char **error_r) { const char *method; enum dcrypt_padding padding; enum dcrypt_signature_format sig_format; + if (!dcrypt_is_initialized()) { *error_r = "No crypto library loaded"; return -1; @@ -199,7 +219,8 @@ static int oauth2_validate_rsa_ecdsa(const struct oauth2_settings *set, /* verify signature */ bool valid; if (!dcrypt_verify(pubkey, method, sig_format, data, strlen(data), - signature->data, signature->used, &valid, padding, error_r)) { + signature->data, signature->used, &valid, padding, + error_r)) { valid = FALSE; } else if (!valid) { *error_r = "Bad signature"; @@ -208,15 +229,19 @@ static int oauth2_validate_rsa_ecdsa(const struct oauth2_settings *set, return valid ? 0 : -1; } -static int oauth2_validate_signature(const struct oauth2_settings *set, - const char *azp, const char *alg, const char *key_id, - const char *const *blobs, const char **error_r) +static int +oauth2_validate_signature(const struct oauth2_settings *set, const char *azp, + const char *alg, const char *key_id, + const char *const *blobs, const char **error_r) { - if (str_begins(alg, "HS")) - return oauth2_validate_hmac(set, azp, alg, key_id, blobs, error_r); - else if (str_begins(alg, "RS") || str_begins(alg, "PS") || - str_begins(alg, "ES")) - return oauth2_validate_rsa_ecdsa(set, azp, alg, key_id, blobs, error_r); + if (str_begins(alg, "HS")) { + return oauth2_validate_hmac(set, azp, alg, key_id, blobs, + error_r); + } else if (str_begins(alg, "RS") || str_begins(alg, "PS") || + str_begins(alg, "ES")) { + return oauth2_validate_rsa_ecdsa(set, azp, alg, key_id, blobs, + error_r); + } *error_r = t_strdup_printf("Unsupported algorithm '%s'", alg); return -1; @@ -227,8 +252,9 @@ oauth2_jwt_copy_fields(ARRAY_TYPE(oauth2_field) *fields, struct json_tree *tree) { pool_t pool = array_get_pool(fields); ARRAY(const struct json_tree_node*) nodes; - t_array_init(&nodes, 1); const struct json_tree_node *root = json_tree_root(tree); + + t_array_init(&nodes, 1); array_push_back(&nodes, &root); while (array_count(&nodes) > 0) { @@ -243,7 +269,8 @@ oauth2_jwt_copy_fields(ARRAY_TYPE(oauth2_field) *fields, struct json_tree *tree) struct oauth2_field *field = array_append_space(fields); field->name = p_strdup(pool, node->key); - field->value = p_strdup(pool, json_tree_get_value_str(node)); + field->value = p_strdup( + pool, json_tree_get_value_str(node)); } node = node->next; } @@ -276,9 +303,10 @@ oauth2_jwt_header_process(struct json_tree *tree, const char **alg_r, } static int -oauth2_jwt_body_process(const struct oauth2_settings *set, const char *alg, const char *kid, - ARRAY_TYPE(oauth2_field) *fields, struct json_tree *tree, - const char *const *blobs, const char **error_r) +oauth2_jwt_body_process(const struct oauth2_settings *set, const char *alg, + const char *kid, ARRAY_TYPE(oauth2_field) *fields, + struct json_tree *tree, const char *const *blobs, + const char **error_r) { const char *sub = get_field(tree, "sub"); @@ -405,7 +433,8 @@ int oauth2_try_parse_jwt(const struct oauth2_settings *set, size_t pos = strcspn(kid, "./%"); if (pos < strlen(kid)) { - /* sanitize kid, cannot allow dots or / in it, so we encode them */ + /* sanitize kid, cannot allow dots or / in it, so we encode them + */ string_t *new_kid = t_str_new(strlen(kid)); /* put initial data */ str_append_data(new_kid, kid, pos); @@ -434,7 +463,8 @@ int oauth2_try_parse_jwt(const struct oauth2_settings *set, t_base64url_decode_str(BASE64_DECODE_FLAG_NO_PADDING, blobs[1]); if (oauth2_json_tree_build(body, &body_tree, error_r) == -1) return -1; - ret = oauth2_jwt_body_process(set, alg, kid, fields, body_tree, blobs, error_r); + ret = oauth2_jwt_body_process(set, alg, kid, fields, body_tree, blobs, + error_r); json_tree_deinit(&body_tree); return ret;