Merge pull request #251 from Palakis/auth-without-mbedtls

auth: get rid of mbedtls
This commit is contained in:
Stéphane Lepin 2018-11-08 19:01:13 +01:00 committed by GitHub
commit 94dcd58c2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 69 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "deps/mbedtls"]
path = deps/mbedtls
url = https://github.com/ARMmbed/mbedtls

View File

@ -15,9 +15,6 @@ find_package(Qt5Core REQUIRED)
find_package(Qt5WebSockets REQUIRED) find_package(Qt5WebSockets REQUIRED)
find_package(Qt5Widgets REQUIRED) find_package(Qt5Widgets REQUIRED)
add_subdirectory(deps/mbedtls EXCLUDE_FROM_ALL)
set(ENABLE_PROGRAMS false)
set(obs-websocket_SOURCES set(obs-websocket_SOURCES
src/obs-websocket.cpp src/obs-websocket.cpp
src/WSServer.cpp src/WSServer.cpp
@ -52,22 +49,17 @@ add_library(obs-websocket MODULE
${obs-websocket_SOURCES} ${obs-websocket_SOURCES}
${obs-websocket_HEADERS}) ${obs-websocket_HEADERS})
add_dependencies(obs-websocket mbedcrypto)
include_directories( include_directories(
"${LIBOBS_INCLUDE_DIR}/../UI/obs-frontend-api" "${LIBOBS_INCLUDE_DIR}/../UI/obs-frontend-api"
${Qt5Core_INCLUDES} ${Qt5Core_INCLUDES}
${Qt5WebSockets_INCLUDES} ${Qt5WebSockets_INCLUDES}
${Qt5Widgets_INCLUDES} ${Qt5Widgets_INCLUDES})
${mbedcrypto_INCLUDES}
"${CMAKE_SOURCE_DIR}/deps/mbedtls/include")
target_link_libraries(obs-websocket target_link_libraries(obs-websocket
libobs libobs
Qt5::Core Qt5::Core
Qt5::WebSockets Qt5::WebSockets
Qt5::Widgets Qt5::Widgets)
mbedcrypto)
# --- End of section --- # --- End of section ---
@ -165,7 +157,6 @@ endif()
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
target_compile_options(mbedcrypto PRIVATE -fPIC)
set_target_properties(obs-websocket PROPERTIES PREFIX "") set_target_properties(obs-websocket PROPERTIES PREFIX "")
target_link_libraries(obs-websocket target_link_libraries(obs-websocket
obs-frontend-api) obs-frontend-api)

1
deps/mbedtls vendored

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

View File

@ -16,11 +16,11 @@ You should have received a copy of the GNU General Public License along
with this program. If not, see <https://www.gnu.org/licenses/> with this program. If not, see <https://www.gnu.org/licenses/>
*/ */
#include <mbedtls/base64.h>
#include <mbedtls/sha256.h>
#include <obs-frontend-api.h> #include <obs-frontend-api.h>
#include <util/config-file.h> #include <util/config-file.h>
#include <string>
#include <QCryptographicHash>
#include <QTime>
#define SECTION_NAME "WebsocketAPI" #define SECTION_NAME "WebsocketAPI"
#define PARAM_ENABLE "ServerEnabled" #define PARAM_ENABLE "ServerEnabled"
@ -48,6 +48,8 @@ Config::Config() :
Salt(""), Salt(""),
SettingsLoaded(false) SettingsLoaded(false)
{ {
qsrand(QTime::currentTime().msec());
// OBS Config defaults // OBS Config defaults
config_t* obsConfig = obs_frontend_get_global_config(); config_t* obsConfig = obs_frontend_get_global_config();
if (obsConfig) { if (obsConfig) {
@ -69,19 +71,15 @@ Config::Config() :
SECTION_NAME, PARAM_SALT, QT_TO_UTF8(Salt)); SECTION_NAME, PARAM_SALT, QT_TO_UTF8(Salt));
} }
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&rng);
mbedtls_ctr_drbg_seed(&rng, mbedtls_entropy_func, &entropy, nullptr, 0);
SessionChallenge = GenerateSalt(); SessionChallenge = GenerateSalt();
} }
Config::~Config() { Config::~Config()
mbedtls_ctr_drbg_free(&rng); {
mbedtls_entropy_free(&entropy);
} }
void Config::Load() { void Config::Load()
{
config_t* obsConfig = obs_frontend_get_global_config(); config_t* obsConfig = obs_frontend_get_global_config();
ServerEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_ENABLE); ServerEnabled = config_get_bool(obsConfig, SECTION_NAME, PARAM_ENABLE);
@ -95,7 +93,8 @@ void Config::Load() {
Salt = config_get_string(obsConfig, SECTION_NAME, PARAM_SALT); Salt = config_get_string(obsConfig, SECTION_NAME, PARAM_SALT);
} }
void Config::Save() { void Config::Save()
{
config_t* obsConfig = obs_frontend_get_global_config(); config_t* obsConfig = obs_frontend_get_global_config();
config_set_bool(obsConfig, SECTION_NAME, PARAM_ENABLE, ServerEnabled); config_set_bool(obsConfig, SECTION_NAME, PARAM_ENABLE, ServerEnabled);
@ -113,46 +112,42 @@ void Config::Save() {
config_save(obsConfig); config_save(obsConfig);
} }
QString Config::GenerateSalt() { QString Config::GenerateSalt()
{
// Generate 32 random chars // Generate 32 random chars
unsigned char* randomChars = (unsigned char*)bzalloc(32); const size_t randomCount = 32;
mbedtls_ctr_drbg_random(&rng, randomChars, 32); QByteArray randomChars;
for (size_t i = 0; i < randomCount; i++) {
randomChars.append((char)qrand());
}
// Convert the 32 random chars to a base64 string // Convert the 32 random chars to a base64 string
char* salt = (char*)bzalloc(64); QString salt = randomChars.toBase64();
size_t saltBytes;
mbedtls_base64_encode(
(unsigned char*)salt, 64, &saltBytes,
randomChars, 32);
bfree(randomChars);
return salt; return salt;
} }
QString Config::GenerateSecret(QString password, QString salt) { QString Config::GenerateSecret(QString password, QString salt)
{
// Concatenate the password and the salt // Concatenate the password and the salt
QString passAndSalt = ""; QString passAndSalt = "";
passAndSalt += password; passAndSalt += password;
passAndSalt += salt; passAndSalt += salt;
// Generate a SHA256 hash of the password // Generate a SHA256 hash of the password and salt
unsigned char* challengeHash = (unsigned char*)bzalloc(32); auto challengeHash = QCryptographicHash::hash(
mbedtls_sha256( passAndSalt.toUtf8(),
(unsigned char*)passAndSalt.toUtf8().constData(), passAndSalt.length(), QCryptographicHash::Algorithm::Sha256
challengeHash, 0); );
// Encode SHA256 hash to Base64 // Encode SHA256 hash to Base64
char* challenge = (char*)bzalloc(64); QString challenge = challengeHash.toBase64();
size_t challengeBytes = 0;
mbedtls_base64_encode(
(unsigned char*)challenge, 64, &challengeBytes,
challengeHash, 32);
bfree(challengeHash);
return challenge; return challenge;
} }
void Config::SetPassword(QString password) { void Config::SetPassword(QString password)
{
QString newSalt = GenerateSalt(); QString newSalt = GenerateSalt();
QString newChallenge = GenerateSecret(password, newSalt); QString newChallenge = GenerateSecret(password, newSalt);
@ -160,37 +155,32 @@ void Config::SetPassword(QString password) {
this->Secret = newChallenge; this->Secret = newChallenge;
} }
bool Config::CheckAuth(QString response) { bool Config::CheckAuth(QString response)
{
// Concatenate auth secret with the challenge sent to the user // Concatenate auth secret with the challenge sent to the user
QString challengeAndResponse = ""; QString challengeAndResponse = "";
challengeAndResponse += Secret; challengeAndResponse += Secret;
challengeAndResponse += SessionChallenge; challengeAndResponse += SessionChallenge;
// Generate a SHA256 hash of challengeAndResponse // Generate a SHA256 hash of challengeAndResponse
unsigned char* hash = (unsigned char*)bzalloc(32); auto hash = QCryptographicHash::hash(
mbedtls_sha256( challengeAndResponse.toUtf8(),
(unsigned char*)challengeAndResponse.toUtf8().constData(), QCryptographicHash::Algorithm::Sha256
challengeAndResponse.length(), );
hash, 0);
// Encode the SHA256 hash to Base64 // Encode the SHA256 hash to Base64
char* expectedResponse = (char*)bzalloc(64); QString expectedResponse = hash.toBase64();
size_t base64_size = 0;
mbedtls_base64_encode(
(unsigned char*)expectedResponse, 64, &base64_size,
hash, 32);
bool authSuccess = false; bool authSuccess = false;
if (response == QString(expectedResponse)) { if (response == expectedResponse) {
SessionChallenge = GenerateSalt(); SessionChallenge = GenerateSalt();
authSuccess = true; authSuccess = true;
} }
bfree(hash);
bfree(expectedResponse);
return authSuccess; return authSuccess;
} }
Config* Config::Current() { Config* Config::Current()
{
return _instance; return _instance;
} }

View File

@ -21,9 +21,6 @@ with this program. If not, see <https://www.gnu.org/licenses/>
#include <QString> #include <QString>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
class Config { class Config {
public: public:
Config(); Config();
@ -53,8 +50,6 @@ class Config {
private: private:
static Config* _instance; static Config* _instance;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context rng;
}; };
#endif // CONFIG_H #endif // CONFIG_H