1
0

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:
peterbell10 2017-08-30 15:00:06 +01:00 committed by Tiger Wang
parent c6bc822054
commit 84941bcc9f
59 changed files with 952 additions and 699 deletions

6
.gitmodules vendored
View File

@ -7,9 +7,9 @@
[submodule "Server/Plugins/ChatLog"] [submodule "Server/Plugins/ChatLog"]
path = Server/Plugins/ChatLog path = Server/Plugins/ChatLog
url = https://github.com/cuberite/ChatLog.git url = https://github.com/cuberite/ChatLog.git
[submodule "lib/polarssl"] [submodule "lib/mbedtls"]
path = lib/polarssl path = lib/mbedtls
url = https://github.com/cuberite/polarssl.git url = https://github.com/ARMmbed/mbedtls.git
ignore = dirty ignore = dirty
[submodule "lib/SQLiteCpp"] [submodule "lib/SQLiteCpp"]
path = lib/SQLiteCpp path = lib/SQLiteCpp

View File

@ -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 # 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) 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?") message(FATAL_ERROR "SQLiteCpp is missing in folder lib/SQLiteCpp. Have you initialized the submodules / downloaded the extra libraries?")
endif() endif()
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/lib/polarssl/CMakeLists.txt) if (NOT EXISTS ${PROJECT_SOURCE_DIR}/lib/mbedtls/CMakeLists.txt)
message(FATAL_ERROR "PolarSSL is missing in folder lib/polarssl. Have you initialized the submodules / downloaded the extra libraries?") message(FATAL_ERROR "mbedTLS is missing in folder lib/mbedtls. Have you initialized the submodules / downloaded the extra libraries?")
endif() endif()
if (NOT EXISTS ${PROJECT_SOURCE_DIR}/lib/libevent/CMakeLists.txt) 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?") 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() endif()
# We use EXCLUDE_FROM_ALL so that only the explicit dependencies are used # 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) # (mbedTLS also has test and example programs in their CMakeLists.txt, we don't want those)
include(lib/polarssl.cmake EXCLUDE_FROM_ALL) include(lib/mbedtls.cmake EXCLUDE_FROM_ALL)
if(NOT MSVC AND "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm") 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 # 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() endif()
set_exe_flags() set_exe_flags()
@ -302,7 +302,9 @@ if (MSVC)
jsoncpp_lib_static jsoncpp_lib_static
lua lua
luaexpat luaexpat
mbedcrypto
mbedtls mbedtls
mbedx509
sqlite sqlite
SQLiteCpp SQLiteCpp
tolualib tolualib

View File

@ -8,7 +8,7 @@ set_lib_flags()
# Set include paths to the used libraries: # Set include paths to the used libraries:
include_directories(SYSTEM "../../lib") include_directories(SYSTEM "../../lib")
include_directories(SYSTEM "../../lib/polarssl/include") include_directories(SYSTEM "../../lib/mbedtls/include")
include_directories("../../src") include_directories("../../src")
function(flatten_files arg1) function(flatten_files arg1)
@ -20,7 +20,7 @@ function(flatten_files arg1)
set(${arg1} "${res}" PARENT_SCOPE) set(${arg1} "${res}" PARENT_SCOPE)
endfunction() endfunction()
include(../../lib/polarssl.cmake) include(../../lib/mbedtls.cmake)
add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib) add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib)
set_exe_flags() set_exe_flags()
@ -30,12 +30,12 @@ set(SHARED_SRC
../../src/ByteBuffer.cpp ../../src/ByteBuffer.cpp
../../src/StringUtils.cpp ../../src/StringUtils.cpp
../../src/UUID.cpp ../../src/UUID.cpp
../../src/PolarSSL++/AesCfb128Decryptor.cpp ../../src/mbedTLS++/AesCfb128Decryptor.cpp
../../src/PolarSSL++/AesCfb128Encryptor.cpp ../../src/mbedTLS++/AesCfb128Encryptor.cpp
../../src/PolarSSL++/CryptoKey.cpp ../../src/mbedTLS++/CryptoKey.cpp
../../src/PolarSSL++/CtrDrbgContext.cpp ../../src/mbedTLS++/CtrDrbgContext.cpp
../../src/PolarSSL++/EntropyContext.cpp ../../src/mbedTLS++/EntropyContext.cpp
../../src/PolarSSL++/RsaPrivateKey.cpp ../../src/mbedTLS++/RsaPrivateKey.cpp
../../src/LoggerListeners.cpp ../../src/LoggerListeners.cpp
../../src/Logger.cpp ../../src/Logger.cpp
) )
@ -43,12 +43,12 @@ set(SHARED_HDR
../../src/ByteBuffer.h ../../src/ByteBuffer.h
../../src/StringUtils.h ../../src/StringUtils.h
../../src/UUID.h ../../src/UUID.h
../../src/PolarSSL++/AesCfb128Decryptor.h ../../src/mbedTLS++/AesCfb128Decryptor.h
../../src/PolarSSL++/AesCfb128Encryptor.h ../../src/mbedTLS++/AesCfb128Encryptor.h
../../src/PolarSSL++/CryptoKey.h ../../src/mbedTLS++/CryptoKey.h
../../src/PolarSSL++/CtrDrbgContext.h ../../src/mbedTLS++/CtrDrbgContext.h
../../src/PolarSSL++/EntropyContext.h ../../src/mbedTLS++/EntropyContext.h
../../src/PolarSSL++/RsaPrivateKey.h ../../src/mbedTLS++/RsaPrivateKey.h
) )
set(SHARED_OSS_SRC set(SHARED_OSS_SRC
../../src/OSSupport/CriticalSection.cpp ../../src/OSSupport/CriticalSection.cpp

View File

@ -1,4 +1,4 @@

// Connection.cpp // Connection.cpp
// Interfaces to the cConnection class representing a single pair of connected sockets // Interfaces to the cConnection class representing a single pair of connected sockets
@ -7,7 +7,7 @@
#include "Connection.h" #include "Connection.h"
#include "Server.h" #include "Server.h"
#include <iostream> #include <iostream>
#include "PolarSSL++/CryptoKey.h" #include "mbedTLS++/CryptoKey.h"
#include "../../src/Logger.h" #include "../../src/Logger.h"
#ifdef _WIN32 #ifdef _WIN32

View File

@ -1,4 +1,4 @@

// Connection.h // Connection.h
// Interfaces to the cConnection class representing a single pair of connected sockets // Interfaces to the cConnection class representing a single pair of connected sockets
@ -10,8 +10,8 @@
#pragma once #pragma once
#include "ByteBuffer.h" #include "ByteBuffer.h"
#include "PolarSSL++/AesCfb128Decryptor.h" #include "mbedTLS++/AesCfb128Decryptor.h"
#include "PolarSSL++/AesCfb128Encryptor.h" #include "mbedTLS++/AesCfb128Encryptor.h"

View File

@ -1,4 +1,4 @@

// Server.h // Server.h
// Interfaces to the cServer class encapsulating the entire "server" // Interfaces to the cServer class encapsulating the entire "server"
@ -9,7 +9,7 @@
#pragma once #pragma once
#include "PolarSSL++/RsaPrivateKey.h" #include "mbedTLS++/RsaPrivateKey.h"

1
lib/mbedtls Submodule

@ -0,0 +1 @@
Subproject commit f2a597fa3dd1c7b15e0fee62f6932b253295803d

View File

@ -1,10 +1,10 @@

# This script includes PolarSSL, if not already included. # This script includes PolarSSL, if not already included.
# It is needed for when multiple projects reference PolarSSL. # It is needed for when multiple projects reference PolarSSL.
if(NOT TARGET mbedtls) if(NOT TARGET mbedtls)
message("including polarssl") message("including mbedtls")
set(ENABLE_TESTING OFF CACHE BOOL "Disable tests") set(ENABLE_TESTING OFF CACHE BOOL "Disable tests")
set(ENABLE_PROGRAMS OFF CACHE BOOL "Disable programs") 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() endif()

@ -1 +0,0 @@
Subproject commit 4f4c5b7450631e46a94cb89adf4a7737fbb178bc

View File

@ -6,8 +6,8 @@
#include "Globals.h" #include "Globals.h"
#include "LuaTCPLink.h" #include "LuaTCPLink.h"
#include "LuaServerHandle.h" #include "LuaServerHandle.h"
#include "../PolarSSL++/X509Cert.h" #include "../mbedTLS++/X509Cert.h"
#include "../PolarSSL++/CryptoKey.h" #include "../mbedTLS++/CryptoKey.h"

View File

@ -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 "ManualBindings.h" #include "ManualBindings.h"
@ -6,8 +6,8 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include "tolua++/include/tolua++.h" #include "tolua++/include/tolua++.h"
#include "polarssl/md5.h" #include "mbedtls/md5.h"
#include "polarssl/sha1.h" #include "mbedtls/sha1.h"
#include "PluginLua.h" #include "PluginLua.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "LuaWindow.h" #include "LuaWindow.h"
@ -1838,7 +1838,7 @@ static int tolua_md5(lua_State * tolua_S)
{ {
return 0; return 0;
} }
md5(SourceString, len, Output); mbedtls_md5(SourceString, len, Output);
lua_pushlstring(tolua_S, reinterpret_cast<const char *>(Output), ARRAYCOUNT(Output)); lua_pushlstring(tolua_S, reinterpret_cast<const char *>(Output), ARRAYCOUNT(Output));
return 1; return 1;
} }
@ -1869,7 +1869,7 @@ static int tolua_md5HexString(lua_State * tolua_S)
{ {
return 0; return 0;
} }
md5(SourceString, len, md5Output); mbedtls_md5(SourceString, len, md5Output);
// Convert the md5 checksum to hex string: // Convert the md5 checksum to hex string:
std::stringstream Output; std::stringstream Output;
@ -1896,7 +1896,7 @@ static int tolua_sha1(lua_State * tolua_S)
{ {
return 0; return 0;
} }
sha1(SourceString, len, Output); mbedtls_sha1(SourceString, len, Output);
lua_pushlstring(tolua_S, reinterpret_cast<const char *>(Output), ARRAYCOUNT(Output)); lua_pushlstring(tolua_S, reinterpret_cast<const char *>(Output), ARRAYCOUNT(Output));
return 1; return 1;
} }
@ -1915,7 +1915,7 @@ static int tolua_sha1HexString(lua_State * tolua_S)
{ {
return 0; return 0;
} }
sha1(SourceString, len, sha1Output); mbedtls_sha1(SourceString, len, sha1Output);
// Convert the sha1 checksum to hex string: // Convert the sha1 checksum to hex string:
std::stringstream Output; std::stringstream Output;

