details: https://hg.nginx.org/njs/rev/646374a97d8c branches: changeset: 2131:646374a97d8c user: Dmitry Volyntsev <xei...@nginx.com> date: Mon May 22 22:48:59 2023 -0700 description: WebCrypto: making njs_webcrypto_key_t more compact by using union.
diffstat: external/njs_webcrypto_module.c | 260 +++++++++++++++++++++------------------ 1 files changed, 142 insertions(+), 118 deletions(-) diffs (814 lines): diff -r 510d8ebedfba -r 646374a97d8c external/njs_webcrypto_module.c --- a/external/njs_webcrypto_module.c Mon May 22 22:48:58 2023 -0700 +++ b/external/njs_webcrypto_module.c Mon May 22 22:48:59 2023 -0700 @@ -69,20 +69,28 @@ typedef struct { njs_webcrypto_alg_t type; unsigned usage; unsigned fmt; + unsigned raw; } njs_webcrypto_algorithm_t; typedef struct { njs_webcrypto_algorithm_t *alg; - njs_webcrypto_hash_t hash; - int curve; - - EVP_PKEY *pkey; - njs_str_t raw; - unsigned usage; njs_bool_t extractable; - njs_bool_t privat; + + njs_webcrypto_hash_t hash; + + union { + struct { + EVP_PKEY *pkey; + njs_bool_t privat; + int curve; + } a; + struct { + njs_str_t raw; + } s; + } u; + } njs_webcrypto_key_t; @@ -151,8 +159,8 @@ static njs_int_t njs_webcrypto_init(njs_ static njs_webcrypto_entry_t njs_webcrypto_alg[] = { -#define njs_webcrypto_algorithm(type, usage_mask, fmt_mask) \ - (uintptr_t) & (njs_webcrypto_algorithm_t) { type, usage_mask, fmt_mask } +#define njs_webcrypto_algorithm(type, usage, fmt, raw) \ + (uintptr_t) & (njs_webcrypto_algorithm_t) { type, usage, fmt, raw } { njs_str("RSASSA-PKCS1-v1_5"), @@ -162,7 +170,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_GENERATE_KEY, NJS_KEY_FORMAT_PKCS8 | NJS_KEY_FORMAT_SPKI | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 0) }, { @@ -173,7 +182,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_GENERATE_KEY, NJS_KEY_FORMAT_PKCS8 | NJS_KEY_FORMAT_SPKI | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 0) }, { @@ -186,7 +196,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_GENERATE_KEY, NJS_KEY_FORMAT_PKCS8 | NJS_KEY_FORMAT_SPKI | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 0) }, { @@ -196,7 +207,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_SIGN | NJS_KEY_USAGE_VERIFY, NJS_KEY_FORMAT_RAW | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 1) }, { @@ -208,7 +220,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_UNWRAP_KEY | NJS_KEY_USAGE_GENERATE_KEY, NJS_KEY_FORMAT_RAW | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 1) }, { @@ -220,7 +233,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_UNWRAP_KEY | NJS_KEY_USAGE_GENERATE_KEY, NJS_KEY_FORMAT_RAW | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 1) }, { @@ -232,7 +246,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_UNWRAP_KEY | NJS_KEY_USAGE_GENERATE_KEY, NJS_KEY_FORMAT_RAW | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 1) }, { @@ -244,7 +259,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_FORMAT_PKCS8 | NJS_KEY_FORMAT_SPKI | NJS_KEY_FORMAT_RAW | - NJS_KEY_FORMAT_JWK) + NJS_KEY_FORMAT_JWK, + 0) }, { @@ -254,7 +270,8 @@ static njs_webcrypto_entry_t njs_webcryp NJS_KEY_USAGE_DERIVE_BITS | NJS_KEY_USAGE_GENERATE_KEY | NJS_KEY_USAGE_UNSUPPORTED, - NJS_KEY_FORMAT_UNKNOWN) + NJS_KEY_FORMAT_UNKNOWN, + 0) }, { @@ -262,7 +279,8 @@ static njs_webcrypto_entry_t njs_webcryp njs_webcrypto_algorithm(NJS_ALGORITHM_PBKDF2, NJS_KEY_USAGE_DERIVE_KEY | NJS_KEY_USAGE_DERIVE_BITS, - NJS_KEY_FORMAT_RAW) + NJS_KEY_FORMAT_RAW, + 1) }, { @@ -270,7 +288,8 @@ static njs_webcrypto_entry_t njs_webcryp njs_webcrypto_algorithm(NJS_ALGORITHM_HKDF, NJS_KEY_USAGE_DERIVE_KEY | NJS_KEY_USAGE_DERIVE_BITS, - NJS_KEY_FORMAT_RAW) + NJS_KEY_FORMAT_RAW, + 1) }, { @@ -706,7 +725,7 @@ njs_cipher_pkey(njs_vm_t *vm, njs_str_t EVP_PKEY_cipher_t cipher; EVP_PKEY_cipher_init_t init; - ctx = EVP_PKEY_CTX_new(key->pkey, NULL); + ctx = EVP_PKEY_CTX_new(key->u.a.pkey, NULL); if (njs_slow_path(ctx == NULL)) { njs_webcrypto_error(vm, "EVP_PKEY_CTX_new() failed"); return NJS_ERROR; @@ -786,7 +805,7 @@ njs_cipher_aes_gcm(njs_vm_t *vm, njs_str static const njs_str_t string_ad = njs_str("additionalData"); static const njs_str_t string_tl = njs_str("tagLength"); - switch (key->raw.length) { + switch (key->u.s.raw.length) { case 16: cipher = EVP_aes_128_gcm(); break; @@ -865,7 +884,7 @@ njs_cipher_aes_gcm(njs_vm_t *vm, njs_str goto fail; } - ret = EVP_CipherInit_ex(ctx, NULL, NULL, key->raw.start, iv.start, + ret = EVP_CipherInit_ex(ctx, NULL, NULL, key->u.s.raw.start, iv.start, encrypt); if (njs_slow_path(ret <= 0)) { njs_webcrypto_error(vm, "EVP_%sInit_ex() failed", @@ -1077,7 +1096,7 @@ njs_cipher_aes_ctr(njs_vm_t *vm, njs_str static const njs_str_t string_counter = njs_str("counter"); - switch (key->raw.length) { + switch (key->u.s.raw.length) { case 16: cipher = EVP_aes_128_ctr(); break; @@ -1199,7 +1218,7 @@ njs_cipher_aes_ctr(njs_vm_t *vm, njs_str * during the ciphering. * */ - ret = njs_cipher_aes_ctr128(vm, cipher, key->raw.start, + ret = njs_cipher_aes_ctr128(vm, cipher, key->u.s.raw.start, data->start, data->length, iv.start, dst, &len, encrypt); if (njs_slow_path(ret != NJS_OK)) { @@ -1217,17 +1236,17 @@ njs_cipher_aes_ctr(njs_vm_t *vm, njs_str size1 = BN_get_word(left) * AES_BLOCK_SIZE; - ret = njs_cipher_aes_ctr128(vm, cipher, key->raw.start, data->start, size1, - iv.start, dst, &len, encrypt); + ret = njs_cipher_aes_ctr128(vm, cipher, key->u.s.raw.start, data->start, + size1, iv.start, dst, &len, encrypt); if (njs_slow_path(ret != NJS_OK)) { goto fail; } njs_counter128_reset(iv.start, (u_char *) iv2, length); - ret = njs_cipher_aes_ctr128(vm, cipher, key->raw.start, &data->start[size1], - data->length - size1, iv2, &dst[size1], &len2, - encrypt); + ret = njs_cipher_aes_ctr128(vm, cipher, key->u.s.raw.start, + &data->start[size1], data->length - size1, + iv2, &dst[size1], &len2, encrypt); if (njs_slow_path(ret != NJS_OK)) { goto fail; } @@ -1274,7 +1293,7 @@ njs_cipher_aes_cbc(njs_vm_t *vm, njs_str static const njs_str_t string_iv = njs_str("iv"); - switch (key->raw.length) { + switch (key->u.s.raw.length) { case 16: cipher = EVP_aes_128_cbc(); break; @@ -1321,7 +1340,7 @@ njs_cipher_aes_cbc(njs_vm_t *vm, njs_str return NJS_ERROR; } - ret = EVP_CipherInit_ex(ctx, cipher, NULL, key->raw.start, iv.start, + ret = EVP_CipherInit_ex(ctx, cipher, NULL, key->u.s.raw.start, iv.start, encrypt); if (njs_slow_path(ret <= 0)) { njs_webcrypto_error(vm, "EVP_%SInit_ex() failed", @@ -1527,7 +1546,7 @@ njs_ext_derive(njs_vm_t *vm, njs_value_t md = njs_algorithm_hash_digest(hash); - ret = PKCS5_PBKDF2_HMAC((char *) key->raw.start, key->raw.length, + ret = PKCS5_PBKDF2_HMAC((char *) key->u.s.raw.start, key->u.s.raw.length, salt.start, salt.length, iterations, md, length, k); if (njs_slow_path(ret <= 0)) { @@ -1591,7 +1610,8 @@ njs_ext_derive(njs_vm_t *vm, njs_value_t goto free; } - ret = EVP_PKEY_CTX_set1_hkdf_key(pctx, key->raw.start, key->raw.length); + ret = EVP_PKEY_CTX_set1_hkdf_key(pctx, key->u.s.raw.start, + key->u.s.raw.length); if (njs_slow_path(ret <= 0)) { njs_webcrypto_error(vm, "EVP_PKEY_CTX_set1_hkdf_key() failed"); goto free; @@ -1641,8 +1661,8 @@ free: } } - dkey->raw.start = k; - dkey->raw.length = length; + dkey->u.s.raw.start = k; + dkey->u.s.raw.length = length; ret = njs_vm_external_create(vm, njs_value_arg(&lvalue), njs_webcrypto_crypto_key_proto_id, @@ -1762,7 +1782,7 @@ njs_export_jwk_rsa(njs_vm_t *vm, njs_web *qi_bn; njs_opaque_value_t nvalue, evalue, alg, rsa_s; - rsa = njs_pkey_get_rsa_key(key->pkey); + rsa = njs_pkey_get_rsa_key(key->u.a.pkey); njs_rsa_get0_key(rsa, &n_bn, &e_bn, &d_bn); @@ -1798,7 +1818,7 @@ njs_export_jwk_rsa(njs_vm_t *vm, njs_web return NJS_ERROR; } - if (key->privat) { + if (key->u.a.privat) { njs_rsa_get0_factors(rsa, &p_bn, &q_bn); njs_rsa_get0_ctr_params(rsa, &dp_bn, &dq_bn, &qi_bn); @@ -1859,7 +1879,7 @@ njs_export_jwk_ec(njs_vm_t *vm, njs_webc y_bn = NULL; d_bn = NULL; - ec = njs_pkey_get_ec_key(key->pkey); + ec = njs_pkey_get_ec_key(key->u.a.pkey); pub = EC_KEY_get0_public_key(ec); group = EC_KEY_get0_group(ec); @@ -1940,7 +1960,7 @@ njs_export_jwk_ec(njs_vm_t *vm, njs_webc return NJS_ERROR; } - if (key->privat) { + if (key->u.a.privat) { d_bn = EC_KEY_get0_private_key(ec); ret = njs_export_base64url_bignum(vm, &dvalue, d_bn, group_bytes); @@ -1980,15 +2000,15 @@ njs_export_raw_ec(njs_vm_t *vm, njs_webc const EC_POINT *point; point_conversion_form_t form; - njs_assert(key->pkey != NULL); - - if (key->privat) { + njs_assert(key->u.a.pkey != NULL); + + if (key->u.a.privat) { njs_vm_error(vm, "private key of \"%V\" cannot be exported " "in \"raw\" format", njs_algorithm_string(key->alg)); return NJS_ERROR; } - ec = njs_pkey_get_ec_key(key->pkey); + ec = njs_pkey_get_ec_key(key->u.a.pkey); group = EC_KEY_get0_group(ec); point = EC_KEY_get0_public_key(ec); @@ -2022,9 +2042,9 @@ njs_export_jwk_asymmetric(njs_vm_t *vm, njs_int_t ret; njs_opaque_value_t ops, extractable; - njs_assert(key->pkey != NULL); - - switch (EVP_PKEY_id(key->pkey)) { + njs_assert(key->u.a.pkey != NULL); + + switch (EVP_PKEY_id(key->u.a.pkey)) { case EVP_PKEY_RSA: #if (OPENSSL_VERSION_NUMBER >= 0x10101001L) case EVP_PKEY_RSA_PSS: @@ -2073,9 +2093,9 @@ njs_export_jwk_oct(njs_vm_t *vm, njs_web njs_opaque_value_t k, alg, ops, extractable, oct_s; njs_webcrypto_alg_t type; - njs_assert(key->raw.start != NULL); - - ret = njs_string_base64url(vm, njs_value_arg(&k), &key->raw); + njs_assert(key->u.s.raw.start != NULL); + + ret = njs_string_base64url(vm, njs_value_arg(&k), &key->u.s.raw); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -2088,12 +2108,12 @@ njs_export_jwk_oct(njs_vm_t *vm, njs_web nm->length); } else { - switch (key->raw.length) { + switch (key->u.s.raw.length) { case 16: case 24: case 32: nm = &njs_webcrypto_alg_aes_name - [type - NJS_ALGORITHM_AES_GCM][(key->raw.length - 16) / 8]; + [type - NJS_ALGORITHM_AES_GCM][(key->u.s.raw.length - 16) / 8]; (void) njs_vm_value_string_set(vm, njs_value_arg(&alg), nm->start, nm->length); break; @@ -2217,7 +2237,7 @@ njs_ext_export_key(njs_vm_t *vm, njs_val break; case NJS_KEY_FORMAT_PKCS8: - if (!key->privat) { + if (!key->u.a.privat) { njs_vm_error(vm, "public key of \"%V\" cannot be exported " "as PKCS8", njs_algorithm_string(key->alg)); goto fail; @@ -2229,9 +2249,9 @@ njs_ext_export_key(njs_vm_t *vm, njs_val goto fail; } - njs_assert(key->pkey != NULL); - - pkcs8 = EVP_PKEY2PKCS8(key->pkey); + njs_assert(key->u.a.pkey != NULL); + + pkcs8 = EVP_PKEY2PKCS8(key->u.a.pkey); if (njs_slow_path(pkcs8 == NULL)) { BIO_free(bio); njs_webcrypto_error(vm, "EVP_PKEY2PKCS8() failed"); @@ -2260,7 +2280,7 @@ njs_ext_export_key(njs_vm_t *vm, njs_val break; case NJS_KEY_FORMAT_SPKI: - if (key->privat) { + if (key->u.a.privat) { njs_vm_error(vm, "private key of \"%V\" cannot be exported " "as SPKI", njs_algorithm_string(key->alg)); goto fail; @@ -2272,9 +2292,9 @@ njs_ext_export_key(njs_vm_t *vm, njs_val goto fail; } - njs_assert(key->pkey != NULL); - - if (!i2d_PUBKEY_bio(bio, key->pkey)) { + njs_assert(key->u.a.pkey != NULL); + + if (!i2d_PUBKEY_bio(bio, key->u.a.pkey)) { BIO_free(bio); njs_webcrypto_error(vm, "i2d_PUBKEY_bio() failed"); goto fail; @@ -2305,7 +2325,8 @@ njs_ext_export_key(njs_vm_t *vm, njs_val } ret = njs_vm_value_array_buffer_set(vm, njs_value_arg(&value), - key->raw.start, key->raw.length); + key->u.s.raw.start, + key->u.s.raw.length); if (njs_slow_path(ret != NJS_OK)) { goto fail; } @@ -2401,7 +2422,7 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v goto fail; } - if (EVP_PKEY_keygen(ctx, &key->pkey) <= 0) { + if (EVP_PKEY_keygen(ctx, &key->u.a.pkey) <= 0) { njs_webcrypto_error(vm, "EVP_PKEY_keygen() failed"); goto fail; } @@ -2409,7 +2430,7 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v EVP_PKEY_CTX_free(ctx); ctx = NULL; - key->privat = 1; + key->u.a.privat = 1; key->usage = (alg->type == NJS_ALGORITHM_RSA_OAEP) ? NJS_KEY_USAGE_DECRYPT : NJS_KEY_USAGE_SIGN; @@ -2419,12 +2440,12 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v goto fail; } - if (njs_pkey_up_ref(key->pkey) <= 0) { + if (njs_pkey_up_ref(key->u.a.pkey) <= 0) { njs_webcrypto_error(vm, "njs_pkey_up_ref() failed"); goto fail; } - keypub->pkey = key->pkey; + keypub->u.a.pkey = key->u.a.pkey; keypub->hash = key->hash; keypub->usage = (alg->type == NJS_ALGORITHM_RSA_OAEP) ? NJS_KEY_USAGE_ENCRYPT @@ -2485,7 +2506,7 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v goto fail; } - if (EVP_PKEY_keygen(ctx, &key->pkey) <= 0) { + if (EVP_PKEY_keygen(ctx, &key->u.a.pkey) <= 0) { njs_webcrypto_error(vm, "EVP_PKEY_keygen() failed"); goto fail; } @@ -2493,7 +2514,7 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v EVP_PKEY_CTX_free(ctx); ctx = NULL; - key->privat = 1; + key->u.a.privat = 1; key->usage = NJS_KEY_USAGE_SIGN; keypub = njs_webcrypto_key_alloc(vm, alg, usage, extractable); @@ -2501,13 +2522,13 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v goto fail; } - if (njs_pkey_up_ref(key->pkey) <= 0) { + if (njs_pkey_up_ref(key->u.a.pkey) <= 0) { njs_webcrypto_error(vm, "njs_pkey_up_ref() failed"); goto fail; } - keypub->pkey = key->pkey; - keypub->curve = key->curve; + keypub->u.a.pkey = key->u.a.pkey; + keypub->u.a.curve = key->u.a.curve; keypub->usage = NJS_KEY_USAGE_VERIFY; ret = njs_vm_external_create(vm, njs_value_arg(&priv), @@ -2552,16 +2573,17 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v goto fail; } - key->raw.length = EVP_MD_size(njs_algorithm_hash_digest(key->hash)); + key->u.s.raw.length = + EVP_MD_size(njs_algorithm_hash_digest(key->hash)); } else { val = njs_vm_object_prop(vm, aobject, &string_length, &value); if (val != NULL) { - key->raw.length = njs_value_number(val) / 8; - - if (key->raw.length != 16 - && key->raw.length != 24 - && key->raw.length != 32) + key->u.s.raw.length = njs_value_number(val) / 8; + + if (key->u.s.raw.length != 16 + && key->u.s.raw.length != 24 + && key->u.s.raw.length != 32) { njs_vm_error(vm, "length for \"%V\" key should be one of " "128, 192, 256", njs_algorithm_string(alg)); @@ -2570,13 +2592,14 @@ njs_ext_generate_key(njs_vm_t *vm, njs_v } } - key->raw.start = njs_mp_alloc(njs_vm_memory_pool(vm), key->raw.length); - if (njs_slow_path(key->raw.start == NULL)) { + key->u.s.raw.start = njs_mp_alloc(njs_vm_memory_pool(vm), + key->u.s.raw.length); + if (njs_slow_path(key->u.s.raw.start == NULL)) { njs_vm_memory_error(vm); goto fail; } - if (RAND_bytes(key->raw.start, key->raw.length) <= 0) { + if (RAND_bytes(key->u.s.raw.start, key->u.s.raw.length) <= 0) { njs_webcrypto_error(vm, "RAND_bytes() failed"); goto fail; } @@ -2672,7 +2695,7 @@ fail0: return NULL; } - key->privat = njs_value_is_string(njs_value_arg(&d)); + key->u.a.privat = njs_value_is_string(njs_value_arg(&d)); val = njs_vm_object_prop(vm, jwk, &key_ops, &value); if (val != NULL && !njs_value_is_undefined(val)){ @@ -2739,7 +2762,7 @@ fail0: goto fail; } - if (!key->privat) { + if (!key->u.a.privat) { goto done; } @@ -2869,7 +2892,7 @@ njs_import_raw_ec(njs_vm_t *vm, njs_str_ EC_POINT *pub; const EC_GROUP *group; - ec = EC_KEY_new_by_curve_name(key->curve); + ec = EC_KEY_new_by_curve_name(key->u.a.curve); if (njs_slow_path(ec == NULL)) { njs_webcrypto_error(vm, "EC_KEY_new_by_curve_name() failed"); return NULL; @@ -2965,7 +2988,7 @@ fail0: return NULL; } - key->privat = njs_value_is_string(njs_value_arg(&d)); + key->u.a.privat = njs_value_is_string(njs_value_arg(&d)); val = njs_vm_object_prop(vm, jwk, &key_ops, &value); if (val != NULL && !njs_value_is_undefined(val)) { @@ -3005,12 +3028,12 @@ fail0: } } - if (curve != key->curve) { + if (curve != key->u.a.curve) { njs_vm_error(vm, "JWK EC curve mismatch"); return NULL; } - ec = EC_KEY_new_by_curve_name(key->curve); + ec = EC_KEY_new_by_curve_name(key->u.a.curve); if (njs_slow_path(ec == NULL)) { njs_webcrypto_error(vm, "EC_KEY_new_by_curve_name() failed"); return NULL; @@ -3026,7 +3049,7 @@ fail0: goto fail; } - if (key->privat) { + if (key->u.a.privat) { d_bn = njs_import_base64url_bignum(vm, &d); if (njs_slow_path(d_bn == NULL)) { goto fail; @@ -3055,7 +3078,7 @@ fail0: goto fail_pkey; } - if (key->privat) { + if (key->u.a.privat) { if (!EC_KEY_set_private_key(ec, d_bn)) { njs_webcrypto_error(vm, "EC_KEY_set_private_key() failed"); goto fail_pkey; @@ -3123,15 +3146,16 @@ njs_import_jwk_oct(njs_vm_t *vm, njs_val njs_value_string_get(val, &b64); - (void) njs_decode_base64url_length(&b64, &key->raw.length); - - key->raw.start = njs_mp_alloc(njs_vm_memory_pool(vm), key->raw.length); - if (njs_slow_path(key->raw.start == NULL)) { + (void) njs_decode_base64url_length(&b64, &key->u.s.raw.length); + + key->u.s.raw.start = njs_mp_alloc(njs_vm_memory_pool(vm), + key->u.s.raw.length); + if (njs_slow_path(key->u.s.raw.start == NULL)) { njs_vm_memory_error(vm); return NJS_ERROR; } - njs_decode_base64url(&key->raw, &b64); + njs_decode_base64url(&key->u.s.raw, &b64); size = 16; @@ -3166,7 +3190,7 @@ njs_import_jwk_oct(njs_vm_t *vm, njs_val done: if (key->alg->type != NJS_ALGORITHM_HMAC) { - if (key->raw.length != size) { + if (key->u.s.raw.length != size) { njs_vm_error(vm, "key size and \"alg\" value \"%V\" mismatch", &alg); return NJS_ERROR; @@ -3278,11 +3302,11 @@ njs_ext_import_key(njs_vm_t *vm, njs_val /* * set by njs_webcrypto_key_alloc(): * - * key->pkey = NULL; - * key->raw.length = 0; - * key->raw.start = NULL; - * key->curve = 0; - * key->privat = 0; + * key->u.a.pkey = NULL; + * key->u.s.raw.length = 0; + * key->u.s.raw.start = NULL; + * key->u.a.curve = 0; + * key->u.a.privat = 0; * key->hash = NJS_HASH_UNSET; */ @@ -3312,7 +3336,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_val PKCS8_PRIV_KEY_INFO_free(pkcs8); BIO_free(bio); - key->privat = 1; + key->u.a.privat = 1; break; @@ -3350,7 +3374,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_val } } else if (njs_strstr_eq(&kty, &njs_str_value("EC"))) { - ret = njs_algorithm_curve(vm, options, &key->curve); + ret = njs_algorithm_curve(vm, options, &key->u.a.curve); if (njs_slow_path(ret == NJS_ERROR)) { goto fail; } @@ -3410,7 +3434,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_val goto fail; } - if (key->privat) { + if (key->u.a.privat) { mask = (alg->type == NJS_ALGORITHM_RSA_OAEP) ? ~(NJS_KEY_USAGE_DECRYPT | NJS_KEY_USAGE_UNWRAP_KEY) : ~(NJS_KEY_USAGE_SIGN); @@ -3427,13 +3451,13 @@ njs_ext_import_key(njs_vm_t *vm, njs_val } key->hash = hash; - key->pkey = pkey; + key->u.a.pkey = pkey; break; case NJS_ALGORITHM_ECDSA: case NJS_ALGORITHM_ECDH: - ret = njs_algorithm_curve(vm, options, &key->curve); + ret = njs_algorithm_curve(vm, options, &key->u.a.curve); if (njs_slow_path(ret == NJS_ERROR)) { goto fail; } @@ -3473,12 +3497,12 @@ njs_ext_import_key(njs_vm_t *vm, njs_val #endif - if (njs_slow_path(key->curve != nid)) { + if (njs_slow_path(key->u.a.curve != nid)) { njs_webcrypto_error(vm, "name curve mismatch"); goto fail; } - mask = key->privat ? ~NJS_KEY_USAGE_SIGN : ~NJS_KEY_USAGE_VERIFY; + mask = key->u.a.privat ? ~NJS_KEY_USAGE_SIGN : ~NJS_KEY_USAGE_VERIFY; if (key->usage & mask) { njs_vm_error(vm, "key usage mismatch for \"%V\" key", @@ -3486,7 +3510,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_val goto fail; } - key->pkey = pkey; + key->u.a.pkey = pkey; break; @@ -3497,7 +3521,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_val goto fail; } - key->raw = key_data; + key->u.s.raw = key_data; } else { /* NJS_KEY_FORMAT_JWK. */ @@ -3530,7 +3554,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_val goto fail; } - key->raw = key_data; + key->u.s.raw = key_data; } break; @@ -3538,7 +3562,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_val case NJS_ALGORITHM_PBKDF2: case NJS_ALGORITHM_HKDF: default: - key->raw = key_data; + key->u.s.raw = key_data; break; } @@ -3885,8 +3909,8 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * outlen = m_len; - p = HMAC(md, key->raw.start, key->raw.length, data.start, data.length, - dst, &m_len); + p = HMAC(md, key->u.s.raw.start, key->u.s.raw.length, data.start, + data.length, dst, &m_len); if (njs_slow_path(p == NULL || m_len != outlen)) { njs_webcrypto_error(vm, "HMAC() failed"); @@ -3927,14 +3951,14 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * goto fail; } - olen = EVP_PKEY_size(key->pkey); + olen = EVP_PKEY_size(key->u.a.pkey); dst = njs_mp_zalloc(njs_vm_memory_pool(vm), olen); if (njs_slow_path(dst == NULL)) { njs_vm_memory_error(vm); goto fail; } - pctx = EVP_PKEY_CTX_new(key->pkey, NULL); + pctx = EVP_PKEY_CTX_new(key->u.a.pkey, NULL); if (njs_slow_path(pctx == NULL)) { njs_webcrypto_error(vm, "EVP_PKEY_CTX_new() failed"); goto fail; @@ -3955,7 +3979,7 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * } } - ret = njs_set_rsa_padding(vm, options, key->pkey, pctx, alg->type); + ret = njs_set_rsa_padding(vm, options, key->u.a.pkey, pctx, alg->type); if (njs_slow_path(ret != NJS_OK)) { goto fail; } @@ -3975,7 +3999,7 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * } if (alg->type == NJS_ALGORITHM_ECDSA) { - ret = njs_convert_der_to_p1363(vm, key->pkey, dst, outlen, + ret = njs_convert_der_to_p1363(vm, key->u.a.pkey, dst, outlen, &dst, &outlen); if (njs_slow_path(ret != NJS_OK)) { goto fail; @@ -3984,7 +4008,7 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t * } else { if (alg->type == NJS_ALGORITHM_ECDSA) { - ret = njs_convert_p1363_to_der(vm, key->pkey, sig.start, + ret = njs_convert_p1363_to_der(vm, key->u.a.pkey, sig.start, sig.length, &sig.start, &sig.length); if (njs_slow_path(ret != NJS_OK)) { @@ -4087,8 +4111,8 @@ njs_webcrypto_cleanup_pkey(void *data) { njs_webcrypto_key_t *key = data; - if (key->pkey != NULL) { - EVP_PKEY_free(key->pkey); + if (!key->alg->raw) { + EVP_PKEY_free(key->u.a.pkey); } } _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel