From 7db87fe0cbac2d4eeba1c8a3d530897e1f16e78f Mon Sep 17 00:00:00 2001 From: Derrick Farris Date: Sat, 4 Feb 2023 02:24:35 -0600 Subject: fix(webcrypto): fix ed25519 keypair gen (#1985) --- src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp | 7 +++-- src/bun.js/bindings/webcrypto/CryptoKeyOKP.h | 3 ++ .../bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp | 35 +++++++++++++++++----- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp index 77d099427..58b46cbc4 100644 --- a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp +++ b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.cpp @@ -37,19 +37,20 @@ namespace WebCore { static const ASCIILiteral X25519 { "X25519"_s }; static const ASCIILiteral Ed25519 { "Ed25519"_s }; -static constexpr size_t keySizeInBytesFromNamedCurve(CryptoKeyOKP::NamedCurve curve) +static constexpr size_t keySizeInBytesFromNamedCurve(CryptoKeyOKP::NamedCurve curve, CryptoKeyType type) { switch (curve) { case CryptoKeyOKP::NamedCurve::X25519: - case CryptoKeyOKP::NamedCurve::Ed25519: return 32; + case CryptoKeyOKP::NamedCurve::Ed25519: + return type == CryptoKeyType::Private ? 64 : 32; } return 32; } RefPtr CryptoKeyOKP::create(CryptoAlgorithmIdentifier identifier, NamedCurve curve, CryptoKeyType type, KeyMaterial&& platformKey, bool extractable, CryptoKeyUsageBitmap usages) { - if (platformKey.size() != keySizeInBytesFromNamedCurve(curve)) + if (platformKey.size() != keySizeInBytesFromNamedCurve(curve, type)) return nullptr; return adoptRef(*new CryptoKeyOKP(identifier, curve, type, WTFMove(platformKey), extractable, usages)); } diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h index db94dbd23..40642fe68 100644 --- a/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h +++ b/src/bun.js/bindings/webcrypto/CryptoKeyOKP.h @@ -75,6 +75,9 @@ private: String generateJwkD() const; String generateJwkX() const; + String getEd25519PublicFromPrivate() const; + String getX25519PublicFromPrivate() const; + static bool isPlatformSupportedCurve(NamedCurve); static std::optional platformGeneratePair(CryptoAlgorithmIdentifier, NamedCurve, bool extractable, CryptoKeyUsageBitmap); Vector platformExportRaw() const; diff --git a/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp b/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp index 79e99d917..0372443fc 100644 --- a/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp +++ b/src/bun.js/bindings/webcrypto/CryptoKeyOKPOpenSSL.cpp @@ -46,17 +46,19 @@ std::optional CryptoKeyOKP::platformGeneratePair(CryptoAlgorithmI if (namedCurve != NamedCurve::Ed25519) return {}; - uint8_t public_key[X25519_PUBLIC_VALUE_LEN], private_key[X25519_PRIVATE_KEY_LEN]; + uint8_t public_key[ED25519_PUBLIC_KEY_LEN], private_key[ED25519_PRIVATE_KEY_LEN]; - if (identifier == CryptoAlgorithmIdentifier::Ed25519) { + bool isEd25519 = identifier == CryptoAlgorithmIdentifier::Ed25519; + if (isEd25519) { ED25519_keypair(public_key, private_key); } else { X25519_keypair(public_key, private_key); } + bool isPublicKeyExtractable = true; auto publicKey = CryptoKeyOKP::create(identifier, namedCurve, CryptoKeyType::Public, Vector(public_key), isPublicKeyExtractable, usages); ASSERT(publicKey); - auto privateKey = CryptoKeyOKP::create(identifier, namedCurve, CryptoKeyType::Private, Vector(private_key), extractable, usages); + auto privateKey = CryptoKeyOKP::create(identifier, namedCurve, CryptoKeyType::Private, Vector(private_key, isEd25519 ? ED25519_PRIVATE_KEY_LEN : X25519_PRIVATE_KEY_LEN), extractable, usages); ASSERT(privateKey); return CryptoKeyPair { WTFMove(publicKey), WTFMove(privateKey) }; } @@ -295,6 +297,25 @@ String CryptoKeyOKP::generateJwkD() const return base64URLEncodeToString(m_data); } +String CryptoKeyOKP::getEd25519PublicFromPrivate() const +{ + uint8_t publicKey[ED25519_PUBLIC_KEY_LEN]; + uint8_t privateKey[ED25519_PRIVATE_KEY_LEN]; + + ED25519_keypair_from_seed(publicKey, privateKey, m_data.data()); + + return base64URLEncodeToString(Span { publicKey, sizeof(publicKey) }); +} + +String CryptoKeyOKP::getX25519PublicFromPrivate() const +{ + uint8_t publicKey[X25519_PUBLIC_VALUE_LEN]; + + X25519_public_from_private(publicKey, m_data.data()); + + return base64URLEncodeToString(Span { publicKey, sizeof(publicKey) }); +} + String CryptoKeyOKP::generateJwkX() const { if (type() == CryptoKeyType::Public) @@ -302,11 +323,11 @@ String CryptoKeyOKP::generateJwkX() const ASSERT(type() == CryptoKeyType::Private); - uint8_t publicKey[ED25519_PUBLIC_KEY_LEN]; - uint8_t privateKey[ED25519_PRIVATE_KEY_LEN]; - ED25519_keypair_from_seed(publicKey, privateKey, m_data.data()); + if (namedCurve() == NamedCurve::Ed25519) + return getEd25519PublicFromPrivate(); - return base64URLEncodeToString(Span { publicKey, sizeof(publicKey) }); + ASSERT(namedCurve() == NamedCurve::X25519); + return getX25519PublicFromPrivate(); } Vector CryptoKeyOKP::platformExportRaw() const -- cgit v1.2.3