Update mbedtls to 2.5.1 (#3964)
* Renaming changes: * macro prefix "POLARSSL" -> "MBEDTLS" * functions now prefixed with "mbedtls_" * rename PolarSSL++ -> mbedTLS++ * rename polarssl submodule * Use mbedtls' AES-CFB8 implementation. * Add cSslConfig to wrap mbedtls_ssl_config * Update cTCPLink and cBlockingSslClientSocket to use cSslConfig * Use cSslConfig in cHTTPServer * Use cSslConfig for cMojangAPI::SecureRequest * CI Fixes * Set -fomit-frame-pointer on the right target
This commit is contained in:
parent
c6bc822054
commit
84941bcc9f
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -7,9 +7,9 @@
|
||||
[submodule "Server/Plugins/ChatLog"]
|
||||
path = Server/Plugins/ChatLog
|
||||
url = https://github.com/cuberite/ChatLog.git
|
||||
[submodule "lib/polarssl"]
|
||||
path = lib/polarssl
|
||||
url = https://github.com/cuberite/polarssl.git
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://github.com/ARMmbed/mbedtls.git
|
||||
ignore = dirty
|
||||
[submodule "lib/SQLiteCpp"]
|
||||
path = lib/SQLiteCpp
|
||||
|
@ -1,4 +1,4 @@
|
||||
# This is the top-level CMakeLists.txt file for the Cuberite project
|
||||
# This is the top-level CMakeLists.txt file for the Cuberite project
|
||||
#
|
||||
# Use CMake to generate the build files for your platform
|
||||
#
|
||||
@ -209,8 +209,8 @@ link_directories(lib/jsoncpp/src/lib_json)
|
||||
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/lib/SQLiteCpp/CMakeLists.txt)
|
||||
message(FATAL_ERROR "SQLiteCpp is missing in folder lib/SQLiteCpp. Have you initialized the submodules / downloaded the extra libraries?")
|
||||
endif()
|
||||
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/lib/polarssl/CMakeLists.txt)
|
||||
message(FATAL_ERROR "PolarSSL is missing in folder lib/polarssl. Have you initialized the submodules / downloaded the extra libraries?")
|
||||
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/lib/mbedtls/CMakeLists.txt)
|
||||
message(FATAL_ERROR "mbedTLS is missing in folder lib/mbedtls. Have you initialized the submodules / downloaded the extra libraries?")
|
||||
endif()
|
||||
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/lib/libevent/CMakeLists.txt)
|
||||
message(FATAL_ERROR "LibEvent is missing in folder lib/libevent. Have you initialized and updated the submodules / downloaded the extra libraries?")
|
||||
@ -274,13 +274,13 @@ if (WIN32)
|
||||
endif()
|
||||
|
||||
# We use EXCLUDE_FROM_ALL so that only the explicit dependencies are used
|
||||
# (PolarSSL also has test and example programs in their CMakeLists.txt, we don't want those)
|
||||
include(lib/polarssl.cmake EXCLUDE_FROM_ALL)
|
||||
# (mbedTLS also has test and example programs in their CMakeLists.txt, we don't want those)
|
||||
include(lib/mbedtls.cmake EXCLUDE_FROM_ALL)
|
||||
|
||||
if(NOT MSVC AND "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm")
|
||||
# mbed TLS uses the frame pointer's register in inline assembly:
|
||||
# mbed TLS uses the frame pointer's register in inline assembly for its bignum implementation:
|
||||
# https://tls.mbed.org/kb/development/arm-thumb-error-r7-cannot-be-used-in-asm-here
|
||||
target_compile_options(mbedtls PUBLIC -fomit-frame-pointer)
|
||||
target_compile_options(mbedcrypto PRIVATE -fomit-frame-pointer)
|
||||
endif()
|
||||
|
||||
set_exe_flags()
|
||||
@ -302,7 +302,9 @@ if (MSVC)
|
||||
jsoncpp_lib_static
|
||||
lua
|
||||
luaexpat
|
||||
mbedcrypto
|
||||
mbedtls
|
||||
mbedx509
|
||||
sqlite
|
||||
SQLiteCpp
|
||||
tolualib
|
||||
|
@ -8,7 +8,7 @@ set_lib_flags()
|
||||
|
||||
# Set include paths to the used libraries:
|
||||
include_directories(SYSTEM "../../lib")
|
||||
include_directories(SYSTEM "../../lib/polarssl/include")
|
||||
include_directories(SYSTEM "../../lib/mbedtls/include")
|
||||
include_directories("../../src")
|
||||
|
||||
function(flatten_files arg1)
|
||||
@ -20,7 +20,7 @@ function(flatten_files arg1)
|
||||
set(${arg1} "${res}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
include(../../lib/polarssl.cmake)
|
||||
include(../../lib/mbedtls.cmake)
|
||||
add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib)
|
||||
|
||||
set_exe_flags()
|
||||
@ -30,12 +30,12 @@ set(SHARED_SRC
|
||||
../../src/ByteBuffer.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/UUID.cpp
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.cpp
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.cpp
|
||||
../../src/PolarSSL++/CryptoKey.cpp
|
||||
../../src/PolarSSL++/CtrDrbgContext.cpp
|
||||
../../src/PolarSSL++/EntropyContext.cpp
|
||||
../../src/PolarSSL++/RsaPrivateKey.cpp
|
||||
../../src/mbedTLS++/AesCfb128Decryptor.cpp
|
||||
../../src/mbedTLS++/AesCfb128Encryptor.cpp
|
||||
../../src/mbedTLS++/CryptoKey.cpp
|
||||
../../src/mbedTLS++/CtrDrbgContext.cpp
|
||||
../../src/mbedTLS++/EntropyContext.cpp
|
||||
../../src/mbedTLS++/RsaPrivateKey.cpp
|
||||
../../src/LoggerListeners.cpp
|
||||
../../src/Logger.cpp
|
||||
)
|
||||
@ -43,12 +43,12 @@ set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/UUID.h
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.h
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.h
|
||||
../../src/PolarSSL++/CryptoKey.h
|
||||
../../src/PolarSSL++/CtrDrbgContext.h
|
||||
../../src/PolarSSL++/EntropyContext.h
|
||||
../../src/PolarSSL++/RsaPrivateKey.h
|
||||
../../src/mbedTLS++/AesCfb128Decryptor.h
|
||||
../../src/mbedTLS++/AesCfb128Encryptor.h
|
||||
../../src/mbedTLS++/CryptoKey.h
|
||||
../../src/mbedTLS++/CtrDrbgContext.h
|
||||
../../src/mbedTLS++/EntropyContext.h
|
||||
../../src/mbedTLS++/RsaPrivateKey.h
|
||||
)
|
||||
set(SHARED_OSS_SRC
|
||||
../../src/OSSupport/CriticalSection.cpp
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// Connection.cpp
|
||||
|
||||
// Interfaces to the cConnection class representing a single pair of connected sockets
|
||||
@ -7,7 +7,7 @@
|
||||
#include "Connection.h"
|
||||
#include "Server.h"
|
||||
#include <iostream>
|
||||
#include "PolarSSL++/CryptoKey.h"
|
||||
#include "mbedTLS++/CryptoKey.h"
|
||||
#include "../../src/Logger.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// Connection.h
|
||||
|
||||
// Interfaces to the cConnection class representing a single pair of connected sockets
|
||||
@ -10,8 +10,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "PolarSSL++/AesCfb128Decryptor.h"
|
||||
#include "PolarSSL++/AesCfb128Encryptor.h"
|
||||
#include "mbedTLS++/AesCfb128Decryptor.h"
|
||||
#include "mbedTLS++/AesCfb128Encryptor.h"
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// Server.h
|
||||
|
||||
// Interfaces to the cServer class encapsulating the entire "server"
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PolarSSL++/RsaPrivateKey.h"
|
||||
#include "mbedTLS++/RsaPrivateKey.h"
|
||||
|
||||
|
||||
|
||||
|
1
lib/mbedtls
Submodule
1
lib/mbedtls
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f2a597fa3dd1c7b15e0fee62f6932b253295803d
|
@ -1,10 +1,10 @@
|
||||
|
||||
|
||||
# This script includes PolarSSL, if not already included.
|
||||
# It is needed for when multiple projects reference PolarSSL.
|
||||
|
||||
if(NOT TARGET mbedtls)
|
||||
message("including polarssl")
|
||||
message("including mbedtls")
|
||||
set(ENABLE_TESTING OFF CACHE BOOL "Disable tests")
|
||||
set(ENABLE_PROGRAMS OFF CACHE BOOL "Disable programs")
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/mbedtls/ ${CMAKE_CURRENT_BINARY_DIR}/lib/mbedtls EXCLUDE_FROM_ALL)
|
||||
endif()
|
@ -1 +0,0 @@
|
||||
Subproject commit 4f4c5b7450631e46a94cb89adf4a7737fbb178bc
|
@ -6,8 +6,8 @@
|
||||
#include "Globals.h"
|
||||
#include "LuaTCPLink.h"
|
||||
#include "LuaServerHandle.h"
|
||||
#include "../PolarSSL++/X509Cert.h"
|
||||
#include "../PolarSSL++/CryptoKey.h"
|
||||
#include "../mbedTLS++/X509Cert.h"
|
||||
#include "../mbedTLS++/CryptoKey.h"
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "ManualBindings.h"
|
||||
@ -6,8 +6,8 @@
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "tolua++/include/tolua++.h"
|
||||
#include "polarssl/md5.h"
|
||||
#include "polarssl/sha1.h"
|
||||
#include "mbedtls/md5.h"
|
||||
#include "mbedtls/sha1.h"
|
||||
#include "PluginLua.h"
|
||||
#include "PluginManager.h"
|
||||
#include "LuaWindow.h"
|
||||
@ -1838,7 +1838,7 @@ static int tolua_md5(lua_State * tolua_S)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
md5(SourceString, len, Output);
|
||||
mbedtls_md5(SourceString, len, Output);
|
||||
lua_pushlstring(tolua_S, reinterpret_cast<const char *>(Output), ARRAYCOUNT(Output));
|
||||
return 1;
|
||||
}
|
||||
@ -1869,7 +1869,7 @@ static int tolua_md5HexString(lua_State * tolua_S)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
md5(SourceString, len, md5Output);
|
||||
mbedtls_md5(SourceString, len, md5Output);
|
||||
|
||||
// Convert the md5 checksum to hex string:
|
||||
std::stringstream Output;
|
||||
@ -1896,7 +1896,7 @@ static int tolua_sha1(lua_State * tolua_S)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
sha1(SourceString, len, Output);
|
||||
mbedtls_sha1(SourceString, len, Output);
|
||||
lua_pushlstring(tolua_S, reinterpret_cast<const char *>(Output), ARRAYCOUNT(Output));
|
||||
return 1;
|
||||
}
|
||||
@ -1915,7 +1915,7 @@ static int tolua_sha1HexString(lua_State * tolua_S)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
sha1(SourceString, len, sha1Output);
|
||||
mbedtls_sha1(SourceString, len, sha1Output);
|
||||
|
||||
// Convert the sha1 checksum to hex string:
|
||||
std::stringstream Output;
|
||||
|
@ -1,13 +1,13 @@
|
||||
project (Cuberite)
|
||||
project (Cuberite)
|
||||
|
||||
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/jsoncpp/include")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/mbedtls/include")
|
||||
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/libevent/include")
|
||||
|
||||
set(FOLDERS
|
||||
OSSupport HTTP Items Blocks Protocol Generating PolarSSL++ Bindings
|
||||
OSSupport HTTP Items Blocks Protocol Generating mbedTLS++ Bindings
|
||||
WorldStorage Mobs Entities Simulator Simulator/IncrementalRedstoneSimulator
|
||||
BlockEntities UI Noise
|
||||
)
|
||||
@ -177,7 +177,7 @@ endif()
|
||||
if (NOT MSVC)
|
||||
# Bindings need to reference other folders, so they are done here instead
|
||||
# lib dependencies are not included
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
|
||||
include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/mbedtls/include")
|
||||
|
||||
foreach(folder ${FOLDERS})
|
||||
add_subdirectory(${folder})
|
||||
@ -349,7 +349,7 @@ if (NOT MSVC)
|
||||
OSSupport HTTPServer Bindings Items Blocks Noise
|
||||
Protocol Generating WorldStorage
|
||||
Mobs Entities Simulator IncrementalRedstoneSimulator
|
||||
BlockEntities UI PolarSSL++
|
||||
BlockEntities UI mbedTLS++
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "ClientHandle.h"
|
||||
#include "Server.h"
|
||||
@ -33,7 +33,7 @@
|
||||
#include "CompositeChat.h"
|
||||
#include "Items/ItemSword.h"
|
||||
|
||||
#include "polarssl/md5.h"
|
||||
#include "mbedtls/md5.h"
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// HTTPServer.cpp
|
||||
|
||||
// Implements the cHTTPServer class representing a HTTP webserver that uses cListenThread and cSocketThreads for processing
|
||||
@ -9,6 +9,7 @@
|
||||
#include "HTTPServerConnection.h"
|
||||
#include "HTTPFormParser.h"
|
||||
#include "SslHTTPServerConnection.h"
|
||||
#include "mbedTLS++/SslConfig.h"
|
||||
|
||||
|
||||
|
||||
@ -88,17 +89,23 @@ bool cHTTPServer::Initialize(void)
|
||||
AString KeyFile = cFile::ReadWholeFile("webadmin/httpskey.pem");
|
||||
if (!CertFile.empty() && !KeyFile.empty())
|
||||
{
|
||||
m_Cert.reset(new cX509Cert);
|
||||
int res = m_Cert->Parse(CertFile.data(), CertFile.size());
|
||||
auto Cert = std::make_shared<cX509Cert>();
|
||||
int res = Cert->Parse(CertFile.data(), CertFile.size());
|
||||
if (res == 0)
|
||||
{
|
||||
m_CertPrivKey.reset(new cCryptoKey);
|
||||
int res2 = m_CertPrivKey->ParsePrivate(KeyFile.data(), KeyFile.size(), "");
|
||||
if (res2 != 0)
|
||||
auto CertPrivKey = std::make_shared<cCryptoKey>();
|
||||
res = CertPrivKey->ParsePrivate(KeyFile.data(), KeyFile.size(), "");
|
||||
if (res == 0)
|
||||
{
|
||||
// Modifyable locally but otherwise must be const
|
||||
auto Config = cSslConfig::MakeDefaultConfig(false);
|
||||
Config->SetOwnCert(Cert, CertPrivKey);
|
||||
m_SslConfig = std::move(Config);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reading the private key failed, reset the cert:
|
||||
LOGWARNING("WebServer: Cannot read HTTPS certificate private key: -0x%x", -res2);
|
||||
m_Cert.reset();
|
||||
LOGWARNING("WebServer: Cannot read HTTPS certificate private key: -0x%x", -res);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -108,7 +115,7 @@ bool cHTTPServer::Initialize(void)
|
||||
}
|
||||
|
||||
// Notify the admin about the HTTPS / HTTP status
|
||||
if (m_Cert.get() == nullptr)
|
||||
if (m_SslConfig == nullptr)
|
||||
{
|
||||
LOGWARNING("WebServer: The server will run in unsecured HTTP mode.");
|
||||
LOGINFO("Put a valid HTTPS certificate in file 'webadmin/httpscert.crt' and its corresponding private key to 'webadmin/httpskey.pem' (without any password) to enable HTTPS support");
|
||||
@ -184,9 +191,9 @@ cTCPLink::cCallbacksPtr cHTTPServer::OnIncomingConnection(const AString & a_Remo
|
||||
UNUSED(a_RemoteIPAddress);
|
||||
UNUSED(a_RemotePort);
|
||||
|
||||
if (m_Cert.get() != nullptr)
|
||||
if (m_SslConfig != nullptr)
|
||||
{
|
||||
return std::make_shared<cSslHTTPServerConnection>(*this, m_Cert, m_CertPrivKey);
|
||||
return std::make_shared<cSslHTTPServerConnection>(*this, m_SslConfig);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// HTTPServer.h
|
||||
|
||||
// Declares the cHTTPServer class representing a HTTP webserver that uses cListenThread and cSocketThreads for processing
|
||||
@ -11,8 +11,8 @@
|
||||
|
||||
#include "../OSSupport/Network.h"
|
||||
#include "../IniFile.h"
|
||||
#include "PolarSSL++/CryptoKey.h"
|
||||
#include "PolarSSL++/X509Cert.h"
|
||||
#include "mbedTLS++/CryptoKey.h"
|
||||
#include "mbedTLS++/X509Cert.h"
|
||||
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
// fwd:
|
||||
class cHTTPIncomingRequest;
|
||||
class cHTTPServerConnection;
|
||||
class cSslConfig;
|
||||
|
||||
|
||||
|
||||
@ -70,11 +71,8 @@ protected:
|
||||
/** The callbacks to call for various events */
|
||||
cCallbacks * m_Callbacks;
|
||||
|
||||
/** The server certificate to use for the SSL connections */
|
||||
cX509CertPtr m_Cert;
|
||||
|
||||
/** The private key for m_Cert. */
|
||||
cCryptoKeyPtr m_CertPrivKey;
|
||||
/** Configuration for server ssl connections. */
|
||||
std::shared_ptr<const cSslConfig> m_SslConfig;
|
||||
|
||||
|
||||
/** Called by cHTTPServerListenCallbacks when there's a new incoming connection.
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// SslHTTPConnection.cpp
|
||||
|
||||
// Implements the cSslHTTPServerConnection class representing a HTTP connection made over a SSL link
|
||||
@ -11,14 +11,18 @@
|
||||
|
||||
|
||||
|
||||
cSslHTTPServerConnection::cSslHTTPServerConnection(cHTTPServer & a_HTTPServer, const cX509CertPtr & a_Cert, const cCryptoKeyPtr & a_PrivateKey) :
|
||||
cSslHTTPServerConnection::cSslHTTPServerConnection(cHTTPServer & a_HTTPServer, std::shared_ptr<const cSslConfig> a_Config):
|
||||
super(a_HTTPServer),
|
||||
m_Ssl(64000),
|
||||
m_Cert(a_Cert),
|
||||
m_PrivateKey(a_PrivateKey)
|
||||
m_Ssl(64000)
|
||||
{
|
||||
m_Ssl.Initialize(false);
|
||||
m_Ssl.SetOwnCert(a_Cert, a_PrivateKey);
|
||||
if (a_Config != nullptr)
|
||||
{
|
||||
m_Ssl.Initialize(a_Config);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Ssl.Initialize(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +63,7 @@ void cSslHTTPServerConnection::OnReceivedData(const char * a_Data, size_t a_Size
|
||||
// The link may have closed while processing the data, bail out:
|
||||
return;
|
||||
}
|
||||
else if (NumRead == POLARSSL_ERR_NET_WANT_READ)
|
||||
else if (NumRead == MBEDTLS_ERR_SSL_WANT_READ)
|
||||
{
|
||||
// SSL requires us to send data to peer first, do so by "sending" empty data:
|
||||
SendData(nullptr, 0);
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// SslHTTPServerConnection.h
|
||||
|
||||
// Declares the cSslHTTPServerConnection class representing a HTTP connection made over an SSL link
|
||||
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "HTTPServerConnection.h"
|
||||
#include "PolarSSL++/BufferedSslContext.h"
|
||||
#include "mbedTLS++/BufferedSslContext.h"
|
||||
|
||||
|
||||
|
||||
@ -24,19 +24,13 @@ class cSslHTTPServerConnection :
|
||||
public:
|
||||
/** Creates a new connection on the specified server.
|
||||
Sends the specified cert as the server certificate, uses the private key for decryption. */
|
||||
cSslHTTPServerConnection(cHTTPServer & a_HTTPServer, const cX509CertPtr & a_Cert, const cCryptoKeyPtr & a_PrivateKey);
|
||||
cSslHTTPServerConnection(cHTTPServer & a_HTTPServer, std::shared_ptr<const cSslConfig> a_Config);
|
||||
|
||||
virtual ~cSslHTTPServerConnection() override;
|
||||
|
||||
protected:
|
||||
cBufferedSslContext m_Ssl;
|
||||
|
||||
/** The certificate to send to the client */
|
||||
cX509CertPtr m_Cert;
|
||||
|
||||
/** The private key used for the certificate */
|
||||
cCryptoKeyPtr m_PrivateKey;
|
||||
|
||||
// cHTTPConnection overrides:
|
||||
virtual void OnReceivedData(const char * a_Data, size_t a_Size) override; // Data is received from the client
|
||||
virtual void SendData(const void * a_Data, size_t a_Size) override; // Data is to be sent to client
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include "UrlClient.h"
|
||||
#include "UrlParser.h"
|
||||
#include "HTTPMessageParser.h"
|
||||
#include "../PolarSSL++/X509Cert.h"
|
||||
#include "../PolarSSL++/CryptoKey.h"
|
||||
#include "../mbedTLS++/X509Cert.h"
|
||||
#include "../mbedTLS++/CryptoKey.h"
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
|
||||
|
||||
// TCPLinkImpl.cpp
|
||||
|
||||
// Implements the cTCPLinkImpl class implementing the TCP link functionality
|
||||
|
||||
#include "Globals.h"
|
||||
#include "TCPLinkImpl.h"
|
||||
#include "mbedTLS++/SslConfig.h"
|
||||
#include "NetworkSingleton.h"
|
||||
#include "ServerHandleImpl.h"
|
||||
#include "event2/buffer.h"
|
||||
@ -245,26 +246,29 @@ AString cTCPLinkImpl::StartTLSClient(
|
||||
{
|
||||
return "TLS is already active on this link";
|
||||
}
|
||||
if (
|
||||
((a_OwnCert == nullptr) && (a_OwnPrivKey != nullptr)) ||
|
||||
((a_OwnCert != nullptr) && (a_OwnPrivKey != nullptr))
|
||||
)
|
||||
if ((a_OwnCert == nullptr) != (a_OwnPrivKey == nullptr))
|
||||
{
|
||||
return "Either provide both the certificate and private key, or neither";
|
||||
}
|
||||
|
||||
// Create the TLS context:
|
||||
m_TlsContext.reset(new cLinkTlsContext(*this));
|
||||
m_TlsContext->Initialize(true);
|
||||
m_TlsContext = std::make_shared<cLinkTlsContext>(*this);
|
||||
if (a_OwnCert != nullptr)
|
||||
{
|
||||
m_TlsContext->SetOwnCert(a_OwnCert, a_OwnPrivKey);
|
||||
auto Config = cSslConfig::MakeDefaultConfig(true);
|
||||
Config->SetOwnCert(std::move(a_OwnCert), std::move(a_OwnPrivKey));
|
||||
m_TlsContext->Initialize(Config);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TlsContext->Initialize(true);
|
||||
}
|
||||
|
||||
m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext));
|
||||
|
||||
// Start the handshake:
|
||||
m_TlsContext->Handshake();
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -282,15 +286,18 @@ AString cTCPLinkImpl::StartTLSServer(
|
||||
{
|
||||
return "TLS is already active on this link";
|
||||
}
|
||||
if ((a_OwnCert == nullptr) || (a_OwnPrivKey == nullptr))
|
||||
if ((a_OwnCert == nullptr) || (a_OwnPrivKey == nullptr))
|
||||
{
|
||||
return "Provide the server certificate and private key";
|
||||
}
|
||||
|
||||
// Create the TLS context:
|
||||
m_TlsContext.reset(new cLinkTlsContext(*this));
|
||||
m_TlsContext->Initialize(false);
|
||||
m_TlsContext->SetOwnCert(a_OwnCert, a_OwnPrivKey);
|
||||
m_TlsContext = std::make_shared<cLinkTlsContext>(*this);
|
||||
{
|
||||
auto Config = cSslConfig::MakeDefaultConfig(false);
|
||||
Config->SetOwnCert(a_OwnCert, a_OwnPrivKey);
|
||||
m_TlsContext->Initialize(std::move(Config));
|
||||
}
|
||||
m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext));
|
||||
|
||||
// Push the initial data:
|
||||
@ -298,7 +305,7 @@ AString cTCPLinkImpl::StartTLSServer(
|
||||
|
||||
// Start the handshake:
|
||||
m_TlsContext->Handshake();
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -659,7 +666,7 @@ int cTCPLinkImpl::cLinkTlsContext::ReceiveEncrypted(unsigned char * a_Buffer, si
|
||||
// If there's nothing queued in the buffer, report empty buffer:
|
||||
if (m_EncryptedData.empty())
|
||||
{
|
||||
return POLARSSL_ERR_NET_WANT_READ;
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
|
||||
// Copy as much data as possible to the provided buffer:
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "Network.h"
|
||||
#include <event2/event.h>
|
||||
#include <event2/bufferevent.h>
|
||||
#include "../PolarSSL++/SslContext.h"
|
||||
#include "../mbedTLS++/SslContext.h"
|
||||
|
||||
|
||||
|
||||
|
@ -1,307 +0,0 @@
|
||||
|
||||
// SslContext.cpp
|
||||
|
||||
// Implements the cSslContext class that holds everything a single SSL context needs to function
|
||||
|
||||
#include "Globals.h"
|
||||
#include "SslContext.h"
|
||||
#include "EntropyContext.h"
|
||||
#include "CtrDrbgContext.h"
|
||||
#include "polarssl/debug.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cSslContext::cSslContext(void) :
|
||||
m_IsValid(false),
|
||||
m_HasHandshaken(false)
|
||||
{
|
||||
memset(&m_Ssl, 0, sizeof(m_Ssl));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cSslContext::~cSslContext()
|
||||
{
|
||||
if (m_IsValid)
|
||||
{
|
||||
ssl_free(&m_Ssl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::Initialize(bool a_IsClient, const std::shared_ptr<cCtrDrbgContext> & a_CtrDrbg)
|
||||
{
|
||||
// Check double-initialization:
|
||||
if (m_IsValid)
|
||||
{
|
||||
LOGWARNING("SSL: Double initialization is not supported.");
|
||||
return POLARSSL_ERR_SSL_BAD_INPUT_DATA; // There is no return value well-suited for this, reuse this one.
|
||||
}
|
||||
|
||||
// Set the CtrDrbg context, create a new one if needed:
|
||||
m_CtrDrbg = a_CtrDrbg;
|
||||
if (m_CtrDrbg.get() == nullptr)
|
||||
{
|
||||
m_CtrDrbg.reset(new cCtrDrbgContext);
|
||||
m_CtrDrbg->Initialize("Cuberite", 8);
|
||||
}
|
||||
|
||||
// Initialize PolarSSL's structures:
|
||||
memset(&m_Ssl, 0, sizeof(m_Ssl));
|
||||
int res = ssl_init(&m_Ssl);
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
ssl_set_endpoint(&m_Ssl, a_IsClient ? SSL_IS_CLIENT : SSL_IS_SERVER);
|
||||
ssl_set_authmode(&m_Ssl, SSL_VERIFY_NONE); // We cannot verify because we don't have a CA chain, required by PolarSSL, implemented yet (TODO)
|
||||
ssl_set_rng(&m_Ssl, ctr_drbg_random, &m_CtrDrbg->m_CtrDrbg);
|
||||
ssl_set_bio(&m_Ssl, ReceiveEncrypted, this, SendEncrypted, this);
|
||||
|
||||
#ifdef _DEBUG
|
||||
/*
|
||||
// These functions allow us to debug SSL and certificate problems, but produce way too much output,
|
||||
// so they're disabled until someone needs them
|
||||
ssl_set_dbg(&m_Ssl, &SSLDebugMessage, this);
|
||||
debug_set_threshold(2);
|
||||
|
||||
ssl_set_verify(&m_Ssl, &SSLVerifyCert, this);
|
||||
//*/
|
||||
|
||||
/*
|
||||
// Set ciphersuite to the easiest one to decode, so that the connection can be wireshark-decoded:
|
||||
static const int CipherSuites[] =
|
||||
{
|
||||
TLS_RSA_WITH_RC4_128_MD5,
|
||||
TLS_RSA_WITH_RC4_128_SHA,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
0, // Must be 0-terminated!
|
||||
};
|
||||
ssl_set_ciphersuites(&m_Ssl, CipherSuites);
|
||||
//*/
|
||||
#endif
|
||||
|
||||
m_IsValid = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cRsaPrivateKeyPtr & a_OwnCertPrivKey)
|
||||
{
|
||||
ASSERT(m_IsValid); // Call Initialize() first
|
||||
|
||||
// Check that both the cert and the key is valid:
|
||||
if ((a_OwnCert.get() == nullptr) || (a_OwnCertPrivKey.get() == nullptr))
|
||||
{
|
||||
LOGWARNING("SSL: Own certificate is not valid, skipping the set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have the cert stored for later, PolarSSL only uses the cert later on
|
||||
m_OwnCert = a_OwnCert;
|
||||
m_OwnCertPrivKey = a_OwnCertPrivKey;
|
||||
|
||||
// Set into the context:
|
||||
ssl_set_own_cert_rsa(&m_Ssl, m_OwnCert->GetInternal(), m_OwnCertPrivKey->GetInternal());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cCryptoKeyPtr & a_OwnCertPrivKey)
|
||||
{
|
||||
ASSERT(m_IsValid); // Call Initialize() first
|
||||
|
||||
// Check that both the cert and the key is valid:
|
||||
if ((a_OwnCert.get() == nullptr) || (a_OwnCertPrivKey.get() == nullptr))
|
||||
{
|
||||
LOGWARNING("SSL: Own certificate is not valid, skipping the set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have the cert stored for later, PolarSSL only uses the cert later on
|
||||
m_OwnCert = a_OwnCert;
|
||||
m_OwnCertPrivKey2 = a_OwnCertPrivKey;
|
||||
|
||||
// Set into the context:
|
||||
ssl_set_own_cert(&m_Ssl, m_OwnCert->GetInternal(), m_OwnCertPrivKey2->GetInternal());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslContext::SetCACerts(const cX509CertPtr & a_CACert, const AString & a_ExpectedPeerName)
|
||||
{
|
||||
ASSERT(m_IsValid); // Call Initialize() first
|
||||
|
||||
// Store the data in our internal buffers, to avoid losing the pointers later on
|
||||
// PolarSSL will need these after this call returns, and the caller may move / delete the data before that:
|
||||
m_ExpectedPeerName = a_ExpectedPeerName;
|
||||
m_CACerts = a_CACert;
|
||||
|
||||
// Set the trusted CA root cert store:
|
||||
ssl_set_authmode(&m_Ssl, SSL_VERIFY_REQUIRED);
|
||||
ssl_set_ca_chain(&m_Ssl, m_CACerts->GetInternal(), nullptr, m_ExpectedPeerName.empty() ? nullptr : m_ExpectedPeerName.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::WritePlain(const void * a_Data, size_t a_NumBytes)
|
||||
{
|
||||
ASSERT(m_IsValid); // Need to call Initialize() first
|
||||
if (!m_HasHandshaken)
|
||||
{
|
||||
int res = Handshake();
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return ssl_write(&m_Ssl, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::ReadPlain(void * a_Data, size_t a_MaxBytes)
|
||||
{
|
||||
ASSERT(m_IsValid); // Need to call Initialize() first
|
||||
if (!m_HasHandshaken)
|
||||
{
|
||||
int res = Handshake();
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return ssl_read(&m_Ssl, reinterpret_cast<unsigned char *>(a_Data), a_MaxBytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::Handshake(void)
|
||||
{
|
||||
ASSERT(m_IsValid); // Need to call Initialize() first
|
||||
ASSERT(!m_HasHandshaken); // Must not call twice
|
||||
|
||||
int res = ssl_handshake(&m_Ssl);
|
||||
if (res == 0)
|
||||
{
|
||||
m_HasHandshaken = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::NotifyClose(void)
|
||||
{
|
||||
return ssl_close_notify(&m_Ssl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
void cSslContext::SSLDebugMessage(void * a_UserParam, int a_Level, const char * a_Text)
|
||||
{
|
||||
if (a_Level > 3)
|
||||
{
|
||||
// Don't want the trace messages
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the terminating LF:
|
||||
size_t len = strlen(a_Text) - 1;
|
||||
while ((len > 0) && (a_Text[len] <= 32))
|
||||
{
|
||||
len--;
|
||||
}
|
||||
AString Text(a_Text, len + 1);
|
||||
|
||||
LOGD("SSL (%d): %s", a_Level, Text.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::SSLVerifyCert(void * a_This, x509_crt * a_Crt, int a_Depth, int * a_Flags)
|
||||
{
|
||||
char buf[1024];
|
||||
UNUSED(a_This);
|
||||
|
||||
LOG("Verify requested for (Depth %d):", a_Depth);
|
||||
x509_crt_info(buf, sizeof(buf) - 1, "", a_Crt);
|
||||
LOG("%s", buf);
|
||||
|
||||
int Flags = *a_Flags;
|
||||
if ((Flags & BADCERT_EXPIRED) != 0)
|
||||
{
|
||||
LOG(" ! server certificate has expired");
|
||||
}
|
||||
|
||||
if ((Flags & BADCERT_REVOKED) != 0)
|
||||
{
|
||||
LOG(" ! server certificate has been revoked");
|
||||
}
|
||||
|
||||
if ((Flags & BADCERT_CN_MISMATCH) != 0)
|
||||
{
|
||||
LOG(" ! CN mismatch");
|
||||
}
|
||||
|
||||
if ((Flags & BADCERT_NOT_TRUSTED) != 0)
|
||||
{
|
||||
LOG(" ! self-signed or not signed by a trusted CA");
|
||||
}
|
||||
|
||||
if ((Flags & BADCRL_NOT_TRUSTED) != 0)
|
||||
{
|
||||
LOG(" ! CRL not trusted");
|
||||
}
|
||||
|
||||
if ((Flags & BADCRL_EXPIRED) != 0)
|
||||
{
|
||||
LOG(" ! CRL expired");
|
||||
}
|
||||
|
||||
if ((Flags & BADCERT_OTHER) != 0)
|
||||
{
|
||||
LOG(" ! other (unknown) flag");
|
||||
}
|
||||
|
||||
if (Flags == 0)
|
||||
{
|
||||
LOG(" This certificate has no flags");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "../IniFile.h"
|
||||
#include "json/json.h"
|
||||
|
||||
#include "PolarSSL++/BlockingSslClientSocket.h"
|
||||
#include "mbedTLS++/BlockingSslClientSocket.h"
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// MojangAPI.cpp
|
||||
|
||||
// Implements the cMojangAPI class representing the various API points provided by Mojang's webservices, and a cache for their results
|
||||
@ -9,7 +9,8 @@
|
||||
#include "SQLiteCpp/Statement.h"
|
||||
#include "../IniFile.h"
|
||||
#include "json/json.h"
|
||||
#include "PolarSSL++/BlockingSslClientSocket.h"
|
||||
#include "mbedTLS++/BlockingSslClientSocket.h"
|
||||
#include "mbedTLS++/SslConfig.h"
|
||||
#include "../RankManager.h"
|
||||
#include "../OSSupport/IsThread.h"
|
||||
#include "../Root.h"
|
||||
@ -39,9 +40,9 @@ const int MAX_PER_QUERY = 100;
|
||||
|
||||
|
||||
/** Returns the CA certificates that should be trusted for Mojang-related connections. */
|
||||
static const AString & GetCACerts(void)
|
||||
static cX509CertPtr GetCACerts(void)
|
||||
{
|
||||
static const AString Cert(
|
||||
static const char CertString[] =
|
||||
// GeoTrust root CA cert
|
||||
// Currently used for signing *.mojang.com's cert
|
||||
// Exported from Mozilla Firefox's built-in CA repository
|
||||
@ -140,9 +141,33 @@ static const AString & GetCACerts(void)
|
||||
"VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n"
|
||||
"WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n"
|
||||
"-----END CERTIFICATE-----\n"
|
||||
);
|
||||
;
|
||||
|
||||
return Cert;
|
||||
static auto X509Cert = [&]()
|
||||
{
|
||||
auto Cert = std::make_shared<cX509Cert>();
|
||||
VERIFY(0 == Cert->Parse(CertString, sizeof(CertString)));
|
||||
return Cert;
|
||||
}();
|
||||
|
||||
return X509Cert;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Returns the config to be used for secure requests. */
|
||||
static std::shared_ptr<const cSslConfig> GetSslConfig()
|
||||
{
|
||||
static const std::shared_ptr<const cSslConfig> Config = []()
|
||||
{
|
||||
auto Conf = cSslConfig::MakeDefaultConfig(true);
|
||||
Conf->SetCACerts(GetCACerts());
|
||||
Conf->SetAuthMode(eSslAuthMode::Required);
|
||||
return Conf;
|
||||
}();
|
||||
return Config;
|
||||
}
|
||||
|
||||
|
||||
@ -432,7 +457,8 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
|
||||
{
|
||||
// Connect the socket:
|
||||
cBlockingSslClientSocket Socket;
|
||||
Socket.SetTrustedRootCertsFromString(GetCACerts(), a_ServerName);
|
||||
Socket.SetSslConfig(GetSslConfig());
|
||||
Socket.SetExpectedPeerName(a_ServerName);
|
||||
if (!Socket.Connect(a_ServerName, 443))
|
||||
{
|
||||
LOGWARNING("%s: Can't connect to %s: %s", __FUNCTION__, a_ServerName.c_str(), Socket.GetLastErrorText().c_str());
|
||||
@ -452,13 +478,13 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
|
||||
{
|
||||
int ret = Socket.Receive(buf, sizeof(buf));
|
||||
|
||||
if ((ret == POLARSSL_ERR_NET_WANT_READ) || (ret == POLARSSL_ERR_NET_WANT_WRITE))
|
||||
if ((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE))
|
||||
{
|
||||
// This value should never be returned, it is handled internally by cBlockingSslClientSocket
|
||||
LOGWARNING("%s: SSL reading failed internally", __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
if (ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
|
||||
if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ Implements the 1.8 protocol classes:
|
||||
#include "json/json.h"
|
||||
#include "Protocol_1_8.h"
|
||||
#include "ChunkDataSerializer.h"
|
||||
#include "PolarSSL++/Sha1Checksum.h"
|
||||
#include "mbedTLS++/Sha1Checksum.h"
|
||||
#include "Packetizer.h"
|
||||
|
||||
#include "../ClientHandle.h"
|
||||
|
@ -29,8 +29,8 @@ Declares the 1.8 protocol classes:
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "PolarSSL++/AesCfb128Decryptor.h"
|
||||
#include "PolarSSL++/AesCfb128Encryptor.h"
|
||||
#include "mbedTLS++/AesCfb128Decryptor.h"
|
||||
#include "mbedTLS++/AesCfb128Encryptor.h"
|
||||
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ Implements the 1.9 protocol classes:
|
||||
#include "json/json.h"
|
||||
#include "Protocol_1_9.h"
|
||||
#include "ChunkDataSerializer.h"
|
||||
#include "PolarSSL++/Sha1Checksum.h"
|
||||
#include "mbedTLS++/Sha1Checksum.h"
|
||||
#include "Packetizer.h"
|
||||
|
||||
#include "../ClientHandle.h"
|
||||
|
@ -35,8 +35,8 @@ Declares the 1.9 protocol classes:
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "PolarSSL++/AesCfb128Decryptor.h"
|
||||
#include "PolarSSL++/AesCfb128Encryptor.h"
|
||||
#include "mbedTLS++/AesCfb128Decryptor.h"
|
||||
#include "mbedTLS++/AesCfb128Encryptor.h"
|
||||
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#pragma warning(disable:4702)
|
||||
#endif
|
||||
|
||||
#include "PolarSSL++/RsaPrivateKey.h"
|
||||
#include "mbedTLS++/RsaPrivateKey.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "Globals.h"
|
||||
#include "UUID.h"
|
||||
|
||||
#include "polarssl/md5.h"
|
||||
#include "mbedtls/md5.h"
|
||||
|
||||
|
||||
/** UUID normalised in textual form. */
|
||||
@ -265,7 +265,7 @@ cUUID cUUID::GenerateVersion3(const AString & a_Name)
|
||||
cUUID UUID;
|
||||
// Generate an md5 checksum, and use it as base for the ID:
|
||||
const Byte * ByteString = reinterpret_cast<const Byte *>(a_Name.data());
|
||||
md5(ByteString, a_Name.length(), UUID.m_UUID.data());
|
||||
mbedtls_md5(ByteString, a_Name.length(), UUID.m_UUID.data());
|
||||
|
||||
// Insert version number
|
||||
UUID.m_UUID[6] = (UUID.m_UUID[6] & 0x0f) | 0x30;
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// AesCfb128Decryptor.cpp
|
||||
|
||||
// Implements the cAesCfb128Decryptor class decrypting data using AES CFB-128
|
||||
@ -10,10 +10,10 @@
|
||||
|
||||
|
||||
|
||||
cAesCfb128Decryptor::cAesCfb128Decryptor(void) :
|
||||
m_IVOffset(0),
|
||||
cAesCfb128Decryptor::cAesCfb128Decryptor(void):
|
||||
m_IsValid(false)
|
||||
{
|
||||
mbedtls_aes_init(&m_Aes);
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ cAesCfb128Decryptor::cAesCfb128Decryptor(void) :
|
||||
cAesCfb128Decryptor::~cAesCfb128Decryptor()
|
||||
{
|
||||
// Clear the leftover in-memory data, so that they can't be accessed by a backdoor
|
||||
memset(&m_Aes, 0, sizeof(m_Aes));
|
||||
mbedtls_aes_free(&m_Aes);
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ void cAesCfb128Decryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
|
||||
ASSERT(!IsValid()); // Cannot Init twice
|
||||
|
||||
memcpy(m_IV, a_IV, 16);
|
||||
aes_setkey_enc(&m_Aes, a_Key, 128);
|
||||
mbedtls_aes_setkey_enc(&m_Aes, a_Key, 128);
|
||||
m_IsValid = true;
|
||||
}
|
||||
|
||||
@ -46,19 +46,7 @@ void cAesCfb128Decryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
|
||||
void cAesCfb128Decryptor::ProcessData(Byte * a_DecryptedOut, const Byte * a_EncryptedIn, size_t a_Length)
|
||||
{
|
||||
ASSERT(IsValid()); // Must Init() first
|
||||
|
||||
// PolarSSL doesn't support AES-CFB8, need to implement it manually:
|
||||
for (size_t i = 0; i < a_Length; i++)
|
||||
{
|
||||
Byte Buffer[sizeof(m_IV)];
|
||||
aes_crypt_ecb(&m_Aes, AES_ENCRYPT, m_IV, Buffer);
|
||||
for (size_t idx = 0; idx < sizeof(m_IV) - 1; idx++)
|
||||
{
|
||||
m_IV[idx] = m_IV[idx + 1];
|
||||
}
|
||||
m_IV[sizeof(m_IV) - 1] = a_EncryptedIn[i];
|
||||
a_DecryptedOut[i] = a_EncryptedIn[i] ^ Buffer[0];
|
||||
}
|
||||
mbedtls_aes_crypt_cfb8(&m_Aes, MBEDTLS_AES_DECRYPT, a_Length, m_IV, a_EncryptedIn, a_DecryptedOut);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// AesCfb128Decryptor.h
|
||||
|
||||
// Declares the cAesCfb128Decryptor class decrypting data using AES CFB-128
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polarssl/aes.h"
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
|
||||
|
||||
@ -33,14 +33,11 @@ public:
|
||||
bool IsValid(void) const { return m_IsValid; }
|
||||
|
||||
protected:
|
||||
aes_context m_Aes;
|
||||
mbedtls_aes_context m_Aes;
|
||||
|
||||
/** The InitialVector, used by the CFB mode decryption */
|
||||
Byte m_IV[16];
|
||||
|
||||
/** Current offset in the m_IV, used by the CFB mode decryption */
|
||||
size_t m_IVOffset;
|
||||
|
||||
/** Indicates whether the object has been initialized with the Key / IV */
|
||||
bool m_IsValid;
|
||||
} ;
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// AesCfb128Encryptor.cpp
|
||||
|
||||
// Implements the cAesCfb128Encryptor class encrypting data using AES CFB-128
|
||||
@ -10,10 +10,10 @@
|
||||
|
||||
|
||||
|
||||
cAesCfb128Encryptor::cAesCfb128Encryptor(void) :
|
||||
m_IVOffset(0),
|
||||
cAesCfb128Encryptor::cAesCfb128Encryptor(void):
|
||||
m_IsValid(false)
|
||||
{
|
||||
mbedtls_aes_init(&m_Aes);
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ cAesCfb128Encryptor::cAesCfb128Encryptor(void) :
|
||||
cAesCfb128Encryptor::~cAesCfb128Encryptor()
|
||||
{
|
||||
// Clear the leftover in-memory data, so that they can't be accessed by a backdoor
|
||||
memset(&m_Aes, 0, sizeof(m_Aes));
|
||||
mbedtls_aes_free(&m_Aes);
|
||||
}
|
||||
|
||||
|
||||
@ -33,10 +33,9 @@ cAesCfb128Encryptor::~cAesCfb128Encryptor()
|
||||
void cAesCfb128Encryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
|
||||
{
|
||||
ASSERT(!IsValid()); // Cannot Init twice
|
||||
ASSERT(m_IVOffset == 0);
|
||||
|
||||
memcpy(m_IV, a_IV, 16);
|
||||
aes_setkey_enc(&m_Aes, a_Key, 128);
|
||||
mbedtls_aes_setkey_enc(&m_Aes, a_Key, 128);
|
||||
m_IsValid = true;
|
||||
}
|
||||
|
||||
@ -47,19 +46,7 @@ void cAesCfb128Encryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
|
||||
void cAesCfb128Encryptor::ProcessData(Byte * a_EncryptedOut, const Byte * a_PlainIn, size_t a_Length)
|
||||
{
|
||||
ASSERT(IsValid()); // Must Init() first
|
||||
|
||||
// PolarSSL doesn't do AES-CFB8, so we need to implement it ourselves:
|
||||
for (size_t i = 0; i < a_Length; i++)
|
||||
{
|
||||
Byte Buffer[sizeof(m_IV)];
|
||||
aes_crypt_ecb(&m_Aes, AES_ENCRYPT, m_IV, Buffer);
|
||||
for (size_t idx = 0; idx < sizeof(m_IV) - 1; idx++)
|
||||
{
|
||||
m_IV[idx] = m_IV[idx + 1];
|
||||
}
|
||||
a_EncryptedOut[i] = a_PlainIn[i] ^ Buffer[0];
|
||||
m_IV[sizeof(m_IV) - 1] = a_EncryptedOut[i];
|
||||
}
|
||||
mbedtls_aes_crypt_cfb8(&m_Aes, MBEDTLS_AES_ENCRYPT, a_Length, m_IV, a_PlainIn, a_EncryptedOut);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// AesCfb128Encryptor.h
|
||||
|
||||
// Declares the cAesCfb128Encryptor class encrypting data using AES CFB-128
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polarssl/aes.h"
|
||||
#include "mbedtls/aes.h"
|
||||
|
||||
|
||||
|
||||
@ -32,14 +32,11 @@ public:
|
||||
bool IsValid(void) const { return m_IsValid; }
|
||||
|
||||
protected:
|
||||
aes_context m_Aes;
|
||||
mbedtls_aes_context m_Aes;
|
||||
|
||||
/** The InitialVector, used by the CFB mode encryption */
|
||||
Byte m_IV[16];
|
||||
|
||||
/** Current offset in the m_IV, used by the CFB mode encryption */
|
||||
size_t m_IVOffset;
|
||||
|
||||
/** Indicates whether the object has been initialized with the Key / IV */
|
||||
bool m_IsValid;
|
||||
} ;
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// BlockingSslClientSocket.cpp
|
||||
|
||||
// Implements the cBlockingSslClientSocket class representing a blocking TCP socket with client SSL encryption over it
|
||||
@ -125,7 +125,16 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po
|
||||
}
|
||||
|
||||
// Initialize the SSL:
|
||||
int ret = m_Ssl.Initialize(true);
|
||||
int ret = 0;
|
||||
if (m_Config != nullptr)
|
||||
{
|
||||
ret = m_Ssl.Initialize(m_Config);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = m_Ssl.Initialize(true);
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
Printf(m_LastErrorText, "SSL initialization failed: -0x%x", -ret);
|
||||
@ -133,9 +142,9 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po
|
||||
}
|
||||
|
||||
// If we have been assigned a trusted CA root cert store, push it into the SSL context:
|
||||
if (m_CACerts.get() != nullptr)
|
||||
if (!m_ExpectedPeerName.empty())
|
||||
{
|
||||
m_Ssl.SetCACerts(m_CACerts, m_ExpectedPeerName);
|
||||
m_Ssl.SetExpectedPeerName(m_ExpectedPeerName);
|
||||
}
|
||||
|
||||
ret = m_Ssl.Handshake();
|
||||
@ -153,28 +162,37 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po
|
||||
|
||||
|
||||
|
||||
bool cBlockingSslClientSocket::SetTrustedRootCertsFromString(const AString & a_CACerts, const AString & a_ExpectedPeerName)
|
||||
void cBlockingSslClientSocket::SetExpectedPeerName(AString a_ExpectedPeerName)
|
||||
{
|
||||
ASSERT(!m_IsConnected); // Must be called before connect
|
||||
|
||||
// Warn if used multiple times, but don't signal an error:
|
||||
if (m_CACerts.get() != nullptr)
|
||||
if (!m_ExpectedPeerName.empty())
|
||||
{
|
||||
LOGWARNING(
|
||||
"SSL: Trying to set multiple trusted CA root cert stores, only the last one will be used. Name: %s",
|
||||
"SSL: Trying to set multiple expected peer names, only the last one will be used. Name: %s",
|
||||
a_ExpectedPeerName.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
// Parse the cert:
|
||||
m_CACerts.reset(new cX509Cert);
|
||||
int ret = m_CACerts->Parse(a_CACerts.data(), a_CACerts.size());
|
||||
if (ret < 0)
|
||||
{
|
||||
Printf(m_LastErrorText, "CA cert parsing failed: -0x%x", -ret);
|
||||
return false;
|
||||
}
|
||||
m_ExpectedPeerName = a_ExpectedPeerName;
|
||||
m_ExpectedPeerName = std::move(a_ExpectedPeerName);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
|
||||
void cBlockingSslClientSocket::SetSslConfig(std::shared_ptr<const cSslConfig> a_Config)
|
||||
{
|
||||
ASSERT(!m_IsConnected); // Must be called before connect
|
||||
|
||||
// Warn if used multiple times, but don't signal an error:
|
||||
if (m_Config != nullptr)
|
||||
{
|
||||
LOGWARNING("SSL: Trying to set multiple configurations, only the last one will be used.");
|
||||
}
|
||||
|
||||
m_Config = std::move(a_Config);
|
||||
}
|
||||
|
||||
|
||||
@ -197,8 +215,8 @@ bool cBlockingSslClientSocket::Send(const void * a_Data, size_t a_NumBytes)
|
||||
int res = m_Ssl.WritePlain(Data, a_NumBytes);
|
||||
if (res < 0)
|
||||
{
|
||||
ASSERT(res != POLARSSL_ERR_NET_WANT_READ); // This should never happen with callback-based SSL
|
||||
ASSERT(res != POLARSSL_ERR_NET_WANT_WRITE); // This should never happen with callback-based SSL
|
||||
ASSERT(res != MBEDTLS_ERR_SSL_WANT_READ); // This should never happen with callback-based SSL
|
||||
ASSERT(res != MBEDTLS_ERR_SSL_WANT_WRITE); // This should never happen with callback-based SSL
|
||||
Printf(m_LastErrorText, "Data cannot be written to SSL context: -0x%x", -res);
|
||||
return false;
|
||||
}
|
||||
@ -272,7 +290,7 @@ int cBlockingSslClientSocket::ReceiveEncrypted(unsigned char * a_Buffer, size_t
|
||||
// If we got disconnected, report an error after processing all data:
|
||||
if (!m_IsConnected && m_IncomingData.empty())
|
||||
{
|
||||
return POLARSSL_ERR_NET_RECV_FAILED;
|
||||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
|
||||
// Copy the data from the incoming buffer into the specified space:
|
||||
@ -291,12 +309,12 @@ int cBlockingSslClientSocket::SendEncrypted(const unsigned char * a_Buffer, size
|
||||
cTCPLinkPtr Socket(m_Socket); // Make a copy so that multiple threads don't race on deleting the socket.
|
||||
if (Socket == nullptr)
|
||||
{
|
||||
return POLARSSL_ERR_NET_SEND_FAILED;
|
||||
return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
}
|
||||
if (!Socket->Send(a_Buffer, a_NumBytes))
|
||||
{
|
||||
// PolarSSL's net routines distinguish between connection reset and general failure, we don't need to
|
||||
return POLARSSL_ERR_NET_SEND_FAILED;
|
||||
// mbedTLS's net routines distinguish between connection reset and general failure, we don't need to
|
||||
return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
}
|
||||
return static_cast<int>(a_NumBytes);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// BlockingSslClientSocket.h
|
||||
|
||||
// Declares the cBlockingSslClientSocket class representing a blocking TCP socket with client SSL encryption over it
|
||||
@ -45,12 +45,15 @@ public:
|
||||
Note that this also frees the internal SSL context, so all the certificates etc. are lost. */
|
||||
void Disconnect(void);
|
||||
|
||||
/** Sets the root certificates that are to be trusted. Forces the connection to use strict cert
|
||||
verification. Needs to be used before calling Connect().
|
||||
a_ExpectedPeerName is the name that we expect to receive in the SSL peer's cert; verification will fail if
|
||||
the presented name is different (possible MITM).
|
||||
Returns true on success, false on failure. Sets internal error text on failure. */
|
||||
bool SetTrustedRootCertsFromString(const AString & a_CACerts, const AString & a_ExpectedPeerName);
|
||||
/** Sets the Expected peer name.
|
||||
Needs to be used before calling Connect().
|
||||
\param a_ExpectedPeerName Name that we expect to receive in the SSL peer's cert; verification will fail if
|
||||
the presented name is different (possible MITM). */
|
||||
void SetExpectedPeerName(AString a_ExpectedPeerName);
|
||||
|
||||
/** Set the config to be used by the SSL context.
|
||||
Config must not be modified after calling connect. */
|
||||
void SetSslConfig(std::shared_ptr<const cSslConfig> a_Config);
|
||||
|
||||
/** Returns the text of the last error that has occurred in this instance. */
|
||||
const AString & GetLastErrorText(void) const { return m_LastErrorText; }
|
||||
@ -68,10 +71,10 @@ protected:
|
||||
/** The object used to signal state changes in the socket (the cause of the blocking). */
|
||||
cEvent m_Event;
|
||||
|
||||
/** The trusted CA root cert store, if we are to verify the cert strictly. Set by SetTrustedRootCertsFromString(). */
|
||||
cX509CertPtr m_CACerts;
|
||||
/** The configuration to be used by the SSL context. Set by SetSslConfig(). */
|
||||
std::shared_ptr<const cSslConfig> m_Config;
|
||||
|
||||
/** The expected SSL peer's name, if we are to verify the cert strictly. Set by SetTrustedRootCertsFromString(). */
|
||||
/** The expected SSL peer's name, if we are to verify the cert strictly. Set by SetExpectedPeerName(). */
|
||||
AString m_ExpectedPeerName;
|
||||
|
||||
/** The hostname to which the socket is connecting (stored for error reporting). */
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// BufferedSslContext.cpp
|
||||
|
||||
// Implements the cBufferedSslContext class representing a SSL context with the SSL peer data backed by a cByteBuffer
|
||||
@ -53,17 +53,17 @@ size_t cBufferedSslContext::ReadOutgoing(void * a_Data, size_t a_DataMaxSize)
|
||||
|
||||
int cBufferedSslContext::ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes)
|
||||
{
|
||||
// Called when PolarSSL wants to read encrypted data from the SSL peer
|
||||
// Called when mbedTLS wants to read encrypted data from the SSL peer
|
||||
// Read the data from the buffer inside this object, where the owner has stored them using WriteIncoming():
|
||||
size_t NumBytes = std::min(a_NumBytes, m_IncomingData.GetReadableSpace());
|
||||
if (NumBytes == 0)
|
||||
{
|
||||
return POLARSSL_ERR_NET_WANT_READ;
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
}
|
||||
if (!m_IncomingData.ReadBuf(a_Buffer, NumBytes))
|
||||
{
|
||||
m_IncomingData.ResetRead();
|
||||
return POLARSSL_ERR_NET_RECV_FAILED;
|
||||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
m_IncomingData.CommitRead();
|
||||
return static_cast<int>(NumBytes);
|
||||
@ -75,15 +75,15 @@ int cBufferedSslContext::ReceiveEncrypted(unsigned char * a_Buffer, size_t a_Num
|
||||
|
||||
int cBufferedSslContext::SendEncrypted(const unsigned char * a_Buffer, size_t a_NumBytes)
|
||||
{
|
||||
// Called when PolarSSL wants to write encrypted data to the SSL peer
|
||||
// Called when mbedTLS wants to write encrypted data to the SSL peer
|
||||
// Write the data into the buffer inside this object, where the owner can later read them using ReadOutgoing():
|
||||
if (!m_OutgoingData.CanWriteBytes(a_NumBytes))
|
||||
{
|
||||
return POLARSSL_ERR_NET_WANT_WRITE;
|
||||
return MBEDTLS_ERR_SSL_WANT_WRITE;
|
||||
}
|
||||
if (!m_OutgoingData.Write(reinterpret_cast<const char *>(a_Buffer), a_NumBytes))
|
||||
{
|
||||
return POLARSSL_ERR_NET_SEND_FAILED;
|
||||
return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
}
|
||||
return static_cast<int>(a_NumBytes);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// BufferedSslContext.h
|
||||
|
||||
// Declares the cBufferedSslContext class representing a SSL context with the SSL peer data backed by a cByteBuffer
|
||||
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "SslContext.h"
|
||||
#include "ErrorCodes.h"
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@ set(SRCS
|
||||
EntropyContext.cpp
|
||||
RsaPrivateKey.cpp
|
||||
Sha1Checksum.cpp
|
||||
SslConfig.cpp
|
||||
SslContext.cpp
|
||||
X509Cert.cpp
|
||||
)
|
||||
@ -26,16 +27,18 @@ set(HDRS
|
||||
CtrDrbgContext.h
|
||||
CryptoKey.h
|
||||
EntropyContext.h
|
||||
ErrorCodes.h
|
||||
RsaPrivateKey.h
|
||||
SslConfig.h
|
||||
SslContext.h
|
||||
Sha1Checksum.h
|
||||
X509Cert.h
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_library(PolarSSL++ ${SRCS} ${HDRS})
|
||||
add_library(mbedTLS++ ${SRCS} ${HDRS})
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(PolarSSL++ mbedtls)
|
||||
target_link_libraries(mbedTLS++ mbedtls)
|
||||
endif()
|
||||
endif()
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// CallbackSslContext.cpp
|
||||
|
||||
// Declares the cCallbackSslContext class representing a SSL context wrapper that uses callbacks to read and write SSL peer data
|
||||
@ -35,7 +35,7 @@ int cCallbackSslContext::ReceiveEncrypted(unsigned char * a_Buffer, size_t a_Num
|
||||
if (m_Callbacks == nullptr)
|
||||
{
|
||||
LOGWARNING("SSL: Trying to receive data with no callbacks, aborting.");
|
||||
return POLARSSL_ERR_NET_RECV_FAILED;
|
||||
return MBEDTLS_ERR_NET_RECV_FAILED;
|
||||
}
|
||||
return m_Callbacks->ReceiveEncrypted(a_Buffer, a_NumBytes);
|
||||
}
|
||||
@ -49,7 +49,7 @@ int cCallbackSslContext::SendEncrypted(const unsigned char * a_Buffer, size_t a_
|
||||
if (m_Callbacks == nullptr)
|
||||
{
|
||||
LOGWARNING("SSL: Trying to send data with no callbacks, aborting.");
|
||||
return POLARSSL_ERR_NET_SEND_FAILED;
|
||||
return MBEDTLS_ERR_NET_SEND_FAILED;
|
||||
}
|
||||
return m_Callbacks->SendEncrypted(a_Buffer, a_NumBytes);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// CallbackSslContext.h
|
||||
|
||||
// Declares the cCallbackSslContext class representing a SSL context wrapper that uses callbacks to read and write SSL peer data
|
||||
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "SslContext.h"
|
||||
#include "ErrorCodes.h"
|
||||
|
||||
|
||||
|
||||
@ -26,17 +27,17 @@ public:
|
||||
// Force a virtual destructor in descendants:
|
||||
virtual ~cDataCallbacks() {}
|
||||
|
||||
/** Called when PolarSSL wants to read encrypted data from the SSL peer.
|
||||
The returned value is the number of bytes received, or a PolarSSL error on failure.
|
||||
The implementation can return POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE to indicate
|
||||
/** Called when mbedTLS wants to read encrypted data from the SSL peer.
|
||||
The returned value is the number of bytes received, or a mbedTLS error on failure.
|
||||
The implementation can return MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE to indicate
|
||||
that there's currently no more data and that there might be more data in the future. In such cases the
|
||||
SSL operation that invoked this call will terminate with the same return value, so that the owner is
|
||||
notified of this condition and can potentially restart the operation later on. */
|
||||
virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0;
|
||||
|
||||
/** Called when PolarSSL wants to write encrypted data to the SSL peer.
|
||||
The returned value is the number of bytes sent, or a PolarSSL error on failure.
|
||||
The implementation can return POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE to indicate
|
||||
/** Called when mbedTLS wants to write encrypted data to the SSL peer.
|
||||
The returned value is the number of bytes sent, or a mbedTLS error on failure.
|
||||
The implementation can return MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE to indicate
|
||||
that there's currently no more data and that there might be more data in the future. In such cases the
|
||||
SSL operation that invoked this call will terminate with the same return value, so that the owner is
|
||||
notified of this condition and can potentially restart the operation later on. */
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// CryptoKey.cpp
|
||||
|
||||
// Implements the cCryptoKey class representing a RSA public key in PolarSSL
|
||||
// Implements the cCryptoKey class representing a RSA public key in mbedTLS
|
||||
|
||||
#include "Globals.h"
|
||||
#include "CryptoKey.h"
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
cCryptoKey::cCryptoKey(void)
|
||||
{
|
||||
pk_init(&m_Pk);
|
||||
mbedtls_pk_init(&m_Pk);
|
||||
m_CtrDrbg.Initialize("rsa_pubkey", 10);
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ cCryptoKey::cCryptoKey(void)
|
||||
|
||||
cCryptoKey::cCryptoKey(const AString & a_PublicKeyData)
|
||||
{
|
||||
pk_init(&m_Pk);
|
||||
mbedtls_pk_init(&m_Pk);
|
||||
m_CtrDrbg.Initialize("rsa_pubkey", 10);
|
||||
int res = ParsePublic(a_PublicKeyData.data(), a_PublicKeyData.size());
|
||||
if (res != 0)
|
||||
@ -39,7 +39,7 @@ cCryptoKey::cCryptoKey(const AString & a_PublicKeyData)
|
||||
|
||||
cCryptoKey::cCryptoKey(const AString & a_PrivateKeyData, const AString & a_Password)
|
||||
{
|
||||
pk_init(&m_Pk);
|
||||
mbedtls_pk_init(&m_Pk);
|
||||
m_CtrDrbg.Initialize("rsa_privkey", 11);
|
||||
int res = ParsePrivate(a_PrivateKeyData.data(), a_PrivateKeyData.size(), a_Password);
|
||||
if (res != 0)
|
||||
@ -56,7 +56,7 @@ cCryptoKey::cCryptoKey(const AString & a_PrivateKeyData, const AString & a_Passw
|
||||
|
||||
cCryptoKey::~cCryptoKey()
|
||||
{
|
||||
pk_free(&m_Pk);
|
||||
mbedtls_pk_free(&m_Pk);
|
||||
}
|
||||
|
||||
|
||||
@ -68,10 +68,10 @@ int cCryptoKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength,
|
||||
ASSERT(IsValid());
|
||||
|
||||
size_t DecryptedLen = a_DecryptedMaxLength;
|
||||
int res = pk_decrypt(&m_Pk,
|
||||
int res = mbedtls_pk_decrypt(&m_Pk,
|
||||
a_EncryptedData, a_EncryptedLength,
|
||||
a_DecryptedData, &DecryptedLen, a_DecryptedMaxLength,
|
||||
ctr_drbg_random, m_CtrDrbg.GetInternal()
|
||||
mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal()
|
||||
);
|
||||
if (res != 0)
|
||||
{
|
||||
@ -89,9 +89,9 @@ int cCryptoKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a
|
||||
ASSERT(IsValid());
|
||||
|
||||
size_t EncryptedLength = a_EncryptedMaxLength;
|
||||
int res = pk_encrypt(&m_Pk,
|
||||
int res = mbedtls_pk_encrypt(&m_Pk,
|
||||
a_PlainData, a_PlainLength, a_EncryptedData, &EncryptedLength, a_EncryptedMaxLength,
|
||||
ctr_drbg_random, m_CtrDrbg.GetInternal()
|
||||
mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal()
|
||||
);
|
||||
if (res != 0)
|
||||
{
|
||||
@ -109,7 +109,7 @@ int cCryptoKey::ParsePublic(const void * a_Data, size_t a_NumBytes)
|
||||
{
|
||||
ASSERT(!IsValid()); // Cannot parse a second key
|
||||
|
||||
return pk_parse_public_key(&m_Pk, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes);
|
||||
return mbedtls_pk_parse_public_key(&m_Pk, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes);
|
||||
}
|
||||
|
||||
|
||||
@ -123,11 +123,11 @@ int cCryptoKey::ParsePrivate(const void * a_Data, size_t a_NumBytes, const AStri
|
||||
|
||||
if (a_Password.empty())
|
||||
{
|
||||
return pk_parse_key(&m_Pk, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes, nullptr, 0);
|
||||
return mbedtls_pk_parse_key(&m_Pk, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes, nullptr, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pk_parse_key(
|
||||
return mbedtls_pk_parse_key(
|
||||
&m_Pk,
|
||||
reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes,
|
||||
reinterpret_cast<const unsigned char *>(a_Password.c_str()), a_Password.size()
|
||||
@ -141,7 +141,7 @@ int cCryptoKey::ParsePrivate(const void * a_Data, size_t a_NumBytes, const AStri
|
||||
|
||||
bool cCryptoKey::IsValid(void) const
|
||||
{
|
||||
return (pk_get_type(&m_Pk) != POLARSSL_PK_NONE);
|
||||
return (mbedtls_pk_get_type(&m_Pk) != MBEDTLS_PK_NONE);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// CryptoKey.h
|
||||
|
||||
// Declares the cCryptoKey class representing a RSA public key in PolarSSL
|
||||
// Declares the cCryptoKey class representing a RSA public key in mbedTLS
|
||||
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CtrDrbgContext.h"
|
||||
#include "polarssl/pk.h"
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
class cCryptoKey
|
||||
{
|
||||
friend class cSslContext;
|
||||
friend class cSslConfig;
|
||||
|
||||
public:
|
||||
/** Constructs an empty key instance. Before use, it needs to be filled by ParsePublic() or ParsePrivate() */
|
||||
@ -45,28 +45,28 @@ public:
|
||||
|
||||
/** Parses the specified data into a public key representation.
|
||||
The key can be DER- or PEM-encoded.
|
||||
Returns 0 on success, PolarSSL error code on failure. */
|
||||
Returns 0 on success, mbedTLS error code on failure. */
|
||||
int ParsePublic(const void * a_Data, size_t a_NumBytes);
|
||||
|
||||
/** Parses the specified data into a private key representation.
|
||||
If a_Password is empty, no password is assumed.
|
||||
The key can be DER- or PEM-encoded.
|
||||
Returns 0 on success, PolarSSL error code on failure. */
|
||||
Returns 0 on success, mbedTLS error code on failure. */
|
||||
int ParsePrivate(const void * a_Data, size_t a_NumBytes, const AString & a_Password);
|
||||
|
||||
/** Returns true if the contained key is valid. */
|
||||
bool IsValid(void) const;
|
||||
|
||||
protected:
|
||||
/** The PolarSSL representation of the key data */
|
||||
pk_context m_Pk;
|
||||
/** The mbedTLS representation of the key data */
|
||||
mbedtls_pk_context m_Pk;
|
||||
|
||||
/** The random generator used in encryption and decryption */
|
||||
cCtrDrbgContext m_CtrDrbg;
|
||||
|
||||
|
||||
/** Returns the internal context ptr. Only use in PolarSSL API calls. */
|
||||
pk_context * GetInternal(void) { return &m_Pk; }
|
||||
/** Returns the internal context ptr. Only use in mbedTLS API calls. */
|
||||
mbedtls_pk_context * GetInternal(void) { return &m_Pk; }
|
||||
} ;
|
||||
|
||||
typedef std::shared_ptr<cCryptoKey> cCryptoKeyPtr;
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// CtrDrbgContext.cpp
|
||||
|
||||
// Implements the cCtrDrbgContext class representing a wrapper over CTR-DRBG implementation in PolarSSL
|
||||
// Implements the cCtrDrbgContext class representing a wrapper over CTR-DRBG implementation in mbedTLS
|
||||
|
||||
#include "Globals.h"
|
||||
#include "CtrDrbgContext.h"
|
||||
@ -12,9 +12,10 @@
|
||||
|
||||
|
||||
cCtrDrbgContext::cCtrDrbgContext(void) :
|
||||
m_EntropyContext(new cEntropyContext),
|
||||
m_EntropyContext(std::make_shared<cEntropyContext>()),
|
||||
m_IsValid(false)
|
||||
{
|
||||
mbedtls_ctr_drbg_init(&m_CtrDrbg);
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +26,7 @@ cCtrDrbgContext::cCtrDrbgContext(const std::shared_ptr<cEntropyContext> & a_Entr
|
||||
m_EntropyContext(a_EntropyContext),
|
||||
m_IsValid(false)
|
||||
{
|
||||
mbedtls_ctr_drbg_init(&m_CtrDrbg);
|
||||
}
|
||||
|
||||
|
||||
@ -39,7 +41,7 @@ int cCtrDrbgContext::Initialize(const void * a_Custom, size_t a_CustomSize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int res = ctr_drbg_init(&m_CtrDrbg, entropy_func, &(m_EntropyContext->m_Entropy), reinterpret_cast<const unsigned char *>(a_Custom), a_CustomSize);
|
||||
int res = mbedtls_ctr_drbg_seed(&m_CtrDrbg, mbedtls_entropy_func, &(m_EntropyContext->m_Entropy), reinterpret_cast<const unsigned char *>(a_Custom), a_CustomSize);
|
||||
m_IsValid = (res == 0);
|
||||
return res;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// CtrDrbgContext.h
|
||||
|
||||
// Declares the cCtrDrbgContext class representing a wrapper over CTR-DRBG implementation in PolarSSL
|
||||
// Declares the cCtrDrbgContext class representing a wrapper over CTR-DRBG implementation in mbedTLS
|
||||
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polarssl/ctr_drbg.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ class cEntropyContext;
|
||||
|
||||
class cCtrDrbgContext
|
||||
{
|
||||
friend class cSslContext;
|
||||
friend class cSslConfig;
|
||||
friend class cRsaPrivateKey;
|
||||
friend class cCryptoKey;
|
||||
|
||||
@ -37,7 +37,7 @@ public:
|
||||
|
||||
/** Initializes the context.
|
||||
a_Custom is optional additional data to use for entropy, nullptr is accepted.
|
||||
Returns 0 if successful, PolarSSL error code on failure. */
|
||||
Returns 0 if successful, mbedTLS error code on failure. */
|
||||
int Initialize(const void * a_Custom, size_t a_CustomSize);
|
||||
|
||||
/** Returns true if the object is valid (has been initialized properly) */
|
||||
@ -48,14 +48,14 @@ protected:
|
||||
std::shared_ptr<cEntropyContext> m_EntropyContext;
|
||||
|
||||
/** The random generator context */
|
||||
ctr_drbg_context m_CtrDrbg;
|
||||
mbedtls_ctr_drbg_context m_CtrDrbg;
|
||||
|
||||
/** Set to true if the object is valid (has been initialized properly) */
|
||||
bool m_IsValid;
|
||||
|
||||
|
||||
/** Returns the internal context ptr. Only use in PolarSSL API calls. */
|
||||
ctr_drbg_context * GetInternal(void) { return &m_CtrDrbg; }
|
||||
/** Returns the internal context ptr. Only use in mbedTLS API calls. */
|
||||
mbedtls_ctr_drbg_context * GetInternal(void) { return &m_CtrDrbg; }
|
||||
} ;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// EntropyContext.cpp
|
||||
|
||||
// Implements the cEntropyContext class representing a wrapper over entropy contexts in PolarSSL
|
||||
// Implements the cEntropyContext class representing a wrapper over entropy contexts in mbedTLS
|
||||
|
||||
#include "Globals.h"
|
||||
#include "EntropyContext.h"
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
cEntropyContext::cEntropyContext(void)
|
||||
{
|
||||
entropy_init(&m_Entropy);
|
||||
mbedtls_entropy_init(&m_Entropy);
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ cEntropyContext::cEntropyContext(void)
|
||||
|
||||
cEntropyContext::~cEntropyContext()
|
||||
{
|
||||
entropy_free(&m_Entropy);
|
||||
mbedtls_entropy_free(&m_Entropy);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// EntropyContext.h
|
||||
|
||||
// Declares the cEntropyContext class representing a wrapper over entropy contexts in PolarSSL
|
||||
// Declares the cEntropyContext class representing a wrapper over entropy contexts in mbedTLS
|
||||
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polarssl/entropy.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ public:
|
||||
~cEntropyContext();
|
||||
|
||||
protected:
|
||||
entropy_context m_Entropy;
|
||||
mbedtls_entropy_context m_Entropy;
|
||||
} ;
|
||||
|
||||
|
18
src/mbedTLS++/ErrorCodes.h
Normal file
18
src/mbedTLS++/ErrorCodes.h
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
/** Error codes from mbedtls net_sockets.h */
|
||||
// TODO: Replace with std::error_code
|
||||
|
||||
#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */
|
||||
#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */
|
||||
#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */
|
||||
#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */
|
||||
#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */
|
||||
#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */
|
||||
#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */
|
||||
#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */
|
||||
#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */
|
||||
#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */
|
||||
#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */
|
||||
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
|
||||
|
||||
// RsaPrivateKey.cpp
|
||||
|
||||
#include "Globals.h"
|
||||
#include "RsaPrivateKey.h"
|
||||
#include <polarssl/pk.h>
|
||||
#include "mbedtls/pk.h"
|
||||
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
cRsaPrivateKey::cRsaPrivateKey(void)
|
||||
{
|
||||
rsa_init(&m_Rsa, RSA_PKCS_V15, 0);
|
||||
mbedtls_rsa_init(&m_Rsa, MBEDTLS_RSA_PKCS_V15, 0);
|
||||
m_CtrDrbg.Initialize("RSA", 3);
|
||||
}
|
||||
|
||||
@ -21,8 +21,8 @@ cRsaPrivateKey::cRsaPrivateKey(void)
|
||||
|
||||
cRsaPrivateKey::cRsaPrivateKey(const cRsaPrivateKey & a_Other)
|
||||
{
|
||||
rsa_init(&m_Rsa, RSA_PKCS_V15, 0);
|
||||
rsa_copy(&m_Rsa, &a_Other.m_Rsa);
|
||||
mbedtls_rsa_init(&m_Rsa, MBEDTLS_RSA_PKCS_V15, 0);
|
||||
mbedtls_rsa_copy(&m_Rsa, &a_Other.m_Rsa);
|
||||
m_CtrDrbg.Initialize("RSA", 3);
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ cRsaPrivateKey::cRsaPrivateKey(const cRsaPrivateKey & a_Other)
|
||||
|
||||
cRsaPrivateKey::~cRsaPrivateKey()
|
||||
{
|
||||
rsa_free(&m_Rsa);
|
||||
mbedtls_rsa_free(&m_Rsa);
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ cRsaPrivateKey::~cRsaPrivateKey()
|
||||
|
||||
bool cRsaPrivateKey::Generate(unsigned a_KeySizeBits)
|
||||
{
|
||||
int res = rsa_gen_key(&m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), a_KeySizeBits, 65537);
|
||||
int res = mbedtls_rsa_gen_key(&m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), a_KeySizeBits, 65537);
|
||||
if (res != 0)
|
||||
{
|
||||
LOG("RSA key generation failed: -0x%x", -res);
|
||||
@ -60,16 +60,16 @@ AString cRsaPrivateKey::GetPubKeyDER(void)
|
||||
class cPubKey
|
||||
{
|
||||
public:
|
||||
cPubKey(rsa_context * a_Rsa) :
|
||||
cPubKey(mbedtls_rsa_context * a_Rsa) :
|
||||
m_IsValid(false)
|
||||
{
|
||||
pk_init(&m_Key);
|
||||
if (pk_init_ctx(&m_Key, pk_info_from_type(POLARSSL_PK_RSA)) != 0)
|
||||
mbedtls_pk_init(&m_Key);
|
||||
if (mbedtls_pk_setup(&m_Key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) != 0)
|
||||
{
|
||||
ASSERT(!"Cannot init PrivKey context");
|
||||
return;
|
||||
}
|
||||
if (rsa_copy(pk_rsa(m_Key), a_Rsa) != 0)
|
||||
if (mbedtls_rsa_copy(mbedtls_pk_rsa(m_Key), a_Rsa) != 0)
|
||||
{
|
||||
ASSERT(!"Cannot copy PrivKey to PK context");
|
||||
return;
|
||||
@ -81,19 +81,19 @@ AString cRsaPrivateKey::GetPubKeyDER(void)
|
||||
{
|
||||
if (m_IsValid)
|
||||
{
|
||||
pk_free(&m_Key);
|
||||
mbedtls_pk_free(&m_Key);
|
||||
}
|
||||
}
|
||||
|
||||
operator pk_context * (void) { return &m_Key; }
|
||||
operator mbedtls_pk_context * (void) { return &m_Key; }
|
||||
|
||||
protected:
|
||||
bool m_IsValid;
|
||||
pk_context m_Key;
|
||||
mbedtls_pk_context m_Key;
|
||||
} PkCtx(&m_Rsa);
|
||||
|
||||
unsigned char buf[3000];
|
||||
int res = pk_write_pubkey_der(PkCtx, buf, sizeof(buf));
|
||||
int res = mbedtls_pk_write_pubkey_der(PkCtx, buf, sizeof(buf));
|
||||
if (res < 0)
|
||||
{
|
||||
return AString();
|
||||
@ -124,8 +124,8 @@ int cRsaPrivateKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLeng
|
||||
return -1;
|
||||
}
|
||||
size_t DecryptedLength;
|
||||
int res = rsa_pkcs1_decrypt(
|
||||
&m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), RSA_PRIVATE, &DecryptedLength,
|
||||
int res = mbedtls_rsa_pkcs1_decrypt(
|
||||
&m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), MBEDTLS_RSA_PRIVATE, &DecryptedLength,
|
||||
a_EncryptedData, a_DecryptedData, a_DecryptedMaxLength
|
||||
);
|
||||
if (res != 0)
|
||||
@ -157,8 +157,8 @@ int cRsaPrivateKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte
|
||||
ASSERT(!"Invalid a_PlainLength!");
|
||||
return -1;
|
||||
}
|
||||
int res = rsa_pkcs1_encrypt(
|
||||
&m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), RSA_PRIVATE,
|
||||
int res = mbedtls_rsa_pkcs1_encrypt(
|
||||
&m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), MBEDTLS_RSA_PRIVATE,
|
||||
a_PlainLength, a_PlainData, a_EncryptedData
|
||||
);
|
||||
if (res != 0)
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// RsaPrivateKey.h
|
||||
|
||||
// Declares the cRsaPrivateKey class representing a private key for RSA operations.
|
||||
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CtrDrbgContext.h"
|
||||
#include "polarssl/rsa.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
|
||||
|
||||
|
||||
@ -48,15 +48,15 @@ public:
|
||||
int Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength);
|
||||
|
||||
protected:
|
||||
/** The PolarSSL key context */
|
||||
rsa_context m_Rsa;
|
||||
/** The mbedTLS key context */
|
||||
mbedtls_rsa_context m_Rsa;
|
||||
|
||||
/** The random generator used for generating the key and encryption / decryption */
|
||||
cCtrDrbgContext m_CtrDrbg;
|
||||
|
||||
|
||||
/** Returns the internal context ptr. Only use in PolarSSL API calls. */
|
||||
rsa_context * GetInternal(void) { return &m_Rsa; }
|
||||
/** Returns the internal context ptr. Only use in mbedTLS API calls. */
|
||||
mbedtls_rsa_context * GetInternal(void) { return &m_Rsa; }
|
||||
} ;
|
||||
|
||||
typedef std::shared_ptr<cRsaPrivateKey> cRsaPrivateKeyPtr;
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// Sha1Checksum.cpp
|
||||
|
||||
// Declares the cSha1Checksum class representing the SHA-1 checksum calculator
|
||||
@ -56,7 +56,7 @@ public:
|
||||
cSha1Checksum::cSha1Checksum(void) :
|
||||
m_DoesAcceptInput(true)
|
||||
{
|
||||
sha1_starts(&m_Sha1);
|
||||
mbedtls_sha1_starts(&m_Sha1);
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ void cSha1Checksum::Update(const Byte * a_Data, size_t a_Length)
|
||||
{
|
||||
ASSERT(m_DoesAcceptInput); // Not Finalize()-d yet, or Restart()-ed
|
||||
|
||||
sha1_update(&m_Sha1, a_Data, a_Length);
|
||||
mbedtls_sha1_update(&m_Sha1, a_Data, a_Length);
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ void cSha1Checksum::Finalize(cSha1Checksum::Checksum & a_Output)
|
||||
{
|
||||
ASSERT(m_DoesAcceptInput); // Not Finalize()-d yet, or Restart()-ed
|
||||
|
||||
sha1_finish(&m_Sha1, a_Output);
|
||||
mbedtls_sha1_finish(&m_Sha1, a_Output);
|
||||
m_DoesAcceptInput = false;
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ void cSha1Checksum::DigestToJava(const Checksum & a_Digest, AString & a_Out)
|
||||
|
||||
void cSha1Checksum::Restart(void)
|
||||
{
|
||||
sha1_starts(&m_Sha1);
|
||||
mbedtls_sha1_starts(&m_Sha1);
|
||||
m_DoesAcceptInput = true;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// Sha1Checksum.h
|
||||
|
||||
// Declares the cSha1Checksum class representing the SHA-1 checksum calculator
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polarssl/sha1.h"
|
||||
#include "mbedtls/sha1.h"
|
||||
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ protected:
|
||||
/** True if the object is accepts more input data, false if Finalize()-d (need to Restart()) */
|
||||
bool m_DoesAcceptInput;
|
||||
|
||||
sha1_context m_Sha1;
|
||||
mbedtls_sha1_context m_Sha1;
|
||||
} ;
|
||||
|
||||
|
287
src/mbedTLS++/SslConfig.cpp
Normal file
287
src/mbedTLS++/SslConfig.cpp
Normal file
@ -0,0 +1,287 @@
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#include "mbedTLS++/SslConfig.h"
|
||||
#include "EntropyContext.h"
|
||||
#include "CtrDrbgContext.h"
|
||||
#include "CryptoKey.h"
|
||||
#include "X509Cert.h"
|
||||
|
||||
|
||||
// This allows us to debug SSL and certificate problems, but produce way too much output,
|
||||
// so it's disabled until someone needs it
|
||||
// #define ENABLE_SSL_DEBUG_MSG
|
||||
|
||||
|
||||
#if defined(_DEBUG) && defined(ENABLE_SSL_DEBUG_MSG)
|
||||
#include "mbedtls/debug.h"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
void SSLDebugMessage(void * a_UserParam, int a_Level, const char * a_Filename, int a_LineNo, const char * a_Text)
|
||||
{
|
||||
if (a_Level > 3)
|
||||
{
|
||||
// Don't want the trace messages
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the terminating LF:
|
||||
size_t len = strlen(a_Text) - 1;
|
||||
while ((len > 0) && (a_Text[len] <= 32))
|
||||
{
|
||||
len--;
|
||||
}
|
||||
AString Text(a_Text, len + 1);
|
||||
|
||||
LOGD("SSL (%d): %s", a_Level, Text.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int SSLVerifyCert(void * a_This, mbedtls_x509_crt * a_Crt, int a_Depth, uint32_t * a_Flags)
|
||||
{
|
||||
char buf[1024];
|
||||
UNUSED(a_This);
|
||||
|
||||
LOG("Verify requested for (Depth %d):", a_Depth);
|
||||
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", a_Crt);
|
||||
LOG("%s", buf);
|
||||
|
||||
uint32_t Flags = *a_Flags;
|
||||
if ((Flags & MBEDTLS_X509_BADCERT_EXPIRED) != 0)
|
||||
{
|
||||
LOG(" ! server certificate has expired");
|
||||
}
|
||||
|
||||
if ((Flags & MBEDTLS_X509_BADCERT_REVOKED) != 0)
|
||||
{
|
||||
LOG(" ! server certificate has been revoked");
|
||||
}
|
||||
|
||||
if ((Flags & MBEDTLS_X509_BADCERT_CN_MISMATCH) != 0)
|
||||
{
|
||||
LOG(" ! CN mismatch");
|
||||
}
|
||||
|
||||
if ((Flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) != 0)
|
||||
{
|
||||
LOG(" ! self-signed or not signed by a trusted CA");
|
||||
}
|
||||
|
||||
if ((Flags & MBEDTLS_X509_BADCRL_NOT_TRUSTED) != 0)
|
||||
{
|
||||
LOG(" ! CRL not trusted");
|
||||
}
|
||||
|
||||
if ((Flags & MBEDTLS_X509_BADCRL_EXPIRED) != 0)
|
||||
{
|
||||
LOG(" ! CRL expired");
|
||||
}
|
||||
|
||||
if ((Flags & MBEDTLS_X509_BADCERT_OTHER) != 0)
|
||||
{
|
||||
LOG(" ! other (unknown) flag");
|
||||
}
|
||||
|
||||
if (Flags == 0)
|
||||
{
|
||||
LOG(" This certificate has no flags");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif // defined(_DEBUG) && defined(ENABLE_SSL_DEBUG_MSG)
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cSslConfig:
|
||||
|
||||
cSslConfig::cSslConfig()
|
||||
{
|
||||
mbedtls_ssl_config_init(&m_Config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cSslConfig::~cSslConfig()
|
||||
{
|
||||
mbedtls_ssl_config_free(&m_Config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslConfig::InitDefaults(const bool a_IsClient)
|
||||
{
|
||||
return mbedtls_ssl_config_defaults(
|
||||
&m_Config,
|
||||
a_IsClient ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslConfig::SetAuthMode(const eSslAuthMode a_AuthMode)
|
||||
{
|
||||
const int Mode = [=]()
|
||||
{
|
||||
switch (a_AuthMode)
|
||||
{
|
||||
case eSslAuthMode::None: return MBEDTLS_SSL_VERIFY_NONE;
|
||||
case eSslAuthMode::Optional: return MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
case eSslAuthMode::Required: return MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
case eSslAuthMode::Unset: return MBEDTLS_SSL_VERIFY_UNSET;
|
||||
#ifndef __clang__
|
||||
default: return MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
#endif
|
||||
}
|
||||
}();
|
||||
|
||||
mbedtls_ssl_conf_authmode(&m_Config, Mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslConfig::SetRng(cCtrDrbgContextPtr a_CtrDrbg)
|
||||
{
|
||||
ASSERT(a_CtrDrbg != nullptr);
|
||||
m_CtrDrbg = std::move(a_CtrDrbg);
|
||||
mbedtls_ssl_conf_rng(&m_Config, mbedtls_ctr_drbg_random, &m_CtrDrbg->m_CtrDrbg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslConfig::SetDebugCallback(cDebugCallback a_CallbackFun, void * a_CallbackData)
|
||||
{
|
||||
mbedtls_ssl_conf_dbg(&m_Config, a_CallbackFun, a_CallbackData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslConfig::SetOwnCert(cX509CertPtr a_OwnCert, cCryptoKeyPtr a_OwnCertPrivKey)
|
||||
{
|
||||
ASSERT(a_OwnCert != nullptr);
|
||||
ASSERT(a_OwnCertPrivKey != nullptr);
|
||||
|
||||
// Make sure we have the cert stored for later, mbedTLS only uses the cert later on
|
||||
m_OwnCert = std::move(a_OwnCert);
|
||||
m_OwnCertPrivKey = std::move(a_OwnCertPrivKey);
|
||||
|
||||
// Set into the config:
|
||||
mbedtls_ssl_conf_own_cert(&m_Config, m_OwnCert->GetInternal(), m_OwnCertPrivKey->GetInternal());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslConfig::SetVerifyCallback(cVerifyCallback a_CallbackFun, void * a_CallbackData)
|
||||
{
|
||||
mbedtls_ssl_conf_verify(&m_Config, a_CallbackFun, a_CallbackData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslConfig::SetCipherSuites(std::vector<int> a_CipherSuites)
|
||||
{
|
||||
m_CipherSuites = std::move(a_CipherSuites);
|
||||
m_CipherSuites.push_back(0); // Must be null terminated
|
||||
mbedtls_ssl_conf_ciphersuites(&m_Config, m_CipherSuites.data());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslConfig::SetCACerts(cX509CertPtr a_CACert)
|
||||
{
|
||||
m_CACerts = std::move(a_CACert);
|
||||
mbedtls_ssl_conf_ca_chain(&m_Config, m_CACerts->GetInternal(), nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<cSslConfig> cSslConfig::MakeDefaultConfig(bool a_IsClient)
|
||||
{
|
||||
// TODO: Default CA chain and SetAuthMode(eSslAuthMode::Required)
|
||||
auto Ret = std::make_shared<cSslConfig>();
|
||||
|
||||
Ret->InitDefaults(a_IsClient);
|
||||
|
||||
{
|
||||
auto CtrDrbg = std::make_shared<cCtrDrbgContext>();
|
||||
CtrDrbg->Initialize("Cuberite", 8);
|
||||
Ret->SetRng(std::move(CtrDrbg));
|
||||
}
|
||||
|
||||
Ret->SetAuthMode(eSslAuthMode::None); // We cannot verify because we don't have a CA chain
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef ENABLE_SSL_DEBUG_MSG
|
||||
Ret->SetDebugCallback(&SSLDebugMessage, nullptr);
|
||||
Ret->SetVerifyCallback(SSLVerifyCert, nullptr);
|
||||
mbedtls_debug_set_threshold(2);
|
||||
#endif
|
||||
|
||||
/*
|
||||
// Set ciphersuite to the easiest one to decode, so that the connection can be wireshark-decoded:
|
||||
Ret->SetCipherSuites(
|
||||
{
|
||||
MBEDTLS_TLS_RSA_WITH_RC4_128_MD5,
|
||||
MBEDTLS_TLS_RSA_WITH_RC4_128_SHA,
|
||||
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
|
||||
}
|
||||
);
|
||||
*/
|
||||
#endif
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<const cSslConfig> cSslConfig::GetDefaultClientConfig()
|
||||
{
|
||||
static const std::shared_ptr<const cSslConfig> ClientConfig = MakeDefaultConfig(true);
|
||||
return ClientConfig;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<const cSslConfig> cSslConfig::GetDefaultServerConfig()
|
||||
{
|
||||
static const std::shared_ptr<const cSslConfig> ServerConfig = MakeDefaultConfig(false);
|
||||
return ServerConfig;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
93
src/mbedTLS++/SslConfig.h
Normal file
93
src/mbedTLS++/SslConfig.h
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mbedtls/ssl.h"
|
||||
|
||||
// fwd:
|
||||
class cCryptoKey;
|
||||
class cCtrDrbgContext;
|
||||
class cX509Cert;
|
||||
|
||||
using cCryptoKeyPtr = std::shared_ptr<cCryptoKey>;
|
||||
using cCtrDrbgContextPtr = std::shared_ptr<cCtrDrbgContext>;
|
||||
using cX509CertPtr = std::shared_ptr<cX509Cert>;
|
||||
|
||||
enum class eSslAuthMode
|
||||
{
|
||||
None = 0, // MBEDTLS_SSL_VERIFY_NONE
|
||||
Optional = 1, // MBEDTLS_SSL_VERIFY_OPTIONAL
|
||||
Required = 2, // MBEDTLS_SSL_VERIFY_REQUIRED
|
||||
Unset = 3, // MBEDTLS_SSL_VERIFY_UNSET
|
||||
};
|
||||
|
||||
|
||||
|
||||
class cSslConfig
|
||||
{
|
||||
friend class cSslContext;
|
||||
public:
|
||||
/** Type of the SSL debug callback.
|
||||
Parameters are:
|
||||
void * Opaque context for the callback
|
||||
int Debug level
|
||||
const char * File name
|
||||
int Line number
|
||||
const char * Message */
|
||||
using cDebugCallback = void(*)(void *, int, const char *, int, const char *);
|
||||
|
||||
/** Type of the SSL certificate verify callback.
|
||||
Parameters are:
|
||||
void * Opaque context for the callback
|
||||
mbedtls_x509_crt * Current cert
|
||||
int Cert chain depth
|
||||
uint32_t * Verification flags */
|
||||
using cVerifyCallback = int(*)(void *, mbedtls_x509_crt *, int, uint32_t *);
|
||||
|
||||
cSslConfig();
|
||||
~cSslConfig();
|
||||
|
||||
/** Initialize with mbedTLS default settings. */
|
||||
int InitDefaults(bool a_IsClient);
|
||||
|
||||
/** Set the authorization mode. */
|
||||
void SetAuthMode(eSslAuthMode a_AuthMode);
|
||||
|
||||
/** Set the random number generator. */
|
||||
void SetRng(cCtrDrbgContextPtr a_CtrDrbg);
|
||||
|
||||
/** Set the debug callback. */
|
||||
void SetDebugCallback(cDebugCallback a_CallbackFun, void * a_CallbackData);
|
||||
|
||||
/** Set the certificate verify callback. */
|
||||
void SetVerifyCallback(cVerifyCallback a_CallbackFun, void * a_CallbackData);
|
||||
|
||||
/** Set the enabled cipher suites. */
|
||||
void SetCipherSuites(std::vector<int> a_CipherSuites);
|
||||
|
||||
/** Set the certificate to use for connections. */
|
||||
void SetOwnCert(cX509CertPtr a_OwnCert, cCryptoKeyPtr a_OwnCertPrivKey);
|
||||
|
||||
/** Set the trusted certificate authority chain. */
|
||||
void SetCACerts(cX509CertPtr a_CACert);
|
||||
|
||||
/** Creates a new config with some sensible defaults on top of mbedTLS basic settings. */
|
||||
static std::shared_ptr<cSslConfig> MakeDefaultConfig(bool a_IsClient);
|
||||
|
||||
/** Returns the default config for client connections. */
|
||||
static std::shared_ptr<const cSslConfig> GetDefaultClientConfig();
|
||||
|
||||
/** Returns the default config for server connections. */
|
||||
static std::shared_ptr<const cSslConfig> GetDefaultServerConfig();
|
||||
|
||||
private:
|
||||
|
||||
/** Returns a pointer to the wrapped mbedtls representation. */
|
||||
const mbedtls_ssl_config * GetInternal() const { return &m_Config; }
|
||||
|
||||
mbedtls_ssl_config m_Config;
|
||||
cCtrDrbgContextPtr m_CtrDrbg;
|
||||
cX509CertPtr m_OwnCert;
|
||||
cCryptoKeyPtr m_OwnCertPrivKey;
|
||||
cX509CertPtr m_CACerts;
|
||||
std::vector<int> m_CipherSuites;
|
||||
};
|
157
src/mbedTLS++/SslContext.cpp
Normal file
157
src/mbedTLS++/SslContext.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
|
||||
// SslContext.cpp
|
||||
|
||||
// Implements the cSslContext class that holds everything a single SSL context needs to function
|
||||
|
||||
#include "Globals.h"
|
||||
#include "mbedTLS++/SslContext.h"
|
||||
#include "mbedTLS++/SslConfig.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cSslContext::cSslContext(void) :
|
||||
m_IsValid(false),
|
||||
m_HasHandshaken(false)
|
||||
{
|
||||
mbedtls_ssl_init(&m_Ssl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cSslContext::~cSslContext()
|
||||
{
|
||||
mbedtls_ssl_free(&m_Ssl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::Initialize(std::shared_ptr<const cSslConfig> a_Config)
|
||||
{
|
||||
// Check double-initialization:
|
||||
if (m_IsValid)
|
||||
{
|
||||
LOGWARNING("SSL: Double initialization is not supported.");
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; // There is no return value well-suited for this, reuse this one.
|
||||
}
|
||||
|
||||
// Check the Config:
|
||||
m_Config = a_Config;
|
||||
if (m_Config == nullptr)
|
||||
{
|
||||
ASSERT(!"Config must not be nullptr");
|
||||
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
|
||||
}
|
||||
|
||||
// Apply the configuration to the ssl context
|
||||
int res = mbedtls_ssl_setup(&m_Ssl, m_Config->GetInternal());
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// Set the io callbacks
|
||||
mbedtls_ssl_set_bio(&m_Ssl, this, SendEncrypted, ReceiveEncrypted, nullptr);
|
||||
|
||||
m_IsValid = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::Initialize(bool a_IsClient)
|
||||
{
|
||||
if (a_IsClient)
|
||||
{
|
||||
return Initialize(cSslConfig::GetDefaultClientConfig());
|
||||
}
|
||||
else
|
||||
{
|
||||
return Initialize(cSslConfig::GetDefaultServerConfig());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSslContext::SetExpectedPeerName(const AString & a_ExpectedPeerName)
|
||||
{
|
||||
ASSERT(m_IsValid); // Call Initialize() first
|
||||
mbedtls_ssl_set_hostname(&m_Ssl, a_ExpectedPeerName.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::WritePlain(const void * a_Data, size_t a_NumBytes)
|
||||
{
|
||||
ASSERT(m_IsValid); // Need to call Initialize() first
|
||||
if (!m_HasHandshaken)
|
||||
{
|
||||
int res = Handshake();
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return mbedtls_ssl_write(&m_Ssl, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::ReadPlain(void * a_Data, size_t a_MaxBytes)
|
||||
{
|
||||
ASSERT(m_IsValid); // Need to call Initialize() first
|
||||
if (!m_HasHandshaken)
|
||||
{
|
||||
int res = Handshake();
|
||||
if (res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return mbedtls_ssl_read(&m_Ssl, reinterpret_cast<unsigned char *>(a_Data), a_MaxBytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::Handshake(void)
|
||||
{
|
||||
ASSERT(m_IsValid); // Need to call Initialize() first
|
||||
ASSERT(!m_HasHandshaken); // Must not call twice
|
||||
|
||||
int res = mbedtls_ssl_handshake(&m_Ssl);
|
||||
if (res == 0)
|
||||
{
|
||||
m_HasHandshaken = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSslContext::NotifyClose(void)
|
||||
{
|
||||
return mbedtls_ssl_close_notify(&m_Ssl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
// SslContext.h
|
||||
|
||||
// Declares the cSslContext class that holds everything a single SSL context needs to function
|
||||
@ -9,11 +9,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polarssl/ssl.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "../ByteBuffer.h"
|
||||
#include "CryptoKey.h"
|
||||
#include "RsaPrivateKey.h"
|
||||
#include "X509Cert.h"
|
||||
|
||||
|
||||
|
||||
@ -21,6 +18,7 @@
|
||||
|
||||
// fwd:
|
||||
class cCtrDrbgContext;
|
||||
class cSslConfig;
|
||||
|
||||
|
||||
|
||||
@ -43,45 +41,40 @@ public:
|
||||
virtual ~cSslContext();
|
||||
|
||||
/** Initializes the context for use as a server or client.
|
||||
Returns 0 on success, PolarSSL error on failure. */
|
||||
int Initialize(bool a_IsClient, const std::shared_ptr<cCtrDrbgContext> & a_CtrDrbg = {});
|
||||
a_Config must not be nullptr and the config must not be changed after this call.
|
||||
Returns 0 on success, mbedTLS error on failure. */
|
||||
int Initialize(std::shared_ptr<const cSslConfig> a_Config);
|
||||
|
||||
/** Initializes the context using the default config. */
|
||||
int Initialize(bool a_IsClient);
|
||||
|
||||
/** Returns true if the object has been initialized properly. */
|
||||
bool IsValid(void) const { return m_IsValid; }
|
||||
|
||||
/** Sets the certificate to use as our own. Must be used when representing a server, optional when client.
|
||||
Must be called after Initialize(). */
|
||||
void SetOwnCert(const cX509CertPtr & a_OwnCert, const cRsaPrivateKeyPtr & a_OwnCertPrivKey);
|
||||
|
||||
/** Sets the certificate to use as our own. Must be used when representing a server, optional when client.
|
||||
Must be called after Initialize(). */
|
||||
void SetOwnCert(const cX509CertPtr & a_OwnCert, const cCryptoKeyPtr & a_OwnCertPrivKey);
|
||||
|
||||
/** Sets a cert chain as the trusted cert store for this context. Must be called after Initialize().
|
||||
Calling this will switch the context into strict cert verification mode.
|
||||
a_ExpectedPeerName is the CommonName that we expect the SSL peer to have in its cert,
|
||||
/** Sets the SSL peer name expected for this context. Must be called after Initialize().
|
||||
\param a_ExpectedPeerName CommonName that we expect the SSL peer to have in its cert,
|
||||
if it is different, the verification will fail. An empty string will disable the CN check. */
|
||||
void SetCACerts(const cX509CertPtr & a_CACert, const AString & a_ExpectedPeerName);
|
||||
void SetExpectedPeerName(const AString & a_ExpectedPeerName);
|
||||
|
||||
/** Writes data to be encrypted and sent to the SSL peer. Will perform SSL handshake, if needed.
|
||||
Returns the number of bytes actually written, or PolarSSL error code.
|
||||
If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any
|
||||
Returns the number of bytes actually written, or mbedTLS error code.
|
||||
If the return value is MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, the owner should send any
|
||||
cached outgoing data to the SSL peer and write any incoming data received from the SSL peer and then call
|
||||
this function again with the same parameters. Note that this may repeat a few times before the data is
|
||||
actually written, mainly due to initial handshake. */
|
||||
int WritePlain(const void * a_Data, size_t a_NumBytes);
|
||||
|
||||
/** Reads data decrypted from the SSL stream. Will perform SSL handshake, if needed.
|
||||
Returns the number of bytes actually read, or PolarSSL error code.
|
||||
If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any
|
||||
Returns the number of bytes actually read, or mbedTLS error code.
|
||||
If the return value is MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, the owner should send any
|
||||
cached outgoing data to the SSL peer and write any incoming data received from the SSL peer and then call
|
||||
this function again with the same parameters. Note that this may repeat a few times before the data is
|
||||
actually read, mainly due to initial handshake. */
|
||||
int ReadPlain(void * a_Data, size_t a_MaxBytes);
|
||||
|
||||
/** Performs the SSL handshake.
|
||||
Returns zero on success, PoladSSL error code on failure.
|
||||
If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any
|
||||
Returns zero on success, mbedTLS error code on failure.
|
||||
If the return value is MBEDTLS_ERR_SSL_WANT_READ or MBEDTLS_ERR_SSL_WANT_WRITE, the owner should send any
|
||||
cached outgoing data to the SSL peer and write any incoming data received from the SSL peer and then call
|
||||
this function again. Note that this may repeat a few times before the handshake is completed. */
|
||||
int Handshake(void);
|
||||
@ -90,64 +83,39 @@ public:
|
||||
bool HasHandshaken(void) const { return m_HasHandshaken; }
|
||||
|
||||
/** Notifies the SSL peer that the connection is being closed.
|
||||
Returns 0 on success, PolarSSL error code on failure. */
|
||||
Returns 0 on success, mbedTLS error code on failure. */
|
||||
int NotifyClose(void);
|
||||
|
||||
protected:
|
||||
|
||||
/** Configuration of the SSL context. */
|
||||
std::shared_ptr<const cSslConfig> m_Config;
|
||||
|
||||
/** The SSL context that mbedTLS uses. */
|
||||
mbedtls_ssl_context m_Ssl;
|
||||
|
||||
/** True if the object has been initialized properly. */
|
||||
bool m_IsValid;
|
||||
|
||||
/** The random generator to use */
|
||||
std::shared_ptr<cCtrDrbgContext> m_CtrDrbg;
|
||||
|
||||
/** The SSL context that PolarSSL uses. */
|
||||
ssl_context m_Ssl;
|
||||
|
||||
/** The certificate that we present to the peer. */
|
||||
cX509CertPtr m_OwnCert;
|
||||
|
||||
/** Private key for m_OwnCert, if initialized from a cRsaPrivateKey. */
|
||||
cRsaPrivateKeyPtr m_OwnCertPrivKey;
|
||||
|
||||
/** Private key for m_OwnCert, if initialized from a cCryptoKey. */
|
||||
cCryptoKeyPtr m_OwnCertPrivKey2;
|
||||
|
||||
/** True if the SSL handshake has been completed. */
|
||||
bool m_HasHandshaken;
|
||||
|
||||
/** A copy of the trusted CA root cert store that is passed to us in SetCACerts(), so that the pointer
|
||||
stays valid even after the call, when PolarSSL finally uses it. */
|
||||
cX509CertPtr m_CACerts;
|
||||
|
||||
/** Buffer for the expected peer name. We need to buffer it because the caller may free the string they
|
||||
give us before PolarSSL consumes the raw pointer it gets to the CN. */
|
||||
AString m_ExpectedPeerName;
|
||||
|
||||
|
||||
/** The callback used by PolarSSL when it wants to read encrypted data. */
|
||||
/** The callback used by mbedTLS when it wants to read encrypted data. */
|
||||
static int ReceiveEncrypted(void * a_This, unsigned char * a_Buffer, size_t a_NumBytes)
|
||||
{
|
||||
return (reinterpret_cast<cSslContext *>(a_This))->ReceiveEncrypted(a_Buffer, a_NumBytes);
|
||||
}
|
||||
|
||||
/** The callback used by PolarSSL when it wants to write encrypted data. */
|
||||
/** The callback used by mbedTLS when it wants to write encrypted data. */
|
||||
static int SendEncrypted(void * a_This, const unsigned char * a_Buffer, size_t a_NumBytes)
|
||||
{
|
||||
return (reinterpret_cast<cSslContext *>(a_This))->SendEncrypted(a_Buffer, a_NumBytes);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
/** The callback used by PolarSSL to output debug messages */
|
||||
static void SSLDebugMessage(void * a_UserParam, int a_Level, const char * a_Text);
|
||||
|
||||
/** The callback used by PolarSSL to log information on the cert chain */
|
||||
static int SSLVerifyCert(void * a_This, x509_crt * a_Crt, int a_Depth, int * a_Flags);
|
||||
#endif // _DEBUG
|
||||
|
||||
/** Called when PolarSSL wants to read encrypted data. */
|
||||
/** Called when mbedTLS wants to read encrypted data. */
|
||||
virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0;
|
||||
|
||||
/** Called when PolarSSL wants to write encrypted data. */
|
||||
/** Called when mbedTLS wants to write encrypted data. */
|
||||
virtual int SendEncrypted(const unsigned char * a_Buffer, size_t a_NumBytes) = 0;
|
||||
} ;
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// X509Cert.cpp
|
||||
|
||||
// Implements the cX509Cert class representing a wrapper over X509 certs in PolarSSL
|
||||
// Implements the cX509Cert class representing a wrapper over X509 certs in mbedTLS
|
||||
|
||||
#include "Globals.h"
|
||||
#include "X509Cert.h"
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
cX509Cert::cX509Cert(void)
|
||||
{
|
||||
x509_crt_init(&m_Cert);
|
||||
mbedtls_x509_crt_init(&m_Cert);
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ cX509Cert::cX509Cert(void)
|
||||
|
||||
cX509Cert::~cX509Cert()
|
||||
{
|
||||
x509_crt_free(&m_Cert);
|
||||
mbedtls_x509_crt_free(&m_Cert);
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ cX509Cert::~cX509Cert()
|
||||
|
||||
int cX509Cert::Parse(const void * a_CertContents, size_t a_Size)
|
||||
{
|
||||
return x509_crt_parse(&m_Cert, reinterpret_cast<const unsigned char *>(a_CertContents), a_Size);
|
||||
return mbedtls_x509_crt_parse(&m_Cert, reinterpret_cast<const unsigned char *>(a_CertContents), a_Size);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
// X509Cert.h
|
||||
|
||||
// Declares the cX509Cert class representing a wrapper over X509 certs in PolarSSL
|
||||
// Declares the cX509Cert class representing a wrapper over X509 certs in mbedTLS
|
||||
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polarssl/x509_crt.h"
|
||||
#include "mbedtls/x509_crt.h"
|
||||
|
||||
|
||||
|
||||
@ -17,21 +17,21 @@
|
||||
|
||||
class cX509Cert
|
||||
{
|
||||
friend class cSslContext;
|
||||
friend class cSslConfig;
|
||||
|
||||
public:
|
||||
cX509Cert(void);
|
||||
~cX509Cert(void);
|
||||
|
||||
/** Parses the certificate chain data into the context.
|
||||
Returns 0 on succes, or PolarSSL error code on failure. */
|
||||
Returns 0 on succes, or mbedTLS error code on failure. */
|
||||
int Parse(const void * a_CertContents, size_t a_Size);
|
||||
|
||||
protected:
|
||||
x509_crt m_Cert;
|
||||
mbedtls_x509_crt m_Cert;
|
||||
|
||||
/** Returns the internal cert ptr. Only use in PolarSSL API calls. */
|
||||
x509_crt * GetInternal(void) { return &m_Cert; }
|
||||
/** Returns the internal cert ptr. Only use in mbedTLS API calls. */
|
||||
mbedtls_x509_crt * GetInternal(void) { return &m_Cert; }
|
||||
} ;
|
||||
|
||||
typedef std::shared_ptr<cX509Cert> cX509CertPtr;
|
@ -1,8 +1,8 @@
|
||||
enable_testing()
|
||||
enable_testing()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/)
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/libevent/include)
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/polarssl/include)
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/mbedtls/include)
|
||||
|
||||
add_definitions(-DTEST_GLOBALS=1)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
enable_testing()
|
||||
enable_testing()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/)
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/libevent/include)
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/polarssl/include)
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/mbedtls/include)
|
||||
|
||||
add_definitions(-DTEST_GLOBALS=1)
|
||||
|
||||
@ -18,11 +18,12 @@ set (Network_SRCS
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkSingleton.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/ServerHandleImpl.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CtrDrbgContext.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CryptoKey.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/EntropyContext.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/SslContext.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/X509Cert.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/CtrDrbgContext.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/CryptoKey.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/EntropyContext.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslConfig.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslContext.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/X509Cert.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/StringUtils.cpp
|
||||
)
|
||||
|
||||
@ -39,11 +40,12 @@ set (Network_HDRS
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/ServerHandleImpl.h
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.h
|
||||
${CMAKE_SOURCE_DIR}/src/OSSupport/Queue.h
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CtrDrbgContext.h
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CryptoKey.h
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/EntropyContext.h
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/SslContext.h
|
||||
${CMAKE_SOURCE_DIR}/src/PolarSSL++/X509Cert.h
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/CtrDrbgContext.h
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/CryptoKey.h
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/EntropyContext.h
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslConfig.h
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslContext.h
|
||||
${CMAKE_SOURCE_DIR}/src/mbedTLS++/X509Cert.h
|
||||
${CMAKE_SOURCE_DIR}/src/StringUtils.h
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user