]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-oauth2: Reformat oauth2-jwt.c.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Fri, 5 Jun 2020 18:51:19 +0000 (20:51 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 7 Dec 2020 08:59:28 +0000 (08:59 +0000)
src/lib-oauth2/oauth2-jwt.c

index a68875e57fc341869e345f96603ab3486b81c0da..83b241c558ec47440cc7752bd43965df4bf3c5d0 100644 (file)
@@ -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;