From: Stephan Bosch Date: Mon, 7 Oct 2019 13:21:28 +0000 (+0200) Subject: lib-dcrypt: Use the new lib-json X-Git-Tag: 2.4.0~2366 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77494e1933406c71dbf9ebd61074508b2dd995d9;p=thirdparty%2Fdovecot%2Fcore.git lib-dcrypt: Use the new lib-json --- diff --git a/src/lib-dcrypt/Makefile.am b/src/lib-dcrypt/Makefile.am index 97cf155d66..af095ed7df 100644 --- a/src/lib-dcrypt/Makefile.am +++ b/src/lib-dcrypt/Makefile.am @@ -6,6 +6,7 @@ NOPLUGIN_LDFLAGS= AM_CPPFLAGS = \ -I$(top_srcdir)/src/lib \ -I$(top_srcdir)/src/lib-test \ + -I$(top_srcdir)/src/lib-json \ -I$(top_srcdir)/src/lib-ssl-iostream \ -DDCRYPT_MODULE_DIR=\"$(pkglibdir)\" @@ -51,6 +52,7 @@ check-local: LIBDOVECOT_TEST_DEPS = \ ../lib-ssl-iostream/libssl_iostream.la \ + ../lib-json/libjson.la \ ../lib-test/libtest.la \ ../lib/liblib.la LIBDOVECOT_TEST = \ @@ -60,7 +62,7 @@ LIBDOVECOT_TEST = \ test_crypto_LDADD = $(LIBDOVECOT_TEST) test_crypto_DEPENDENCIES = $(LIBDOVECOT_TEST_DEPS) if HAVE_WHOLE_ARCHIVE -test_crypto_LDFLAGS = -Wl,$(LD_WHOLE_ARCHIVE),../lib-ssl-iostream/.libs/libssl_iostream.a,$(LD_NO_WHOLE_ARCHIVE) +test_crypto_LDFLAGS = -export-dynamic -Wl,$(LD_WHOLE_ARCHIVE),../lib-json/.libs/libjson.a,../lib-ssl-iostream/.libs/libssl_iostream.a,$(LD_NO_WHOLE_ARCHIVE) endif test_crypto_CFLAGS = $(AM_CPPFLAGS) -DDCRYPT_SRC_DIR=\"$(top_srcdir)/src/lib-dcrypt\" test_crypto_SOURCES = $(libdcrypt_la_SOURCES) test-crypto.c @@ -68,7 +70,7 @@ test_crypto_SOURCES = $(libdcrypt_la_SOURCES) test-crypto.c test_stream_LDADD = $(LIBDOVECOT_TEST) test_stream_DEPENDENCIES = $(LIBDOVECOT_TEST_DEPS) if HAVE_WHOLE_ARCHIVE -test_stream_LDFLAGS = -Wl,$(LD_WHOLE_ARCHIVE),../lib-ssl-iostream/.libs/libssl_iostream.a,$(LD_NO_WHOLE_ARCHIVE) +test_stream_LDFLAGS = -export-dynamic -Wl,$(LD_WHOLE_ARCHIVE),../lib-json/.libs/libjson.a,../lib-ssl-iostream/.libs/libssl_iostream.a,$(LD_NO_WHOLE_ARCHIVE) endif test_stream_CFLAGS = $(AM_CPPFLAGS) -DDCRYPT_SRC_DIR=\"$(top_srcdir)/src/lib-dcrypt\" test_stream_SOURCES = $(libdcrypt_la_SOURCES) test-stream.c diff --git a/src/lib-dcrypt/dcrypt-openssl1.c b/src/lib-dcrypt/dcrypt-openssl1.c index 07875a5819..464328872e 100644 --- a/src/lib-dcrypt/dcrypt-openssl1.c +++ b/src/lib-dcrypt/dcrypt-openssl1.c @@ -12,7 +12,7 @@ #include "array.h" #include "module-dir.h" #include "istream.h" -#include "json-tree.h" +#include "json-ostream.h" #include "dovecot-openssl-common.h" #include #include @@ -1546,26 +1546,26 @@ static bool load_jwk_ec_key(EVP_PKEY **key_r, bool want_private_key, const char *crv, *x, *y, *d; const struct json_tree_node *node; - if ((node = json_tree_find_key(root, "crv")) == NULL || - (crv = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "crv")) == NULL || + (crv = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing crv parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "x")) == NULL || - (x = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "x")) == NULL || + (x = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing x parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "y")) == NULL || - (y = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "y")) == NULL || + (y = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing y parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "d")) == NULL || - (d = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "d")) == NULL || + (d = json_tree_node_get_str(node)) == NULL) { if (want_private_key) { *error_r = "Missing d parameter"; return FALSE; @@ -1702,51 +1702,51 @@ static bool load_jwk_rsa_key(EVP_PKEY **key_r, bool want_private_key, const struct json_tree_node *node; /* n and e must be present */ - if ((node = json_tree_find_key(root, "n")) == NULL || - (n = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "n")) == NULL || + (n = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing n parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "e")) == NULL || - (e = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "e")) == NULL || + (e = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing e parameter"; return FALSE; } if (want_private_key) { - if ((node = json_tree_find_key(root, "d")) == NULL || - (d = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "d")) == NULL || + (d = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing d parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "p")) == NULL || - (p = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "p")) == NULL || + (p = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing p parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "q")) == NULL || - (q = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "q")) == NULL || + (q = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing q parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "dp")) == NULL || - (dp = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "dp")) == NULL || + (dp = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing dp parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "dq")) == NULL || - (dq = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "dq")) == NULL || + (dq = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing dq parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "qi")) == NULL || - (qi = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "qi")) == NULL || + (qi = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing qi parameter"; return FALSE; } @@ -1861,16 +1861,16 @@ dcrypt_openssl_load_private_key_jwk(struct dcrypt_private_key **key_r, return FALSE; } - root = json_tree_root(key_tree); + root = json_tree_get_root(key_tree); /* check key type */ - if ((node = json_tree_find_key(root, "kty")) == NULL) { + if ((node = json_tree_node_get_member(root, "kty")) == NULL) { *error_r = "Cannot load JWK private key: no kty parameter"; - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return FALSE; } - kty = json_tree_get_value_str(node); + kty = json_tree_node_get_str(node); if (null_strcmp(kty, "EC") == 0) { ret = load_jwk_ec_key(&pkey, TRUE, root, password, dec_key, &error); @@ -1890,14 +1890,18 @@ dcrypt_openssl_load_private_key_jwk(struct dcrypt_private_key **key_r, (*key_r)->key = pkey; (*key_r)->ref++; /* check if kid is present */ - if ((node = json_tree_find_key(root, "kid")) != NULL) - (*key_r)->key_id = i_strdup_empty(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "kid")) != NULL) { + (*key_r)->key_id = i_strdup_empty( + json_tree_node_get_str(node)); + } /* check if use is present */ - if ((node = json_tree_find_key(root, "use")) != NULL) - (*key_r)->usage = jwk_use_to_key_usage(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "use")) != NULL) { + (*key_r)->usage = jwk_use_to_key_usage( + json_tree_node_get_str(node)); + } } - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return ret; } @@ -1919,16 +1923,16 @@ dcrypt_openssl_load_public_key_jwk(struct dcrypt_public_key **key_r, return FALSE; } - root = json_tree_root(key_tree); + root = json_tree_get_root(key_tree); /* check key type */ - if ((node = json_tree_find_key(root, "kty")) == NULL) { + if ((node = json_tree_node_get_member(root, "kty")) == NULL) { *error_r = "Cannot load JWK public key: no kty parameter"; - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return FALSE; } - kty = json_tree_get_value_str(node); + kty = json_tree_node_get_str(node); if (null_strcmp(kty, "EC") == 0) { ret = load_jwk_ec_key(&pkey, FALSE, root, NULL, NULL, &error); @@ -1948,14 +1952,18 @@ dcrypt_openssl_load_public_key_jwk(struct dcrypt_public_key **key_r, (*key_r)->key = pkey; (*key_r)->ref++; /* check if kid is present */ - if ((node = json_tree_find_key(root, "kid")) != NULL) - (*key_r)->key_id = i_strdup_empty(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "kid")) != NULL) { + (*key_r)->key_id = i_strdup_empty( + json_tree_node_get_str(node)); + } /* check if use is present */ - if ((node = json_tree_find_key(root, "use")) != NULL) - (*key_r)->usage = jwk_use_to_key_usage(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "use")) != NULL) { + (*key_r)->usage = jwk_use_to_key_usage( + json_tree_node_get_str(node)); + } } - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return ret; } @@ -1982,7 +1990,6 @@ static bool store_jwk_ec_key(EVP_PKEY *pkey, bool is_private_key, string_t *dest, const char **error_r) { i_assert(cipher == NULL && password == NULL && enc_key == NULL); - string_t *temp = t_str_new(256); const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); i_assert(ec_key != NULL); @@ -2001,21 +2008,23 @@ static bool store_jwk_ec_key(EVP_PKEY *pkey, bool is_private_key, const char *curve = nid_to_jwk_curve(nid); const char *use = key_usage_to_jwk_use(usage); - - str_printfa(temp, "{\"kty\":\"EC\",\"crv\":\"%s\"", curve); - str_append(temp, ",\"x\":\""); - bn2base64url(x, temp); - str_append(temp, "\",\"y\":\""); - bn2base64url(y, temp); - - if (use != NULL) { - str_append(temp, "\",\"use\":\""); - json_append_escaped(temp, use); - } - if (key_id != NULL) { - str_append(temp, "\",\"kid\":\""); - json_append_escaped(temp, key_id); - } + string_t *temp = t_str_new(256); + string_t *b64url_temp = t_str_new(256); + struct json_ostream *joutput = json_ostream_create_str(temp, 0); + + json_ostream_ndescend_object(joutput, NULL); + json_ostream_nwrite_string(joutput, "kty", "EC"); + json_ostream_nwrite_string(joutput, "crv", curve); + bn2base64url(x, b64url_temp); + json_ostream_nwrite_string_buffer(joutput, "x", b64url_temp); + str_truncate(b64url_temp, 0); + bn2base64url(y, b64url_temp); + json_ostream_nwrite_string_buffer(joutput, "y", b64url_temp); + + if (use != NULL) + json_ostream_nwrite_string(joutput, "use", use); + if (key_id != NULL) + json_ostream_nwrite_string(joutput, "kid", key_id); BN_free(x); BN_free(y); @@ -2023,12 +2032,15 @@ static bool store_jwk_ec_key(EVP_PKEY *pkey, bool is_private_key, const BIGNUM *d = EC_KEY_get0_private_key(ec_key); if (d == NULL) { *error_r = "No private key available"; + json_ostream_destroy(&joutput); return FALSE; } - str_append(temp, "\",\"d\":\""); - bn2base64url(d, temp); + str_truncate(b64url_temp, 0); + bn2base64url(d, b64url_temp); + json_ostream_nwrite_string_buffer(joutput, "d", b64url_temp); } - str_append(temp, "\"}"); + json_ostream_nascend_object(joutput); + json_ostream_nfinish_destroy(&joutput); str_append_str(dest, temp); return TRUE; } @@ -2765,28 +2777,28 @@ dcrypt_openssl_key_string_get_info( } /* determine key type */ - root = json_tree_root(tree); - if ((node = json_tree_find_key(root, "kty")) == NULL || - (value = json_tree_get_value_str(node)) == NULL) { - json_tree_deinit(&tree); + root = json_tree_get_root(tree); + if ((node = json_tree_node_get_member(root, "kty")) == NULL || + (value = json_tree_node_get_str(node)) == NULL) { + json_tree_unref(&tree); *error_r = "Invalid JWK key: Missing kty parameter"; return FALSE; } else if (strcmp(value, "RSA") == 0) { - if (json_tree_find_key(root, "d") != NULL) + if (json_tree_node_get_member(root, "d") != NULL) kind = DCRYPT_KEY_KIND_PRIVATE; else kind = DCRYPT_KEY_KIND_PUBLIC; } else if (strcmp(value, "EC") == 0) { - if (json_tree_find_key(root, "d") != NULL) + if (json_tree_node_get_member(root, "d") != NULL) kind = DCRYPT_KEY_KIND_PRIVATE; else kind = DCRYPT_KEY_KIND_PUBLIC; } else { - json_tree_deinit(&tree); + json_tree_unref(&tree); *error_r = "Unsupported JWK key type"; return FALSE; } - json_tree_deinit(&tree); + json_tree_unref(&tree); } else { if (str_begins_with(key_data, "1:")) { *error_r = "Dovecot v1 key format uses tab to separate fields"; diff --git a/src/lib-dcrypt/dcrypt-openssl3.c b/src/lib-dcrypt/dcrypt-openssl3.c index abb2c34d51..91287fd252 100644 --- a/src/lib-dcrypt/dcrypt-openssl3.c +++ b/src/lib-dcrypt/dcrypt-openssl3.c @@ -12,7 +12,7 @@ #include "array.h" #include "module-dir.h" #include "istream.h" -#include "json-tree.h" +#include "json-ostream.h" #include "dovecot-openssl-common.h" #include "dcrypt.h" #include "dcrypt-private.h" @@ -1539,20 +1539,20 @@ static bool load_jwk_ec_key(EVP_PKEY **key_r, bool want_private_key, const char *crv, *x, *y, *d; const struct json_tree_node *node; - if ((node = json_tree_find_key(root, "crv")) == NULL || - (crv = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "crv")) == NULL || + (crv = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing crv parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "x")) == NULL || - (x = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "x")) == NULL || + (x = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing x parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "y")) == NULL || - (y = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "y")) == NULL || + (y = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing y parameter"; return FALSE; } @@ -1570,8 +1570,8 @@ static bool load_jwk_ec_key(EVP_PKEY **key_r, bool want_private_key, /* FIXME: Support decryption */ if (want_private_key) { - if ((node = json_tree_find_key(root, "d")) == NULL || - (d = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "d")) == NULL || + (d = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing d parameter"; return FALSE; } @@ -1652,51 +1652,51 @@ static bool load_jwk_rsa_key(EVP_PKEY **key_r, bool want_private_key, const struct json_tree_node *node; /* n and e must be present */ - if ((node = json_tree_find_key(root, "n")) == NULL || - (n = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "n")) == NULL || + (n = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing n parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "e")) == NULL || - (e = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "e")) == NULL || + (e = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing e parameter"; return FALSE; } if (want_private_key) { - if ((node = json_tree_find_key(root, "d")) == NULL || - (d = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "d")) == NULL || + (d = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing d parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "p")) == NULL || - (p = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "p")) == NULL || + (p = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing p parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "q")) == NULL || - (q = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "q")) == NULL || + (q = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing q parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "dp")) == NULL || - (dp = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "dp")) == NULL || + (dp = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing dp parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "dq")) == NULL || - (dq = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "dq")) == NULL || + (dq = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing dq parameter"; return FALSE; } - if ((node = json_tree_find_key(root, "qi")) == NULL || - (qi = json_tree_get_value_str(node)) == NULL) { + if ((node = json_tree_node_get_member(root, "qi")) == NULL || + (qi = json_tree_node_get_str(node)) == NULL) { *error_r = "Missing qi parameter"; return FALSE; } @@ -1826,16 +1826,16 @@ dcrypt_openssl_load_private_key_jwk(struct dcrypt_private_key **key_r, return FALSE; } - root = json_tree_root(key_tree); + root = json_tree_get_root(key_tree); /* check key type */ - if ((node = json_tree_find_key(root, "kty")) == NULL) { + if ((node = json_tree_node_get_member(root, "kty")) == NULL) { *error_r = "Cannot load JWK private key: no kty parameter"; - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return FALSE; } - kty = json_tree_get_value_str(node); + kty = json_tree_node_get_str(node); if (null_strcmp(kty, "EC") == 0) { ret = load_jwk_ec_key(&pkey, TRUE, root, password, dec_key, &error); @@ -1855,14 +1855,18 @@ dcrypt_openssl_load_private_key_jwk(struct dcrypt_private_key **key_r, (*key_r)->key = pkey; (*key_r)->ref++; /* check if kid is present */ - if ((node = json_tree_find_key(root, "kid")) != NULL) - (*key_r)->key_id = i_strdup_empty(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "kid")) != NULL) { + (*key_r)->key_id = i_strdup_empty( + json_tree_node_get_str(node)); + } /* check if use is present */ - if ((node = json_tree_find_key(root, "use")) != NULL) - (*key_r)->usage = jwk_use_to_key_usage(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "use")) != NULL) { + (*key_r)->usage = jwk_use_to_key_usage( + json_tree_node_get_str(node)); + } } - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return ret; } @@ -1884,16 +1888,16 @@ dcrypt_openssl_load_public_key_jwk(struct dcrypt_public_key **key_r, return FALSE; } - root = json_tree_root(key_tree); + root = json_tree_get_root(key_tree); /* check key type */ - if ((node = json_tree_find_key(root, "kty")) == NULL) { + if ((node = json_tree_node_get_member(root, "kty")) == NULL) { *error_r = "Cannot load JWK public key: no kty parameter"; - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return FALSE; } - kty = json_tree_get_value_str(node); + kty = json_tree_node_get_str(node); if (null_strcmp(kty, "EC") == 0) { ret = load_jwk_ec_key(&pkey, FALSE, root, NULL, NULL, &error); @@ -1913,14 +1917,18 @@ dcrypt_openssl_load_public_key_jwk(struct dcrypt_public_key **key_r, (*key_r)->key = pkey; (*key_r)->ref++; /* check if kid is present */ - if ((node = json_tree_find_key(root, "kid")) != NULL) - (*key_r)->key_id = i_strdup_empty(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "kid")) != NULL) { + (*key_r)->key_id = i_strdup_empty( + json_tree_node_get_str(node)); + } /* check if use is present */ - if ((node = json_tree_find_key(root, "use")) != NULL) - (*key_r)->usage = jwk_use_to_key_usage(json_tree_get_value_str(node)); + if ((node = json_tree_node_get_member(root, "use")) != NULL) { + (*key_r)->usage = jwk_use_to_key_usage( + json_tree_node_get_str(node)); + } } - json_tree_deinit(&key_tree); + json_tree_unref(&key_tree); return ret; } @@ -1963,21 +1971,22 @@ static bool store_jwk_ec_key(EVP_PKEY *pkey, bool is_private_key, const char *curve = nid_to_jwk_curve(nid); const char *use = key_usage_to_jwk_use(usage); string_t *temp = t_str_new(256); - - str_printfa(temp, "{\"kty\":\"EC\",\"crv\":\"%s\"", curve); - str_append(temp, ",\"x\":\""); - bn2base64url(x, temp); - str_append(temp, "\",\"y\":\""); - bn2base64url(y, temp); - - if (use != NULL) { - str_append(temp, "\",\"use\":\""); - json_append_escaped(temp, use); - } - if (key_id != NULL) { - str_append(temp, "\",\"kid\":\""); - json_append_escaped(temp, key_id); - } + string_t *b64url_temp = t_str_new(256); + struct json_ostream *joutput = json_ostream_create_str(temp, 0); + + json_ostream_ndescend_object(joutput, NULL); + json_ostream_nwrite_string(joutput, "kty", "EC"); + json_ostream_nwrite_string(joutput, "crv", curve); + bn2base64url(x, b64url_temp); + json_ostream_nwrite_string_buffer(joutput, "x", b64url_temp); + str_truncate(b64url_temp, 0); + bn2base64url(y, b64url_temp); + json_ostream_nwrite_string_buffer(joutput, "y", b64url_temp); + + if (use != NULL) + json_ostream_nwrite_string(joutput, "use", use); + if (key_id != NULL) + json_ostream_nwrite_string(joutput, "kid", key_id); BN_free(x); BN_free(y); @@ -1986,13 +1995,16 @@ static bool store_jwk_ec_key(EVP_PKEY *pkey, bool is_private_key, EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &d); if (d == NULL) { *error_r = "No private key available"; + json_ostream_destroy(&joutput); return FALSE; } - str_append(temp, "\",\"d\":\""); - bn2base64url(d, temp); + str_truncate(b64url_temp, 0); + bn2base64url(d, b64url_temp); + json_ostream_nwrite_string_buffer(joutput, "d", b64url_temp); BN_free(d); } - str_append(temp, "\"}"); + json_ostream_nascend_object(joutput); + json_ostream_nfinish_destroy(&joutput); str_append_str(dest, temp); return TRUE; } @@ -2672,28 +2684,28 @@ dcrypt_openssl_key_string_get_info( } /* determine key type */ - root = json_tree_root(tree); - if ((node = json_tree_find_key(root, "kty")) == NULL || - (value = json_tree_get_value_str(node)) == NULL) { - json_tree_deinit(&tree); + root = json_tree_get_root(tree); + if ((node = json_tree_node_get_member(root, "kty")) == NULL || + (value = json_tree_node_get_str(node)) == NULL) { + json_tree_unref(&tree); *error_r = "Invalid JWK key: Missing kty parameter"; return FALSE; } else if (strcmp(value, "RSA") == 0) { - if (json_tree_find_key(root, "d") != NULL) + if (json_tree_node_get_member(root, "d") != NULL) kind = DCRYPT_KEY_KIND_PRIVATE; else kind = DCRYPT_KEY_KIND_PUBLIC; } else if (strcmp(value, "EC") == 0) { - if (json_tree_find_key(root, "d") != NULL) + if (json_tree_node_get_member(root, "d") != NULL) kind = DCRYPT_KEY_KIND_PRIVATE; else kind = DCRYPT_KEY_KIND_PUBLIC; } else { - json_tree_deinit(&tree); + json_tree_unref(&tree); *error_r = "Unsupported JWK key type"; return FALSE; } - json_tree_deinit(&tree); + json_tree_unref(&tree); } else { if (str_begins_with(key_data, "1:")) { *error_r = "Dovecot v1 key format uses tab to separate fields"; diff --git a/src/lib-dcrypt/dcrypt-private.h b/src/lib-dcrypt/dcrypt-private.h index 7b37de983a..49bf90fa0b 100644 --- a/src/lib-dcrypt/dcrypt-private.h +++ b/src/lib-dcrypt/dcrypt-private.h @@ -203,7 +203,7 @@ void dcrypt_set_vfs(struct dcrypt_vfs *vfs); void dcrypt_openssl_init(struct module *module ATTR_UNUSED); void dcrypt_openssl_deinit(void); -int parse_jwk_key(const char *key_data, struct json_tree **tree_r, +int parse_jwk_key(const char *key_data, struct json_tree **jtree_r, const char **error_r); #endif diff --git a/src/lib-dcrypt/dcrypt.c b/src/lib-dcrypt/dcrypt.c index 9916754eae..94a15576fa 100644 --- a/src/lib-dcrypt/dcrypt.c +++ b/src/lib-dcrypt/dcrypt.c @@ -4,7 +4,7 @@ #include "module-dir.h" #include "dcrypt.h" #include "istream.h" -#include "json-tree.h" +#include "json-tree-io.h" #include "dcrypt-private.h" static struct module *dcrypt_module = NULL; @@ -628,33 +628,10 @@ bool dcrypt_verify(struct dcrypt_public_key *key, const char *algorithm, valid_r, padding, error_r); } -int parse_jwk_key(const char *key_data, struct json_tree **tree_r, +int parse_jwk_key(const char *key_data, struct json_tree **jtree_r, const char **error_r) { - struct istream *is = i_stream_create_from_data(key_data, strlen(key_data)); - struct json_parser *parser = json_parser_init(is); - struct json_tree *tree = json_tree_init(); - const char *error; - enum json_type type; - const char *value; - int ret; - - i_stream_unref(&is); - - while ((ret = json_parse_next(parser, &type, &value)) == 1) - json_tree_append(tree, type, value); - - i_assert(ret == -1); - - if (json_parser_deinit(&parser, &error) != 0) { - json_tree_deinit(&tree); - *error_r = error; - if (error == NULL) - *error_r = "Truncated JSON"; - return -1; - } - - *tree_r = tree; - - return 0; + return json_tree_read_cstr(key_data, + JSON_PARSER_FLAG_NUMBERS_AS_STRING, + jtree_r, error_r); } diff --git a/src/lib-dcrypt/test-crypto.c b/src/lib-dcrypt/test-crypto.c index 248225300e..c00d8fef44 100644 --- a/src/lib-dcrypt/test-crypto.c +++ b/src/lib-dcrypt/test-crypto.c @@ -13,7 +13,6 @@ #include "randgen.h" #include "test-common.h" #include "hex-binary.h" -#include "json-parser.h" #include #include #include diff --git a/src/lib-json/json-text.h b/src/lib-json/json-text.h index 754c5957c6..644cc1ae16 100644 --- a/src/lib-json/json-text.h +++ b/src/lib-json/json-text.h @@ -1,7 +1,7 @@ #ifndef JSON_TEXT_H #define JSON_TEXT_H -#include "json-parser.h" +#include "json-parser.new.h" #include "json-generator.h" int json_text_format_data(const void *data, size_t size, diff --git a/src/lib-oauth2/Makefile.am b/src/lib-oauth2/Makefile.am index 7ae5372a54..0403ce1c99 100644 --- a/src/lib-oauth2/Makefile.am +++ b/src/lib-oauth2/Makefile.am @@ -32,6 +32,7 @@ test_libs = \ $(noinst_LTLIBRARIES) \ ../lib-dcrypt/libdcrypt.la \ ../lib-http/libhttp.la \ + ../lib-json/libjson.la \ ../lib-dns/libdns.la \ ../lib-ssl-iostream/libssl_iostream.la \ ../lib-master/libmaster.la \ @@ -45,6 +46,7 @@ test_deps = \ $(noinst_LTLIBRARIES) \ ../lib-dcrypt/libdcrypt.la \ ../lib-http/libhttp.la \ + ../lib-json/libjson.la \ ../lib-dns/libdns.la \ ../lib-ssl-iostream/libssl_iostream.la \ ../lib-master/libmaster.la \