View File

@ -1,13 +1,13 @@
project (Cuberite) project (Cuberite)
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/") 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/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") include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/libevent/include")
set(FOLDERS set(FOLDERS
OSSupport HTTP Items Blocks Protocol Generating PolarSSL++ Bindings OSSupport HTTP Items Blocks Protocol Generating mbedTLS++ Bindings
WorldStorage Mobs Entities Simulator Simulator/IncrementalRedstoneSimulator WorldStorage Mobs Entities Simulator Simulator/IncrementalRedstoneSimulator
BlockEntities UI Noise BlockEntities UI Noise
) )
@ -177,7 +177,7 @@ endif()
if (NOT MSVC) if (NOT MSVC)
# Bindings need to reference other folders, so they are done here instead # Bindings need to reference other folders, so they are done here instead
# lib dependencies are not included # 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}) foreach(folder ${FOLDERS})
add_subdirectory(${folder}) add_subdirectory(${folder})
@ -349,7 +349,7 @@ if (NOT MSVC)
OSSupport HTTPServer Bindings Items Blocks Noise OSSupport HTTPServer Bindings Items Blocks Noise
Protocol Generating WorldStorage Protocol Generating WorldStorage
Mobs Entities Simulator IncrementalRedstoneSimulator Mobs Entities Simulator IncrementalRedstoneSimulator
BlockEntities UI PolarSSL++ BlockEntities UI mbedTLS++
) )
endif () endif ()

View File

@ -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 "ClientHandle.h"
#include "Server.h" #include "Server.h"
@ -33,7 +33,7 @@
#include "CompositeChat.h" #include "CompositeChat.h"
#include "Items/ItemSword.h" #include "Items/ItemSword.h"
#include "polarssl/md5.h" #include "mbedtls/md5.h"

View File

@ -1,4 +1,4 @@

// HTTPServer.cpp // HTTPServer.cpp
// Implements the cHTTPServer class representing a HTTP webserver that uses cListenThread and cSocketThreads for processing // Implements the cHTTPServer class representing a HTTP webserver that uses cListenThread and cSocketThreads for processing
@ -9,6 +9,7 @@
#include "HTTPServerConnection.h" #include "HTTPServerConnection.h"
#include "HTTPFormParser.h" #include "HTTPFormParser.h"
#include "SslHTTPServerConnection.h" #include "SslHTTPServerConnection.h"
#include "mbedTLS++/SslConfig.h"
@ -88,17 +89,23 @@ bool cHTTPServer::Initialize(void)
AString KeyFile = cFile::ReadWholeFile("webadmin/httpskey.pem"); AString KeyFile = cFile::ReadWholeFile("webadmin/httpskey.pem");
if (!CertFile.empty() && !KeyFile.empty()) if (!CertFile.empty() && !KeyFile.empty())
{ {
m_Cert.reset(new cX509Cert); auto Cert = std::make_shared<cX509Cert>();
int res = m_Cert->Parse(CertFile.data(), CertFile.size()); int res = Cert->Parse(CertFile.data(), CertFile.size());
if (res == 0) if (res == 0)
{ {
m_CertPrivKey.reset(new cCryptoKey); auto CertPrivKey = std::make_shared<cCryptoKey>();
int res2 = m_CertPrivKey->ParsePrivate(KeyFile.data(), KeyFile.size(), ""); res = CertPrivKey->ParsePrivate(KeyFile.data(), KeyFile.size(), "");
if (res2 != 0) 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: // Reading the private key failed, reset the cert:
LOGWARNING("WebServer: Cannot read HTTPS certificate private key: -0x%x", -res2); LOGWARNING("WebServer: Cannot read HTTPS certificate private key: -0x%x", -res);
m_Cert.reset();
} }
} }
else else
@ -108,7 +115,7 @@ bool cHTTPServer::Initialize(void)
} }
// Notify the admin about the HTTPS / HTTP status // 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."); 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"); 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_RemoteIPAddress);
UNUSED(a_RemotePort); 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 else
{ {

View File

@ -1,4 +1,4 @@

// HTTPServer.h // HTTPServer.h
// Declares the cHTTPServer class representing a HTTP webserver that uses cListenThread and cSocketThreads for processing // Declares the cHTTPServer class representing a HTTP webserver that uses cListenThread and cSocketThreads for processing
@ -11,8 +11,8 @@
#include "../OSSupport/Network.h" #include "../OSSupport/Network.h"
#include "../IniFile.h" #include "../IniFile.h"
#include "PolarSSL++/CryptoKey.h" #include "mbedTLS++/CryptoKey.h"
#include "PolarSSL++/X509Cert.h" #include "mbedTLS++/X509Cert.h"
@ -21,6 +21,7 @@
// fwd: // fwd:
class cHTTPIncomingRequest; class cHTTPIncomingRequest;
class cHTTPServerConnection; class cHTTPServerConnection;
class cSslConfig;
@ -70,11 +71,8 @@ protected:
/** The callbacks to call for various events */ /** The callbacks to call for various events */
cCallbacks * m_Callbacks; cCallbacks * m_Callbacks;
/** The server certificate to use for the SSL connections */ /** Configuration for server ssl connections. */
cX509CertPtr m_Cert; std::shared_ptr<const cSslConfig> m_SslConfig;
/** The private key for m_Cert. */
cCryptoKeyPtr m_CertPrivKey;
/** Called by cHTTPServerListenCallbacks when there's a new incoming connection. /** Called by cHTTPServerListenCallbacks when there's a new incoming connection.

View File

@ -1,4 +1,4 @@

// SslHTTPConnection.cpp // SslHTTPConnection.cpp
// Implements the cSslHTTPServerConnection class representing a HTTP connection made over a SSL link // 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), super(a_HTTPServer),
m_Ssl(64000), m_Ssl(64000)
m_Cert(a_Cert),
m_PrivateKey(a_PrivateKey)
{ {
m_Ssl.Initialize(false); if (a_Config != nullptr)
m_Ssl.SetOwnCert(a_Cert, a_PrivateKey); {
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: // The link may have closed while processing the data, bail out:
return; 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: // SSL requires us to send data to peer first, do so by "sending" empty data:
SendData(nullptr, 0); SendData(nullptr, 0);

View File

@ -1,4 +1,4 @@

// SslHTTPServerConnection.h // SslHTTPServerConnection.h
// Declares the cSslHTTPServerConnection class representing a HTTP connection made over an SSL link // Declares the cSslHTTPServerConnection class representing a HTTP connection made over an SSL link
@ -10,7 +10,7 @@
#pragma once #pragma once
#include "HTTPServerConnection.h" #include "HTTPServerConnection.h"
#include "PolarSSL++/BufferedSslContext.h" #include "mbedTLS++/BufferedSslContext.h"
@ -24,19 +24,13 @@ class cSslHTTPServerConnection :
public: public:
/** Creates a new connection on the specified server. /** Creates a new connection on the specified server.
Sends the specified cert as the server certificate, uses the private key for decryption. */ 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; virtual ~cSslHTTPServerConnection() override;
protected: protected:
cBufferedSslContext m_Ssl; 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: // cHTTPConnection overrides:
virtual void OnReceivedData(const char * a_Data, size_t a_Size) override; // Data is received from the client 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 virtual void SendData(const void * a_Data, size_t a_Size) override; // Data is to be sent to client

View File

@ -7,8 +7,8 @@
#include "UrlClient.h" #include "UrlClient.h"
#include "UrlParser.h" #include "UrlParser.h"
#include "HTTPMessageParser.h" #include "HTTPMessageParser.h"
#include "../PolarSSL++/X509Cert.h" #include "../mbedTLS++/X509Cert.h"
#include "../PolarSSL++/CryptoKey.h" #include "../mbedTLS++/CryptoKey.h"

View File

@ -1,10 +1,11 @@

// TCPLinkImpl.cpp // TCPLinkImpl.cpp
// Implements the cTCPLinkImpl class implementing the TCP link functionality // Implements the cTCPLinkImpl class implementing the TCP link functionality
#include "Globals.h" #include "Globals.h"
#include "TCPLinkImpl.h" #include "TCPLinkImpl.h"
#include "mbedTLS++/SslConfig.h"
#include "NetworkSingleton.h" #include "NetworkSingleton.h"
#include "ServerHandleImpl.h" #include "ServerHandleImpl.h"
#include "event2/buffer.h" #include "event2/buffer.h"
@ -245,26 +246,29 @@ AString cTCPLinkImpl::StartTLSClient(
{ {
return "TLS is already active on this link"; return "TLS is already active on this link";
} }
if ( if ((a_OwnCert == nullptr) != (a_OwnPrivKey == nullptr))
((a_OwnCert == nullptr) && (a_OwnPrivKey != nullptr)) ||
((a_OwnCert != nullptr) && (a_OwnPrivKey != nullptr))
)
{ {
return "Either provide both the certificate and private key, or neither"; return "Either provide both the certificate and private key, or neither";
} }
// Create the TLS context: // Create the TLS context:
m_TlsContext.reset(new cLinkTlsContext(*this)); m_TlsContext = std::make_shared<cLinkTlsContext>(*this);
m_TlsContext->Initialize(true);
if (a_OwnCert != nullptr) 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)); m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext));
// Start the handshake: // Start the handshake:
m_TlsContext->Handshake(); m_TlsContext->Handshake();
return ""; return {};
} }
@ -282,15 +286,18 @@ AString cTCPLinkImpl::StartTLSServer(
{ {
return "TLS is already active on this link"; 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"; return "Provide the server certificate and private key";
} }
// Create the TLS context: // Create the TLS context:
m_TlsContext.reset(new cLinkTlsContext(*this)); m_TlsContext = std::make_shared<cLinkTlsContext>(*this);
m_TlsContext->Initialize(false); {
m_TlsContext->SetOwnCert(a_OwnCert, a_OwnPrivKey); auto Config = cSslConfig::MakeDefaultConfig(false);
Config->SetOwnCert(a_OwnCert, a_OwnPrivKey);
m_TlsContext->Initialize(std::move(Config));
}
m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext)); m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext));
// Push the initial data: // Push the initial data:
@ -298,7 +305,7 @@ AString cTCPLinkImpl::StartTLSServer(
// Start the handshake: // Start the handshake:
m_TlsContext->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 there's nothing queued in the buffer, report empty buffer:
if (m_EncryptedData.empty()) 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: // Copy as much data as possible to the provided buffer:

View File

@ -14,7 +14,7 @@
#include "Network.h" #include "Network.h"
#include <event2/event.h> #include <event2/event.h>
#include <event2/bufferevent.h> #include <event2/bufferevent.h>
#include "../PolarSSL++/SslContext.h" #include "../mbedTLS++/SslContext.h"

View File

@ -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

View File

@ -11,7 +11,7 @@
#include "../IniFile.h" #include "../IniFile.h"
#include "json/json.h" #include "json/json.h"
#include "PolarSSL++/BlockingSslClientSocket.h" #include "mbedTLS++/BlockingSslClientSocket.h"

View File

@ -1,4 +1,4 @@

// MojangAPI.cpp // MojangAPI.cpp
// Implements the cMojangAPI class representing the various API points provided by Mojang's webservices, and a cache for their results // 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 "SQLiteCpp/Statement.h"
#include "../IniFile.h" #include "../IniFile.h"
#include "json/json.h" #include "json/json.h"
#include "PolarSSL++/BlockingSslClientSocket.h" #include "mbedTLS++/BlockingSslClientSocket.h"
#include "mbedTLS++/SslConfig.h"
#include "../RankManager.h" #include "../RankManager.h"
#include "../OSSupport/IsThread.h" #include "../OSSupport/IsThread.h"
#include "../Root.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. */ /** 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 // GeoTrust root CA cert
// Currently used for signing *.mojang.com's cert // Currently used for signing *.mojang.com's cert
// Exported from Mozilla Firefox's built-in CA repository // Exported from Mozilla Firefox's built-in CA repository
@ -140,9 +141,33 @@ static const AString & GetCACerts(void)
"VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n" "VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n"
"WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n" "WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n"
"-----END CERTIFICATE-----\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: // Connect the socket:
cBlockingSslClientSocket Socket; cBlockingSslClientSocket Socket;
Socket.SetTrustedRootCertsFromString(GetCACerts(), a_ServerName); Socket.SetSslConfig(GetSslConfig());
Socket.SetExpectedPeerName(a_ServerName);
if (!Socket.Connect(a_ServerName, 443)) if (!Socket.Connect(a_ServerName, 443))
{ {
LOGWARNING("%s: Can't connect to %s: %s", __FUNCTION__, a_ServerName.c_str(), Socket.GetLastErrorText().c_str()); 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)); 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 // This value should never be returned, it is handled internally by cBlockingSslClientSocket
LOGWARNING("%s: SSL reading failed internally", __FUNCTION__); LOGWARNING("%s: SSL reading failed internally", __FUNCTION__);
return false; return false;
} }
if (ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
{ {
break; break;
} }

View File

@ -11,7 +11,7 @@ Implements the 1.8 protocol classes:
#include "json/json.h" #include "json/json.h"
#include "Protocol_1_8.h" #include "Protocol_1_8.h"
#include "ChunkDataSerializer.h" #include "ChunkDataSerializer.h"
#include "PolarSSL++/Sha1Checksum.h" #include "mbedTLS++/Sha1Checksum.h"
#include "Packetizer.h" #include "Packetizer.h"
#include "../ClientHandle.h" #include "../ClientHandle.h"

View File

@ -29,8 +29,8 @@ Declares the 1.8 protocol classes:
#pragma warning(pop) #pragma warning(pop)
#endif #endif
#include "PolarSSL++/AesCfb128Decryptor.h" #include "mbedTLS++/AesCfb128Decryptor.h"
#include "PolarSSL++/AesCfb128Encryptor.h" #include "mbedTLS++/AesCfb128Encryptor.h"

View File

@ -17,7 +17,7 @@ Implements the 1.9 protocol classes:
#include "json/json.h" #include "json/json.h"
#include "Protocol_1_9.h" #include "Protocol_1_9.h"
#include "ChunkDataSerializer.h" #include "ChunkDataSerializer.h"
#include "PolarSSL++/Sha1Checksum.h" #include "mbedTLS++/Sha1Checksum.h"
#include "Packetizer.h" #include "Packetizer.h"
#include "../ClientHandle.h" #include "../ClientHandle.h"

View File

@ -35,8 +35,8 @@ Declares the 1.9 protocol classes:
#pragma warning(pop) #pragma warning(pop)
#endif #endif
#include "PolarSSL++/AesCfb128Decryptor.h" #include "mbedTLS++/AesCfb128Decryptor.h"
#include "PolarSSL++/AesCfb128Encryptor.h" #include "mbedTLS++/AesCfb128Encryptor.h"

View File

@ -22,7 +22,7 @@
#pragma warning(disable:4702) #pragma warning(disable:4702)
#endif #endif
#include "PolarSSL++/RsaPrivateKey.h" #include "mbedTLS++/RsaPrivateKey.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)

View File

@ -5,7 +5,7 @@
#include "Globals.h" #include "Globals.h"
#include "UUID.h" #include "UUID.h"
#include "polarssl/md5.h" #include "mbedtls/md5.h"
/** UUID normalised in textual form. */ /** UUID normalised in textual form. */
@ -265,7 +265,7 @@ cUUID cUUID::GenerateVersion3(const AString & a_Name)
cUUID UUID; cUUID UUID;
// Generate an md5 checksum, and use it as base for the ID: // Generate an md5 checksum, and use it as base for the ID:
const Byte * ByteString = reinterpret_cast<const Byte *>(a_Name.data()); 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 // Insert version number
UUID.m_UUID[6] = (UUID.m_UUID[6] & 0x0f) | 0x30; UUID.m_UUID[6] = (UUID.m_UUID[6] & 0x0f) | 0x30;

View File

@ -1,4 +1,4 @@

// AesCfb128Decryptor.cpp // AesCfb128Decryptor.cpp
// Implements the cAesCfb128Decryptor class decrypting data using AES CFB-128 // Implements the cAesCfb128Decryptor class decrypting data using AES CFB-128
@ -10,10 +10,10 @@
cAesCfb128Decryptor::cAesCfb128Decryptor(void) : cAesCfb128Decryptor::cAesCfb128Decryptor(void):
m_IVOffset(0),
m_IsValid(false) m_IsValid(false)
{ {
mbedtls_aes_init(&m_Aes);
} }
@ -23,7 +23,7 @@ cAesCfb128Decryptor::cAesCfb128Decryptor(void) :
cAesCfb128Decryptor::~cAesCfb128Decryptor() cAesCfb128Decryptor::~cAesCfb128Decryptor()
{ {
// Clear the leftover in-memory data, so that they can't be accessed by a backdoor // 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 ASSERT(!IsValid()); // Cannot Init twice
memcpy(m_IV, a_IV, 16); 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; 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) void cAesCfb128Decryptor::ProcessData(Byte * a_DecryptedOut, const Byte * a_EncryptedIn, size_t a_Length)
{ {
ASSERT(IsValid()); // Must Init() first ASSERT(IsValid()); // Must Init() first
mbedtls_aes_crypt_cfb8(&m_Aes, MBEDTLS_AES_DECRYPT, a_Length, m_IV, a_EncryptedIn, a_DecryptedOut);
// 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];
}
} }

View File

@ -1,4 +1,4 @@

// AesCfb128Decryptor.h // AesCfb128Decryptor.h
// Declares the cAesCfb128Decryptor class decrypting data using AES CFB-128 // Declares the cAesCfb128Decryptor class decrypting data using AES CFB-128
@ -9,7 +9,7 @@
#pragma once #pragma once
#include "polarssl/aes.h" #include "mbedtls/aes.h"
@ -33,14 +33,11 @@ public:
bool IsValid(void) const { return m_IsValid; } bool IsValid(void) const { return m_IsValid; }
protected: protected:
aes_context m_Aes; mbedtls_aes_context m_Aes;
/** The InitialVector, used by the CFB mode decryption */ /** The InitialVector, used by the CFB mode decryption */
Byte m_IV[16]; 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 */ /** Indicates whether the object has been initialized with the Key / IV */
bool m_IsValid; bool m_IsValid;
} ; } ;

