CryptoAlgorithms.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /*
  2. * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/EnumBits.h>
  8. #include <AK/String.h>
  9. #include <LibCrypto/BigInt/UnsignedBigInteger.h>
  10. #include <LibJS/Forward.h>
  11. #include <LibJS/Heap/GCPtr.h>
  12. #include <LibWeb/Bindings/SubtleCryptoPrototype.h>
  13. #include <LibWeb/Crypto/CryptoBindings.h>
  14. #include <LibWeb/Crypto/CryptoKey.h>
  15. #include <LibWeb/WebIDL/Buffers.h>
  16. #include <LibWeb/WebIDL/ExceptionOr.h>
  17. namespace Web::Crypto {
  18. using AlgorithmIdentifier = Variant<JS::Handle<JS::Object>, String>;
  19. using HashAlgorithmIdentifier = AlgorithmIdentifier;
  20. using NamedCurve = String;
  21. using KeyDataType = Variant<JS::Handle<WebIDL::BufferSource>, Bindings::JsonWebKey>;
  22. // https://w3c.github.io/webcrypto/#algorithm-overview
  23. struct AlgorithmParams {
  24. virtual ~AlgorithmParams();
  25. explicit AlgorithmParams(String name)
  26. : name(move(name))
  27. {
  28. }
  29. String name;
  30. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  31. };
  32. // https://w3c.github.io/webcrypto/#aes-cbc
  33. struct AesCbcParams : public AlgorithmParams {
  34. virtual ~AesCbcParams() override;
  35. AesCbcParams(String name, ByteBuffer iv)
  36. : AlgorithmParams(move(name))
  37. , iv(move(iv))
  38. {
  39. }
  40. ByteBuffer iv;
  41. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  42. };
  43. // https://w3c.github.io/webcrypto/#hkdf-params
  44. struct HKDFParams : public AlgorithmParams {
  45. virtual ~HKDFParams() override;
  46. HKDFParams(String name, HashAlgorithmIdentifier hash, ByteBuffer salt, ByteBuffer info)
  47. : AlgorithmParams(move(name))
  48. , hash(move(hash))
  49. , salt(move(salt))
  50. , info(move(info))
  51. {
  52. }
  53. HashAlgorithmIdentifier hash;
  54. ByteBuffer salt;
  55. ByteBuffer info;
  56. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  57. };
  58. // https://w3c.github.io/webcrypto/#pbkdf2-params
  59. struct PBKDF2Params : public AlgorithmParams {
  60. virtual ~PBKDF2Params() override;
  61. PBKDF2Params(String name, ByteBuffer salt, u32 iterations, HashAlgorithmIdentifier hash)
  62. : AlgorithmParams(move(name))
  63. , salt(move(salt))
  64. , iterations(iterations)
  65. , hash(move(hash))
  66. {
  67. }
  68. ByteBuffer salt;
  69. u32 iterations;
  70. HashAlgorithmIdentifier hash;
  71. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  72. };
  73. // https://w3c.github.io/webcrypto/#dfn-RsaKeyGenParams
  74. struct RsaKeyGenParams : public AlgorithmParams {
  75. virtual ~RsaKeyGenParams() override;
  76. RsaKeyGenParams(String name, u32 modulus_length, ::Crypto::UnsignedBigInteger public_exponent)
  77. : AlgorithmParams(move(name))
  78. , modulus_length(modulus_length)
  79. , public_exponent(move(public_exponent))
  80. {
  81. }
  82. u32 modulus_length;
  83. // NOTE that the raw data is going to be in Big Endian u8[] format
  84. ::Crypto::UnsignedBigInteger public_exponent;
  85. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  86. };
  87. // https://w3c.github.io/webcrypto/#dfn-RsaHashedKeyGenParams
  88. struct RsaHashedKeyGenParams : public RsaKeyGenParams {
  89. virtual ~RsaHashedKeyGenParams() override;
  90. RsaHashedKeyGenParams(String name, u32 modulus_length, ::Crypto::UnsignedBigInteger public_exponent, HashAlgorithmIdentifier hash)
  91. : RsaKeyGenParams(move(name), modulus_length, move(public_exponent))
  92. , hash(move(hash))
  93. {
  94. }
  95. HashAlgorithmIdentifier hash;
  96. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  97. };
  98. // https://w3c.github.io/webcrypto/#dfn-RsaHashedImportParams
  99. struct RsaHashedImportParams : public AlgorithmParams {
  100. virtual ~RsaHashedImportParams() override;
  101. RsaHashedImportParams(String name, HashAlgorithmIdentifier hash)
  102. : AlgorithmParams(move(name))
  103. , hash(move(hash))
  104. {
  105. }
  106. HashAlgorithmIdentifier hash;
  107. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  108. };
  109. // https://w3c.github.io/webcrypto/#dfn-RsaOaepParams
  110. struct RsaOaepParams : public AlgorithmParams {
  111. virtual ~RsaOaepParams() override;
  112. RsaOaepParams(String name, ByteBuffer label)
  113. : AlgorithmParams(move(name))
  114. , label(move(label))
  115. {
  116. }
  117. ByteBuffer label;
  118. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  119. };
  120. // https://w3c.github.io/webcrypto/#dfn-EcdsaParams
  121. struct EcdsaParams : public AlgorithmParams {
  122. virtual ~EcdsaParams() override;
  123. EcdsaParams(String name, HashAlgorithmIdentifier hash)
  124. : AlgorithmParams(move(name))
  125. , hash(move(hash))
  126. {
  127. }
  128. HashAlgorithmIdentifier hash;
  129. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  130. };
  131. // https://w3c.github.io/webcrypto/#dfn-EcKeyGenParams
  132. struct EcKeyGenParams : public AlgorithmParams {
  133. virtual ~EcKeyGenParams() override;
  134. EcKeyGenParams(String name, NamedCurve named_curve)
  135. : AlgorithmParams(move(name))
  136. , named_curve(move(named_curve))
  137. {
  138. }
  139. NamedCurve named_curve;
  140. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  141. };
  142. class AlgorithmMethods {
  143. public:
  144. virtual ~AlgorithmMethods();
  145. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&)
  146. {
  147. return WebIDL::NotSupportedError::create(m_realm, "encrypt is not supported"_string);
  148. }
  149. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&)
  150. {
  151. return WebIDL::NotSupportedError::create(m_realm, "decrypt is not supported"_string);
  152. }
  153. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&)
  154. {
  155. return WebIDL::NotSupportedError::create(m_realm, "sign is not supported"_string);
  156. }
  157. virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&, ByteBuffer const&)
  158. {
  159. return WebIDL::NotSupportedError::create(m_realm, "verify is not supported"_string);
  160. }
  161. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> digest(AlgorithmParams const&, ByteBuffer const&)
  162. {
  163. return WebIDL::NotSupportedError::create(m_realm, "digest is not supported"_string);
  164. }
  165. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, Optional<u32>)
  166. {
  167. return WebIDL::NotSupportedError::create(m_realm, "deriveBits is not supported"_string);
  168. }
  169. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&)
  170. {
  171. return WebIDL::NotSupportedError::create(m_realm, "importKey is not supported"_string);
  172. }
  173. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&)
  174. {
  175. return WebIDL::NotSupportedError::create(m_realm, "generateKey is not supported"_string);
  176. }
  177. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>)
  178. {
  179. return WebIDL::NotSupportedError::create(m_realm, "exportKey is not supported"_string);
  180. }
  181. virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams const&)
  182. {
  183. return WebIDL::NotSupportedError::create(m_realm, "getKeyLength is not supported"_string);
  184. }
  185. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AlgorithmMethods(realm)); }
  186. protected:
  187. explicit AlgorithmMethods(JS::Realm& realm)
  188. : m_realm(realm)
  189. {
  190. }
  191. JS::NonnullGCPtr<JS::Realm> m_realm;
  192. };
  193. class RSAOAEP : public AlgorithmMethods {
  194. public:
  195. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  196. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  197. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
  198. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
  199. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>) override;
  200. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new RSAOAEP(realm)); }
  201. private:
  202. explicit RSAOAEP(JS::Realm& realm)
  203. : AlgorithmMethods(realm)
  204. {
  205. }
  206. };
  207. class AesCbc : public AlgorithmMethods {
  208. public:
  209. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  210. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  211. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
  212. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
  213. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>) override;
  214. virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams const&) override;
  215. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AesCbc(realm)); }
  216. private:
  217. explicit AesCbc(JS::Realm& realm)
  218. : AlgorithmMethods(realm)
  219. {
  220. }
  221. };
  222. class HKDF : public AlgorithmMethods {
  223. public:
  224. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
  225. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, Optional<u32>) override;
  226. virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams const&) override;
  227. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new HKDF(realm)); }
  228. private:
  229. explicit HKDF(JS::Realm& realm)
  230. : AlgorithmMethods(realm)
  231. {
  232. }
  233. };
  234. class PBKDF2 : public AlgorithmMethods {
  235. public:
  236. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
  237. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, Optional<u32>) override;
  238. virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams const&) override;
  239. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new PBKDF2(realm)); }
  240. private:
  241. explicit PBKDF2(JS::Realm& realm)
  242. : AlgorithmMethods(realm)
  243. {
  244. }
  245. };
  246. class SHA : public AlgorithmMethods {
  247. public:
  248. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> digest(AlgorithmParams const&, ByteBuffer const&) override;
  249. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new SHA(realm)); }
  250. private:
  251. explicit SHA(JS::Realm& realm)
  252. : AlgorithmMethods(realm)
  253. {
  254. }
  255. };
  256. class ECDSA : public AlgorithmMethods {
  257. public:
  258. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  259. virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&, ByteBuffer const&) override;
  260. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
  261. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ECDSA(realm)); }
  262. private:
  263. explicit ECDSA(JS::Realm& realm)
  264. : AlgorithmMethods(realm)
  265. {
  266. }
  267. };
  268. class ED25519 : public AlgorithmMethods {
  269. public:
  270. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  271. virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&, ByteBuffer const&) override;
  272. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
  273. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ED25519(realm)); }
  274. private:
  275. explicit ED25519(JS::Realm& realm)
  276. : AlgorithmMethods(realm)
  277. {
  278. }
  279. };
  280. ErrorOr<String> base64_url_uint_encode(::Crypto::UnsignedBigInteger);
  281. WebIDL::ExceptionOr<ByteBuffer> base64_url_bytes_decode(JS::Realm&, String const& base64_url_string);
  282. WebIDL::ExceptionOr<::Crypto::UnsignedBigInteger> base64_url_uint_decode(JS::Realm&, String const& base64_url_string);
  283. }