details: https://hg.nginx.org/njs/rev/30e03dbc6baf branches: changeset: 1856:30e03dbc6baf user: Dmitry Volyntsev <xei...@nginx.com> date: Mon May 16 22:57:27 2022 -0700 description: Fixed compatibility with BoringSSL.
The fix is to use more conventional API when dealing with HMAC algorithm. This closes #455 issue on Github. diffstat: external/njs_openssl.h | 1 + external/njs_webcrypto_module.c | 83 ++++++++++------------------------------ 2 files changed, 23 insertions(+), 61 deletions(-) diffs (182 lines): diff -r 6a28cdbc8cb6 -r 30e03dbc6baf external/njs_openssl.h --- a/external/njs_openssl.h Wed May 11 21:08:21 2022 -0700 +++ b/external/njs_openssl.h Mon May 16 22:57:27 2022 -0700 @@ -19,6 +19,7 @@ #include <openssl/rsa.h> #include <openssl/err.h> #include <openssl/rand.h> +#include <openssl/hmac.h> #include <openssl/crypto.h> #ifdef EVP_PKEY_HKDF diff -r 6a28cdbc8cb6 -r 30e03dbc6baf external/njs_webcrypto_module.c --- a/external/njs_webcrypto_module.c Wed May 11 21:08:21 2022 -0700 +++ b/external/njs_webcrypto_module.c Mon May 16 22:57:27 2022 -0700 @@ -1254,14 +1254,12 @@ njs_ext_derive(njs_vm_t *vm, njs_value_t u_char *k; size_t olen; int64_t iterations, length; - EVP_PKEY *pkey; unsigned usage, mask; njs_int_t ret; njs_str_t salt, info; njs_value_t value, *aobject, *dobject; const EVP_MD *md; EVP_PKEY_CTX *pctx; - njs_mp_cleanup_t *cln; njs_webcrypto_key_t *key, *dkey; njs_webcrypto_hash_t hash; njs_webcrypto_algorithm_t *alg, *dalg; @@ -1544,29 +1542,11 @@ free: if (njs_slow_path(ret == NJS_ERROR)) { goto fail; } - - pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, k, length); - if (njs_slow_path(pkey == NULL)) { - njs_webcrypto_error(vm, "EVP_PKEY_new_mac_key() failed"); - goto fail; - } - - cln = njs_mp_cleanup_add(njs_vm_memory_pool(vm), 0); - if (cln == NULL) { - njs_memory_error(vm); - goto fail; - } - - cln->handler = njs_webcrypto_cleanup_pkey; - cln->data = key; - - dkey->pkey = pkey; - - } else { - dkey->raw.start = k; - dkey->raw.length = length; } + dkey->raw.start = k; + dkey->raw.length = length; + ret = njs_vm_external_create(vm, &value, njs_webcrypto_crypto_key_proto_id, dkey, 0); @@ -1856,21 +1836,12 @@ njs_ext_import_key(njs_vm_t *vm, njs_val break; case NJS_ALGORITHM_HMAC: - pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key_data.start, - key_data.length); - if (njs_slow_path(pkey == NULL)) { - njs_webcrypto_error(vm, "EVP_PKEY_new_mac_key() failed"); - goto fail; - } - ret = njs_algorithm_hash(vm, options, &key->hash); if (njs_slow_path(ret == NJS_ERROR)) { goto fail; } - key->pkey = pkey; - - break; + /* Fall through. */ case NJS_ALGORITHM_AES_GCM: case NJS_ALGORITHM_AES_CTR: @@ -1968,7 +1939,7 @@ static njs_int_t njs_ext_sign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t verify) { - u_char *dst; + u_char *dst, *p; size_t olen, outlen; unsigned mask, m_len; njs_int_t ret; @@ -2030,12 +2001,6 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * } } - mctx = njs_evp_md_ctx_new(); - if (njs_slow_path(mctx == NULL)) { - njs_webcrypto_error(vm, "njs_evp_md_ctx_new() failed"); - goto fail; - } - if (alg->type == NJS_ALGORITHM_ECDSA) { ret = njs_algorithm_hash(vm, options, &hash); if (njs_slow_path(ret == NJS_ERROR)) { @@ -2052,22 +2017,10 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * switch (alg->type) { case NJS_ALGORITHM_HMAC: - ret = EVP_DigestSignInit(mctx, NULL, md, NULL, key->pkey); - if (njs_slow_path(ret <= 0)) { - njs_webcrypto_error(vm, "EVP_DigestSignInit() failed"); - goto fail; - } - - ret = EVP_DigestSignUpdate(mctx, data.start, data.length); - if (njs_slow_path(ret <= 0)) { - njs_webcrypto_error(vm, "EVP_DigestSignUpdate() failed"); - goto fail; - } - - olen = EVP_MD_size(md); + m_len = EVP_MD_size(md); if (!verify) { - dst = njs_mp_zalloc(njs_vm_memory_pool(vm), olen); + dst = njs_mp_alloc(njs_vm_memory_pool(vm), m_len); if (njs_slow_path(dst == NULL)) { njs_memory_error(vm); goto fail; @@ -2077,11 +2030,13 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * dst = (u_char *) &m[0]; } - outlen = olen; - - ret = EVP_DigestSignFinal(mctx, dst, &outlen); - if (njs_slow_path(ret <= 0 || olen != outlen)) { - njs_webcrypto_error(vm, "EVP_DigestSignFinal() failed"); + outlen = m_len; + + p = HMAC(md, key->raw.start, key->raw.length, data.start, data.length, + dst, &m_len); + + if (njs_slow_path(p == NULL || m_len != outlen)) { + njs_webcrypto_error(vm, "HMAC() failed"); goto fail; } @@ -2095,6 +2050,12 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * case NJS_ALGORITHM_RSA_PSS: case NJS_ALGORITHM_ECDSA: default: + mctx = njs_evp_md_ctx_new(); + if (njs_slow_path(mctx == NULL)) { + njs_webcrypto_error(vm, "njs_evp_md_ctx_new() failed"); + goto fail; + } + ret = EVP_DigestInit_ex(mctx, md, NULL); if (njs_slow_path(ret <= 0)) { njs_webcrypto_error(vm, "EVP_DigestInit_ex() failed"); @@ -2168,6 +2129,8 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * } } + njs_evp_md_ctx_free(mctx); + EVP_PKEY_CTX_free(pctx); break; @@ -2183,8 +2146,6 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * njs_set_boolean(&value, ret != 0); } - njs_evp_md_ctx_free(mctx); - return njs_webcrypto_result(vm, &value, NJS_OK); fail: _______________________________________________ nginx-devel mailing list -- nginx-devel@nginx.org To unsubscribe send an email to nginx-devel-le...@nginx.org