View File

@ -1,4 +1,4 @@

// AesCfb128Encryptor.cpp // AesCfb128Encryptor.cpp
// Implements the cAesCfb128Encryptor class encrypting data using AES CFB-128 // Implements the cAesCfb128Encryptor class encrypting data using AES CFB-128
@ -10,10 +10,10 @@
cAesCfb128Encryptor::cAesCfb128Encryptor(void) : cAesCfb128Encryptor::cAesCfb128Encryptor(void):
m_IVOffset(0),
m_IsValid(false) m_IsValid(false)
{ {
mbedtls_aes_init(&m_Aes);
} }
@ -23,7 +23,7 @@ cAesCfb128Encryptor::cAesCfb128Encryptor(void) :
cAesCfb128Encryptor::~cAesCfb128Encryptor() cAesCfb128Encryptor::~cAesCfb128Encryptor()
{ {
// Clear the leftover in-memory data, so that they can't be accessed by a backdoor // 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]) void cAesCfb128Encryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
{ {
ASSERT(!IsValid()); // Cannot Init twice ASSERT(!IsValid()); // Cannot Init twice
ASSERT(m_IVOffset == 0);
memcpy(m_IV, a_IV, 16); 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; 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) void cAesCfb128Encryptor::ProcessData(Byte * a_EncryptedOut, const Byte * a_PlainIn, size_t a_Length)
{ {
ASSERT(IsValid()); // Must Init() first ASSERT(IsValid()); // Must Init() first
mbedtls_aes_crypt_cfb8(&m_Aes, MBEDTLS_AES_ENCRYPT, a_Length, m_IV, a_PlainIn, a_EncryptedOut);
// 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];
}
} }

View File

@ -1,4 +1,4 @@

// AesCfb128Encryptor.h // AesCfb128Encryptor.h
// Declares the cAesCfb128Encryptor class encrypting data using AES CFB-128 // Declares the cAesCfb128Encryptor class encrypting data using AES CFB-128
@ -9,7 +9,7 @@
#pragma once #pragma once
#include "polarssl/aes.h" #include "mbedtls/aes.h"
@ -32,14 +32,11 @@ public:
bool IsValid(void) const { return m_IsValid; } bool IsValid(void) const { return m_IsValid; }
protected: protected:
aes_context m_Aes; mbedtls_aes_context m_Aes;
/** The InitialVector, used by the CFB mode encryption */ /** The InitialVector, used by the CFB mode encryption */
Byte m_IV[16]; 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 */ /** Indicates whether the object has been initialized with the Key / IV */
bool m_IsValid; bool m_IsValid;
} ; } ;

View File

@ -1,4 +1,4 @@

