mirror of
https://github.com/oven-sh/bun
synced 2026-02-16 22:01:47 +00:00
@@ -20,13 +20,14 @@ using namespace JSC;
|
||||
init.set(jsOwnedString(init.vm, name.string())); \
|
||||
});
|
||||
|
||||
#define BUN_COMMON_STRINGS_LAZY_PROPERTY_DEFINITION_NOT_BUILTIN_NAMES(jsName) \
|
||||
this->m_commonString_##jsName.initLater( \
|
||||
[](const JSC::LazyProperty<JSGlobalObject, JSString>::Initializer& init) { \
|
||||
init.set(jsOwnedString(init.vm, #jsName##_s)); \
|
||||
#define BUN_COMMON_STRINGS_LAZY_PROPERTY_DEFINITION_NOT_BUILTIN_NAMES(methodName, stringLiteral) \
|
||||
this->m_commonString_##methodName.initLater( \
|
||||
[](const JSC::LazyProperty<JSGlobalObject, JSString>::Initializer& init) { \
|
||||
init.set(jsOwnedString(init.vm, stringLiteral##_s)); \
|
||||
});
|
||||
|
||||
#define BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR(name) this->m_commonString_##name.visit(visitor);
|
||||
#define BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR_NOT_BUILTIN_NAMES(name, literal) this->m_commonString_##name.visit(visitor);
|
||||
|
||||
void CommonStrings::initialize()
|
||||
{
|
||||
@@ -38,7 +39,7 @@ template<typename Visitor>
|
||||
void CommonStrings::visit(Visitor& visitor)
|
||||
{
|
||||
BUN_COMMON_STRINGS_EACH_NAME(BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR)
|
||||
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR)
|
||||
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR_NOT_BUILTIN_NAMES)
|
||||
}
|
||||
|
||||
template void CommonStrings::visit(JSC::AbstractSlotVisitor&);
|
||||
|
||||
@@ -11,17 +11,23 @@
|
||||
// These ones don't need to be in BunBuiltinNames.h
|
||||
// If we don't use it as an identifier name, but we want to avoid allocating the string frequently, put it in this list.
|
||||
#define BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(macro) \
|
||||
macro(SystemError) \
|
||||
macro(S3Error) \
|
||||
macro(utf8) \
|
||||
macro(ucs2) \
|
||||
macro(utf16le) \
|
||||
macro(latin1) \
|
||||
macro(ascii) \
|
||||
macro(base64) \
|
||||
macro(base64url) \
|
||||
macro(hex) \
|
||||
macro(buffer)
|
||||
macro(systemError, "SystemError") \
|
||||
macro(s3Error, "S3Error") \
|
||||
macro(utf8, "utf8") \
|
||||
macro(ucs2, "ucs2") \
|
||||
macro(utf16le, "utf16le") \
|
||||
macro(latin1, "latin1") \
|
||||
macro(ascii, "ascii") \
|
||||
macro(base64, "base64") \
|
||||
macro(base64url, "base64url") \
|
||||
macro(hex, "hex") \
|
||||
macro(buffer, "buffer") \
|
||||
macro(rsa, "rsa") \
|
||||
macro(rsaPss, "rsa-pss") \
|
||||
macro(ec, "ec") \
|
||||
macro(x25519, "x25519") \
|
||||
macro(ed25519, "ed25519")
|
||||
|
||||
// clang-format on
|
||||
|
||||
#define BUN_COMMON_STRINGS_ACCESSOR_DEFINITION(name) \
|
||||
@@ -30,15 +36,21 @@
|
||||
return m_commonString_##name.getInitializedOnMainThread(globalObject); \
|
||||
}
|
||||
|
||||
#define BUN_COMMON_STRINGS_ACCESSOR_DEFINITION_NOT_BUILTIN_NAMES(name, literal) \
|
||||
BUN_COMMON_STRINGS_ACCESSOR_DEFINITION(name)
|
||||
|
||||
#define BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION(name) \
|
||||
JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSString> m_commonString_##name;
|
||||
|
||||
#define BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION_NOT_BUILTIN_NAMES(name, literal) \
|
||||
BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION(name)
|
||||
|
||||
namespace Bun {
|
||||
|
||||
class CommonStrings {
|
||||
public:
|
||||
BUN_COMMON_STRINGS_EACH_NAME(BUN_COMMON_STRINGS_ACCESSOR_DEFINITION)
|
||||
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_ACCESSOR_DEFINITION)
|
||||
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_ACCESSOR_DEFINITION_NOT_BUILTIN_NAMES)
|
||||
void initialize();
|
||||
|
||||
template<typename Visitor>
|
||||
@@ -46,10 +58,12 @@ public:
|
||||
|
||||
private:
|
||||
BUN_COMMON_STRINGS_EACH_NAME(BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION)
|
||||
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION)
|
||||
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION_NOT_BUILTIN_NAMES)
|
||||
};
|
||||
|
||||
} // namespace Bun
|
||||
|
||||
#undef BUN_COMMON_STRINGS_ACCESSOR_DEFINITION
|
||||
#undef BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION
|
||||
#undef BUN_COMMON_STRINGS_ACCESSOR_DEFINITION_NOT_BUILTIN_NAMES
|
||||
#undef BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION_NOT_BUILTIN_NAMES
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
|
||||
#include "root.h"
|
||||
#include "ErrorCode.h"
|
||||
#include "BunCommonStrings.h"
|
||||
#include "KeyObject.h"
|
||||
#include "JavaScriptCore/JSArrayBufferView.h"
|
||||
#include "JavaScriptCore/JSCJSValue.h"
|
||||
@@ -611,9 +613,9 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject__createPrivateKey, (JSC::JSGlobalObject * glo
|
||||
auto impl = result.releaseNonNull();
|
||||
return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
|
||||
} else if (pKeyID == EVP_PKEY_X25519) {
|
||||
auto result = CryptoKeyOKP::importPkcs8(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>(std::span { (uint8_t*)data, byteLength }), true, CryptoKeyUsageSign);
|
||||
auto result = CryptoKeyOKP::importPkcs8(CryptoAlgorithmIdentifier::X25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>(std::span { (uint8_t*)data, byteLength }), true, CryptoKeyUsageDeriveKey);
|
||||
if (UNLIKELY(result == nullptr)) {
|
||||
throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 private key"_s));
|
||||
throwException(globalObject, scope, createTypeError(globalObject, "Invalid X25519 private key"_s));
|
||||
return {};
|
||||
}
|
||||
auto impl = result.releaseNonNull();
|
||||
@@ -987,7 +989,7 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject__createPublicKey, (JSC::JSGlobalObject * glob
|
||||
}
|
||||
return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
|
||||
} else if (jwk.crv == "X25519"_s) {
|
||||
auto result = CryptoKeyOKP::importPublicJwk(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, WTFMove(jwk), true, CryptoKeyUsageVerify);
|
||||
auto result = CryptoKeyOKP::importPublicJwk(CryptoAlgorithmIdentifier::X25519, CryptoKeyOKP::NamedCurve::X25519, WTFMove(jwk), true, CryptoKeyUsageDeriveKey);
|
||||
if (UNLIKELY(result == nullptr)) {
|
||||
throwException(globalObject, scope, createTypeError(globalObject, "Invalid X25519 public key"_s));
|
||||
return {};
|
||||
@@ -1076,12 +1078,12 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject__createPublicKey, (JSC::JSGlobalObject * glob
|
||||
auto impl = result.releaseNonNull();
|
||||
return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
|
||||
} else if (pKeyID == EVP_PKEY_X25519) {
|
||||
auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>(std::span { (uint8_t*)pem.der_data, (size_t)pem.der_len }), true, CryptoKeyUsageVerify);
|
||||
auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::X25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>(std::span { (uint8_t*)pem.der_data, (size_t)pem.der_len }), true, CryptoKeyUsageDeriveKey);
|
||||
if (pem.der_data) {
|
||||
OPENSSL_clear_free(pem.der_data, pem.der_len);
|
||||
}
|
||||
if (UNLIKELY(result == nullptr)) {
|
||||
throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 public key"_s));
|
||||
throwException(globalObject, scope, createTypeError(globalObject, "Invalid X25519 public key"_s));
|
||||
return {};
|
||||
}
|
||||
auto impl = result.releaseNonNull();
|
||||
@@ -1196,9 +1198,9 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject__createPublicKey, (JSC::JSGlobalObject * glob
|
||||
auto impl = result.releaseNonNull();
|
||||
return JSC::JSValue::encode(JSCryptoKey::create(structure, zigGlobalObject, WTFMove(impl)));
|
||||
} else if (pKeyID == EVP_PKEY_X25519) {
|
||||
auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::Ed25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>(std::span { (uint8_t*)data, byteLength }), true, CryptoKeyUsageVerify);
|
||||
auto result = CryptoKeyOKP::importSpki(CryptoAlgorithmIdentifier::X25519, CryptoKeyOKP::NamedCurve::X25519, Vector<uint8_t>(std::span { (uint8_t*)data, byteLength }), true, CryptoKeyUsageDeriveKey);
|
||||
if (UNLIKELY(result == nullptr)) {
|
||||
throwException(globalObject, scope, createTypeError(globalObject, "Invalid Ed25519 public key"_s));
|
||||
throwException(globalObject, scope, createTypeError(globalObject, "Invalid X25519 public key"_s));
|
||||
return {};
|
||||
}
|
||||
auto impl = result.releaseNonNull();
|
||||
@@ -2502,11 +2504,15 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject_AsymmetricKeyDetails, (JSC::JSGlobalObject *
|
||||
obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "namedCurve"_s)), JSC::jsString(vm, named_curve), 0);
|
||||
return JSC::JSValue::encode(obj);
|
||||
}
|
||||
case CryptoAlgorithmIdentifier::X25519:
|
||||
case CryptoAlgorithmIdentifier::Ed25519: {
|
||||
auto* obj = JSC::constructEmptyObject(lexicalGlobalObject, lexicalGlobalObject->objectPrototype(), 1);
|
||||
auto& wrapped = key->wrapped();
|
||||
const auto& okp = downcast<WebCore::CryptoKeyOKP>(wrapped);
|
||||
obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "namedCurve"_s)), JSC::jsString(vm, okp.namedCurveString()), 0);
|
||||
auto* globalObject = defaultGlobalObject(lexicalGlobalObject);
|
||||
auto& commonStrings = globalObject->commonStrings();
|
||||
JSString* namedCurveString = okp.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? commonStrings.x25519String(lexicalGlobalObject) : commonStrings.ed25519String(lexicalGlobalObject);
|
||||
obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "namedCurve"_s)), namedCurveString, 0);
|
||||
return JSC::JSValue::encode(obj);
|
||||
}
|
||||
default:
|
||||
@@ -2722,7 +2728,7 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject__generateKeyPairSync, (JSC::JSGlobalObject *
|
||||
obj->putDirect(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "privateKey"_s)), JSCryptoKey::create(structure, zigGlobalObject, pair.privateKey.releaseNonNull()), 0);
|
||||
return JSValue::encode(obj);
|
||||
} else if (type_str == "x25519"_s) {
|
||||
auto result = CryptoKeyOKP::generatePair(CryptoAlgorithmIdentifier::X25519, CryptoKeyOKP::NamedCurve::X25519, true, CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits);
|
||||
auto result = CryptoKeyOKP::generatePair(CryptoAlgorithmIdentifier::X25519, CryptoKeyOKP::NamedCurve::X25519, true, CryptoKeyUsageDeriveKey | CryptoKeyUsageDeriveBits | CryptoKeyUsageSign | CryptoKeyUsageVerify);
|
||||
if (result.hasException()) {
|
||||
WebCore::propagateException(*lexicalGlobalObject, scope, result.releaseException());
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
@@ -2802,13 +2808,8 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject__generateKeySync, (JSC::JSGlobalObject * lexi
|
||||
JSC_DEFINE_HOST_FUNCTION(KeyObject__AsymmetricKeyType, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
ncrypto::ClearErrorOnReturn clearErrorOnReturn;
|
||||
static const NeverDestroyed<String> values[] = {
|
||||
MAKE_STATIC_STRING_IMPL("rsa"),
|
||||
MAKE_STATIC_STRING_IMPL("rsa-pss"),
|
||||
MAKE_STATIC_STRING_IMPL("ec"),
|
||||
MAKE_STATIC_STRING_IMPL("x25519"),
|
||||
MAKE_STATIC_STRING_IMPL("ed25519"),
|
||||
};
|
||||
auto* globalObject = defaultGlobalObject(lexicalGlobalObject);
|
||||
auto& commonStrings = globalObject->commonStrings();
|
||||
|
||||
// TODO: Look into DSA and DH
|
||||
if (auto* key = jsDynamicCast<JSCryptoKey*>(callFrame->argument(0))) {
|
||||
@@ -2817,16 +2818,16 @@ JSC_DEFINE_HOST_FUNCTION(KeyObject__AsymmetricKeyType, (JSC::JSGlobalObject * le
|
||||
case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5:
|
||||
case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5:
|
||||
case CryptoAlgorithmIdentifier::RSA_OAEP:
|
||||
return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), values[0]));
|
||||
return JSC::JSValue::encode(commonStrings.rsaString(globalObject));
|
||||
case CryptoAlgorithmIdentifier::RSA_PSS:
|
||||
return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), values[1]));
|
||||
return JSC::JSValue::encode(commonStrings.rsaPssString(globalObject));
|
||||
case CryptoAlgorithmIdentifier::ECDSA:
|
||||
case CryptoAlgorithmIdentifier::ECDH:
|
||||
return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), values[2]));
|
||||
case CryptoAlgorithmIdentifier::Ed25519: {
|
||||
return JSC::JSValue::encode(commonStrings.ecString(globalObject));
|
||||
case CryptoAlgorithmIdentifier::Ed25519:
|
||||
case CryptoAlgorithmIdentifier::X25519: {
|
||||
const auto& okpKey = downcast<WebCore::CryptoKeyOKP>(key->wrapped());
|
||||
// TODO: CHECK THIS WHEN X488 AND ED448 ARE ADDED
|
||||
return JSC::JSValue::encode(JSC::jsStringWithCache(lexicalGlobalObject->vm(), String(okpKey.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? values[3] : values[4])));
|
||||
return JSC::JSValue::encode(okpKey.namedCurve() == CryptoKeyOKP::NamedCurve::X25519 ? commonStrings.x25519String(globalObject) : commonStrings.ed25519String(globalObject));
|
||||
}
|
||||
default:
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
|
||||
@@ -40,7 +40,7 @@ SYSV_ABI JSC::EncodedJSValue S3Error__toErrorInstance(const S3Error* arg0,
|
||||
JSC::JSObject* result = JSC::ErrorInstance::create(globalObject, prototype, message, options);
|
||||
result->putDirect(
|
||||
vm, vm.propertyNames->name,
|
||||
JSC::JSValue(defaultGlobalObject(globalObject)->commonStrings().S3ErrorString(globalObject)),
|
||||
JSC::JSValue(defaultGlobalObject(globalObject)->commonStrings().s3ErrorString(globalObject)),
|
||||
JSC::PropertyAttribute::DontEnum | 0);
|
||||
if (err.code.tag != BunStringTag::Empty) {
|
||||
JSC::JSValue code = Bun::toJS(globalObject, err.code);
|
||||
|
||||
@@ -1664,10 +1664,13 @@ test("Ed25519 should work", async () => {
|
||||
|
||||
expect(publicKey.type).toBe("public");
|
||||
expect(publicKey.asymmetricKeyType).toBe("ed25519");
|
||||
expect(publicKey.asymmetricKeyDetails).toEqual({ namedCurve: "Ed25519" });
|
||||
|
||||
expect(privateKey.type).toBe("private");
|
||||
expect(privateKey.asymmetricKeyType).toBe("ed25519");
|
||||
expect(privateKey.asymmetricKeyDetails).toEqual({ namedCurve: "Ed25519" });
|
||||
|
||||
// TODO: this should be an empty object. Node doesn't always include the details.
|
||||
expect(privateKey.asymmetricKeyDetails).toBeObject();
|
||||
expect(publicKey.asymmetricKeyDetails).toBeObject();
|
||||
|
||||
{
|
||||
const signature = sign(undefined, Buffer.from("foo"), privateKey);
|
||||
|
||||
Reference in New Issue
Block a user