1 | /**************************************************************************/ |
2 | /* crypto.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef CRYPTO_H |
32 | #define CRYPTO_H |
33 | |
34 | #include "core/crypto/hashing_context.h" |
35 | #include "core/io/resource.h" |
36 | #include "core/io/resource_loader.h" |
37 | #include "core/io/resource_saver.h" |
38 | #include "core/object/ref_counted.h" |
39 | |
40 | class CryptoKey : public Resource { |
41 | GDCLASS(CryptoKey, Resource); |
42 | |
43 | protected: |
44 | static void _bind_methods(); |
45 | static CryptoKey *(*_create)(); |
46 | |
47 | public: |
48 | static CryptoKey *create(); |
49 | virtual Error load(String p_path, bool p_public_only = false) = 0; |
50 | virtual Error save(String p_path, bool p_public_only = false) = 0; |
51 | virtual String save_to_string(bool p_public_only = false) = 0; |
52 | virtual Error load_from_string(String p_string_key, bool p_public_only = false) = 0; |
53 | virtual bool is_public_only() const = 0; |
54 | }; |
55 | |
56 | class X509Certificate : public Resource { |
57 | GDCLASS(X509Certificate, Resource); |
58 | |
59 | protected: |
60 | static void _bind_methods(); |
61 | static X509Certificate *(*_create)(); |
62 | |
63 | public: |
64 | static X509Certificate *create(); |
65 | virtual Error load(String p_path) = 0; |
66 | virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0; |
67 | virtual Error save(String p_path) = 0; |
68 | virtual String save_to_string() = 0; |
69 | virtual Error load_from_string(const String &string) = 0; |
70 | }; |
71 | |
72 | class TLSOptions : public RefCounted { |
73 | GDCLASS(TLSOptions, RefCounted); |
74 | |
75 | public: |
76 | enum TLSVerifyMode { |
77 | TLS_VERIFY_NONE = 0, |
78 | TLS_VERIFY_CERT = 1, |
79 | TLS_VERIFY_FULL = 2, |
80 | }; |
81 | |
82 | private: |
83 | bool server_mode = false; |
84 | String common_name; |
85 | TLSVerifyMode verify_mode = TLS_VERIFY_FULL; |
86 | Ref<X509Certificate> trusted_ca_chain; |
87 | Ref<X509Certificate> own_certificate; |
88 | Ref<CryptoKey> private_key; |
89 | |
90 | protected: |
91 | static void _bind_methods(); |
92 | |
93 | public: |
94 | static Ref<TLSOptions> client(Ref<X509Certificate> p_trusted_chain = Ref<X509Certificate>(), const String &p_common_name_override = String()); |
95 | static Ref<TLSOptions> client_unsafe(Ref<X509Certificate> p_trusted_chain); |
96 | static Ref<TLSOptions> server(Ref<CryptoKey> p_own_key, Ref<X509Certificate> p_own_certificate); |
97 | |
98 | TLSVerifyMode get_verify_mode() const { return verify_mode; } |
99 | String get_common_name() const { return common_name; } |
100 | Ref<X509Certificate> get_trusted_ca_chain() const { return trusted_ca_chain; } |
101 | Ref<X509Certificate> get_own_certificate() const { return own_certificate; } |
102 | Ref<CryptoKey> get_private_key() const { return private_key; } |
103 | bool is_server() const { return server_mode; } |
104 | }; |
105 | |
106 | class HMACContext : public RefCounted { |
107 | GDCLASS(HMACContext, RefCounted); |
108 | |
109 | protected: |
110 | static void _bind_methods(); |
111 | static HMACContext *(*_create)(); |
112 | |
113 | public: |
114 | static HMACContext *create(); |
115 | |
116 | virtual Error start(HashingContext::HashType p_hash_type, PackedByteArray p_key) = 0; |
117 | virtual Error update(PackedByteArray p_data) = 0; |
118 | virtual PackedByteArray finish() = 0; |
119 | |
120 | HMACContext() {} |
121 | virtual ~HMACContext() {} |
122 | }; |
123 | |
124 | class Crypto : public RefCounted { |
125 | GDCLASS(Crypto, RefCounted); |
126 | |
127 | protected: |
128 | static void _bind_methods(); |
129 | static Crypto *(*_create)(); |
130 | static void (*_load_default_certificates)(String p_path); |
131 | |
132 | public: |
133 | static Crypto *create(); |
134 | static void load_default_certificates(String p_path); |
135 | |
136 | virtual PackedByteArray generate_random_bytes(int p_bytes) = 0; |
137 | virtual Ref<CryptoKey> generate_rsa(int p_bytes) = 0; |
138 | virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) = 0; |
139 | |
140 | virtual Vector<uint8_t> sign(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Ref<CryptoKey> p_key) = 0; |
141 | virtual bool verify(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Vector<uint8_t> p_signature, Ref<CryptoKey> p_key) = 0; |
142 | virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_plaintext) = 0; |
143 | virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_ciphertext) = 0; |
144 | |
145 | PackedByteArray hmac_digest(HashingContext::HashType p_hash_type, PackedByteArray p_key, PackedByteArray p_msg); |
146 | |
147 | // Compares two PackedByteArrays for equality without leaking timing information in order to prevent timing attacks. |
148 | // @see: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy |
149 | bool constant_time_compare(PackedByteArray p_trusted, PackedByteArray p_received); |
150 | |
151 | Crypto() {} |
152 | }; |
153 | |
154 | class ResourceFormatLoaderCrypto : public ResourceFormatLoader { |
155 | public: |
156 | virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "" , Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE); |
157 | virtual void get_recognized_extensions(List<String> *p_extensions) const; |
158 | virtual bool handles_type(const String &p_type) const; |
159 | virtual String get_resource_type(const String &p_path) const; |
160 | }; |
161 | |
162 | class ResourceFormatSaverCrypto : public ResourceFormatSaver { |
163 | public: |
164 | virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0); |
165 | virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; |
166 | virtual bool recognize(const Ref<Resource> &p_resource) const; |
167 | }; |
168 | |
169 | #endif // CRYPTO_H |
170 | |