// BlockingSslClientSocket.cpp // BlockingSslClientSocket.cpp
// Implements the cBlockingSslClientSocket class representing a blocking TCP socket with client SSL encryption over it // 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: // 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) if (ret != 0)
{ {
Printf(m_LastErrorText, "SSL initialization failed: -0x%x", -ret); 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 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(); 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: // Warn if used multiple times, but don't signal an error:
if (m_CACerts.get() != nullptr) if (!m_ExpectedPeerName.empty())
{ {
LOGWARNING( 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() a_ExpectedPeerName.c_str()
); );
} }
// Parse the cert: m_ExpectedPeerName = std::move(a_ExpectedPeerName);
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;
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); int res = m_Ssl.WritePlain(Data, a_NumBytes);
if (res < 0) if (res < 0)
{ {
ASSERT(res != POLARSSL_ERR_NET_WANT_READ); // 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 != POLARSSL_ERR_NET_WANT_WRITE); // 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); Printf(m_LastErrorText, "Data cannot be written to SSL context: -0x%x", -res);
return false; 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 we got disconnected, report an error after processing all data:
if (!m_IsConnected && m_IncomingData.empty()) 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: // 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. cTCPLinkPtr Socket(m_Socket); // Make a copy so that multiple threads don't race on deleting the socket.
if (Socket == nullptr) if (Socket == nullptr)
{ {
return POLARSSL_ERR_NET_SEND_FAILED; return MBEDTLS_ERR_NET_SEND_FAILED;
} }
if (!Socket->Send(a_Buffer, a_NumBytes)) if (!Socket->Send(a_Buffer, a_NumBytes))
{ {
// PolarSSL's net routines distinguish between connection reset and general failure, we don't need to // mbedTLS's net routines distinguish between connection reset and general failure, we don't need to
return POLARSSL_ERR_NET_SEND_FAILED; return MBEDTLS_ERR_NET_SEND_FAILED;
} }
return static_cast<int>(a_NumBytes); return static_cast<int>(a_NumBytes);
} }

View File

@ -1,4 +1,4 @@

// BlockingSslClientSocket.h // BlockingSslClientSocket.h
// Declares the cBlockingSslClientSocket class representing a blocking TCP socket with client SSL encryption over it // 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. */ Note that this also frees the internal SSL context, so all the certificates etc. are lost. */
void Disconnect(void); void Disconnect(void);
/** Sets the root certificates that are to be trusted. Forces the connection to use strict cert /** Sets the Expected peer name.
verification. Needs to be used before calling Connect(). 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 \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). the presented name is different (possible MITM). */
Returns true on success, false on failure. Sets internal error text on failure. */ void SetExpectedPeerName(AString a_ExpectedPeerName);
bool SetTrustedRootCertsFromString(const AString & a_CACerts, const 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. */ /** Returns the text of the last error that has occurred in this instance. */
const AString & GetLastErrorText(void) const { return m_LastErrorText; } 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). */ /** The object used to signal state changes in the socket (the cause of the blocking). */
cEvent m_Event; cEvent m_Event;
/** The trusted CA root cert store, if we are to verify the cert strictly. Set by SetTrustedRootCertsFromString(). */ /** The configuration to be used by the SSL context. Set by SetSslConfig(). */
cX509CertPtr m_CACerts; 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; AString m_ExpectedPeerName;
/** The hostname to which the socket is connecting (stored for error reporting). */ /** The hostname to which the socket is connecting (stored for error reporting). */

View File

@ -1,4 +1,4 @@

// BufferedSslContext.cpp // BufferedSslContext.cpp
// Implements the cBufferedSslContext class representing a SSL context with the SSL peer data backed by a cByteBuffer // 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) 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(): // 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()); size_t NumBytes = std::min(a_NumBytes, m_IncomingData.GetReadableSpace());
if (NumBytes == 0) if (NumBytes == 0)
{ {
return POLARSSL_ERR_NET_WANT_READ; return MBEDTLS_ERR_SSL_WANT_READ;
} }
if (!m_IncomingData.ReadBuf(a_Buffer, NumBytes)) if (!m_IncomingData.ReadBuf(a_Buffer, NumBytes))
{ {
m_IncomingData.ResetRead(); m_IncomingData.ResetRead();
return POLARSSL_ERR_NET_RECV_FAILED; return MBEDTLS_ERR_NET_RECV_FAILED;
} }
m_IncomingData.CommitRead(); m_IncomingData.CommitRead();
return static_cast<int>(NumBytes); 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) 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(): // Write the data into the buffer inside this object, where the owner can later read them using ReadOutgoing():
if (!m_OutgoingData.CanWriteBytes(a_NumBytes)) 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)) 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); return static_cast<int>(a_NumBytes);
} }

View File

@ -1,4 +1,4 @@

// BufferedSslContext.h // BufferedSslContext.h
// Declares the cBufferedSslContext class representing a SSL context with the SSL peer data backed by a cByteBuffer // Declares the cBufferedSslContext class representing a SSL context with the SSL peer data backed by a cByteBuffer
@ -10,6 +10,7 @@
#pragma once #pragma once
#include "SslContext.h" #include "SslContext.h"
#include "ErrorCodes.h"

View File

@ -13,6 +13,7 @@ set(SRCS
EntropyContext.cpp EntropyContext.cpp
RsaPrivateKey.cpp RsaPrivateKey.cpp
Sha1Checksum.cpp Sha1Checksum.cpp
SslConfig.cpp
SslContext.cpp SslContext.cpp
X509Cert.cpp X509Cert.cpp
) )
@ -26,16 +27,18 @@ set(HDRS
CtrDrbgContext.h CtrDrbgContext.h
CryptoKey.h CryptoKey.h
EntropyContext.h EntropyContext.h
ErrorCodes.h
RsaPrivateKey.h RsaPrivateKey.h
SslConfig.h
SslContext.h SslContext.h
Sha1Checksum.h Sha1Checksum.h
X509Cert.h X509Cert.h
) )
if(NOT MSVC) if(NOT MSVC)
add_library(PolarSSL++ ${SRCS} ${HDRS}) add_library(mbedTLS++ ${SRCS} ${HDRS})
if (UNIX) if (UNIX)
target_link_libraries(PolarSSL++ mbedtls) target_link_libraries(mbedTLS++ mbedtls)
endif() endif()
endif() endif()

View File

@ -1,4 +1,4 @@

// CallbackSslContext.cpp // CallbackSslContext.cpp
// Declares the cCallbackSslContext class representing a SSL context wrapper that uses callbacks to read and write SSL peer data // 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) if (m_Callbacks == nullptr)
{ {
LOGWARNING("SSL: Trying to receive data with no callbacks, aborting."); 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); 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) if (m_Callbacks == nullptr)
{ {
LOGWARNING("SSL: Trying to send data with no callbacks, aborting."); 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); return m_Callbacks->SendEncrypted(a_Buffer, a_NumBytes);
} }

View File

@ -1,4 +1,4 @@

// CallbackSslContext.h // CallbackSslContext.h
// Declares the cCallbackSslContext class representing a SSL context wrapper that uses callbacks to read and write SSL peer data // 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 #pragma once
#include "SslContext.h" #include "SslContext.h"
#include "ErrorCodes.h"
@ -26,17 +27,17 @@ public:
// Force a virtual destructor in descendants: // Force a virtual destructor in descendants:
virtual ~cDataCallbacks() {} virtual ~cDataCallbacks() {}
/** Called when PolarSSL wants to read encrypted data from the SSL peer. /** Called when mbedTLS 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 returned value is the number of bytes received, or a mbedTLS error on failure.
The implementation can return POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE to indicate 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 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 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. */ notified of this condition and can potentially restart the operation later on. */
virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0; virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0;
/** Called when PolarSSL wants to write encrypted data to the SSL peer. /** Called when mbedTLS 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 returned value is the number of bytes sent, or a mbedTLS error on failure.
The implementation can return POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE to indicate 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 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 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. */ notified of this condition and can potentially restart the operation later on. */

