| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/EnumBits.h>
 | 
					
						
							|  |  |  | #include <AK/String.h>
 | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  | #include <LibCrypto/BigInt/UnsignedBigInteger.h>
 | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  | #include <LibJS/Forward.h>
 | 
					
						
							|  |  |  | #include <LibJS/Heap/GCPtr.h>
 | 
					
						
							|  |  |  | #include <LibWeb/Bindings/SubtleCryptoPrototype.h>
 | 
					
						
							|  |  |  | #include <LibWeb/Crypto/CryptoBindings.h>
 | 
					
						
							|  |  |  | #include <LibWeb/Crypto/CryptoKey.h>
 | 
					
						
							|  |  |  | #include <LibWeb/WebIDL/Buffers.h>
 | 
					
						
							|  |  |  | #include <LibWeb/WebIDL/ExceptionOr.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Web::Crypto { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using AlgorithmIdentifier = Variant<JS::Handle<JS::Object>, String>; | 
					
						
							|  |  |  | using HashAlgorithmIdentifier = AlgorithmIdentifier; | 
					
						
							| 
									
										
										
										
											2024-03-27 01:27:42 +01:00
										 |  |  | using NamedCurve = String; | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  | using KeyDataType = Variant<JS::Handle<WebIDL::BufferSource>, Bindings::JsonWebKey>; | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // https://w3c.github.io/webcrypto/#algorithm-overview
 | 
					
						
							|  |  |  | struct AlgorithmParams { | 
					
						
							| 
									
										
										
										
											2024-03-13 21:26:00 -06:00
										 |  |  |     virtual ~AlgorithmParams(); | 
					
						
							|  |  |  |     explicit AlgorithmParams(String name) | 
					
						
							|  |  |  |         : name(move(name)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  |     String name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // https://w3c.github.io/webcrypto/#pbkdf2-params
 | 
					
						
							|  |  |  | struct PBKDF2Params : public AlgorithmParams { | 
					
						
							| 
									
										
										
										
											2024-03-13 21:26:00 -06:00
										 |  |  |     virtual ~PBKDF2Params() override; | 
					
						
							| 
									
										
										
										
											2024-03-14 22:11:56 -06:00
										 |  |  |     PBKDF2Params(String name, ByteBuffer salt, u32 iterations, HashAlgorithmIdentifier hash) | 
					
						
							| 
									
										
										
										
											2024-03-13 21:26:00 -06:00
										 |  |  |         : AlgorithmParams(move(name)) | 
					
						
							|  |  |  |         , salt(move(salt)) | 
					
						
							|  |  |  |         , iterations(iterations) | 
					
						
							|  |  |  |         , hash(move(hash)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-14 22:11:56 -06:00
										 |  |  |     ByteBuffer salt; | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  |     u32 iterations; | 
					
						
							|  |  |  |     HashAlgorithmIdentifier hash; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  | // https://w3c.github.io/webcrypto/#dfn-RsaKeyGenParams
 | 
					
						
							|  |  |  | struct RsaKeyGenParams : public AlgorithmParams { | 
					
						
							| 
									
										
										
										
											2024-03-13 21:26:00 -06:00
										 |  |  |     virtual ~RsaKeyGenParams() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RsaKeyGenParams(String name, u32 modulus_length, ::Crypto::UnsignedBigInteger public_exponent) | 
					
						
							|  |  |  |         : AlgorithmParams(move(name)) | 
					
						
							|  |  |  |         , modulus_length(modulus_length) | 
					
						
							|  |  |  |         , public_exponent(move(public_exponent)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  |     u32 modulus_length; | 
					
						
							|  |  |  |     // NOTE that the raw data is going to be in Big Endian u8[] format
 | 
					
						
							|  |  |  |     ::Crypto::UnsignedBigInteger public_exponent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // https://w3c.github.io/webcrypto/#dfn-RsaHashedKeyGenParams
 | 
					
						
							|  |  |  | struct RsaHashedKeyGenParams : public RsaKeyGenParams { | 
					
						
							| 
									
										
										
										
											2024-03-13 21:26:00 -06:00
										 |  |  |     virtual ~RsaHashedKeyGenParams() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RsaHashedKeyGenParams(String name, u32 modulus_length, ::Crypto::UnsignedBigInteger public_exponent, HashAlgorithmIdentifier hash) | 
					
						
							|  |  |  |         : RsaKeyGenParams(move(name), modulus_length, move(public_exponent)) | 
					
						
							|  |  |  |         , hash(move(hash)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  |     HashAlgorithmIdentifier hash; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-14 21:57:32 -06:00
										 |  |  | // https://w3c.github.io/webcrypto/#dfn-RsaHashedImportParams
 | 
					
						
							|  |  |  | struct RsaHashedImportParams : public AlgorithmParams { | 
					
						
							|  |  |  |     virtual ~RsaHashedImportParams() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RsaHashedImportParams(String name, HashAlgorithmIdentifier hash) | 
					
						
							|  |  |  |         : AlgorithmParams(move(name)) | 
					
						
							|  |  |  |         , hash(move(hash)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     HashAlgorithmIdentifier hash; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-14 23:07:13 -06:00
										 |  |  | // https://w3c.github.io/webcrypto/#dfn-RsaOaepParams
 | 
					
						
							|  |  |  | struct RsaOaepParams : public AlgorithmParams { | 
					
						
							|  |  |  |     virtual ~RsaOaepParams() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RsaOaepParams(String name, ByteBuffer label) | 
					
						
							|  |  |  |         : AlgorithmParams(move(name)) | 
					
						
							|  |  |  |         , label(move(label)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ByteBuffer label; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2024-03-27 01:27:42 +01:00
										 |  |  | // https://w3c.github.io/webcrypto/#dfn-EcKeyGenParams
 | 
					
						
							|  |  |  | struct EcKeyGenParams : public AlgorithmParams { | 
					
						
							|  |  |  |     virtual ~EcKeyGenParams() override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     EcKeyGenParams(String name, NamedCurve named_curve) | 
					
						
							|  |  |  |         : AlgorithmParams(move(name)) | 
					
						
							|  |  |  |         , named_curve(move(named_curve)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NamedCurve named_curve; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static JS::ThrowCompletionOr<NonnullOwnPtr<AlgorithmParams>> from_value(JS::VM&, JS::Value); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2024-03-14 23:07:13 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  | class AlgorithmMethods { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     virtual ~AlgorithmMethods(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-14 22:39:48 -06:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return WebIDL::NotSupportedError::create(m_realm, "encrypt is not supported"_fly_string); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-14 22:47:06 -06:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return WebIDL::NotSupportedError::create(m_realm, "decrypt is not supported"_fly_string); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 23:53:35 +01:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> sign(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return WebIDL::NotSupportedError::create(m_realm, "sign is not supported"_fly_string); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> digest(AlgorithmParams const&, ByteBuffer const&) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return WebIDL::NotSupportedError::create(m_realm, "digest is not supported"_fly_string); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return WebIDL::NotSupportedError::create(m_realm, "importKey is not supported"_fly_string); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 19:15:03 -07:00
										 |  |  |     virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return WebIDL::NotSupportedError::create(m_realm, "generateKey is not supported"_fly_string); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-13 21:19:57 -06:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return WebIDL::NotSupportedError::create(m_realm, "exportKey is not supported"_fly_string); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  |     static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new AlgorithmMethods(realm)); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  |     explicit AlgorithmMethods(JS::Realm& realm) | 
					
						
							|  |  |  |         : m_realm(realm) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     JS::Realm& m_realm; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  | class RSAOAEP : public AlgorithmMethods { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2024-03-14 23:07:13 -06:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> encrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override; | 
					
						
							| 
									
										
										
										
											2024-03-14 23:12:13 -06:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> decrypt(AlgorithmParams const&, JS::NonnullGCPtr<CryptoKey>, ByteBuffer const&) override; | 
					
						
							| 
									
										
										
										
											2024-03-14 23:07:13 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  |     virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override; | 
					
						
							| 
									
										
										
										
											2024-03-14 21:57:32 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override; | 
					
						
							| 
									
										
										
										
											2024-03-13 21:19:57 -06:00
										 |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Object>> export_key(Bindings::KeyFormat, JS::NonnullGCPtr<CryptoKey>) override; | 
					
						
							| 
									
										
										
										
											2024-03-08 16:30:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new RSAOAEP(realm)); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     explicit RSAOAEP(JS::Realm& realm) | 
					
						
							|  |  |  |         : AlgorithmMethods(realm) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  | class PBKDF2 : public AlgorithmMethods { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<CryptoKey>> import_key(AlgorithmParams const&, Bindings::KeyFormat, CryptoKey::InternalKeyData, bool, Vector<Bindings::KeyUsage> const&) override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new PBKDF2(realm)); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     explicit PBKDF2(JS::Realm& realm) | 
					
						
							|  |  |  |         : AlgorithmMethods(realm) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SHA : public AlgorithmMethods { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     virtual WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> digest(AlgorithmParams const&, ByteBuffer const&) override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new SHA(realm)); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     explicit SHA(JS::Realm& realm) | 
					
						
							|  |  |  |         : AlgorithmMethods(realm) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-27 01:27:42 +01:00
										 |  |  | class ECDSA : public AlgorithmMethods { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     virtual WebIDL::ExceptionOr<Variant<JS::NonnullGCPtr<CryptoKey>, JS::NonnullGCPtr<CryptoKeyPair>>> generate_key(AlgorithmParams const&, bool, Vector<Bindings::KeyUsage> const&) override; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static NonnullOwnPtr<AlgorithmMethods> create(JS::Realm& realm) { return adopt_own(*new ECDSA(realm)); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     explicit ECDSA(JS::Realm& realm) | 
					
						
							|  |  |  |         : AlgorithmMethods(realm) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-13 21:19:57 -06:00
										 |  |  | ErrorOr<String> base64_url_uint_encode(::Crypto::UnsignedBigInteger); | 
					
						
							| 
									
										
										
										
											2024-03-14 21:57:32 -06:00
										 |  |  | WebIDL::ExceptionOr<::Crypto::UnsignedBigInteger> base64_url_uint_decode(JS::Realm&, String const& base64_url_string); | 
					
						
							| 
									
										
										
										
											2024-03-13 21:19:57 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-06 16:53:50 -07:00
										 |  |  | } |