#pragma once #include "crypto.h" #include "keys.h" #include #include #include #include namespace workerd::api { class Rsa final { public: static kj::Maybe tryGetRsa(const EVP_PKEY* key); Rsa(RSA* rsa); size_t getModulusBits() const; size_t getModulusSize() const; inline const BIGNUM* getN() const { return n; } inline const BIGNUM* getE() const { return e; } inline const BIGNUM* getD() const { return d; } jsg::JsUint8Array getPublicExponent(jsg::Lock& js) KJ_WARN_UNUSED_RESULT; CryptoKey::AsymmetricKeyDetails getAsymmetricKeyDetail(jsg::Lock& js) const KJ_WARN_UNUSED_RESULT; jsg::JsArrayBuffer sign( jsg::Lock& js, kj::ArrayPtr data) const KJ_WARN_UNUSED_RESULT; static kj::Maybe fromJwk( jsg::Lock& js, KeyType keyType, const SubtleCrypto::JsonWebKey& jwk) KJ_WARN_UNUSED_RESULT; SubtleCrypto::JsonWebKey toJwk( KeyType keytype, kj::Maybe maybeHashAlgorithm) const KJ_WARN_UNUSED_RESULT; struct CipherOptions { const EVP_CIPHER* cipher; kj::ArrayPtr passphrase; }; kj::String toPem(jsg::Lock& js, KeyEncoding encoding, KeyType keyType, kj::Maybe options = kj::none) const KJ_WARN_UNUSED_RESULT; jsg::JsArrayBuffer toDer(jsg::Lock& js, KeyEncoding encoding, KeyType keyType, kj::Maybe options = kj::none) const KJ_WARN_UNUSED_RESULT; using EncryptDecryptFunction = decltype(EVP_PKEY_encrypt); jsg::JsArrayBuffer cipher(jsg::Lock& js, EVP_PKEY_CTX* ctx, SubtleCrypto::EncryptAlgorithm&& algorithm, kj::ArrayPtr data, EncryptDecryptFunction encryptDecrypt, const EVP_MD* cipher) const KJ_WARN_UNUSED_RESULT; // The W3C standard itself doesn't describe any parameter validation but the conformance tests // do test "bad" exponents, likely because everyone uses OpenSSL that suffers from poor behavior // with these bad exponents (e.g. if an exponent < 3 or 65535 generates an infinite loop, a // library might be expected to handle such cases on its own, no?). static void validateRsaParams(jsg::Lock& js, size_t modulusLength, kj::ArrayPtr publicExponent, bool isImport = false); static bool isRSAPrivateKey(kj::ArrayPtr keyData) KJ_WARN_UNUSED_RESULT; private: RSA* rsa; const BIGNUM* n = nullptr; const BIGNUM* e = nullptr; const BIGNUM* d = nullptr; }; } // namespace workerd::api