View File

@ -1,7 +1,7 @@

// CryptoKey.cpp // 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 "Globals.h"
#include "CryptoKey.h" #include "CryptoKey.h"
@ -12,7 +12,7 @@
cCryptoKey::cCryptoKey(void) cCryptoKey::cCryptoKey(void)
{ {
pk_init(&m_Pk); mbedtls_pk_init(&m_Pk);
m_CtrDrbg.Initialize("rsa_pubkey", 10); m_CtrDrbg.Initialize("rsa_pubkey", 10);
} }
@ -22,7 +22,7 @@ cCryptoKey::cCryptoKey(void)
cCryptoKey::cCryptoKey(const AString & a_PublicKeyData) cCryptoKey::cCryptoKey(const AString & a_PublicKeyData)
{ {
pk_init(&m_Pk); mbedtls_pk_init(&m_Pk);
m_CtrDrbg.Initialize("rsa_pubkey", 10); m_CtrDrbg.Initialize("rsa_pubkey", 10);
int res = ParsePublic(a_PublicKeyData.data(), a_PublicKeyData.size()); int res = ParsePublic(a_PublicKeyData.data(), a_PublicKeyData.size());
if (res != 0) if (res != 0)
@ -39,7 +39,7 @@ cCryptoKey::cCryptoKey(const AString & a_PublicKeyData)
cCryptoKey::cCryptoKey(const AString & a_PrivateKeyData, const AString & a_Password) 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); m_CtrDrbg.Initialize("rsa_privkey", 11);
int res = ParsePrivate(a_PrivateKeyData.data(), a_PrivateKeyData.size(), a_Password); int res = ParsePrivate(a_PrivateKeyData.data(), a_PrivateKeyData.size(), a_Password);
if (res != 0) if (res != 0)
@ -56,7 +56,7 @@ cCryptoKey::cCryptoKey(const AString & a_PrivateKeyData, const AString & a_Passw
cCryptoKey::~cCryptoKey() 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()); ASSERT(IsValid());
size_t DecryptedLen = a_DecryptedMaxLength; size_t DecryptedLen = a_DecryptedMaxLength;
int res = pk_decrypt(&m_Pk, int res = mbedtls_pk_decrypt(&m_Pk,
a_EncryptedData, a_EncryptedLength, a_EncryptedData, a_EncryptedLength,
a_DecryptedData, &DecryptedLen, a_DecryptedMaxLength, a_DecryptedData, &DecryptedLen, a_DecryptedMaxLength,
ctr_drbg_random, m_CtrDrbg.GetInternal() mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal()
); );
if (res != 0) if (res != 0)
{ {
@ -89,9 +89,9 @@ int cCryptoKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a
ASSERT(IsValid()); ASSERT(IsValid());
size_t EncryptedLength = a_EncryptedMaxLength; 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, 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) 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 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()) 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 else
{ {
return pk_parse_key( return mbedtls_pk_parse_key(
&m_Pk, &m_Pk,
reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes,
reinterpret_cast<const unsigned char *>(a_Password.c_str()), a_Password.size() 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 bool cCryptoKey::IsValid(void) const
{ {
return (pk_get_type(&m_Pk) != POLARSSL_PK_NONE); return (mbedtls_pk_get_type(&m_Pk) != MBEDTLS_PK_NONE);
} }

View File

@ -1,7 +1,7 @@

// CryptoKey.h // 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 #pragma once
#include "CtrDrbgContext.h" #include "CtrDrbgContext.h"
#include "polarssl/pk.h" #include "mbedtls/pk.h"
@ -18,7 +18,7 @@
class cCryptoKey class cCryptoKey
{ {
friend class cSslContext; friend class cSslConfig;
public: public:
/** Constructs an empty key instance. Before use, it needs to be filled by ParsePublic() or ParsePrivate() */ /** 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. /** Parses the specified data into a public key representation.
The key can be DER- or PEM-encoded. 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); int ParsePublic(const void * a_Data, size_t a_NumBytes);
/** Parses the specified data into a private key representation. /** Parses the specified data into a private key representation.
If a_Password is empty, no password is assumed. If a_Password is empty, no password is assumed.
The key can be DER- or PEM-encoded. 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); int ParsePrivate(const void * a_Data, size_t a_NumBytes, const AString & a_Password);
/** Returns true if the contained key is valid. */ /** Returns true if the contained key is valid. */
bool IsValid(void) const; bool IsValid(void) const;
protected: protected:
/** The PolarSSL representation of the key data */ /** The mbedTLS representation of the key data */
pk_context m_Pk; mbedtls_pk_context m_Pk;
/** The random generator used in encryption and decryption */ /** The random generator used in encryption and decryption */
cCtrDrbgContext m_CtrDrbg; cCtrDrbgContext m_CtrDrbg;
/** Returns the internal context ptr. Only use in PolarSSL API calls. */ /** Returns the internal context ptr. Only use in mbedTLS API calls. */
pk_context * GetInternal(void) { return &m_Pk; } mbedtls_pk_context * GetInternal(void) { return &m_Pk; }
} ; } ;
typedef std::shared_ptr<cCryptoKey> cCryptoKeyPtr; typedef std::shared_ptr<cCryptoKey> cCryptoKeyPtr;

View File

@ -1,7 +1,7 @@

// CtrDrbgContext.cpp // 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 "Globals.h"
#include "CtrDrbgContext.h" #include "CtrDrbgContext.h"
@ -12,9 +12,10 @@
cCtrDrbgContext::cCtrDrbgContext(void) : cCtrDrbgContext::cCtrDrbgContext(void) :
m_EntropyContext(new cEntropyContext), m_EntropyContext(std::make_shared<cEntropyContext>()),
m_IsValid(false) 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_EntropyContext(a_EntropyContext),
m_IsValid(false) 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; 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); m_IsValid = (res == 0);
return res; return res;
} }

View File

@ -1,7 +1,7 @@

// CtrDrbgContext.h // 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 #pragma once
#include "polarssl/ctr_drbg.h" #include "mbedtls/ctr_drbg.h"
@ -24,7 +24,7 @@ class cEntropyContext;
class cCtrDrbgContext class cCtrDrbgContext
{ {
friend class cSslContext; friend class cSslConfig;
friend class cRsaPrivateKey; friend class cRsaPrivateKey;
friend class cCryptoKey; friend class cCryptoKey;
@ -37,7 +37,7 @@ public:
/** Initializes the context. /** Initializes the context.
a_Custom is optional additional data to use for entropy, nullptr is accepted. 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); int Initialize(const void * a_Custom, size_t a_CustomSize);
/** Returns true if the object is valid (has been initialized properly) */ /** Returns true if the object is valid (has been initialized properly) */
@ -48,14 +48,14 @@ protected:
std::shared_ptr<cEntropyContext> m_EntropyContext; std::shared_ptr<cEntropyContext> m_EntropyContext;
/** The random generator context */ /** 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) */ /** Set to true if the object is valid (has been initialized properly) */
bool m_IsValid; bool m_IsValid;
/** Returns the internal context ptr. Only use in PolarSSL API calls. */ /** Returns the internal context ptr. Only use in mbedTLS API calls. */
ctr_drbg_context * GetInternal(void) { return &m_CtrDrbg; } mbedtls_ctr_drbg_context * GetInternal(void) { return &m_CtrDrbg; }
} ; } ;

View File

@ -1,7 +1,7 @@

// EntropyContext.cpp // 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 "Globals.h"
#include "EntropyContext.h" #include "EntropyContext.h"
@ -12,7 +12,7 @@
cEntropyContext::cEntropyContext(void) cEntropyContext::cEntropyContext(void)
{ {
entropy_init(&m_Entropy); mbedtls_entropy_init(&m_Entropy);
} }
@ -21,7 +21,7 @@ cEntropyContext::cEntropyContext(void)
cEntropyContext::~cEntropyContext() cEntropyContext::~cEntropyContext()
{ {
entropy_free(&m_Entropy); mbedtls_entropy_free(&m_Entropy);
} }

View File

@ -1,7 +1,7 @@

// EntropyContext.h // 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 #pragma once
#include "polarssl/entropy.h" #include "mbedtls/entropy.h"
@ -23,7 +23,7 @@ public:
~cEntropyContext(); ~cEntropyContext();
protected: protected:
entropy_context m_Entropy; mbedtls_entropy_context m_Entropy;
} ; } ;

