From eb24bb6584651f9baced3b66197a1e489b58bd01 Mon Sep 17 00:00:00 2001 From: Mike Aizatsky Date: Wed, 17 Jul 2024 11:16:55 -0700 Subject: [PATCH] eliminating VLAs (#2408) --- src/workerd/api/crypto/ec.c++ | 83 +++++++++++++++++++---------------- src/workerd/io/worker.c++ | 6 +-- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/workerd/api/crypto/ec.c++ b/src/workerd/api/crypto/ec.c++ index b424fe8de1f..ffeaaaf2d29 100644 --- a/src/workerd/api/crypto/ec.c++ +++ b/src/workerd/api/crypto/ec.c++ @@ -995,53 +995,62 @@ private: }; -kj::OneOf, CryptoKeyPair> EdDsaKey::generateKey( - kj::StringPtr normalizedName, int nid, CryptoKeyUsageSet privateKeyUsages, - CryptoKeyUsageSet publicKeyUsages, bool extractablePrivateKey) { - auto [curveName, keypair, keylen] = [nid, normalizedName] { - switch (nid) { - // BoringSSL doesn't support ED448/X448. - case NID_ED25519: - return std::make_tuple("Ed25519"_kj, ED25519_keypair, ED25519_PUBLIC_KEY_LEN); - case NID_X25519: - return std::make_tuple("X25519"_kj, X25519_keypair, X25519_PUBLIC_VALUE_LEN); - } - - KJ_FAIL_REQUIRE("ED ", normalizedName, " unimplemented", nid); - }(); - - uint8_t rawPublicKey[keylen]; - uint8_t rawPrivateKey[keylen * 2]; - keypair(rawPublicKey, rawPrivateKey); +template +CryptoKeyPair generateKeyImpl(kj::StringPtr normalizedName, int nid, + CryptoKeyUsageSet privateKeyUsages, CryptoKeyUsageSet publicKeyUsages, + bool extractablePrivateKey, kj::StringPtr curveName) { + uint8_t rawPublicKey[keySize]; + uint8_t rawPrivateKey[keySize * 2]; + KeypairInit(rawPublicKey, rawPrivateKey); // The private key technically also contains the public key. Why does the keypair function bother // writing out the public key to a separate buffer? - auto privateEvpPKey = OSSLCALL_OWN(EVP_PKEY, EVP_PKEY_new_raw_private_key(nid, nullptr, - rawPrivateKey, keylen), InternalDOMOperationError, "Error constructing ", curveName, - " private key", internalDescribeOpensslErrors()); + auto privateEvpPKey = + OSSLCALL_OWN(EVP_PKEY, EVP_PKEY_new_raw_private_key(nid, nullptr, rawPrivateKey, keySize), + InternalDOMOperationError, "Error constructing ", curveName, " private key", + internalDescribeOpensslErrors()); - auto publicEvpPKey = OSSLCALL_OWN(EVP_PKEY, EVP_PKEY_new_raw_public_key(nid, nullptr, - rawPublicKey, keylen), InternalDOMOperationError, "Internal error construct ", curveName, - "public key", internalDescribeOpensslErrors()); + auto publicEvpPKey = + OSSLCALL_OWN(EVP_PKEY, EVP_PKEY_new_raw_public_key(nid, nullptr, rawPublicKey, keySize), + InternalDOMOperationError, "Internal error construct ", curveName, "public key", + internalDescribeOpensslErrors()); - AsymmetricKeyData privateKeyData { - .evpPkey = kj::mv(privateEvpPKey), - .keyType = KeyType::PRIVATE, - .usages = privateKeyUsages, + AsymmetricKeyData privateKeyData{ + .evpPkey = kj::mv(privateEvpPKey), + .keyType = KeyType::PRIVATE, + .usages = privateKeyUsages, }; - AsymmetricKeyData publicKeyData { - .evpPkey = kj::mv(publicEvpPKey), - .keyType = KeyType::PUBLIC, - .usages = publicKeyUsages, + AsymmetricKeyData publicKeyData{ + .evpPkey = kj::mv(publicEvpPKey), + .keyType = KeyType::PUBLIC, + .usages = publicKeyUsages, }; - auto privateKey = jsg::alloc(kj::heap(kj::mv(privateKeyData), - normalizedName, extractablePrivateKey)); - auto publicKey = jsg::alloc(kj::heap(kj::mv(publicKeyData), - normalizedName, true)); + auto privateKey = jsg::alloc( + kj::heap(kj::mv(privateKeyData), normalizedName, extractablePrivateKey)); + auto publicKey = + jsg::alloc(kj::heap(kj::mv(publicKeyData), normalizedName, true)); + + return CryptoKeyPair{.publicKey = kj::mv(publicKey), .privateKey = kj::mv(privateKey)}; +} + +kj::OneOf, CryptoKeyPair> EdDsaKey::generateKey( + kj::StringPtr normalizedName, int nid, CryptoKeyUsageSet privateKeyUsages, + CryptoKeyUsageSet publicKeyUsages, bool extractablePrivateKey) { + switch (nid) { + // BoringSSL doesn't support ED448/X448. + case NID_ED25519: + return generateKeyImpl( + normalizedName, nid, privateKeyUsages, publicKeyUsages, extractablePrivateKey, + "Ed25519"_kj); + case NID_X25519: + return generateKeyImpl( + normalizedName, nid, privateKeyUsages, publicKeyUsages, extractablePrivateKey, + "X25519"_kj); + } - return CryptoKeyPair {.publicKey = kj::mv(publicKey), .privateKey = kj::mv(privateKey)}; + KJ_FAIL_REQUIRE("ED ", normalizedName, " unimplemented", nid); } } // namespace diff --git a/src/workerd/io/worker.c++ b/src/workerd/io/worker.c++ index a830acce5c1..dde4c2b764c 100644 --- a/src/workerd/io/worker.c++ +++ b/src/workerd/io/worker.c++ @@ -1614,9 +1614,9 @@ void Worker::handleLog(jsg::Lock& js, ConsoleMode consoleMode, LogLevel level, // Call original V8 implementation so messages sent to connected inspector if any auto context = js.v8Context(); int length = info.Length(); - v8::Local args[length + 1]; // + 1 used for `colors` later + KJ_STACK_ARRAY(v8::Local, args, length + 1, 64, 64); // + 1 used for `colors` later for (auto i: kj::zeroTo(length)) args[i] = info[i]; - jsg::check(original.Get(js.v8Isolate)->Call(context, info.This(), length, args)); + jsg::check(original.Get(js.v8Isolate)->Call(context, info.This(), length, args.begin())); // The TryCatch is initialised here to catch cases where the v8 isolate's execution is // terminating, usually as a result of an infinite loop. We need to perform the initialisation @@ -1735,7 +1735,7 @@ void Worker::handleLog(jsg::Lock& js, ConsoleMode consoleMode, LogLevel level, auto recv = js.v8Undefined(); args[length] = v8::Boolean::New(js.v8Isolate, colors); - auto formatted = js.toString(jsg::check(formatLog->Call(context, recv, length + 1, args))); + auto formatted = js.toString(jsg::check(formatLog->Call(context, recv, length + 1, args.begin()))); fprintf(fd, "%s\n", formatted.cStr()); fflush(fd); }