Skip to content
File

Blob: src/workerd/api/crypto/rsa.h

cpp88 lines
1#pragma once
2 
3#include "crypto.h"
4#include "keys.h"
5 
6#include <workerd/jsg/jsvalue.h>
7 
8#include <openssl/base.h>
9#include <openssl/evp.h>
10 
11#include <kj/common.h>
12 
13namespace workerd::api {
14 
15class Rsa final {
16 public:
17 static kj::Maybe<Rsa> tryGetRsa(const EVP_PKEY* key);
18 Rsa(RSA* rsa);
19 
20 size_t getModulusBits() const;
21 size_t getModulusSize() const;
22 
23 inline const BIGNUM* getN() const {
24 return n;
25 }
26 inline const BIGNUM* getE() const {
27 return e;
28 }
29 inline const BIGNUM* getD() const {
30 return d;
31 }
32 
33 jsg::JsUint8Array getPublicExponent(jsg::Lock& js) KJ_WARN_UNUSED_RESULT;
34 
35 CryptoKey::AsymmetricKeyDetails getAsymmetricKeyDetail(jsg::Lock& js) const KJ_WARN_UNUSED_RESULT;
36 
37 jsg::JsArrayBuffer sign(
38 jsg::Lock& js, kj::ArrayPtr<const kj::byte> data) const KJ_WARN_UNUSED_RESULT;
39 
40 static kj::Maybe<AsymmetricKeyData> fromJwk(
41 jsg::Lock& js, KeyType keyType, const SubtleCrypto::JsonWebKey& jwk) KJ_WARN_UNUSED_RESULT;
42 
43 SubtleCrypto::JsonWebKey toJwk(
44 KeyType keytype, kj::Maybe<kj::String> maybeHashAlgorithm) const KJ_WARN_UNUSED_RESULT;
45 
46 struct CipherOptions {
47 const EVP_CIPHER* cipher;
48 kj::ArrayPtr<const kj::byte> passphrase;
49 };
50 
51 kj::String toPem(jsg::Lock& js,
52 KeyEncoding encoding,
53 KeyType keyType,
54 kj::Maybe<CipherOptions> options = kj::none) const KJ_WARN_UNUSED_RESULT;
55 
56 jsg::JsArrayBuffer toDer(jsg::Lock& js,
57 KeyEncoding encoding,
58 KeyType keyType,
59 kj::Maybe<CipherOptions> options = kj::none) const KJ_WARN_UNUSED_RESULT;
60 
61 using EncryptDecryptFunction = decltype(EVP_PKEY_encrypt);
62 jsg::JsArrayBuffer cipher(jsg::Lock& js,
63 EVP_PKEY_CTX* ctx,
64 SubtleCrypto::EncryptAlgorithm&& algorithm,
65 kj::ArrayPtr<const kj::byte> data,
66 EncryptDecryptFunction encryptDecrypt,
67 const EVP_MD* cipher) const KJ_WARN_UNUSED_RESULT;
68 
69 // The W3C standard itself doesn't describe any parameter validation but the conformance tests
70 // do test "bad" exponents, likely because everyone uses OpenSSL that suffers from poor behavior
71 // with these bad exponents (e.g. if an exponent < 3 or 65535 generates an infinite loop, a
72 // library might be expected to handle such cases on its own, no?).
73 static void validateRsaParams(jsg::Lock& js,
74 size_t modulusLength,
75 kj::ArrayPtr<kj::byte> publicExponent,
76 bool isImport = false);
77 
78 static bool isRSAPrivateKey(kj::ArrayPtr<const kj::byte> keyData) KJ_WARN_UNUSED_RESULT;
79 
80 private:
81 RSA* rsa;
82 const BIGNUM* n = nullptr;
83 const BIGNUM* e = nullptr;
84 const BIGNUM* d = nullptr;
85};
86 
87} // namespace workerd::api