View 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. */

View File

@ -1,9 +1,9 @@

// RsaPrivateKey.cpp // RsaPrivateKey.cpp
#include "Globals.h" #include "Globals.h"
#include "RsaPrivateKey.h" #include "RsaPrivateKey.h"
#include <polarssl/pk.h> #include "mbedtls/pk.h"
@ -11,7 +11,7 @@
cRsaPrivateKey::cRsaPrivateKey(void) 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); m_CtrDrbg.Initialize("RSA", 3);
} }
@ -21,8 +21,8 @@ cRsaPrivateKey::cRsaPrivateKey(void)
cRsaPrivateKey::cRsaPrivateKey(const cRsaPrivateKey & a_Other) cRsaPrivateKey::cRsaPrivateKey(const cRsaPrivateKey & a_Other)
{ {
rsa_init(&m_Rsa, RSA_PKCS_V15, 0); mbedtls_rsa_init(&m_Rsa, MBEDTLS_RSA_PKCS_V15, 0);
rsa_copy(&m_Rsa, &a_Other.m_Rsa); mbedtls_rsa_copy(&m_Rsa, &a_Other.m_Rsa);
m_CtrDrbg.Initialize("RSA", 3); m_CtrDrbg.Initialize("RSA", 3);
} }
@ -32,7 +32,7 @@ cRsaPrivateKey::cRsaPrivateKey(const cRsaPrivateKey & a_Other)
cRsaPrivateKey::~cRsaPrivateKey() cRsaPrivateKey::~cRsaPrivateKey()
{ {
rsa_free(&m_Rsa); mbedtls_rsa_free(&m_Rsa);
} }
@ -41,7 +41,7 @@ cRsaPrivateKey::~cRsaPrivateKey()
bool cRsaPrivateKey::Generate(unsigned a_KeySizeBits) 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) if (res != 0)
{ {
LOG("RSA key generation failed: -0x%x", -res); LOG("RSA key generation failed: -0x%x", -res);
@ -60,16 +60,16 @@ AString cRsaPrivateKey::GetPubKeyDER(void)
class cPubKey class cPubKey
{ {
public: public:
cPubKey(rsa_context * a_Rsa) : cPubKey(mbedtls_rsa_context * a_Rsa) :
m_IsValid(false) m_IsValid(false)
{ {
pk_init(&m_Key); mbedtls_pk_init(&m_Key);
if (pk_init_ctx(&m_Key, pk_info_from_type(POLARSSL_PK_RSA)) != 0) if (mbedtls_pk_setup(&m_Key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) != 0)
{ {
ASSERT(!"Cannot init PrivKey context"); ASSERT(!"Cannot init PrivKey context");
return; 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"); ASSERT(!"Cannot copy PrivKey to PK context");
return; return;
@ -81,19 +81,19 @@ AString cRsaPrivateKey::GetPubKeyDER(void)
{ {
if (m_IsValid) 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: protected:
bool m_IsValid; bool m_IsValid;
pk_context m_Key; mbedtls_pk_context m_Key;
} PkCtx(&m_Rsa); } PkCtx(&m_Rsa);
unsigned char buf[3000]; 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) if (res < 0)
{ {
return AString(); return AString();
@ -124,8 +124,8 @@ int cRsaPrivateKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLeng
return -1; return -1;
} }
size_t DecryptedLength; size_t DecryptedLength;
int res = rsa_pkcs1_decrypt( int res = mbedtls_rsa_pkcs1_decrypt(
&m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), RSA_PRIVATE, &DecryptedLength, &m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), MBEDTLS_RSA_PRIVATE, &DecryptedLength,
a_EncryptedData, a_DecryptedData, a_DecryptedMaxLength a_EncryptedData, a_DecryptedData, a_DecryptedMaxLength
); );
if (res != 0) if (res != 0)
@ -157,8 +157,8 @@ int cRsaPrivateKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte
ASSERT(!"Invalid a_PlainLength!"); ASSERT(!"Invalid a_PlainLength!");
return -1; return -1;
} }
int res = rsa_pkcs1_encrypt( int res = mbedtls_rsa_pkcs1_encrypt(
&m_Rsa, ctr_drbg_random, m_CtrDrbg.GetInternal(), RSA_PRIVATE, &m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), MBEDTLS_RSA_PRIVATE,
a_PlainLength, a_PlainData, a_EncryptedData a_PlainLength, a_PlainData, a_EncryptedData
); );
if (res != 0) if (res != 0)

View File

@ -1,4 +1,4 @@

// RsaPrivateKey.h // RsaPrivateKey.h
// Declares the cRsaPrivateKey class representing a private key for RSA operations. // Declares the cRsaPrivateKey class representing a private key for RSA operations.
@ -10,7 +10,7 @@
#pragma once #pragma once
#include "CtrDrbgContext.h" #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); int Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength);
protected: protected:
/** The PolarSSL key context */ /** The mbedTLS key context */
rsa_context m_Rsa; mbedtls_rsa_context m_Rsa;
/** The random generator used for generating the key and encryption / decryption */ /** The random generator used for generating the key and encryption / decryption */
cCtrDrbgContext m_CtrDrbg; cCtrDrbgContext m_CtrDrbg;
/** Returns the internal context ptr. Only use in PolarSSL API calls. */ /** Returns the internal context ptr. Only use in mbedTLS API calls. */
rsa_context * GetInternal(void) { return &m_Rsa; } mbedtls_rsa_context * GetInternal(void) { return &m_Rsa; }
} ; } ;
typedef std::shared_ptr<cRsaPrivateKey> cRsaPrivateKeyPtr; typedef std::shared_ptr<cRsaPrivateKey> cRsaPrivateKeyPtr;

View File

@ -1,4 +1,4 @@

// Sha1Checksum.cpp // Sha1Checksum.cpp
// Declares the cSha1Checksum class representing the SHA-1 checksum calculator // Declares the cSha1Checksum class representing the SHA-1 checksum calculator
@ -56,7 +56,7 @@ public:
cSha1Checksum::cSha1Checksum(void) : cSha1Checksum::cSha1Checksum(void) :
m_DoesAcceptInput(true) 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 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 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; m_DoesAcceptInput = false;
} }
@ -129,7 +129,7 @@ void cSha1Checksum::DigestToJava(const Checksum & a_Digest, AString & a_Out)
void cSha1Checksum::Restart(void) void cSha1Checksum::Restart(void)
{ {
sha1_starts(&m_Sha1); mbedtls_sha1_starts(&m_Sha1);
m_DoesAcceptInput = true; m_DoesAcceptInput = true;
} }

View File

@ -1,4 +1,4 @@

// Sha1Checksum.h // Sha1Checksum.h
// Declares the cSha1Checksum class representing the SHA-1 checksum calculator // Declares the cSha1Checksum class representing the SHA-1 checksum calculator
@ -9,7 +9,7 @@
#pragma once #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()) */ /** True if the object is accepts more input data, false if Finalize()-d (need to Restart()) */
bool m_DoesAcceptInput; bool m_DoesAcceptInput;
sha1_context m_Sha1; mbedtls_sha1_context m_Sha1;
} ; } ;

287
src/mbedTLS++/SslConfig.cpp Normal file
View 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
View 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;
};

View 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);
}

View File

@ -1,4 +1,4 @@

