| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  crypto.cpp                                                           */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                      https://godotengine.org                          */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-01-01 11:16:22 +01:00
										 |  |  | /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "crypto.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "core/engine.h"
 | 
					
						
							|  |  |  | #include "core/io/certs_compressed.gen.h"
 | 
					
						
							|  |  |  | #include "core/io/compression.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Resources
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | CryptoKey *(*CryptoKey::_create)() = nullptr; | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | CryptoKey *CryptoKey::create() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (_create) { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		return _create(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CryptoKey::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | X509Certificate *(*X509Certificate::_create)() = nullptr; | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | X509Certificate *X509Certificate::create() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (_create) { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		return _create(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void X509Certificate::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Crypto
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | void (*Crypto::_load_default_certificates)(String p_path) = nullptr; | 
					
						
							|  |  |  | Crypto *(*Crypto::_create)() = nullptr; | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | Crypto *Crypto::create() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (_create) { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		return _create(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 	return memnew(Crypto); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Crypto::load_default_certificates(String p_path) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (_load_default_certificates) { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		_load_default_certificates(p_path); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Crypto::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000")); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | PackedByteArray Crypto::generate_random_bytes(int p_bytes) { | 
					
						
							|  |  |  | 	ERR_FAIL_V_MSG(PackedByteArray(), "generate_random_bytes is not available when mbedtls module is disabled."); | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<CryptoKey> Crypto::generate_rsa(int p_bytes) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_V_MSG(nullptr, "generate_rsa is not available when mbedtls module is disabled."); | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<X509Certificate> Crypto::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_V_MSG(nullptr, "generate_self_signed_certificate is not available when mbedtls module is disabled."); | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Resource loader/saver
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-19 23:19:21 -03:00
										 |  |  | RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 	String el = p_path.get_extension().to_lower(); | 
					
						
							|  |  |  | 	if (el == "crt") { | 
					
						
							|  |  |  | 		X509Certificate *cert = X509Certificate::create(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (cert) { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 			cert->load(p_path); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		return cert; | 
					
						
							|  |  |  | 	} else if (el == "key") { | 
					
						
							|  |  |  | 		CryptoKey *key = CryptoKey::create(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (key) { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 			key->load(p_path); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		return key; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	return nullptr; | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const { | 
					
						
							|  |  |  | 	p_extensions->push_back("crt"); | 
					
						
							|  |  |  | 	p_extensions->push_back("key"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const { | 
					
						
							|  |  |  | 	return p_type == "X509Certificate" || p_type == "CryptoKey"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const { | 
					
						
							|  |  |  | 	String el = p_path.get_extension().to_lower(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (el == "crt") { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		return "X509Certificate"; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else if (el == "key") { | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 		return "CryptoKey"; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 	return ""; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { | 
					
						
							|  |  |  | 	Error err; | 
					
						
							|  |  |  | 	Ref<X509Certificate> cert = p_resource; | 
					
						
							|  |  |  | 	Ref<CryptoKey> key = p_resource; | 
					
						
							|  |  |  | 	if (cert.is_valid()) { | 
					
						
							|  |  |  | 		err = cert->save(p_path); | 
					
						
							|  |  |  | 	} else if (key.is_valid()) { | 
					
						
							|  |  |  | 		err = key->save(p_path); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ERR_FAIL_V(ERR_INVALID_PARAMETER); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save Crypto resource to file '" + p_path + "'."); | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { | 
					
						
							|  |  |  | 	const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource); | 
					
						
							|  |  |  | 	const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource); | 
					
						
							|  |  |  | 	if (cert) { | 
					
						
							|  |  |  | 		p_extensions->push_back("crt"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (key) { | 
					
						
							|  |  |  | 		p_extensions->push_back("key"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-11 15:26:44 +02:00
										 |  |  | bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const { | 
					
						
							|  |  |  | 	return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource); | 
					
						
							|  |  |  | } |