Skip to content

Commit

Permalink
Update Node.js crypto dh to use BufferSource
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell committed Nov 13, 2024
1 parent 158d137 commit c51e9f3
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 40 deletions.
32 changes: 16 additions & 16 deletions src/workerd/api/crypto/dh.c++
Original file line number Diff line number Diff line change
Expand Up @@ -217,31 +217,31 @@ void DiffieHellman::setPublicKey(kj::ArrayPtr<kj::byte> key) {
OSSLCALL(DH_set0_key(dh, toBignumUnowned(key), nullptr));
}

kj::Array<kj::byte> DiffieHellman::getPublicKey() {
jsg::BufferSource DiffieHellman::getPublicKey(jsg::Lock& js) {
const BIGNUM* pub_key = DH_get0_pub_key(dh);
return JSG_REQUIRE_NONNULL(
bignumToArrayPadded(*pub_key), Error, "Error while retrieving DiffieHellman public key");
bignumToArrayPadded(js, *pub_key), Error, "Error while retrieving DiffieHellman public key");
}

kj::Array<kj::byte> DiffieHellman::getPrivateKey() {
jsg::BufferSource DiffieHellman::getPrivateKey(jsg::Lock& js) {
const BIGNUM* priv_key = DH_get0_priv_key(dh);
return JSG_REQUIRE_NONNULL(
bignumToArrayPadded(*priv_key), Error, "Error while retrieving DiffieHellman private key");
return JSG_REQUIRE_NONNULL(bignumToArrayPadded(js, *priv_key), Error,
"Error while retrieving DiffieHellman private key");
}

kj::Array<kj::byte> DiffieHellman::getGenerator() {
jsg::BufferSource DiffieHellman::getGenerator(jsg::Lock& js) {
const BIGNUM* g = DH_get0_g(dh);
return JSG_REQUIRE_NONNULL(
bignumToArrayPadded(*g), Error, "Error while retrieving DiffieHellman generator");
bignumToArrayPadded(js, *g), Error, "Error while retrieving DiffieHellman generator");
}

kj::Array<kj::byte> DiffieHellman::getPrime() {
jsg::BufferSource DiffieHellman::getPrime(jsg::Lock& js) {
const BIGNUM* p = DH_get0_p(dh);
return JSG_REQUIRE_NONNULL(
bignumToArrayPadded(*p), Error, "Error while retrieving DiffieHellman prime");
bignumToArrayPadded(js, *p), Error, "Error while retrieving DiffieHellman prime");
}

kj::Array<kj::byte> DiffieHellman::computeSecret(kj::ArrayPtr<kj::byte> key) {
jsg::BufferSource DiffieHellman::computeSecret(jsg::Lock& js, kj::ArrayPtr<kj::byte> key) {
JSG_REQUIRE(key.size() <= INT32_MAX, RangeError,
"DiffieHellman computeSecret() failed: key is too large");
JSG_REQUIRE(key.size() > 0, Error, "DiffieHellman computeSecret() failed: invalid key");
Expand All @@ -251,9 +251,9 @@ kj::Array<kj::byte> DiffieHellman::computeSecret(kj::ArrayPtr<kj::byte> key) {
toBignum(key), Error, "Error getting key while computing DiffieHellman secret");

size_t prime_size = DH_size(dh);
auto prime_enc = kj::heapArray<kj::byte>(prime_size);
auto prime_enc = jsg::BackingStore::alloc<v8::ArrayBuffer>(js, prime_size);

int size = DH_compute_key(prime_enc.begin(), k.get(), dh);
int size = DH_compute_key(prime_enc.asArrayPtr().begin(), k.get(), dh);
if (size == -1) {
// various error checking
int checkResult;
Expand All @@ -269,16 +269,16 @@ kj::Array<kj::byte> DiffieHellman::computeSecret(kj::ArrayPtr<kj::byte> key) {
}

KJ_ASSERT(size >= 0);
zeroPadDiffieHellmanSecret(size, prime_enc.begin(), prime_size);
return prime_enc;
zeroPadDiffieHellmanSecret(size, prime_enc.asArrayPtr().begin(), prime_size);
return jsg::BufferSource(js, kj::mv(prime_enc));
}

kj::Array<kj::byte> DiffieHellman::generateKeys() {
jsg::BufferSource DiffieHellman::generateKeys(jsg::Lock& js) {
ClearErrorOnReturn clear_error_on_return;
OSSLCALL(DH_generate_key(dh));
const BIGNUM* pub_key = DH_get0_pub_key(dh);
return JSG_REQUIRE_NONNULL(
bignumToArrayPadded(*pub_key), Error, "Error while generating DiffieHellman keys");
bignumToArrayPadded(js, *pub_key), Error, "Error while generating DiffieHellman keys");
}

} // namespace workerd::api
14 changes: 8 additions & 6 deletions src/workerd/api/crypto/dh.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "impl.h"

#include <workerd/jsg/jsg.h>

#include <openssl/dh.h>

#include <kj/common.h>
Expand All @@ -20,12 +22,12 @@ class DiffieHellman final {
void setPrivateKey(kj::ArrayPtr<kj::byte> key);
void setPublicKey(kj::ArrayPtr<kj::byte> key);

kj::Array<kj::byte> getPublicKey() KJ_WARN_UNUSED_RESULT;
kj::Array<kj::byte> getPrivateKey() KJ_WARN_UNUSED_RESULT;
kj::Array<kj::byte> getGenerator() KJ_WARN_UNUSED_RESULT;
kj::Array<kj::byte> getPrime() KJ_WARN_UNUSED_RESULT;
kj::Array<kj::byte> computeSecret(kj::ArrayPtr<kj::byte> key) KJ_WARN_UNUSED_RESULT;
kj::Array<kj::byte> generateKeys() KJ_WARN_UNUSED_RESULT;
jsg::BufferSource getPublicKey(jsg::Lock& js) KJ_WARN_UNUSED_RESULT;
jsg::BufferSource getPrivateKey(jsg::Lock& js) KJ_WARN_UNUSED_RESULT;
jsg::BufferSource getGenerator(jsg::Lock& js) KJ_WARN_UNUSED_RESULT;
jsg::BufferSource getPrime(jsg::Lock& js) KJ_WARN_UNUSED_RESULT;
jsg::BufferSource computeSecret(jsg::Lock& js, kj::ArrayPtr<kj::byte> key) KJ_WARN_UNUSED_RESULT;
jsg::BufferSource generateKeys(jsg::Lock& js) KJ_WARN_UNUSED_RESULT;

kj::Maybe<int> check() KJ_WARN_UNUSED_RESULT;

Expand Down
17 changes: 17 additions & 0 deletions src/workerd/api/crypto/impl.c++
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,23 @@ kj::Maybe<kj::Array<kj::byte>> bignumToArrayPadded(const BIGNUM& n, size_t padde
return kj::mv(result);
}

kj::Maybe<jsg::BufferSource> bignumToArrayPadded(jsg::Lock& js, const BIGNUM& n) {
auto result = jsg::BackingStore::alloc<v8::ArrayBuffer>(js, BN_num_bytes(&n));
if (BN_bn2binpad(&n, result.asArrayPtr().begin(), result.size()) != result.size()) {
return kj::none;
}
return jsg::BufferSource(js, kj::mv(result));
}

kj::Maybe<jsg::BufferSource> bignumToArrayPadded(
jsg::Lock& js, const BIGNUM& n, size_t paddedLength) {
auto result = jsg::BackingStore::alloc<v8::ArrayBuffer>(js, paddedLength);
if (BN_bn2bin_padded(result.asArrayPtr().begin(), paddedLength, &n) == 0) {
return kj::none;
}
return jsg::BufferSource(js, kj::mv(result));
}

kj::Own<BIGNUM> newBignum() {
return kj::Own<BIGNUM>(BN_new(), workerd::api::SslDisposer<BIGNUM, &BIGNUM_free>::INSTANCE);
}
Expand Down
3 changes: 3 additions & 0 deletions src/workerd/api/crypto/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ BIGNUM* toBignumUnowned(kj::ArrayPtr<const kj::byte> data);
kj::Maybe<kj::Array<kj::byte>> bignumToArray(const BIGNUM& bignum);
kj::Maybe<kj::Array<kj::byte>> bignumToArrayPadded(const BIGNUM& bignum);
kj::Maybe<kj::Array<kj::byte>> bignumToArrayPadded(const BIGNUM& bignum, size_t paddedLength);
kj::Maybe<jsg::BufferSource> bignumToArrayPadded(jsg::Lock& js, const BIGNUM& bignum);
kj::Maybe<jsg::BufferSource> bignumToArrayPadded(
jsg::Lock& js, const BIGNUM& bignum, size_t paddedLength);
kj::Own<BIGNUM> newBignum();

#define OSSL_BIO_MEM() \
Expand Down
25 changes: 13 additions & 12 deletions src/workerd/api/node/crypto.c++
Original file line number Diff line number Diff line change
Expand Up @@ -216,28 +216,29 @@ void CryptoImpl::DiffieHellmanHandle::setPublicKey(kj::Array<kj::byte> key) {
dh.setPublicKey(key);
}

kj::Array<kj::byte> CryptoImpl::DiffieHellmanHandle::getPublicKey() {
return dh.getPublicKey();
jsg::BufferSource CryptoImpl::DiffieHellmanHandle::getPublicKey(jsg::Lock& js) {
return dh.getPublicKey(js);
}

kj::Array<kj::byte> CryptoImpl::DiffieHellmanHandle::getPrivateKey() {
return dh.getPrivateKey();
jsg::BufferSource CryptoImpl::DiffieHellmanHandle::getPrivateKey(jsg::Lock& js) {
return dh.getPrivateKey(js);
}

kj::Array<kj::byte> CryptoImpl::DiffieHellmanHandle::getGenerator() {
return dh.getGenerator();
jsg::BufferSource CryptoImpl::DiffieHellmanHandle::getGenerator(jsg::Lock& js) {
return dh.getGenerator(js);
}

kj::Array<kj::byte> CryptoImpl::DiffieHellmanHandle::getPrime() {
return dh.getPrime();
jsg::BufferSource CryptoImpl::DiffieHellmanHandle::getPrime(jsg::Lock& js) {
return dh.getPrime(js);
}

kj::Array<kj::byte> CryptoImpl::DiffieHellmanHandle::computeSecret(kj::Array<kj::byte> key) {
return dh.computeSecret(key);
jsg::BufferSource CryptoImpl::DiffieHellmanHandle::computeSecret(
jsg::Lock& js, kj::Array<kj::byte> key) {
return dh.computeSecret(js, key);
}

kj::Array<kj::byte> CryptoImpl::DiffieHellmanHandle::generateKeys() {
return dh.generateKeys();
jsg::BufferSource CryptoImpl::DiffieHellmanHandle::generateKeys(jsg::Lock& js) {
return dh.generateKeys(js);
}

int CryptoImpl::DiffieHellmanHandle::getVerifyError() {
Expand Down
12 changes: 6 additions & 6 deletions src/workerd/api/node/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ class CryptoImpl final: public jsg::Object {

void setPrivateKey(kj::Array<kj::byte> key);
void setPublicKey(kj::Array<kj::byte> key);
kj::Array<kj::byte> getPublicKey();
kj::Array<kj::byte> getPrivateKey();
kj::Array<kj::byte> getGenerator();
kj::Array<kj::byte> getPrime();
kj::Array<kj::byte> computeSecret(kj::Array<kj::byte> key);
kj::Array<kj::byte> generateKeys();
jsg::BufferSource getPublicKey(jsg::Lock& js);
jsg::BufferSource getPrivateKey(jsg::Lock& js);
jsg::BufferSource getGenerator(jsg::Lock& js);
jsg::BufferSource getPrime(jsg::Lock& js);
jsg::BufferSource computeSecret(jsg::Lock& js, kj::Array<kj::byte> key);
jsg::BufferSource generateKeys(jsg::Lock& js);
int getVerifyError();

JSG_RESOURCE_TYPE(DiffieHellmanHandle) {
Expand Down

0 comments on commit c51e9f3

Please sign in to comment.