[njs] Fixed compatibility with BoringSSL.
Dmitry Volyntsev
xeioex at nginx.com
Tue May 17 22:54:04 UTC 2022
details: https://hg.nginx.org/njs/rev/30e03dbc6baf
branches:
changeset: 1856:30e03dbc6baf
user: Dmitry Volyntsev <xeioex at 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:
More information about the nginx-devel
mailing list