CryptoAlgorithms.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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/#pbkdf2-params
  33. struct PBKDF2Params : public AlgorithmParams {
  34. virtual ~PBKDF2Params() override;
  35. PBKDF2Params(String name, ByteBuffer salt, u32 iterations, HashAlgorithmIdentifier hash)
  36. : AlgorithmParams(move(name))
  37. , salt(move(salt))
  38. , iterations(iterations)
  39. , hash(move(hash))
  40. {
  41. }
  42. ByteBuffer salt;
  43. u32 iterations;
  44. HashAlgorithmIdentifier hash;
  45. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  46. };
  47. // https://w3c.github.io/webcrypto/#dfn-RsaKeyGenParams
  48. struct RsaKeyGenParams : public AlgorithmParams {
  49. virtual ~RsaKeyGenParams() override;
  50. RsaKeyGenParams(String name, u32 modulus_length, ::Crypto::UnsignedBigInteger public_exponent)
  51. : AlgorithmParams(move(name))
  52. , modulus_length(modulus_length)
  53. , public_exponent(move(public_exponent))
  54. {
  55. }
  56. u32 modulus_length;
  57. // NOTE that the raw data is going to be in Big Endian u8[] format
  58. ::Crypto::UnsignedBigInteger public_exponent;
  59. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  60. };
  61. // https://w3c.github.io/webcrypto/#dfn-RsaHashedKeyGenParams
  62. struct RsaHashedKeyGenParams : public RsaKeyGenParams {
  63. virtual ~RsaHashedKeyGenParams() override;
  64. RsaHashedKeyGenParams(String name, u32 modulus_length, ::Crypto::UnsignedBigInteger public_exponent, HashAlgorithmIdentifier hash)
  65. : RsaKeyGenParams(move(name), modulus_length, move(public_exponent))
  66. , hash(move(hash))
  67. {
  68. }
  69. HashAlgorithmIdentifier hash;
  70. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  71. };
  72. // https://w3c.github.io/webcrypto/#dfn-RsaHashedImportParams
  73. struct RsaHashedImportParams : public AlgorithmParams {
  74. virtual ~RsaHashedImportParams() override;
  75. RsaHashedImportParams(String name, HashAlgorithmIdentifier hash)
  76. : AlgorithmParams(move(name))
  77. , hash(move(hash))
  78. {
  79. }
  80. HashAlgorithmIdentifier hash;
  81. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  82. };
  83. // https://w3c.github.io/webcrypto/#dfn-RsaOaepParams
  84. struct RsaOaepParams : public AlgorithmParams {
  85. virtual ~RsaOaepParams() override;
  86. RsaOaepParams(String name, ByteBuffer label)
  87. : AlgorithmParams(move(name))
  88. , label(move(label))
  89. {
  90. }
  91. ByteBuffer label;
  92. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  93. };
  94. // https://w3c.github.io/webcrypto/#dfn-EcdsaParams
  95. struct EcdsaParams : public AlgorithmParams {
  96. virtual ~EcdsaParams() override;
  97. EcdsaParams(String name, HashAlgorithmIdentifier hash)
  98. : AlgorithmParams(move(name))
  99. , hash(move(hash))
  100. {
  101. }
  102. HashAlgorithmIdentifier hash;
  103. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  104. };
  105. // https://w3c.github.io/webcrypto/#dfn-EcKeyGenParams
  106. struct EcKeyGenParams : public AlgorithmParams {
  107. virtual ~EcKeyGenParams() override;
  108. EcKeyGenParams(String name, NamedCurve named_curve)
  109. : AlgorithmParams(move(name))
  110. , named_curve(move(named_curve))
  111. {
  112. }
  113. NamedCurve named_curve;
  114. static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value);
  115. };
  116. class AlgorithmMethods {
  117. public:
  118. virtual ~AlgorithmMethods();
  119. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&)
  120. {
  121. return WebIDL::NotSupportedError::create(m_realm, "encrypt is not supported"_fly_string);
  122. }
  123. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&)
  124. {
  125. return WebIDL::NotSupportedError::create(m_realm, "decrypt is not supported"_fly_string);
  126. }
  127. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&)
  128. {
  129. return WebIDL::NotSupportedError::create(m_realm, "sign is not supported"_fly_string);
  130. }
  131. virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&, ByteBuffer const&)
  132. {
  133. return WebIDL::NotSupportedError::create(m_realm, "verify is not supported"_fly_string);
  134. }
  135. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> digest(AlgorithmParams const&, ByteBuffer const&)
  136. {
  137. return WebIDL::NotSupportedError::create(m_realm, "digest is not supported"_fly_string);
  138. }
  139. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, u32)
  140. {
  141. return WebIDL::NotSupportedError::create(m_realm, "deriveBits is not supported"_fly_string);
  142. }
  143. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&)
  144. {
  145. return WebIDL::NotSupportedError::create(m_realm, "importKey is not supported"_fly_string);
  146. }
  147. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&)
  148. {
  149. return WebIDL::NotSupportedError::create(m_realm, "generateKey is not supported"_fly_string);
  150. }
  151. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>)
  152. {
  153. return WebIDL::NotSupportedError::create(m_realm, "exportKey is not supported"_fly_string);
  154. }
  155. virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams const&)
  156. {
  157. return WebIDL::NotSupportedError::create(m_realm, "getKeyLength is not supported"_fly_string);
  158. }
  159. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AlgorithmMethods(realm)); }
  160. protected:
  161. explicit AlgorithmMethods(JS::Realm& realm)
  162. : m_realm(realm)
  163. {
  164. }
  165. JS::Realm& m_realm;
  166. };
  167. class RSAOAEP : public AlgorithmMethods {
  168. public:
  169. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  170. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  171. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
  172. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
  173. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>) override;
  174. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new RSAOAEP(realm)); }
  175. private:
  176. explicit RSAOAEP(JS::Realm& realm)
  177. : AlgorithmMethods(realm)
  178. {
  179. }
  180. };
  181. class PBKDF2 : public AlgorithmMethods {
  182. public:
  183. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override;
  184. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> derive_bits(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, u32) override;
  185. virtual WebIDL::ExceptionOr<JS::Value> get_key_length(AlgorithmParams const&) override;
  186. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new PBKDF2(realm)); }
  187. private:
  188. explicit PBKDF2(JS::Realm& realm)
  189. : AlgorithmMethods(realm)
  190. {
  191. }
  192. };
  193. class SHA : public AlgorithmMethods {
  194. public:
  195. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> digest(AlgorithmParams const&, ByteBuffer const&) override;
  196. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new SHA(realm)); }
  197. private:
  198. explicit SHA(JS::Realm& realm)
  199. : AlgorithmMethods(realm)
  200. {
  201. }
  202. };
  203. class ECDSA : public AlgorithmMethods {
  204. public:
  205. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  206. virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&, ByteBuffer const&) override;
  207. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
  208. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ECDSA(realm)); }
  209. private:
  210. explicit ECDSA(JS::Realm& realm)
  211. : AlgorithmMethods(realm)
  212. {
  213. }
  214. };
  215. class ED25519 : public AlgorithmMethods {
  216. public:
  217. virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override;
  218. virtual WebIDL::ExceptionOr<JS::Value> verify(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&, ByteBuffer const&) override;
  219. virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override;
  220. static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ED25519(realm)); }
  221. private:
  222. explicit ED25519(JS::Realm& realm)
  223. : AlgorithmMethods(realm)
  224. {
  225. }
  226. };
  227. ErrorOr<String> base64_url_uint_encode(::Crypto::UnsignedBigInteger);
  228. WebIDL::ExceptionOr<::Crypto::UnsignedBigInteger> base64_url_uint_decode(JS::Realm&, String const& base64_url_string);
  229. }