summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub1
-rw-r--r--core/bind/core_bind.cpp2
-rw-r--r--core/crypto/SCsub38
-rw-r--r--core/crypto/crypto.cpp170
-rw-r--r--core/crypto/crypto.h105
-rw-r--r--core/crypto/crypto_core.cpp (renamed from core/math/crypto_core.cpp)32
-rw-r--r--core/crypto/crypto_core.h (renamed from core/math/crypto_core.h)20
-rw-r--r--core/crypto/hashing_context.cpp137
-rw-r--r--core/crypto/hashing_context.h66
-rw-r--r--core/io/file_access_encrypted.cpp2
-rw-r--r--core/io/stream_peer_ssl.cpp68
-rw-r--r--core/io/stream_peer_ssl.h13
-rw-r--r--core/math/SCsub33
-rw-r--r--core/os/file_access.cpp2
-rw-r--r--core/os/input.cpp1
-rw-r--r--core/os/input.h1
-rw-r--r--core/os/os.cpp5
-rw-r--r--core/os/os.h1
-rw-r--r--core/register_core_types.cpp24
-rw-r--r--core/ustring.cpp2
-rw-r--r--core/variant_call.cpp11
21 files changed, 610 insertions, 124 deletions
diff --git a/core/SCsub b/core/SCsub
index 85e5f1b089..ed9a0a231d 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -159,6 +159,7 @@ env.CommandNoCache('#core/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]
# Chain load SCsubs
SConscript('os/SCsub')
SConscript('math/SCsub')
+SConscript('crypto/SCsub')
SConscript('io/SCsub')
SConscript('bind/SCsub')
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 56369a3cc6..8e0d156438 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -30,11 +30,11 @@
#include "core_bind.h"
+#include "core/crypto/crypto_core.h"
#include "core/io/file_access_compressed.h"
#include "core/io/file_access_encrypted.h"
#include "core/io/json.h"
#include "core/io/marshalls.h"
-#include "core/math/crypto_core.h"
#include "core/math/geometry.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
diff --git a/core/crypto/SCsub b/core/crypto/SCsub
new file mode 100644
index 0000000000..0a3f05d87a
--- /dev/null
+++ b/core/crypto/SCsub
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env_crypto = env.Clone()
+
+is_builtin = env["builtin_mbedtls"]
+has_module = env["module_mbedtls_enabled"]
+
+if is_builtin or not has_module:
+ # Use our headers for builtin or if the module is not going to be compiled.
+ # We decided not to depend on system mbedtls just for these few files that can
+ # be easily extracted.
+ env_crypto.Prepend(CPPPATH=["#thirdparty/mbedtls/include"])
+
+# MbedTLS core functions (for CryptoCore).
+# If the mbedtls module is compiled we don't need to add the .c files with our
+# custom config since they will be built by the module itself.
+# Only if the module is not enabled, we must compile here the required sources
+# to make a "light" build with only the necessary mbedtls files.
+if not has_module:
+ env_thirdparty = env_crypto.Clone()
+ env_thirdparty.disable_warnings()
+ # Custom config file
+ env_thirdparty.Append(CPPDEFINES=[('MBEDTLS_CONFIG_FILE', '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')])
+ thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/"
+ thirdparty_mbedtls_sources = [
+ "aes.c",
+ "base64.c",
+ "md5.c",
+ "sha1.c",
+ "sha256.c",
+ "godot_core_mbedtls_platform.c"
+ ]
+ thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources]
+ env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources)
+
+env_crypto.add_source_files(env.core_sources, "*.cpp")
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
new file mode 100644
index 0000000000..925a01b36a
--- /dev/null
+++ b/core/crypto/crypto.cpp
@@ -0,0 +1,170 @@
+/*************************************************************************/
+/* crypto.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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
+
+CryptoKey *(*CryptoKey::_create)() = NULL;
+CryptoKey *CryptoKey::create() {
+ if (_create)
+ return _create();
+ return NULL;
+}
+
+void CryptoKey::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save);
+ ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load);
+}
+
+X509Certificate *(*X509Certificate::_create)() = NULL;
+X509Certificate *X509Certificate::create() {
+ if (_create)
+ return _create();
+ return NULL;
+}
+
+void X509Certificate::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save);
+ ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load);
+}
+
+/// Crypto
+
+void (*Crypto::_load_default_certificates)(String p_path) = NULL;
+Crypto *(*Crypto::_create)() = NULL;
+Crypto *Crypto::create() {
+ if (_create)
+ return _create();
+ return memnew(Crypto);
+}
+
+void Crypto::load_default_certificates(String p_path) {
+
+ if (_load_default_certificates)
+ _load_default_certificates(p_path);
+}
+
+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"));
+}
+
+PoolByteArray Crypto::generate_random_bytes(int p_bytes) {
+ ERR_FAIL_V_MSG(PoolByteArray(), "generate_random_bytes is not available when mbedtls module is disabled.");
+}
+
+Ref<CryptoKey> Crypto::generate_rsa(int p_bytes) {
+ ERR_FAIL_V_MSG(NULL, "generate_rsa is not available when mbedtls module is disabled.");
+}
+
+Ref<X509Certificate> Crypto::generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) {
+ ERR_FAIL_V_MSG(NULL, "generate_self_signed_certificate is not available when mbedtls module is disabled.");
+}
+
+Crypto::Crypto() {
+}
+
+/// Resource loader/saver
+
+RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error) {
+
+ String el = p_path.get_extension().to_lower();
+ if (el == "crt") {
+ X509Certificate *cert = X509Certificate::create();
+ if (cert)
+ cert->load(p_path);
+ return cert;
+ } else if (el == "key") {
+ CryptoKey *key = CryptoKey::create();
+ if (key)
+ key->load(p_path);
+ return key;
+ }
+ return NULL;
+}
+
+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();
+ if (el == "crt")
+ return "X509Certificate";
+ else if (el == "key")
+ return "CryptoKey";
+ 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);
+ }
+ ERR_FAIL_COND_V(err != OK, err);
+ 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");
+ }
+}
+bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
+
+ return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
+}
diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h
new file mode 100644
index 0000000000..2de81f5b57
--- /dev/null
+++ b/core/crypto/crypto.h
@@ -0,0 +1,105 @@
+/*************************************************************************/
+/* crypto.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef CRYPTO_H
+#define CRYPTO_H
+
+#include "core/reference.h"
+#include "core/resource.h"
+
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+
+class CryptoKey : public Resource {
+ GDCLASS(CryptoKey, Resource);
+
+protected:
+ static void _bind_methods();
+ static CryptoKey *(*_create)();
+
+public:
+ static CryptoKey *create();
+ virtual Error load(String p_path) = 0;
+ virtual Error save(String p_path) = 0;
+};
+
+class X509Certificate : public Resource {
+ GDCLASS(X509Certificate, Resource);
+
+protected:
+ static void _bind_methods();
+ static X509Certificate *(*_create)();
+
+public:
+ static X509Certificate *create();
+ virtual Error load(String p_path) = 0;
+ virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
+ virtual Error save(String p_path) = 0;
+};
+
+class Crypto : public Reference {
+ GDCLASS(Crypto, Reference);
+
+protected:
+ static void _bind_methods();
+ static Crypto *(*_create)();
+ static void (*_load_default_certificates)(String p_path);
+
+public:
+ static Crypto *create();
+ static void load_default_certificates(String p_path);
+
+ virtual PoolByteArray generate_random_bytes(int p_bytes);
+ virtual Ref<CryptoKey> generate_rsa(int p_bytes);
+ virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
+
+ Crypto();
+};
+
+class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
+ GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader);
+
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
+class ResourceFormatSaverCrypto : public ResourceFormatSaver {
+ GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver);
+
+public:
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+ virtual bool recognize(const RES &p_resource) const;
+};
+
+#endif // CRYPTO_H
diff --git a/core/math/crypto_core.cpp b/core/crypto/crypto_core.cpp
index d7ba54e469..51c2e3c9e5 100644
--- a/core/math/crypto_core.cpp
+++ b/core/crypto/crypto_core.cpp
@@ -52,7 +52,7 @@ Error CryptoCore::MD5Context::start() {
return ret ? FAILED : OK;
}
-Error CryptoCore::MD5Context::update(uint8_t *p_src, size_t p_len) {
+Error CryptoCore::MD5Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
@@ -62,6 +62,32 @@ Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) {
return ret ? FAILED : OK;
}
+// SHA1
+CryptoCore::SHA1Context::SHA1Context() {
+ ctx = memalloc(sizeof(mbedtls_sha1_context));
+ mbedtls_sha1_init((mbedtls_sha1_context *)ctx);
+}
+
+CryptoCore::SHA1Context::~SHA1Context() {
+ mbedtls_sha1_free((mbedtls_sha1_context *)ctx);
+ memfree((mbedtls_sha1_context *)ctx);
+}
+
+Error CryptoCore::SHA1Context::start() {
+ int ret = mbedtls_sha1_starts_ret((mbedtls_sha1_context *)ctx);
+ return ret ? FAILED : OK;
+}
+
+Error CryptoCore::SHA1Context::update(const uint8_t *p_src, size_t p_len) {
+ int ret = mbedtls_sha1_update_ret((mbedtls_sha1_context *)ctx, p_src, p_len);
+ return ret ? FAILED : OK;
+}
+
+Error CryptoCore::SHA1Context::finish(unsigned char r_hash[20]) {
+ int ret = mbedtls_sha1_finish_ret((mbedtls_sha1_context *)ctx, r_hash);
+ return ret ? FAILED : OK;
+}
+
// SHA256
CryptoCore::SHA256Context::SHA256Context() {
ctx = memalloc(sizeof(mbedtls_sha256_context));
@@ -78,12 +104,12 @@ Error CryptoCore::SHA256Context::start() {
return ret ? FAILED : OK;
}
-Error CryptoCore::SHA256Context::update(uint8_t *p_src, size_t p_len) {
+Error CryptoCore::SHA256Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
-Error CryptoCore::SHA256Context::finish(unsigned char r_hash[16]) {
+Error CryptoCore::SHA256Context::finish(unsigned char r_hash[32]) {
int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
diff --git a/core/math/crypto_core.h b/core/crypto/crypto_core.h
index e28cb5a792..c859d612d4 100644
--- a/core/math/crypto_core.h
+++ b/core/crypto/crypto_core.h
@@ -46,10 +46,24 @@ public:
~MD5Context();
Error start();
- Error update(uint8_t *p_src, size_t p_len);
+ Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[16]);
};
+ class SHA1Context {
+
+ private:
+ void *ctx; // To include, or not to include...
+
+ public:
+ SHA1Context();
+ ~SHA1Context();
+
+ Error start();
+ Error update(const uint8_t *p_src, size_t p_len);
+ Error finish(unsigned char r_hash[20]);
+ };
+
class SHA256Context {
private:
@@ -60,8 +74,8 @@ public:
~SHA256Context();
Error start();
- Error update(uint8_t *p_src, size_t p_len);
- Error finish(unsigned char r_hash[16]);
+ Error update(const uint8_t *p_src, size_t p_len);
+ Error finish(unsigned char r_hash[32]);
};
class AESContext {
diff --git a/core/crypto/hashing_context.cpp b/core/crypto/hashing_context.cpp
new file mode 100644
index 0000000000..bdccb258dd
--- /dev/null
+++ b/core/crypto/hashing_context.cpp
@@ -0,0 +1,137 @@
+/*************************************************************************/
+/* hashing_context.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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 "hashing_context.h"
+
+#include "core/crypto/crypto_core.h"
+
+Error HashingContext::start(HashType p_type) {
+ ERR_FAIL_COND_V(ctx != NULL, ERR_ALREADY_IN_USE);
+ _create_ctx(p_type);
+ ERR_FAIL_COND_V(ctx == NULL, ERR_UNAVAILABLE);
+ switch (type) {
+ case HASH_MD5:
+ return ((CryptoCore::MD5Context *)ctx)->start();
+ case HASH_SHA1:
+ return ((CryptoCore::SHA1Context *)ctx)->start();
+ case HASH_SHA256:
+ return ((CryptoCore::SHA256Context *)ctx)->start();
+ }
+ return ERR_UNAVAILABLE;
+}
+
+Error HashingContext::update(PoolByteArray p_chunk) {
+ ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED);
+ size_t len = p_chunk.size();
+ PoolByteArray::Read r = p_chunk.read();
+ switch (type) {
+ case HASH_MD5:
+ return ((CryptoCore::MD5Context *)ctx)->update(&r[0], len);
+ case HASH_SHA1:
+ return ((CryptoCore::SHA1Context *)ctx)->update(&r[0], len);
+ case HASH_SHA256:
+ return ((CryptoCore::SHA256Context *)ctx)->update(&r[0], len);
+ }
+ return ERR_UNAVAILABLE;
+}
+
+PoolByteArray HashingContext::finish() {
+ ERR_FAIL_COND_V(ctx == NULL, PoolByteArray());
+ PoolByteArray out;
+ Error err = FAILED;
+ switch (type) {
+ case HASH_MD5:
+ out.resize(16);
+ err = ((CryptoCore::MD5Context *)ctx)->finish(out.write().ptr());
+ break;
+ case HASH_SHA1:
+ out.resize(20);
+ err = ((CryptoCore::SHA1Context *)ctx)->finish(out.write().ptr());
+ break;
+ case HASH_SHA256:
+ out.resize(32);
+ err = ((CryptoCore::SHA256Context *)ctx)->finish(out.write().ptr());
+ break;
+ }
+ _delete_ctx();
+ ERR_FAIL_COND_V(err != OK, PoolByteArray());
+ return out;
+}
+
+void HashingContext::_create_ctx(HashType p_type) {
+ type = p_type;
+ switch (type) {
+ case HASH_MD5:
+ ctx = memnew(CryptoCore::MD5Context);
+ break;
+ case HASH_SHA1:
+ ctx = memnew(CryptoCore::SHA1Context);
+ break;
+ case HASH_SHA256:
+ ctx = memnew(CryptoCore::SHA256Context);
+ break;
+ default:
+ ctx = NULL;
+ }
+}
+
+void HashingContext::_delete_ctx() {
+ return;
+ switch (type) {
+ case HASH_MD5:
+ memdelete((CryptoCore::MD5Context *)ctx);
+ break;
+ case HASH_SHA1:
+ memdelete((CryptoCore::SHA1Context *)ctx);
+ break;
+ case HASH_SHA256:
+ memdelete((CryptoCore::SHA256Context *)ctx);
+ break;
+ }
+ ctx = NULL;
+}
+
+void HashingContext::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("start", "type"), &HashingContext::start);
+ ClassDB::bind_method(D_METHOD("update", "chunk"), &HashingContext::update);
+ ClassDB::bind_method(D_METHOD("finish"), &HashingContext::finish);
+ BIND_ENUM_CONSTANT(HASH_MD5);
+ BIND_ENUM_CONSTANT(HASH_SHA1);
+ BIND_ENUM_CONSTANT(HASH_SHA256);
+}
+
+HashingContext::HashingContext() {
+ ctx = NULL;
+}
+
+HashingContext::~HashingContext() {
+ if (ctx != NULL)
+ _delete_ctx();
+}
diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h
new file mode 100644
index 0000000000..aa69636f2c
--- /dev/null
+++ b/core/crypto/hashing_context.h
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* hashing_context.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef HASHING_CONTEXT_H
+#define HASHING_CONTEXT_H
+
+#include "core/reference.h"
+
+class HashingContext : public Reference {
+ GDCLASS(HashingContext, Reference);
+
+public:
+ enum HashType {
+ HASH_MD5,
+ HASH_SHA1,
+ HASH_SHA256
+ };
+
+private:
+ void *ctx;
+ HashType type;
+
+protected:
+ static void _bind_methods();
+ void _create_ctx(HashType p_type);
+ void _delete_ctx();
+
+public:
+ Error start(HashType p_type);
+ Error update(PoolByteArray p_chunk);
+ PoolByteArray finish();
+
+ HashingContext();
+ ~HashingContext();
+};
+
+VARIANT_ENUM_CAST(HashingContext::HashType);
+
+#endif // HASHING_CONTEXT_H
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 1452c61d1a..77decc107d 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -30,7 +30,7 @@
#include "file_access_encrypted.h"
-#include "core/math/crypto_core.h"
+#include "core/crypto/crypto_core.h"
#include "core/os/copymem.h"
#include "core/print_string.h"
#include "core/variant.h"
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index ccce48ccd7..f2eaf57acc 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -30,10 +30,7 @@
#include "stream_peer_ssl.h"
-#include "core/io/certs_compressed.gen.h"
-#include "core/io/compression.h"
-#include "core/os/file_access.h"
-#include "core/project_settings.h"
+#include "core/engine.h"
StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL;
@@ -44,22 +41,8 @@ StreamPeerSSL *StreamPeerSSL::create() {
return NULL;
}
-StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL;
bool StreamPeerSSL::available = false;
-void StreamPeerSSL::load_certs_from_memory(const PoolByteArray &p_memory) {
- if (load_certs_func)
- load_certs_func(p_memory);
-}
-
-void StreamPeerSSL::load_certs_from_file(String p_path) {
- if (p_path != "") {
- PoolByteArray certs = get_cert_file_as_array(p_path);
- if (certs.size() > 0)
- load_certs_func(certs);
- }
-}
-
bool StreamPeerSSL::is_available() {
return available;
}
@@ -72,56 +55,11 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
return blocking_handshake;
}
-PoolByteArray StreamPeerSSL::get_cert_file_as_array(String p_path) {
-
- PoolByteArray out;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (f) {
- int flen = f->get_len();
- out.resize(flen + 1);
- PoolByteArray::Write w = out.write();
- f->get_buffer(w.ptr(), flen);
- w[flen] = 0; // Make sure it ends with string terminator
- memdelete(f);
-#ifdef DEBUG_ENABLED
- print_verbose(vformat("Loaded certs from '%s'.", p_path));
-#endif
- }
-
- return out;
-}
-
-PoolByteArray StreamPeerSSL::get_project_cert_array() {
-
- PoolByteArray out;
- String certs_path = GLOBAL_DEF("network/ssl/certificates", "");
- ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
-
- if (certs_path != "") {
- // Use certs defined in project settings.
- return get_cert_file_as_array(certs_path);
- }
-#ifdef BUILTIN_CERTS_ENABLED
- else {
- // Use builtin certs only if user did not override it in project settings.
- out.resize(_certs_uncompressed_size + 1);
- PoolByteArray::Write w = out.write();
- Compression::decompress(w.ptr(), _certs_uncompressed_size, _certs_compressed, _certs_compressed_size, Compression::MODE_DEFLATE);
- w[_certs_uncompressed_size] = 0; // Make sure it ends with string terminator
-#ifdef DEBUG_ENABLED
- print_verbose("Loaded builtin certs");
-#endif
- }
-#endif
-
- return out;
-}
-
void StreamPeerSSL::_bind_methods() {
ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
- ClassDB::bind_method(D_METHOD("accept_stream", "base"), &StreamPeerSSL::accept_stream);
- ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()));
+ ClassDB::bind_method(D_METHOD("accept_stream", "stream", "private_key", "certificate", "chain"), &StreamPeerSSL::accept_stream, DEFVAL(Ref<X509Certificate>()));
+ ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname", "valid_certificate"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()), DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerSSL::get_status);
ClassDB::bind_method(D_METHOD("disconnect_from_stream"), &StreamPeerSSL::disconnect_from_stream);
ClassDB::bind_method(D_METHOD("set_blocking_handshake_enabled", "enabled"), &StreamPeerSSL::set_blocking_handshake_enabled);
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index 482576c4c6..dedc35b9ac 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -31,19 +31,16 @@
#ifndef STREAM_PEER_SSL_H
#define STREAM_PEER_SSL_H
+#include "core/crypto/crypto.h"
#include "core/io/stream_peer.h"
class StreamPeerSSL : public StreamPeer {
GDCLASS(StreamPeerSSL, StreamPeer);
-public:
- typedef void (*LoadCertsFromMemory)(const PoolByteArray &p_certs);
-
protected:
static StreamPeerSSL *(*_create)();
static void _bind_methods();
- static LoadCertsFromMemory load_certs_func;
static bool available;
bool blocking_handshake;
@@ -61,18 +58,14 @@ public:
bool is_blocking_handshake_enabled() const;
virtual void poll() = 0;
- virtual Error accept_stream(Ref<StreamPeer> p_base) = 0;
- virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String()) = 0;
+ virtual Error accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>()) = 0;
+ virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String(), Ref<X509Certificate> p_valid_cert = Ref<X509Certificate>()) = 0;
virtual Status get_status() const = 0;
virtual void disconnect_from_stream() = 0;
static StreamPeerSSL *create();
- static PoolByteArray get_cert_file_as_array(String p_path);
- static PoolByteArray get_project_cert_array();
- static void load_certs_from_file(String p_path);
- static void load_certs_from_memory(const PoolByteArray &p_memory);
static bool is_available();
StreamPeerSSL();
diff --git a/core/math/SCsub b/core/math/SCsub
index 0995298a4b..be438fcfbe 100644
--- a/core/math/SCsub
+++ b/core/math/SCsub
@@ -2,37 +2,6 @@
Import('env')
-env_math = env.Clone() # Maybe make one specific for crypto?
-
-is_builtin = env["builtin_mbedtls"]
-has_module = env["module_mbedtls_enabled"]
-
-if is_builtin or not has_module:
- # Use our headers for builtin or if the module is not going to be compiled.
- # We decided not to depend on system mbedtls just for these few files that can
- # be easily extracted.
- env_math.Prepend(CPPPATH=["#thirdparty/mbedtls/include"])
-
-# MbedTLS core functions (for CryptoCore).
-# If the mbedtls module is compiled we don't need to add the .c files with our
-# custom config since they will be built by the module itself.
-# Only if the module is not enabled, we must compile here the required sources
-# to make a "light" build with only the necessary mbedtls files.
-if not has_module:
- env_thirdparty = env_math.Clone()
- env_thirdparty.disable_warnings()
- # Custom config file
- env_thirdparty.Append(CPPDEFINES=[('MBEDTLS_CONFIG_FILE', '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')])
- thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/"
- thirdparty_mbedtls_sources = [
- "aes.c",
- "base64.c",
- "md5.c",
- "sha1.c",
- "sha256.c",
- "godot_core_mbedtls_platform.c"
- ]
- thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources]
- env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources)
+env_math = env.Clone()
env_math.add_source_files(env.core_sources, "*.cpp")
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index ba94e87da6..9a8315a3bb 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -30,9 +30,9 @@
#include "file_access.h"
+#include "core/crypto/crypto_core.h"
#include "core/io/file_access_pack.h"
#include "core/io/marshalls.h"
-#include "core/math/crypto_core.h"
#include "core/os/os.h"
#include "core/project_settings.h"
diff --git a/core/os/input.cpp b/core/os/input.cpp
index f04d4a1b3e..51cb41b184 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -80,6 +80,7 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string);
ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
+ ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500));
ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity);
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
diff --git a/core/os/input.h b/core/os/input.h
index de04f239e6..a12ded176b 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -100,6 +100,7 @@ public:
virtual uint64_t get_joy_vibration_timestamp(int p_device) = 0;
virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0) = 0;
virtual void stop_joy_vibration(int p_device) = 0;
+ virtual void vibrate_handheld(int p_duration_ms = 500) = 0;
virtual Point2 get_mouse_position() const = 0;
virtual Point2 get_last_mouse_speed() const = 0;
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 0d7d150914..7531900480 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -186,6 +186,11 @@ int OS::get_process_id() const {
return -1;
};
+void OS::vibrate_handheld(int p_duration_ms) {
+
+ WARN_PRINTS("vibrate_handheld() only works with Android and iOS");
+}
+
bool OS::is_stdout_verbose() const {
return _verbose_stdout;
diff --git a/core/os/os.h b/core/os/os.h
index c0c346e9aa..e627773d88 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -265,6 +265,7 @@ public:
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL) = 0;
virtual Error kill(const ProcessID &p_pid) = 0;
virtual int get_process_id() const;
+ virtual void vibrate_handheld(int p_duration_ms = 500);
virtual Error shell_open(String p_uri);
virtual Error set_cwd(const String &p_cwd);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index e442546124..efc77bde48 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -34,6 +34,8 @@
#include "core/class_db.h"
#include "core/compressed_translation.h"
#include "core/core_string_names.h"
+#include "core/crypto/crypto.h"
+#include "core/crypto/hashing_context.h"
#include "core/engine.h"
#include "core/func_ref.h"
#include "core/input_map.h"
@@ -70,6 +72,8 @@ static Ref<ResourceFormatLoaderBinary> resource_loader_binary;
static Ref<ResourceFormatImporter> resource_format_importer;
static Ref<ResourceFormatLoaderImage> resource_format_image;
static Ref<TranslationLoaderPO> resource_format_po;
+static Ref<ResourceFormatSaverCrypto> resource_format_saver_crypto;
+static Ref<ResourceFormatLoaderCrypto> resource_format_loader_crypto;
static _ResourceLoader *_resource_loader = NULL;
static _ResourceSaver *_resource_saver = NULL;
@@ -151,7 +155,19 @@ void register_core_types() {
ClassDB::register_class<StreamPeerTCP>();
ClassDB::register_class<TCP_Server>();
ClassDB::register_class<PacketPeerUDP>();
+
+ // Crypto
+ ClassDB::register_class<HashingContext>();
+ ClassDB::register_custom_instance_class<X509Certificate>();
+ ClassDB::register_custom_instance_class<CryptoKey>();
+ ClassDB::register_custom_instance_class<Crypto>();
ClassDB::register_custom_instance_class<StreamPeerSSL>();
+
+ resource_format_saver_crypto.instance();
+ ResourceSaver::add_resource_format_saver(resource_format_saver_crypto);
+ resource_format_loader_crypto.instance();
+ ResourceLoader::add_resource_format_loader(resource_format_loader_crypto);
+
ClassDB::register_virtual_class<IP>();
ClassDB::register_virtual_class<PacketPeer>();
ClassDB::register_class<PacketPeerStream>();
@@ -211,6 +227,9 @@ void register_core_settings() {
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1"));
GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16));
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater"));
+
+ GLOBAL_DEF("network/ssl/certificates", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
}
void register_core_singletons() {
@@ -272,6 +291,11 @@ void unregister_core_types() {
ResourceLoader::remove_resource_format_loader(resource_format_po);
resource_format_po.unref();
+ ResourceSaver::remove_resource_format_saver(resource_format_saver_crypto);
+ resource_format_saver_crypto.unref();
+ ResourceLoader::remove_resource_format_loader(resource_format_loader_crypto);
+ resource_format_loader_crypto.unref();
+
if (ip)
memdelete(ip);
diff --git a/core/ustring.cpp b/core/ustring.cpp
index ed401c3763..4e9ab7be6b 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -31,7 +31,7 @@
#include "ustring.h"
#include "core/color.h"
-#include "core/math/crypto_core.h"
+#include "core/crypto/crypto_core.h"
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/print_string.h"
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 9ea2fed5ae..3ab1386b13 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -32,8 +32,8 @@
#include "core/color_names.inc"
#include "core/core_string_names.h"
+#include "core/crypto/crypto_core.h"
#include "core/io/compression.h"
-#include "core/math/crypto_core.h"
#include "core/object.h"
#include "core/os/os.h"
#include "core/script_language.h"
@@ -596,13 +596,10 @@ struct _VariantCall {
r_ret = decompressed;
}
- static void _call_PoolByteArray_sha256_string(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ static void _call_PoolByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) {
PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
PoolByteArray::Read r = ba->read();
- String s;
- unsigned char hash[32];
- CryptoCore::sha256((unsigned char *)r.ptr(), ba->size(), hash);
- s = String::hex_encode_buffer(hash, 32);
+ String s = String::hex_encode_buffer(&r[0], ba->size());
r_ret = s;
}
@@ -1762,7 +1759,7 @@ void register_variant_methods() {
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_ascii, varray());
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_utf8, varray());
- ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, sha256_string, varray());
+ ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, hex_encode, varray());
ADDFUNC1R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, compress, INT, "compression_mode", varray(0));
ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));