From dc38b27485d00fb1483a657ce0010c69673db264 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 31 Mar 2014 12:31:34 -0700 Subject: [PATCH] using GnuTLS read self-signed key and cert on DS load --- cmake/modules/FindGnuTLS.cmake | 28 +++++++++++ cmake/modules/FindQxmpp.cmake | 12 +---- domain-server/CMakeLists.txt | 6 +-- domain-server/src/DomainServer.cpp | 77 ++++++++++++------------------ domain-server/src/DomainServer.h | 4 ++ domain-server/src/main.cpp | 2 + interface/CMakeLists.txt | 4 +- 7 files changed, 69 insertions(+), 64 deletions(-) create mode 100644 cmake/modules/FindGnuTLS.cmake diff --git a/cmake/modules/FindGnuTLS.cmake b/cmake/modules/FindGnuTLS.cmake new file mode 100644 index 0000000000..d09ba38fb7 --- /dev/null +++ b/cmake/modules/FindGnuTLS.cmake @@ -0,0 +1,28 @@ +# Try to find the GnuTLS library +# +# You can provide a GNUTLS_ROOT_DIR which contains lib and include directories +# +# Once done this will define +# +# GNUTLS_FOUND - system found GnuTLS +# GNUTLS_INCLUDE_DIRS - the GnuTLS include directory +# GNUTLS_LIBRARY - Link this to use GnuTLS +# +# Created on 3/31/2014 by Stephen Birarda +# Copyright (c) 2014 High Fidelity +# + +if (GNUTLS_LIBRARY AND GNUTLS_INCLUDE_DIRS) + # in cache already + set(GNUTLS_FOUND TRUE) +else () + + set(GNUTLS_SEARCH_DIRS "${GNUTLS_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/gnutls") + + find_path(GNUTLS_INCLUDE_DIR gnutls.h PATH_SUFFIXES include gnutls HINTS ${GNUTLS_SEARCH_DIRS}) + + find_library(GNUTLS_LIBRARY NAMES gnutls PATH_SUFFIXES lib HINTS ${GNUTLS_SEARCH_DIRS}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(GNUTLS DEFAULT_MSG GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) +endif () \ No newline at end of file diff --git a/cmake/modules/FindQxmpp.cmake b/cmake/modules/FindQxmpp.cmake index 415b184a65..2e883e02f2 100644 --- a/cmake/modules/FindQxmpp.cmake +++ b/cmake/modules/FindQxmpp.cmake @@ -6,7 +6,7 @@ # # QXMPP_FOUND - system found qxmpp # QXMPP_INCLUDE_DIRS - the qxmpp include directory -# QXMPP_LIBRARIES - Link this to use qxmpp +# QXMPP_LIBRARY - Link this to use qxmpp # # Created on 3/10/2014 by Stephen Birarda # Copyright (c) 2014 High Fidelity @@ -25,14 +25,4 @@ else () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(QXMPP DEFAULT_MSG QXMPP_INCLUDE_DIR QXMPP_LIBRARY) - - if (QXMPP_FOUND) - if (NOT QXMPP_FIND_QUIETLY) - message(STATUS "Found qxmpp: ${QXMPP_LIBRARY}") - endif () - else () - if (QXMPP_FIND_REQUIRED) - message(FATAL_ERROR "Could not find qxmpp") - endif () - endif () endif () \ No newline at end of file diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index 57c9fa848c..4cbc29c62d 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -17,7 +17,7 @@ include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} "${ROOT_DIR}") find_package(Qt5Network REQUIRED) -find_package(QCA REQUIRED) +find_package(GnuTLS REQUIRED) include(${MACRO_DIR}/SetupHifiProject.cmake) @@ -38,11 +38,11 @@ link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") link_hifi_library(embedded-webserver ${TARGET_NAME} "${ROOT_DIR}") # include the QCA dir -include_directories(QCA_INCLUDE_DIR) +include_directories(GNUTLS_INCLUDE_DIR) IF (WIN32) target_link_libraries(${TARGET_NAME} Winmm Ws2_32) ENDIF(WIN32) # link QtNetwork and QCA -target_link_libraries(${TARGET_NAME} Qt5::Network "${QCA_LIBRARY}") \ No newline at end of file +target_link_libraries(${TARGET_NAME} Qt5::Network "${GNUTLS_LIBRARY}") \ No newline at end of file diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 1f1e3a4207..80a86da8a0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -16,6 +16,8 @@ #include #include +#include + #include #include #include @@ -32,7 +34,8 @@ DomainServer::DomainServer(int argc, char* argv[]) : QCoreApplication(argc, argv), _HTTPManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this), _staticAssignmentHash(), - _assignmentQueue() + _assignmentQueue(), + _x509Credentials() { setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); @@ -49,56 +52,36 @@ DomainServer::DomainServer(int argc, char* argv[]) : } bool DomainServer::readCertificateAndPrivateKey() { - const QString X509_CERTIFICATE_PATH_OPTION = "--cert"; - const QString PRIVATE_KEY_OPTION = "--key"; - const QString PRIVATE_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE"; + const QString X509_CERTIFICATE_OPTION = "--cert"; + const QString X509_PRIVATE_KEY_OPTION = "--key"; + const QString X509_KEY_PASSPHRASE_ENV = "DOMAIN_SERVER_KEY_PASSPHRASE"; + + int certIndex = _argumentList.indexOf(X509_CERTIFICATE_OPTION); + int keyIndex = _argumentList.indexOf(X509_PRIVATE_KEY_OPTION); - int certificateIndex = _argumentList.indexOf(X509_CERTIFICATE_PATH_OPTION); - int keyIndex = _argumentList.indexOf(PRIVATE_KEY_OPTION); - - if (certificateIndex != -1 && keyIndex != -1) { + if (certIndex != -1 && keyIndex != -1) { // the user wants to use DTLS to encrypt communication with nodes - // let's make sure we can load the certificate and private key - -// QCA::ConvertResult conversionResult = QCA::ErrorFile; -// -// QFile certificateFile(_argumentList.value(certificateIndex + 1)); -// qDebug() << "Attempting to read X.509 certificate from" << certificateFile.fileName(); -// -// if (certificateFile.exists()) { -// certificateFile.open(QIODevice::ReadOnly); -// QByteArray filearray = certificateFile.readAll(); -// qDebug() << filearray; -// _certificate = QCA::Certificate::fromPEM(filearray, &conversionResult); -// certificateFile.close(); -// } -// -// if (conversionResult != QCA::ConvertGood) { -// // couldn't read the certificate from file, bail -// qCritical() << "Error" << conversionResult << "reading certificate from file. domain-server will now quit." ; -// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); -// return false; -// } -// -// QByteArray keyPassphrase = QProcessEnvironment::systemEnvironment().value(PRIVATE_KEY_PASSPHRASE_ENV).toLocal8Bit(); -// QCA::SecureArray keySecureArray = QCA::SecureArray(keyPassphrase); -// -// QString keyFileString(_argumentList.value(keyIndex + 1)); -// qDebug() << "Attempting to read private key from" << keyFileString; -// _privateKey = QCA::PrivateKey::fromPEMFile(keyFileString, keySecureArray, &conversionResult); -// -// if (conversionResult != QCA::ConvertGood) { -// // couldn't read the private key from file, bail -// qCritical() << "Error" << conversionResult << "reading private key from file. domain-server will now quit."; -// QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); -// return false; -// } + // let's make sure we can load the ey + gnutls_certificate_allocate_credentials(&_x509Credentials); + + QString keyPassphraseString = QProcessEnvironment::systemEnvironment().value(X509_KEY_PASSPHRASE_ENV); + + int gnutlsReturn = gnutls_certificate_set_x509_key_file2(_x509Credentials, + _argumentList[certIndex + 1].toLocal8Bit().constData(), + _argumentList[keyIndex + 1].toLocal8Bit().constData(), + GNUTLS_X509_FMT_PEM, + keyPassphraseString.toLocal8Bit().constData(), + 0); + + if (gnutlsReturn < 0) { + qDebug() << "Unable to load certificate or key file." << "Error" << gnutlsReturn << "- domain-server will now quit."; + QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); + return false; + } qDebug() << "Successfully read certificate and private key. Using DTLS for node communication."; - } else if (certificateIndex != -1 || keyIndex != -1) { - // one of the certificate or private key was missing, can't use one without the other - // bail - qCritical("Missing certificate or private key. domain-server will now quit."); + } else if (certIndex != -1 || keyIndex != -1) { + qDebug() << "Missing certificate or private key. domain-server will now quit."; QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection); return false; } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index c6a9879555..244621c7b1 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -17,6 +17,8 @@ #include #include +#include + #include #include #include @@ -78,6 +80,8 @@ private: QQueue _assignmentQueue; QStringList _argumentList; + + gnutls_certificate_credentials_t _x509Credentials; }; #endif /* defined(__hifi__DomainServer__) */ diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 096431e0a4..4bfa35fac5 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -24,6 +24,8 @@ int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); #endif + gnutls_global_init(); + qInstallMessageHandler(Logging::verboseMessageHandler); DomainServer domainServer(argc, argv); diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index b260f994a3..f991212a6e 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -67,7 +67,6 @@ foreach(EXTERNAL_SOURCE_SUBDIR ${EXTERNAL_SOURCE_SUBDIRS}) endforeach(EXTERNAL_SOURCE_SUBDIR) find_package(Qt5 COMPONENTS Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets Xml UiTools) -find_package(QCA REQUIRED) # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) @@ -188,7 +187,7 @@ include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes" # include external library headers # use system flag so warnings are supressed -include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}" "${QCA_INCLUDE_DIR}") +include_directories(SYSTEM "${FACESHIFT_INCLUDE_DIRS}") target_link_libraries( ${TARGET_NAME} @@ -196,7 +195,6 @@ target_link_libraries( "${ZLIB_LIBRARIES}" Qt5::Core Qt5::Gui Qt5::Multimedia Qt5::Network Qt5::OpenGL Qt5::Script Qt5::Svg Qt5::WebKit Qt5::WebKitWidgets Qt5::Xml Qt5::UiTools - "${QCA_LIBRARY}" ) if (APPLE)