Skip to content

Commit

Permalink
eliminating VLAs (cloudflare#2408)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikea authored and ns476 committed Aug 2, 2024
1 parent 7eb345d commit eb24bb6
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 40 deletions.
83 changes: 46 additions & 37 deletions src/workerd/api/crypto/ec.c++
Original file line number Diff line number Diff line change
Expand Up @@ -995,53 +995,62 @@ private:

};

kj::OneOf<jsg::Ref<CryptoKey>, 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 <size_t keySize, void (*KeypairInit)(uint8_t[keySize], uint8_t[keySize*2])>
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<CryptoKey>(kj::heap<EdDsaKey>(kj::mv(privateKeyData),
normalizedName, extractablePrivateKey));
auto publicKey = jsg::alloc<CryptoKey>(kj::heap<EdDsaKey>(kj::mv(publicKeyData),
normalizedName, true));
auto privateKey = jsg::alloc<CryptoKey>(
kj::heap<EdDsaKey>(kj::mv(privateKeyData), normalizedName, extractablePrivateKey));
auto publicKey =
jsg::alloc<CryptoKey>(kj::heap<EdDsaKey>(kj::mv(publicKeyData), normalizedName, true));

return CryptoKeyPair{.publicKey = kj::mv(publicKey), .privateKey = kj::mv(privateKey)};
}

kj::OneOf<jsg::Ref<CryptoKey>, 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<ED25519_PUBLIC_KEY_LEN, ED25519_keypair>(
normalizedName, nid, privateKeyUsages, publicKeyUsages, extractablePrivateKey,
"Ed25519"_kj);
case NID_X25519:
return generateKeyImpl<X25519_PUBLIC_VALUE_LEN, X25519_keypair>(
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
Expand Down
6 changes: 3 additions & 3 deletions src/workerd/io/worker.c++
Original file line number Diff line number Diff line change
Expand Up @@ -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<v8::Value> args[length + 1]; // + 1 used for `colors` later
KJ_STACK_ARRAY(v8::Local<v8::Value>, 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
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit eb24bb6

Please sign in to comment.