]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-var-expand-crypt: Check that hex decoding actually succeeds
authorAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 24 Apr 2026 11:13:03 +0000 (14:13 +0300)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Tue, 28 Apr 2026 15:43:34 +0000 (15:43 +0000)
Found by Aurelien DESBRIERES <aurelien@hackers.camp>

src/lib-var-expand-crypt/test-var-expand-crypt.c
src/lib-var-expand-crypt/var-expand-crypt.c

index 85151447b49572cdd5bac6e254745fbbac30f351..025e9e962d922aaaf81e3c771027b3599e5fd46f 100644 (file)
@@ -26,6 +26,19 @@ static struct var_expand_table table[] = {
        { .key = "user", .value = "foo" },
        { .key = "salt-encrypted", .value ="s=foo,r=1000$da793a4ae62eb1d415228b40c43b93a8$" },
        { .key = "ecb-encrypted", .value = "$3bca3caa565f2d940acef1244a07c836$" },
+       { .key = "trunckey", .value = "cc2981c8f38aea59cc2981c8f38aea5" },
+       { .key = "invalidkey", .value = "invalid" },
+       { .key = "trunciv", .value = "cc2981c8f38aea59cc2981c8f38aea5" },
+       { .key = "invalidiv", .value = "invalid" },
+       {
+               .key = "encrypted-bad-1",
+               .value = "98b3b40a48ca40f998b3b40a48ca40fx$46b58741763fe22598014be26331a082$"
+       },
+       {
+               .key = "encrypted-bad-2",
+               .value = "98b3b40a48ca40f998b3b40a48ca40f9$46b58741763fe22598014be26331a08x$"
+       },
+
        { NULL, NULL, NULL }
 };
 
@@ -111,6 +124,41 @@ static void test_var_expand_crypt(void)
                        "hello, world",
                        0
                },
+               {
+                       "%{decrypted|encrypt(algorithm='aes-128-cbc',key=trunckey,iv=iv)|"
+                       "decrypt(key=trunckey,algorithm='aes-128-cbc')}",
+                       "Invalid key",
+                       -1
+               },
+               {
+                       "%{decrypted|encrypt(algorithm='aes-128-cbc',key=invalidkey,iv=iv)|"
+                       "decrypt(key=invalidkey,algorithm='aes-128-cbc')}",
+                       "Invalid key",
+                       -1
+               },
+               {
+                       "%{decrypted|encrypt(algorithm='aes-128-cbc',key=key,iv=trunciv)|"
+                       "decrypt(key=key,algorithm='aes-128-cbc')}",
+                       "Invalid iv",
+                       -1
+               },
+               {
+                       "%{decrypted|encrypt(algorithm='aes-128-cbc',key=key,iv=invalidiv)|"
+                       "decrypt(key=key,algorithm='aes-128-cbc')}",
+                       "Invalid iv",
+                       -1
+               },
+               {
+                       "%{encrypted-bad-1|decrypt(algorithm='aes-128-cbc',key=key)}",
+                       "Invalid iv",
+                       -1
+               },
+               {
+                       "%{encrypted-bad-2|decrypt(algorithm='aes-128-cbc',key=key)}",
+                       "Invalid input",
+                       -1
+               },
+
        };
 
        unsigned int i;
index fea766cd588e2b45f27f84247f491e297e7c5fb3..b025ee8ec6a38cde339baa9836929adf4cb5259b 100644 (file)
@@ -55,10 +55,16 @@ static int parse_parameters(struct var_expand_crypt_context *ctx,
                }
        } else {
                ctx->iv = t_buffer_create(32);
-               hex_to_binary(parts[0], ctx->iv);
+               if (hex_to_binary(parts[0], ctx->iv) < 0) {
+                       *error_r = "Invalid iv";
+                       return -1;
+               }
        }
        ctx->input = t_buffer_create(strlen(parts[1]) / 2);
-       hex_to_binary(parts[1], ctx->input);
+       if (hex_to_binary(parts[1], ctx->input) < 0) {
+               *error_r = "Invalid input";
+               return -1;
+       }
        return 0;
 }
 
@@ -144,7 +150,10 @@ static int var_expand_crypt_settings(struct var_expand_state *state,
                                return -1;
                        }
                        ctx->iv = t_buffer_create(strlen(iv) / 2);
-                       hex_to_binary(iv, ctx->iv);
+                       if (hex_to_binary(iv, ctx->iv) < 0) {
+                               *error_r = "Invalid iv";
+                               return -1;
+                       }
                } else if (strcmp(key, "key") == 0) {
                        if (var_expand_parameter_string_or_var(state, par, &enckey,
                                                               error_r) < 0) {
@@ -229,7 +238,10 @@ static int var_expand_crypt_settings(struct var_expand_state *state,
                buffer_append(ctx->iv, data + enckey_len, iv_len);
        } else {
                ctx->enckey = t_buffer_create(strlen(enckey) / 2);
-               hex_to_binary(enckey, ctx->enckey);
+               if (hex_to_binary(enckey, ctx->enckey) < 0) {
+                       *error_r = "Invalid key";
+                       return -1;
+               }
        }
 
        /* IV can be optional in some algorithms */