// SslContext.h // SslContext.h
// Declares the cSslContext class that holds everything a single SSL context needs to function // Declares the cSslContext class that holds everything a single SSL context needs to function
@ -9,11 +9,8 @@
#pragma once #pragma once
#include "polarssl/ssl.h" #include "mbedtls/ssl.h"
#include "../ByteBuffer.h" #include "../ByteBuffer.h"
#include "CryptoKey.h"
#include "RsaPrivateKey.h"
#include "X509Cert.h"
@ -21,6 +18,7 @@
// fwd: // fwd:
class cCtrDrbgContext; class cCtrDrbgContext;
class cSslConfig;
@ -43,45 +41,40 @@ public:
virtual ~cSslContext(); virtual ~cSslContext();
/** Initializes the context for use as a server or client. /** Initializes the context for use as a server or client.
Returns 0 on success, PolarSSL error on failure. */ a_Config must not be nullptr and the config must not be changed after this call.
int Initialize(bool a_IsClient, const std::shared_ptr<cCtrDrbgContext> & a_CtrDrbg = {}); 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. */ /** Returns true if the object has been initialized properly. */
bool IsValid(void) const { return m_IsValid; } 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. /** Sets the SSL peer name expected for this context. Must be called after Initialize().
Must be called after Initialize(). */ \param a_ExpectedPeerName CommonName that we expect the SSL peer to have in its cert,
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,
if it is different, the verification will fail. An empty string will disable the CN check. */ 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. /** 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. Returns the number of bytes actually written, or mbedTLS error code.
If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any 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 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 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. */ actually written, mainly due to initial handshake. */
int WritePlain(const void * a_Data, size_t a_NumBytes); int WritePlain(const void * a_Data, size_t a_NumBytes);
/** Reads data decrypted from the SSL stream. Will perform SSL handshake, if needed. /** Reads data decrypted from the SSL stream. Will perform SSL handshake, if needed.
Returns the number of bytes actually read, or PolarSSL error code. Returns the number of bytes actually read, or mbedTLS error code.
If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any 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 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 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. */ actually read, mainly due to initial handshake. */
int ReadPlain(void * a_Data, size_t a_MaxBytes); int ReadPlain(void * a_Data, size_t a_MaxBytes);
/** Performs the SSL handshake. /** Performs the SSL handshake.
Returns zero on success, PoladSSL error code on failure. Returns zero on success, mbedTLS 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 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 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. */ this function again. Note that this may repeat a few times before the handshake is completed. */
int Handshake(void); int Handshake(void);
@ -90,64 +83,39 @@ public:
bool HasHandshaken(void) const { return m_HasHandshaken; } bool HasHandshaken(void) const { return m_HasHandshaken; }
/** Notifies the SSL peer that the connection is being closed. /** 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); int NotifyClose(void);
protected: 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. */ /** True if the object has been initialized properly. */
bool m_IsValid; 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. */ /** True if the SSL handshake has been completed. */
bool m_HasHandshaken; bool m_HasHandshaken;
/** A copy of the trusted CA root cert store that is passed to us in SetCACerts(), so that the pointer /** The callback used by mbedTLS when it wants to read encrypted data. */
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. */
static int ReceiveEncrypted(void * a_This, unsigned char * a_Buffer, size_t a_NumBytes) 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); 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) 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); return (reinterpret_cast<cSslContext *>(a_This))->SendEncrypted(a_Buffer, a_NumBytes);
} }
#ifdef _DEBUG /** Called when mbedTLS wants to read encrypted data. */
/** 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. */
virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0; 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; virtual int SendEncrypted(const unsigned char * a_Buffer, size_t a_NumBytes) = 0;
} ; } ;

View File

@ -1,7 +1,7 @@

// X509Cert.cpp // 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 "Globals.h"
#include "X509Cert.h" #include "X509Cert.h"
@ -12,7 +12,7 @@
cX509Cert::cX509Cert(void) cX509Cert::cX509Cert(void)
{ {
x509_crt_init(&m_Cert); mbedtls_x509_crt_init(&m_Cert);
} }
@ -21,7 +21,7 @@ cX509Cert::cX509Cert(void)
cX509Cert::~cX509Cert() 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) 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);
} }

View File

@ -1,7 +1,7 @@

// X509Cert.h // 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 #pragma once
#include "polarssl/x509_crt.h" #include "mbedtls/x509_crt.h"
@ -17,21 +17,21 @@
class cX509Cert class cX509Cert
{ {
friend class cSslContext; friend class cSslConfig;
public: public:
cX509Cert(void); cX509Cert(void);
~cX509Cert(void); ~cX509Cert(void);
/** Parses the certificate chain data into the context. /** 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); int Parse(const void * a_CertContents, size_t a_Size);
protected: protected:
x509_crt m_Cert; mbedtls_x509_crt m_Cert;
/** Returns the internal cert ptr. Only use in PolarSSL API calls. */ /** Returns the internal cert ptr. Only use in mbedTLS API calls. */
x509_crt * GetInternal(void) { return &m_Cert; } mbedtls_x509_crt * GetInternal(void) { return &m_Cert; }
} ; } ;
typedef std::shared_ptr<cX509Cert> cX509CertPtr; typedef std::shared_ptr<cX509Cert> cX509CertPtr;

View File

@ -1,8 +1,8 @@
enable_testing() enable_testing()
include_directories(${CMAKE_SOURCE_DIR}/src/) include_directories(${CMAKE_SOURCE_DIR}/src/)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/libevent/include) 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) add_definitions(-DTEST_GLOBALS=1)

View File

@ -1,8 +1,8 @@
enable_testing() enable_testing()
include_directories(${CMAKE_SOURCE_DIR}/src/) include_directories(${CMAKE_SOURCE_DIR}/src/)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/lib/libevent/include) 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) add_definitions(-DTEST_GLOBALS=1)
@ -18,11 +18,12 @@ set (Network_SRCS
${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkSingleton.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/NetworkSingleton.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/ServerHandleImpl.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/ServerHandleImpl.cpp
${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.cpp ${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.cpp
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CtrDrbgContext.cpp ${CMAKE_SOURCE_DIR}/src/mbedTLS++/CtrDrbgContext.cpp
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CryptoKey.cpp ${CMAKE_SOURCE_DIR}/src/mbedTLS++/CryptoKey.cpp
${CMAKE_SOURCE_DIR}/src/PolarSSL++/EntropyContext.cpp ${CMAKE_SOURCE_DIR}/src/mbedTLS++/EntropyContext.cpp
${CMAKE_SOURCE_DIR}/src/PolarSSL++/SslContext.cpp ${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslConfig.cpp
${CMAKE_SOURCE_DIR}/src/PolarSSL++/X509Cert.cpp ${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslContext.cpp
${CMAKE_SOURCE_DIR}/src/mbedTLS++/X509Cert.cpp
${CMAKE_SOURCE_DIR}/src/StringUtils.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/ServerHandleImpl.h
${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.h ${CMAKE_SOURCE_DIR}/src/OSSupport/TCPLinkImpl.h
${CMAKE_SOURCE_DIR}/src/OSSupport/Queue.h ${CMAKE_SOURCE_DIR}/src/OSSupport/Queue.h
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CtrDrbgContext.h ${CMAKE_SOURCE_DIR}/src/mbedTLS++/CtrDrbgContext.h
${CMAKE_SOURCE_DIR}/src/PolarSSL++/CryptoKey.h ${CMAKE_SOURCE_DIR}/src/mbedTLS++/CryptoKey.h
${CMAKE_SOURCE_DIR}/src/PolarSSL++/EntropyContext.h ${CMAKE_SOURCE_DIR}/src/mbedTLS++/EntropyContext.h
${CMAKE_SOURCE_DIR}/src/PolarSSL++/SslContext.h ${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslConfig.h
${CMAKE_SOURCE_DIR}/src/PolarSSL++/X509Cert.h ${CMAKE_SOURCE_DIR}/src/mbedTLS++/SslContext.h
${CMAKE_SOURCE_DIR}/src/mbedTLS++/X509Cert.h
${CMAKE_SOURCE_DIR}/src/StringUtils.h ${CMAKE_SOURCE_DIR}/src/StringUtils.h
) )