mirror of
https://github.com/rock88/moonlight-nx
synced 2024-11-27 05:50:18 +00:00
Reimplemet CryptoManager for use mbedtls, other fixes...
This commit is contained in:
parent
246f4abd4d
commit
d12e1090f8
18 changed files with 594 additions and 381 deletions
|
@ -39,7 +39,8 @@ include $(DEVKITPRO)/libnx/switch_rules
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := moonlight
|
TARGET := moonlight
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := libgamestream src/nanogui_resources src src/streaming src/streaming/ffmpeg src/streaming/video src/ui/windows src/ui/buttons src/ui \
|
SOURCES := libgamestream src/nanogui_resources src src/streaming src/streaming/ffmpeg \
|
||||||
|
src/crypto src/streaming/video src/ui/windows src/ui/buttons src/ui \
|
||||||
third_party/moonlight-common-c/enet third_party/moonlight-common-c/reedsolomon third_party/moonlight-common-c/src \
|
third_party/moonlight-common-c/enet third_party/moonlight-common-c/reedsolomon third_party/moonlight-common-c/src \
|
||||||
third_party/nanogui/ext/nanovg/src third_party/nanogui/src
|
third_party/nanogui/ext/nanovg/src third_party/nanogui/src
|
||||||
DATA := data
|
DATA := data
|
||||||
|
@ -52,7 +53,7 @@ INCLUDES := include
|
||||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
||||||
|
|
||||||
M_INCLUDES := \
|
M_INCLUDES := \
|
||||||
-I$(TOPDIR)/src -I$(TOPDIR)/src/streaming \
|
-I$(TOPDIR)/src -I$(TOPDIR)/src/streaming -I$(TOPDIR)/src/crypto -I$(TOPDIR)/src/crypto/keys \
|
||||||
-I$(TOPDIR)/src/streaming/ffmpeg -I$(TOPDIR)/src/streaming/video -I$(TOPDIR)/src/streaming/audio \
|
-I$(TOPDIR)/src/streaming/ffmpeg -I$(TOPDIR)/src/streaming/video -I$(TOPDIR)/src/streaming/audio \
|
||||||
-I$(TOPDIR)/src/nanogui_resources \
|
-I$(TOPDIR)/src/nanogui_resources \
|
||||||
-I$(TOPDIR)/src/ui -I$(TOPDIR)/src/ui/buttons -I$(TOPDIR)/src/ui/windows \
|
-I$(TOPDIR)/src/ui -I$(TOPDIR)/src/ui/buttons -I$(TOPDIR)/src/ui/windows \
|
||||||
|
@ -62,10 +63,11 @@ M_INCLUDES := \
|
||||||
-I$(TOPDIR)/third_party/moonlight-common-c/enet/include \
|
-I$(TOPDIR)/third_party/moonlight-common-c/enet/include \
|
||||||
-I$(TOPDIR)/third_party/nanogui/include \
|
-I$(TOPDIR)/third_party/nanogui/include \
|
||||||
-I$(TOPDIR)/third_party/nanogui/ext/nanovg/src \
|
-I$(TOPDIR)/third_party/nanogui/ext/nanovg/src \
|
||||||
-I$(TOPDIR)/third_party/json/single_include/nlohmann
|
-I$(TOPDIR)/third_party/json/single_include/nlohmann \
|
||||||
|
-I/Users/rock88/Downloads/moonlight-switch-master/dependencies/include
|
||||||
|
|
||||||
DEFINES := -DNANOGUI_USE_OPENGL -DNVG_STB_IMAGE_IMPLEMENTATION -DNANOGUI_NO_GLFW \
|
DEFINES := -DNANOGUI_USE_OPENGL -DNVG_STB_IMAGE_IMPLEMENTATION -DNANOGUI_NO_GLFW \
|
||||||
-DHAS_SOCKLEN_T -DHAS_POLL -DHAS_FCNTL -D_GNU_SOURCE
|
-DHAS_SOCKLEN_T -DHAS_POLL -DHAS_FCNTL -D_GNU_SOURCE -DUSE_MBEDTLS_CRYPTO
|
||||||
|
|
||||||
CFLAGS := -g -Wall -O0 -ffunction-sections \
|
CFLAGS := -g -Wall -O0 -ffunction-sections \
|
||||||
$(ARCH) $(DEFINES)
|
$(ARCH) $(DEFINES)
|
||||||
|
@ -81,14 +83,15 @@ LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto \
|
||||||
-lavcodec -lavutil -lopus -lssl -lcrypto -lbz2 -lz -lexpat -lm \
|
-lavcodec -lavutil -lopus -lssl -lcrypto -lbz2 -lz -lexpat -lm \
|
||||||
-lglad -lEGL -lglapi -ldrm_nouveau -lglfw3 \
|
-lglad -lEGL -lglapi -ldrm_nouveau -lglfw3 \
|
||||||
-lnx -lwebp -lswresample -lavformat -lvpx \
|
-lnx -lwebp -lswresample -lavformat -lvpx \
|
||||||
-L/Users/rock88/Documents/Projects/Switch/moonlight-switch-new/deps/lib
|
-L/Users/rock88/Downloads/moonlight-switch-master/dependencies/lib
|
||||||
|
|
||||||
LIBGAMESTREAM_SOURCES = \
|
LIBGAMESTREAM_C_SOURCES = \
|
||||||
client.c \
|
|
||||||
http.c \
|
|
||||||
mkcert.c \
|
|
||||||
xml.c
|
xml.c
|
||||||
|
|
||||||
|
LIBGAMESTREAM_CPP_SOURCES = \
|
||||||
|
client.cpp \
|
||||||
|
http.cpp
|
||||||
|
|
||||||
MOONLIGHT_LIBRETRO_C_SOURCES = \
|
MOONLIGHT_LIBRETRO_C_SOURCES = \
|
||||||
nanogui_resources.c \
|
nanogui_resources.c \
|
||||||
moonlight_libnx.c \
|
moonlight_libnx.c \
|
||||||
|
@ -111,7 +114,9 @@ MOONLIGHT_LIBRETRO_CXX_SOURCES = \
|
||||||
InputController.cpp \
|
InputController.cpp \
|
||||||
MoonlightSession.cpp \
|
MoonlightSession.cpp \
|
||||||
FFmpegVideoDecoder.cpp \
|
FFmpegVideoDecoder.cpp \
|
||||||
GLVideoRenderer.cpp
|
GLVideoRenderer.cpp \
|
||||||
|
Data.cpp \
|
||||||
|
MbedTLSCryptoManager.cpp
|
||||||
|
|
||||||
MOONLIGHT_COMMON_C_SOURCES = \
|
MOONLIGHT_COMMON_C_SOURCES = \
|
||||||
callbacks.c \
|
callbacks.c \
|
||||||
|
@ -202,8 +207,8 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
|
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
CFILES := $(LIBGAMESTREAM_SOURCES) $(MOONLIGHT_LIBRETRO_C_SOURCES) $(MOONLIGHT_COMMON_C_SOURCES) $(NANOGUI_C_SOURCES)
|
CFILES := $(LIBGAMESTREAM_C_SOURCES) $(MOONLIGHT_LIBRETRO_C_SOURCES) $(MOONLIGHT_COMMON_C_SOURCES) $(NANOGUI_C_SOURCES)
|
||||||
CPPFILES := $(MOONLIGHT_LIBRETRO_CXX_SOURCES) $(NANOGUI_CXX_SOURCES)
|
CPPFILES := $(LIBGAMESTREAM_CPP_SOURCES) $(MOONLIGHT_LIBRETRO_CXX_SOURCES) $(NANOGUI_CXX_SOURCES)
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "mkcert.h"
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
|
@ -40,10 +39,6 @@
|
||||||
static char* unique_id = "0123456789ABCDEF";
|
static char* unique_id = "0123456789ABCDEF";
|
||||||
const char* gs_error;
|
const char* gs_error;
|
||||||
|
|
||||||
uid_t getuid() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdirtree(const char* directory) {
|
int mkdirtree(const char* directory) {
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
char* p = buffer;
|
char* p = buffer;
|
||||||
|
@ -207,10 +202,10 @@ static int gs_pair_validate(Data &data, char** result) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(*result, "1") != 0) {
|
// if (strcmp(*result, "1") != 0) {
|
||||||
gs_error = "Pairing failed";
|
// gs_error = "Pairing failed";
|
||||||
ret = GS_FAILED;
|
// ret = GS_FAILED;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (*result) {
|
if (*result) {
|
||||||
free(*result);
|
free(*result);
|
||||||
|
@ -252,7 +247,7 @@ int gs_pair(PSERVER_DATA server, char* pin) {
|
||||||
Data salted_pin = salt.append(Data(pin, strlen(pin)));
|
Data salted_pin = salt.append(Data(pin, strlen(pin)));
|
||||||
LOG_FMT("PIN: %s, salt %s\n", pin, salt.hex().bytes());
|
LOG_FMT("PIN: %s, salt %s\n", pin, salt.hex().bytes());
|
||||||
|
|
||||||
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", server->serverInfo.address, unique_id, salt.hex().bytes(), CryptoManager::read_cert_from_file().hex().bytes());
|
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&phrase=getservercert&salt=%s&clientcert=%s", server->serverInfo.address, unique_id, salt.hex().bytes(), CryptoManager::cert_data().hex().bytes());
|
||||||
|
|
||||||
if ((ret = http_request(url, &data)) != GS_OK) {
|
if ((ret = http_request(url, &data)) != GS_OK) {
|
||||||
return gs_pair_cleanup(ret, server, &result);
|
return gs_pair_cleanup(ret, server, &result);
|
||||||
|
@ -308,7 +303,7 @@ int gs_pair(PSERVER_DATA server, char* pin) {
|
||||||
Data serverChallenge = decServerChallengeResp.subdata(hashLength, 16);
|
Data serverChallenge = decServerChallengeResp.subdata(hashLength, 16);
|
||||||
|
|
||||||
Data clientSecret = Data::random_bytes(16);
|
Data clientSecret = Data::random_bytes(16);
|
||||||
Data challengeRespHashInput = serverChallenge.append(CryptoManager::get_signature_from_cert(CryptoManager::read_cert_from_file())).append(clientSecret);
|
Data challengeRespHashInput = serverChallenge.append(CryptoManager::signature(CryptoManager::cert_data())).append(clientSecret);
|
||||||
|
|
||||||
Data challengeRespHash;
|
Data challengeRespHash;
|
||||||
|
|
||||||
|
@ -347,7 +342,7 @@ int gs_pair(PSERVER_DATA server, char* pin) {
|
||||||
return gs_pair_cleanup(ret, server, &result);
|
return gs_pair_cleanup(ret, server, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data serverChallengeRespHashInput = randomChallenge.append(CryptoManager::get_signature_from_cert(plainCert.hex_to_bytes())).append(serverSecret);
|
Data serverChallengeRespHashInput = randomChallenge.append(CryptoManager::signature(plainCert.hex_to_bytes())).append(serverSecret);
|
||||||
Data serverChallengeRespHash;
|
Data serverChallengeRespHash;
|
||||||
if (server->serverMajorVersion >= 7) {
|
if (server->serverMajorVersion >= 7) {
|
||||||
serverChallengeRespHash = CryptoManager::SHA256_hash_data(serverChallengeRespHashInput);
|
serverChallengeRespHash = CryptoManager::SHA256_hash_data(serverChallengeRespHashInput);
|
||||||
|
@ -356,7 +351,7 @@ int gs_pair(PSERVER_DATA server, char* pin) {
|
||||||
serverChallengeRespHash = CryptoManager::SHA1_hash_data(serverChallengeRespHashInput);
|
serverChallengeRespHash = CryptoManager::SHA1_hash_data(serverChallengeRespHashInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data clientPairingSecret = clientSecret.append(CryptoManager::sign_data(clientSecret, CryptoManager::read_key_from_file()));
|
Data clientPairingSecret = clientSecret.append(CryptoManager::sign_data(clientSecret, CryptoManager::key_data()));
|
||||||
|
|
||||||
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", server->serverInfo.address, unique_id, clientPairingSecret.hex().bytes());
|
snprintf(url, sizeof(url), "http://%s:47989/pair?uniqueid=%s&devicename=roth&updateState=1&clientpairingsecret=%s", server->serverInfo.address, unique_id, clientPairingSecret.hex().bytes());
|
||||||
if ((ret = http_request(url, &data)) != GS_OK) {
|
if ((ret = http_request(url, &data)) != GS_OK) {
|
||||||
|
@ -512,16 +507,16 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
int gs_init(PSERVER_DATA server, char *address, const char *keyDirectory, int log_level, bool unsupported) {
|
int gs_init(PSERVER_DATA server, char *address, const char *keyDirectory, int log_level, bool unsupported) {
|
||||||
if (!CryptoManager::certs_exists()) {
|
if (!CryptoManager::load_cert_key_pair()) {
|
||||||
LOG("No certs, generate new...\n");
|
LOG("No certs, generate new...\n");
|
||||||
|
|
||||||
if (!CryptoManager::generate_certs()) {
|
if (!CryptoManager::generate_new_cert_key_pair()) {
|
||||||
LOG("Failed to generate certs...\n");
|
LOG("Failed to generate certs...\n");
|
||||||
return GS_FAILED;
|
return GS_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
http_init(keyDirectory, log_level);
|
http_init(keyDirectory, 2);
|
||||||
|
|
||||||
LiInitializeServerInformation(&server->serverInfo);
|
LiInitializeServerInformation(&server->serverInfo);
|
||||||
server->serverInfo.address = address;
|
server->serverInfo.address = address;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
#include "CryptoManager.hpp"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -47,6 +49,13 @@ static size_t _write_curl(void *contents, size_t size, size_t nmemb, void *userp
|
||||||
}
|
}
|
||||||
|
|
||||||
int http_init(const char* key_directory, int log_level) {
|
int http_init(const char* key_directory, int log_level) {
|
||||||
|
if (!curl) {
|
||||||
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
LOG_FMT("Curl version: %s\n", curl_version());
|
||||||
|
} else {
|
||||||
|
return GS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
debug = log_level >= 2;
|
debug = log_level >= 2;
|
||||||
|
|
||||||
|
@ -59,9 +68,12 @@ int http_init(const char* key_directory, int log_level) {
|
||||||
char keyFilePath[4096];
|
char keyFilePath[4096];
|
||||||
sprintf(&keyFilePath[0], "%s/%s", key_directory, KEY_FILE_NAME);
|
sprintf(&keyFilePath[0], "%s/%s", key_directory, KEY_FILE_NAME);
|
||||||
|
|
||||||
|
LOG_FMT("certificateFilePath: %s\n", certificateFilePath);
|
||||||
|
LOG_FMT("keyFilePath: %s\n", keyFilePath);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L);
|
curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE,"PEM");
|
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLCERT, certificateFilePath);
|
curl_easy_setopt(curl, CURLOPT_SSLCERT, certificateFilePath);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
|
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLKEY, keyFilePath);
|
curl_easy_setopt(curl, CURLOPT_SSLKEY, keyFilePath);
|
||||||
|
@ -75,7 +87,7 @@ int http_init(const char* key_directory, int log_level) {
|
||||||
|
|
||||||
int http_request(char* url, Data* data) {
|
int http_request(char* url, Data* data) {
|
||||||
if (debug)
|
if (debug)
|
||||||
printf("Request %s\n", url);
|
LOG_FMT("Request %s\n", url);
|
||||||
|
|
||||||
HTTP_DATA* http_data = (HTTP_DATA*)malloc(sizeof(HTTP_DATA));
|
HTTP_DATA* http_data = (HTTP_DATA*)malloc(sizeof(HTTP_DATA));
|
||||||
http_data->memory = (char*)malloc(1);
|
http_data->memory = (char*)malloc(1);
|
||||||
|
@ -88,19 +100,20 @@ int http_request(char* url, Data* data) {
|
||||||
|
|
||||||
if (res != CURLE_OK) {
|
if (res != CURLE_OK) {
|
||||||
gs_error = curl_easy_strerror(res);
|
gs_error = curl_easy_strerror(res);
|
||||||
|
LOG_FMT("Curl error: %s\n", gs_error);
|
||||||
return GS_FAILED;
|
return GS_FAILED;
|
||||||
} else if (http_data->memory == NULL) {
|
} else if (http_data->memory == NULL) {
|
||||||
|
LOG("Curl error: memory = NULL\n");
|
||||||
return GS_OUT_OF_MEMORY;
|
return GS_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
*data = Data(http_data->memory, http_data->size);
|
*data = Data(http_data->memory, http_data->size);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
LOG_FMT("Response:\n%s\n\n", http_data->memory);
|
||||||
|
|
||||||
free(http_data->memory);
|
free(http_data->memory);
|
||||||
free(http_data);
|
free(http_data);
|
||||||
|
|
||||||
if (debug)
|
|
||||||
printf("Response:\n%s\n\n", http_data->memory);
|
|
||||||
|
|
||||||
return GS_OK;
|
return GS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,5 @@
|
||||||
|
|
||||||
#include "Data.hpp"
|
#include "Data.hpp"
|
||||||
|
|
||||||
#define CERTIFICATE_FILE_NAME "client.pem"
|
|
||||||
#define KEY_FILE_NAME "key.pem"
|
|
||||||
|
|
||||||
int http_init(const char* key_directory, int log_level);
|
int http_init(const char* key_directory, int log_level);
|
||||||
int http_request(char* url, Data* data);
|
int http_request(char* url, Data* data);
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
/*
|
|
||||||
* Moonlight is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Moonlight is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mkcert.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <openssl/crypto.h>
|
|
||||||
#include <openssl/pem.h>
|
|
||||||
#include <openssl/conf.h>
|
|
||||||
#include <openssl/pkcs12.h>
|
|
||||||
#include <openssl/bio.h>
|
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_ENGINE
|
|
||||||
#include <openssl/engine.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const int NUM_BITS = 2048;
|
|
||||||
static const int SERIAL = 0;
|
|
||||||
static const int NUM_YEARS = 10;
|
|
||||||
|
|
||||||
int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years);
|
|
||||||
|
|
||||||
CERT_KEY_PAIR mkcert_generate() {
|
|
||||||
BIO *bio_err;
|
|
||||||
X509 *x509 = NULL;
|
|
||||||
EVP_PKEY *pkey = NULL;
|
|
||||||
PKCS12 *p12 = NULL;
|
|
||||||
|
|
||||||
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
|
||||||
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
|
||||||
|
|
||||||
mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS);
|
|
||||||
|
|
||||||
p12 = PKCS12_create("limelight", "GameStream", pkey, x509, NULL, 0, 0, 0, 0, 0);
|
|
||||||
if (p12 == NULL) {
|
|
||||||
printf("Error generating a valid PKCS12 certificate.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
BIO_free(bio_err);
|
|
||||||
|
|
||||||
return (CERT_KEY_PAIR){x509, pkey, p12};
|
|
||||||
}
|
|
||||||
|
|
||||||
void mkcert_free(CERT_KEY_PAIR certKeyPair) {
|
|
||||||
X509_free(certKeyPair.x509);
|
|
||||||
EVP_PKEY_free(certKeyPair.pkey);
|
|
||||||
PKCS12_free(certKeyPair.p12);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mkcert_save(const char* certFile, const char* p12File, const char* keyPairFile, CERT_KEY_PAIR certKeyPair) {
|
|
||||||
FILE* certFilePtr = fopen(certFile, "w");
|
|
||||||
FILE* keyPairFilePtr = fopen(keyPairFile, "w");
|
|
||||||
FILE* p12FilePtr = fopen(p12File, "wb");
|
|
||||||
|
|
||||||
//TODO: error check
|
|
||||||
PEM_write_PrivateKey(keyPairFilePtr, certKeyPair.pkey, NULL, NULL, 0, NULL, NULL);
|
|
||||||
PEM_write_X509(certFilePtr, certKeyPair.x509);
|
|
||||||
i2d_PKCS12_fp(p12FilePtr, certKeyPair.p12);
|
|
||||||
|
|
||||||
fclose(p12FilePtr);
|
|
||||||
fclose(certFilePtr);
|
|
||||||
fclose(keyPairFilePtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
|
|
||||||
X509* cert = X509_new();
|
|
||||||
EVP_PKEY* pk = EVP_PKEY_new();
|
|
||||||
BIGNUM* bne = BN_new();
|
|
||||||
RSA* rsa = RSA_new();
|
|
||||||
|
|
||||||
BN_set_word(bne, RSA_F4);
|
|
||||||
RSA_generate_key_ex(rsa, bits, bne, NULL);
|
|
||||||
|
|
||||||
EVP_PKEY_assign_RSA(pk, rsa);
|
|
||||||
|
|
||||||
X509_set_version(cert, 2);
|
|
||||||
ASN1_INTEGER_set(X509_get_serialNumber(cert), serial);
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
||||||
X509_gmtime_adj(X509_get_notBefore(cert), 0);
|
|
||||||
X509_gmtime_adj(X509_get_notAfter(cert), 60 * 60 * 24 * 365 * years);
|
|
||||||
#else
|
|
||||||
ASN1_TIME* before = ASN1_STRING_dup(X509_get0_notBefore(cert));
|
|
||||||
ASN1_TIME* after = ASN1_STRING_dup(X509_get0_notAfter(cert));
|
|
||||||
|
|
||||||
X509_gmtime_adj(before, 0);
|
|
||||||
X509_gmtime_adj(after, 60 * 60 * 24 * 365 * years);
|
|
||||||
|
|
||||||
X509_set1_notBefore(cert, before);
|
|
||||||
X509_set1_notAfter(cert, after);
|
|
||||||
|
|
||||||
ASN1_STRING_free(before);
|
|
||||||
ASN1_STRING_free(after);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
X509_set_pubkey(cert, pk);
|
|
||||||
|
|
||||||
X509_NAME* name = X509_get_subject_name(cert);
|
|
||||||
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
|
|
||||||
(const unsigned char*)"NVIDIA GameStream Client",
|
|
||||||
-1, -1, 0);
|
|
||||||
X509_set_issuer_name(cert, name);
|
|
||||||
|
|
||||||
X509_sign(cert, pk, EVP_sha256());
|
|
||||||
|
|
||||||
BN_free(bne);
|
|
||||||
|
|
||||||
*x509p = cert;
|
|
||||||
*pkeyp = pk;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* Created by Diego Waxemberg on 10/16/14.
|
|
||||||
* Copyright (c) 2014 Limelight Stream. All rights reserved.
|
|
||||||
*
|
|
||||||
* Moonlight is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Moonlight is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <openssl/x509v3.h>
|
|
||||||
#include <openssl/pkcs12.h>
|
|
||||||
|
|
||||||
typedef struct _CERT_KEY_PAIR {
|
|
||||||
X509 *x509;
|
|
||||||
EVP_PKEY *pkey;
|
|
||||||
PKCS12 *p12;
|
|
||||||
} CERT_KEY_PAIR, *PCERT_KEY_PAIR;
|
|
||||||
|
|
||||||
CERT_KEY_PAIR mkcert_generate();
|
|
||||||
void mkcert_free(CERT_KEY_PAIR);
|
|
||||||
void mkcert_save(const char* certFile, const char* p12File, const char* keyPairFile, CERT_KEY_PAIR certKeyPair);
|
|
|
@ -11,6 +11,8 @@
|
||||||
3602C3BA245DB3C800368900 /* AppListWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3602C3B8245DB3C800368900 /* AppListWindow.cpp */; };
|
3602C3BA245DB3C800368900 /* AppListWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3602C3B8245DB3C800368900 /* AppListWindow.cpp */; };
|
||||||
3602C3BD245DBA9100368900 /* AppButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3602C3BB245DBA9100368900 /* AppButton.cpp */; };
|
3602C3BD245DBA9100368900 /* AppButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3602C3BB245DBA9100368900 /* AppButton.cpp */; };
|
||||||
3603E93C246316400051287D /* InputController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3603E93A246316400051287D /* InputController.cpp */; };
|
3603E93C246316400051287D /* InputController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3603E93A246316400051287D /* InputController.cpp */; };
|
||||||
|
363898332471B7C500F99920 /* OpenSSLCryptoManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 363898302471B7C500F99920 /* OpenSSLCryptoManager.cpp */; };
|
||||||
|
363898342471B7C500F99920 /* MbedTLSCryptoManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 363898312471B7C500F99920 /* MbedTLSCryptoManager.cpp */; };
|
||||||
3652EFCD245B3B00001FABF3 /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF0F245B3B00001FABF3 /* widget.cpp */; };
|
3652EFCD245B3B00001FABF3 /* widget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF0F245B3B00001FABF3 /* widget.cpp */; };
|
||||||
3652EFCE245B3B00001FABF3 /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF10245B3B00001FABF3 /* common.cpp */; };
|
3652EFCE245B3B00001FABF3 /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF10245B3B00001FABF3 /* common.cpp */; };
|
||||||
3652EFCF245B3B00001FABF3 /* checkbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF11245B3B00001FABF3 /* checkbox.cpp */; };
|
3652EFCF245B3B00001FABF3 /* checkbox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652EF11245B3B00001FABF3 /* checkbox.cpp */; };
|
||||||
|
@ -50,7 +52,6 @@
|
||||||
3652F005245C28C6001FABF3 /* GameStreamClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652F003245C28C6001FABF3 /* GameStreamClient.cpp */; };
|
3652F005245C28C6001FABF3 /* GameStreamClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652F003245C28C6001FABF3 /* GameStreamClient.cpp */; };
|
||||||
3652F010245C2919001FABF3 /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = 3652F008245C2918001FABF3 /* xml.c */; };
|
3652F010245C2919001FABF3 /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = 3652F008245C2918001FABF3 /* xml.c */; };
|
||||||
3652F011245C2919001FABF3 /* client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652F00C245C2918001FABF3 /* client.cpp */; };
|
3652F011245C2919001FABF3 /* client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652F00C245C2918001FABF3 /* client.cpp */; };
|
||||||
3652F012245C2919001FABF3 /* mkcert.c in Sources */ = {isa = PBXBuildFile; fileRef = 3652F00D245C2918001FABF3 /* mkcert.c */; };
|
|
||||||
3652F013245C2919001FABF3 /* http.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652F00F245C2918001FABF3 /* http.cpp */; };
|
3652F013245C2919001FABF3 /* http.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3652F00F245C2918001FABF3 /* http.cpp */; };
|
||||||
3652F065245C292B001FABF3 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = 3652F017245C292B001FABF3 /* list.c */; };
|
3652F065245C292B001FABF3 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = 3652F017245C292B001FABF3 /* list.c */; };
|
||||||
3652F066245C292B001FABF3 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 3652F01B245C292B001FABF3 /* compress.c */; };
|
3652F066245C292B001FABF3 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 3652F01B245C292B001FABF3 /* compress.c */; };
|
||||||
|
@ -100,7 +101,6 @@
|
||||||
36DFE0CE2459FAB100FC51CE /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36DBDEA22450C2640057C8D3 /* OpenGL.framework */; };
|
36DFE0CE2459FAB100FC51CE /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36DBDEA22450C2640057C8D3 /* OpenGL.framework */; };
|
||||||
36DFE217245A278700FC51CE /* glsym_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = 36DFE0DB245A1FEC00FC51CE /* glsym_gl.c */; };
|
36DFE217245A278700FC51CE /* glsym_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = 36DFE0DB245A1FEC00FC51CE /* glsym_gl.c */; };
|
||||||
36DFE218245A278900FC51CE /* rglgen.c in Sources */ = {isa = PBXBuildFile; fileRef = 36DFE0DE245A1FEC00FC51CE /* rglgen.c */; };
|
36DFE218245A278900FC51CE /* rglgen.c in Sources */ = {isa = PBXBuildFile; fileRef = 36DFE0DE245A1FEC00FC51CE /* rglgen.c */; };
|
||||||
36E6378C246FFFF30032F5FB /* CryptoManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36E6378A246FFFF30032F5FB /* CryptoManager.cpp */; };
|
|
||||||
36E63790247010C70032F5FB /* Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36E6378E247010C70032F5FB /* Data.cpp */; };
|
36E63790247010C70032F5FB /* Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36E6378E247010C70032F5FB /* Data.cpp */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
@ -126,6 +126,10 @@
|
||||||
3602C3C0245DC7E300368900 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
3602C3C0245DC7E300368900 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
|
||||||
3603E93A246316400051287D /* InputController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InputController.cpp; sourceTree = "<group>"; };
|
3603E93A246316400051287D /* InputController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InputController.cpp; sourceTree = "<group>"; };
|
||||||
3603E93B246316400051287D /* InputController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = InputController.hpp; sourceTree = "<group>"; };
|
3603E93B246316400051287D /* InputController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = InputController.hpp; sourceTree = "<group>"; };
|
||||||
|
3638982F2471B7C500F99920 /* MbedTLSCryptoManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MbedTLSCryptoManager.hpp; sourceTree = "<group>"; };
|
||||||
|
363898302471B7C500F99920 /* OpenSSLCryptoManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpenSSLCryptoManager.cpp; sourceTree = "<group>"; };
|
||||||
|
363898312471B7C500F99920 /* MbedTLSCryptoManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MbedTLSCryptoManager.cpp; sourceTree = "<group>"; };
|
||||||
|
363898322471B7C500F99920 /* OpenSSLCryptoManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenSSLCryptoManager.hpp; sourceTree = "<group>"; };
|
||||||
3652ECE8245B3AFF001FABF3 /* colorpicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colorpicker.h; sourceTree = "<group>"; };
|
3652ECE8245B3AFF001FABF3 /* colorpicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = colorpicker.h; sourceTree = "<group>"; };
|
||||||
3652ECE9245B3AFF001FABF3 /* renderpass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = renderpass.h; sourceTree = "<group>"; };
|
3652ECE9245B3AFF001FABF3 /* renderpass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = renderpass.h; sourceTree = "<group>"; };
|
||||||
3652ECEA245B3AFF001FABF3 /* theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = theme.h; sourceTree = "<group>"; };
|
3652ECEA245B3AFF001FABF3 /* theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = theme.h; sourceTree = "<group>"; };
|
||||||
|
@ -212,13 +216,11 @@
|
||||||
3652F001245B6961001FABF3 /* AddHostWindow.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AddHostWindow.hpp; sourceTree = "<group>"; };
|
3652F001245B6961001FABF3 /* AddHostWindow.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AddHostWindow.hpp; sourceTree = "<group>"; };
|
||||||
3652F003245C28C6001FABF3 /* GameStreamClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GameStreamClient.cpp; sourceTree = "<group>"; };
|
3652F003245C28C6001FABF3 /* GameStreamClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GameStreamClient.cpp; sourceTree = "<group>"; };
|
||||||
3652F004245C28C6001FABF3 /* GameStreamClient.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = GameStreamClient.hpp; sourceTree = "<group>"; };
|
3652F004245C28C6001FABF3 /* GameStreamClient.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = GameStreamClient.hpp; sourceTree = "<group>"; };
|
||||||
3652F007245C2918001FABF3 /* mkcert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mkcert.h; sourceTree = "<group>"; };
|
|
||||||
3652F008245C2918001FABF3 /* xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xml.c; sourceTree = "<group>"; };
|
3652F008245C2918001FABF3 /* xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xml.c; sourceTree = "<group>"; };
|
||||||
3652F009245C2918001FABF3 /* client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = client.h; sourceTree = "<group>"; };
|
3652F009245C2918001FABF3 /* client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = client.h; sourceTree = "<group>"; };
|
||||||
3652F00A245C2918001FABF3 /* http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http.h; sourceTree = "<group>"; };
|
3652F00A245C2918001FABF3 /* http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = http.h; sourceTree = "<group>"; };
|
||||||
3652F00B245C2918001FABF3 /* errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = errors.h; sourceTree = "<group>"; };
|
3652F00B245C2918001FABF3 /* errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = errors.h; sourceTree = "<group>"; };
|
||||||
3652F00C245C2918001FABF3 /* client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = client.cpp; sourceTree = "<group>"; };
|
3652F00C245C2918001FABF3 /* client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = client.cpp; sourceTree = "<group>"; };
|
||||||
3652F00D245C2918001FABF3 /* mkcert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mkcert.c; sourceTree = "<group>"; };
|
|
||||||
3652F00E245C2918001FABF3 /* xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xml.h; sourceTree = "<group>"; };
|
3652F00E245C2918001FABF3 /* xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xml.h; sourceTree = "<group>"; };
|
||||||
3652F00F245C2918001FABF3 /* http.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http.cpp; sourceTree = "<group>"; };
|
3652F00F245C2918001FABF3 /* http.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = http.cpp; sourceTree = "<group>"; };
|
||||||
3652F017245C292B001FABF3 /* list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = list.c; sourceTree = "<group>"; };
|
3652F017245C292B001FABF3 /* list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = list.c; sourceTree = "<group>"; };
|
||||||
|
@ -301,6 +303,7 @@
|
||||||
36D3F8432469B5C400CDEF9B /* MoonlightSession.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MoonlightSession.hpp; sourceTree = "<group>"; };
|
36D3F8432469B5C400CDEF9B /* MoonlightSession.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MoonlightSession.hpp; sourceTree = "<group>"; };
|
||||||
36D3F8452469C6BC00CDEF9B /* Log.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = "<group>"; };
|
36D3F8452469C6BC00CDEF9B /* Log.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = "<group>"; };
|
||||||
36D3F8492469CC2600CDEF9B /* IAudioRenderer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = IAudioRenderer.hpp; sourceTree = "<group>"; };
|
36D3F8492469CC2600CDEF9B /* IAudioRenderer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = IAudioRenderer.hpp; sourceTree = "<group>"; };
|
||||||
|
36D461BE24709B8F00A543B4 /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = build.sh; path = "../../../../Downloads/openssl-1.1.1g/build.sh"; sourceTree = "<group>"; };
|
||||||
36DBDE8E2450BB7E0057C8D3 /* moonlight */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = moonlight; sourceTree = BUILT_PRODUCTS_DIR; };
|
36DBDE8E2450BB7E0057C8D3 /* moonlight */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = moonlight; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
36DBDE992450BCD50057C8D3 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
36DBDE992450BCD50057C8D3 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
||||||
36DBDE9B2450BCD90057C8D3 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
36DBDE9B2450BCD90057C8D3 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||||
|
@ -320,7 +323,6 @@
|
||||||
36DFE0DF245A1FEC00FC51CE /* rglgen_headers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rglgen_headers.h; sourceTree = "<group>"; };
|
36DFE0DF245A1FEC00FC51CE /* rglgen_headers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rglgen_headers.h; sourceTree = "<group>"; };
|
||||||
36DFE0E1245A1FEC00FC51CE /* glsym_es3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glsym_es3.h; sourceTree = "<group>"; };
|
36DFE0E1245A1FEC00FC51CE /* glsym_es3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glsym_es3.h; sourceTree = "<group>"; };
|
||||||
36DFE0E3245A1FEC00FC51CE /* glsym_gl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glsym_gl.h; sourceTree = "<group>"; };
|
36DFE0E3245A1FEC00FC51CE /* glsym_gl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glsym_gl.h; sourceTree = "<group>"; };
|
||||||
36E6378A246FFFF30032F5FB /* CryptoManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoManager.cpp; sourceTree = "<group>"; };
|
|
||||||
36E6378B246FFFF30032F5FB /* CryptoManager.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CryptoManager.hpp; sourceTree = "<group>"; };
|
36E6378B246FFFF30032F5FB /* CryptoManager.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CryptoManager.hpp; sourceTree = "<group>"; };
|
||||||
36E6378E247010C70032F5FB /* Data.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Data.cpp; sourceTree = "<group>"; };
|
36E6378E247010C70032F5FB /* Data.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Data.cpp; sourceTree = "<group>"; };
|
||||||
36E6378F247010C70032F5FB /* Data.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Data.hpp; sourceTree = "<group>"; };
|
36E6378F247010C70032F5FB /* Data.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Data.hpp; sourceTree = "<group>"; };
|
||||||
|
@ -515,8 +517,6 @@
|
||||||
3652F009245C2918001FABF3 /* client.h */,
|
3652F009245C2918001FABF3 /* client.h */,
|
||||||
3652F00F245C2918001FABF3 /* http.cpp */,
|
3652F00F245C2918001FABF3 /* http.cpp */,
|
||||||
3652F00A245C2918001FABF3 /* http.h */,
|
3652F00A245C2918001FABF3 /* http.h */,
|
||||||
3652F00D245C2918001FABF3 /* mkcert.c */,
|
|
||||||
3652F007245C2918001FABF3 /* mkcert.h */,
|
|
||||||
3652F008245C2918001FABF3 /* xml.c */,
|
3652F008245C2918001FABF3 /* xml.c */,
|
||||||
3652F00E245C2918001FABF3 /* xml.h */,
|
3652F00E245C2918001FABF3 /* xml.h */,
|
||||||
3652F00B245C2918001FABF3 /* errors.h */,
|
3652F00B245C2918001FABF3 /* errors.h */,
|
||||||
|
@ -689,6 +689,7 @@
|
||||||
36DBDE852450BB7E0057C8D3 = {
|
36DBDE852450BB7E0057C8D3 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
36D461BE24709B8F00A543B4 /* build.sh */,
|
||||||
3602C3C0245DC7E300368900 /* Makefile */,
|
3602C3C0245DC7E300368900 /* Makefile */,
|
||||||
369445A82466CE2700786D0A /* Makefile.libnx */,
|
369445A82466CE2700786D0A /* Makefile.libnx */,
|
||||||
36A0C03E2461FFF10083289C /* build_opus_lakka_switch.sh */,
|
36A0C03E2461FFF10083289C /* build_opus_lakka_switch.sh */,
|
||||||
|
@ -771,10 +772,13 @@
|
||||||
36E63789246FFFDC0032F5FB /* crypto */ = {
|
36E63789246FFFDC0032F5FB /* crypto */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
36E6378B246FFFF30032F5FB /* CryptoManager.hpp */,
|
||||||
|
363898312471B7C500F99920 /* MbedTLSCryptoManager.cpp */,
|
||||||
|
3638982F2471B7C500F99920 /* MbedTLSCryptoManager.hpp */,
|
||||||
|
363898302471B7C500F99920 /* OpenSSLCryptoManager.cpp */,
|
||||||
|
363898322471B7C500F99920 /* OpenSSLCryptoManager.hpp */,
|
||||||
36E6378E247010C70032F5FB /* Data.cpp */,
|
36E6378E247010C70032F5FB /* Data.cpp */,
|
||||||
36E6378F247010C70032F5FB /* Data.hpp */,
|
36E6378F247010C70032F5FB /* Data.hpp */,
|
||||||
36E6378A246FFFF30032F5FB /* CryptoManager.cpp */,
|
|
||||||
36E6378B246FFFF30032F5FB /* CryptoManager.hpp */,
|
|
||||||
);
|
);
|
||||||
path = crypto;
|
path = crypto;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -867,6 +871,7 @@
|
||||||
36DFE0CD2459FA3F00FC51CE /* nanogui_resources.cpp in Sources */,
|
36DFE0CD2459FA3F00FC51CE /* nanogui_resources.cpp in Sources */,
|
||||||
36DFE217245A278700FC51CE /* glsym_gl.c in Sources */,
|
36DFE217245A278700FC51CE /* glsym_gl.c in Sources */,
|
||||||
3652F06A245C292B001FABF3 /* protocol.c in Sources */,
|
3652F06A245C292B001FABF3 /* protocol.c in Sources */,
|
||||||
|
363898332471B7C500F99920 /* OpenSSLCryptoManager.cpp in Sources */,
|
||||||
3652EFFC245B6434001FABF3 /* MainWindow.cpp in Sources */,
|
3652EFFC245B6434001FABF3 /* MainWindow.cpp in Sources */,
|
||||||
3652F086245C6CFC001FABF3 /* moonlight_libretro.cpp in Sources */,
|
3652F086245C6CFC001FABF3 /* moonlight_libretro.cpp in Sources */,
|
||||||
3652EFD3245B3B00001FABF3 /* button.cpp in Sources */,
|
3652EFD3245B3B00001FABF3 /* button.cpp in Sources */,
|
||||||
|
@ -892,6 +897,7 @@
|
||||||
3652EFF6245B3CF2001FABF3 /* nanovg.c in Sources */,
|
3652EFF6245B3CF2001FABF3 /* nanovg.c in Sources */,
|
||||||
3652F067245C292B001FABF3 /* packet.c in Sources */,
|
3652F067245C292B001FABF3 /* packet.c in Sources */,
|
||||||
3661D2F92469D1940060EE24 /* FFmpegVideoDecoder.cpp in Sources */,
|
3661D2F92469D1940060EE24 /* FFmpegVideoDecoder.cpp in Sources */,
|
||||||
|
363898342471B7C500F99920 /* MbedTLSCryptoManager.cpp in Sources */,
|
||||||
3652F072245C292B001FABF3 /* RtspConnection.c in Sources */,
|
3652F072245C292B001FABF3 /* RtspConnection.c in Sources */,
|
||||||
3652F005245C28C6001FABF3 /* GameStreamClient.cpp in Sources */,
|
3652F005245C28C6001FABF3 /* GameStreamClient.cpp in Sources */,
|
||||||
3652EFE8245B3B00001FABF3 /* opengl.cpp in Sources */,
|
3652EFE8245B3B00001FABF3 /* opengl.cpp in Sources */,
|
||||||
|
@ -900,7 +906,6 @@
|
||||||
3652EFF5245B3B00001FABF3 /* popupbutton.cpp in Sources */,
|
3652EFF5245B3B00001FABF3 /* popupbutton.cpp in Sources */,
|
||||||
3652EFF0245B3B00001FABF3 /* colorwheel.cpp in Sources */,
|
3652EFF0245B3B00001FABF3 /* colorwheel.cpp in Sources */,
|
||||||
3652F068245C292B001FABF3 /* unix.c in Sources */,
|
3652F068245C292B001FABF3 /* unix.c in Sources */,
|
||||||
36E6378C246FFFF30032F5FB /* CryptoManager.cpp in Sources */,
|
|
||||||
3652F07B245C292B001FABF3 /* RtspParser.c in Sources */,
|
3652F07B245C292B001FABF3 /* RtspParser.c in Sources */,
|
||||||
3652EFCF245B3B00001FABF3 /* checkbox.cpp in Sources */,
|
3652EFCF245B3B00001FABF3 /* checkbox.cpp in Sources */,
|
||||||
36A0C03A2461E4C00083289C /* SettingsWindow.cpp in Sources */,
|
36A0C03A2461E4C00083289C /* SettingsWindow.cpp in Sources */,
|
||||||
|
@ -925,7 +930,6 @@
|
||||||
3602C3B7245D903000368900 /* HostButton.cpp in Sources */,
|
3602C3B7245D903000368900 /* HostButton.cpp in Sources */,
|
||||||
3652EFD0245B3B00001FABF3 /* vscrollpanel.cpp in Sources */,
|
3652EFD0245B3B00001FABF3 /* vscrollpanel.cpp in Sources */,
|
||||||
3652F06D245C292B001FABF3 /* win32.c in Sources */,
|
3652F06D245C292B001FABF3 /* win32.c in Sources */,
|
||||||
3652F012245C2919001FABF3 /* mkcert.c in Sources */,
|
|
||||||
3652F002245B6961001FABF3 /* AddHostWindow.cpp in Sources */,
|
3652F002245B6961001FABF3 /* AddHostWindow.cpp in Sources */,
|
||||||
3652EFF8245B4EE2001FABF3 /* Application.cpp in Sources */,
|
3652EFF8245B4EE2001FABF3 /* Application.cpp in Sources */,
|
||||||
3652F07E245C292B001FABF3 /* AudioStream.c in Sources */,
|
3652F07E245C292B001FABF3 /* AudioStream.c in Sources */,
|
||||||
|
@ -1031,6 +1035,7 @@
|
||||||
"-DHAS_POLL",
|
"-DHAS_POLL",
|
||||||
"-DHAS_FCNTL",
|
"-DHAS_FCNTL",
|
||||||
"-DHAVE_PULSE",
|
"-DHAVE_PULSE",
|
||||||
|
"-DUSE_MBEDTLS_CRYPTO",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-lglfw3",
|
"-lglfw3",
|
||||||
|
@ -1044,6 +1049,9 @@
|
||||||
"-lavdevice",
|
"-lavdevice",
|
||||||
"-lz",
|
"-lz",
|
||||||
"-lopus",
|
"-lopus",
|
||||||
|
"-lmbedtls",
|
||||||
|
"-lmbedx509",
|
||||||
|
"-lmbedcrypto",
|
||||||
);
|
);
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
};
|
};
|
||||||
|
@ -1120,6 +1128,7 @@
|
||||||
"-DHAS_POLL",
|
"-DHAS_POLL",
|
||||||
"-DHAS_FCNTL",
|
"-DHAS_FCNTL",
|
||||||
"-DHAVE_PULSE",
|
"-DHAVE_PULSE",
|
||||||
|
"-DUSE_MBEDTLS_CRYPTO",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-lglfw3",
|
"-lglfw3",
|
||||||
|
@ -1133,6 +1142,9 @@
|
||||||
"-lavdevice",
|
"-lavdevice",
|
||||||
"-lz",
|
"-lz",
|
||||||
"-lopus",
|
"-lopus",
|
||||||
|
"-lmbedtls",
|
||||||
|
"-lmbedx509",
|
||||||
|
"-lmbedcrypto",
|
||||||
);
|
);
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
};
|
};
|
||||||
|
|
1
run.sh
1
run.sh
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
rm -fr moonlight.nro moonlight.elf moonlight.nacp
|
||||||
make -f Makefile.libnx
|
make -f Makefile.libnx
|
||||||
/opt/devkitpro/tools/bin/nxlink -s moonlight.nro
|
/opt/devkitpro/tools/bin/nxlink -s moonlight.nro
|
||||||
|
|
|
@ -15,22 +15,28 @@ static std::vector<std::function<void()>> m_tasks;
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
static Thread thread;
|
||||||
|
static bool run = true;
|
||||||
|
void terminate_gamestream_thread() {
|
||||||
|
run = false;
|
||||||
|
threadWaitForExit(&thread);
|
||||||
|
}
|
||||||
|
|
||||||
static void task_loop() {
|
static void task_loop() {
|
||||||
Thread thread;
|
|
||||||
threadCreate(
|
threadCreate(
|
||||||
&thread,
|
&thread,
|
||||||
[](void* a) {
|
[](void* a) {
|
||||||
while (1) {
|
while (run) {
|
||||||
std::vector<std::function<void()>> m_tasks_copy; {
|
std::vector<std::function<void()>> m_tasks_copy; {
|
||||||
std::lock_guard<std::mutex> guard(m_async_mutex);
|
std::lock_guard<std::mutex> guard(m_async_mutex);
|
||||||
m_tasks_copy = m_tasks;
|
m_tasks_copy = m_tasks;
|
||||||
m_tasks.clear();
|
m_tasks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto task: m_tasks_copy) {
|
for (auto task: m_tasks_copy) {
|
||||||
task();
|
task();
|
||||||
}
|
}
|
||||||
|
|
||||||
usleep(500'000);
|
usleep(500'000);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -41,7 +47,6 @@ static void task_loop() {
|
||||||
-2
|
-2
|
||||||
);
|
);
|
||||||
threadStart(&thread);
|
threadStart(&thread);
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void task_loop() {
|
static void task_loop() {
|
||||||
|
|
|
@ -1,38 +1,16 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "Data.hpp"
|
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "mkcert.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define CERTIFICATE_FILE_NAME "client.pem"
|
#if defined(USE_OPENSSL_CRYPTO)
|
||||||
#define P12_FILE_NAME "client.p12"
|
|
||||||
#define KEY_FILE_NAME "key.pem"
|
|
||||||
|
|
||||||
class CryptoManager {
|
#include "OpenSSLCryptoManager.hpp"
|
||||||
public:
|
#define CryptoManager OpenSSLCryptoManager
|
||||||
static bool certs_exists();
|
|
||||||
static bool load_certs();
|
#elif defined(USE_MBEDTLS_CRYPTO)
|
||||||
static bool generate_certs();
|
|
||||||
|
#include "MbedTLSCryptoManager.hpp"
|
||||||
static Data read_cert_from_file();
|
#define CryptoManager MbedTLSCryptoManager
|
||||||
static Data read_p12_from_file();
|
|
||||||
static Data read_key_from_file();
|
#else
|
||||||
|
#error Select crypto!
|
||||||
static Data SHA1_hash_data(Data data);
|
#endif
|
||||||
static Data SHA256_hash_data(Data data);
|
|
||||||
static Data create_AES_key_from_salt_SHA1(Data salted_pin);
|
|
||||||
static Data create_AES_key_from_salt_SHA256(Data salted_pin);
|
|
||||||
static Data aes_encrypt(Data data, Data key);
|
|
||||||
static Data aes_decrypt(Data data, Data key);
|
|
||||||
static Data pem_to_der(Data pem_cert_bytes);
|
|
||||||
static bool verify_signature(Data data, Data signature, Data cert);
|
|
||||||
static Data sign_data(Data data, Data key);
|
|
||||||
static Data get_signature_from_cert(Data cert);
|
|
||||||
static Data get_key_from_cert_key_pair(PCERT_KEY_PAIR cert_key_pair);
|
|
||||||
static Data get_p12_from_cert_key_pair(PCERT_KEY_PAIR cert_key_pair);
|
|
||||||
static Data get_cert_from_cert_key_pair(PCERT_KEY_PAIR cert_key_pair);
|
|
||||||
};
|
|
||||||
|
|
|
@ -5,18 +5,18 @@
|
||||||
|
|
||||||
Data::Data(unsigned char* bytes, size_t size) {
|
Data::Data(unsigned char* bytes, size_t size) {
|
||||||
if (bytes && size > 0) {
|
if (bytes && size > 0) {
|
||||||
m_bytes = (unsigned char *)malloc(size);
|
m_bytes = (unsigned char *)malloc(size + 1);
|
||||||
|
m_bytes[size] = '\0';
|
||||||
memcpy(m_bytes, bytes, size);
|
memcpy(m_bytes, bytes, size);
|
||||||
m_size = size;
|
m_size = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::Data(size_t capacity) {
|
Data::Data(size_t capacity) {
|
||||||
if (capacity > 0) {
|
m_bytes = (unsigned char *)malloc(capacity + 1);
|
||||||
m_bytes = (unsigned char *)malloc(capacity + 1);
|
memset(m_bytes, 0, capacity + 1);
|
||||||
m_bytes[capacity] = '\0';
|
m_bytes[capacity] = '\0';
|
||||||
m_size = capacity;
|
m_size = capacity;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::~Data() {
|
Data::~Data() {
|
||||||
|
@ -45,9 +45,14 @@ Data Data::append(Data other) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::Data(const Data& that): Data(0) {
|
Data::Data(const Data& that): Data(0) {
|
||||||
m_bytes = (unsigned char *)malloc(that.size());
|
if (m_bytes) {
|
||||||
memcpy(m_bytes, that.bytes(), that.size());
|
free(m_bytes);
|
||||||
m_size = that.size();
|
}
|
||||||
|
|
||||||
|
m_bytes = (unsigned char *)malloc(that.size() + 1);
|
||||||
|
memcpy(m_bytes, that.m_bytes, that.m_size);
|
||||||
|
m_bytes[that.m_size] = '\0';
|
||||||
|
m_size = that.m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data& Data::operator=(const Data& that) {
|
Data& Data::operator=(const Data& that) {
|
||||||
|
@ -56,8 +61,9 @@ Data& Data::operator=(const Data& that) {
|
||||||
free(m_bytes);
|
free(m_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bytes = (unsigned char *)malloc(that.m_size);
|
m_bytes = (unsigned char *)malloc(that.m_size + 1);
|
||||||
memcpy(m_bytes, that.m_bytes, that.m_size);
|
memcpy(m_bytes, that.m_bytes, that.m_size);
|
||||||
|
m_bytes[that.m_size] = '\0';
|
||||||
m_size = that.m_size;
|
m_size = that.m_size;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -65,7 +71,12 @@ Data& Data::operator=(const Data& that) {
|
||||||
|
|
||||||
Data Data::random_bytes(size_t size) {
|
Data Data::random_bytes(size_t size) {
|
||||||
unsigned char* bytes = (unsigned char*)malloc(sizeof(char) * size);
|
unsigned char* bytes = (unsigned char*)malloc(sizeof(char) * size);
|
||||||
arc4random_buf(bytes, size);
|
srand(time(NULL));
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
bytes[i] = rand() % 255;
|
||||||
|
}
|
||||||
|
|
||||||
Data random_data(size);
|
Data random_data(size);
|
||||||
memcpy(random_data.m_bytes, bytes, size);
|
memcpy(random_data.m_bytes, bytes, size);
|
||||||
free(bytes);
|
free(bytes);
|
||||||
|
@ -81,6 +92,7 @@ Data Data::read_from_file(std::string path) {
|
||||||
|
|
||||||
char* buffer = (char*)malloc(size);
|
char* buffer = (char*)malloc(size);
|
||||||
fread(buffer, 1, size, f);
|
fread(buffer, 1, size, f);
|
||||||
|
|
||||||
Data data(buffer, size);
|
Data data(buffer, size);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@ -89,6 +101,16 @@ Data Data::read_from_file(std::string path) {
|
||||||
return Data();
|
return Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Data::write_to_file(std::string path) {
|
||||||
|
FILE *f = fopen(path.c_str(), "w");
|
||||||
|
if (f) {
|
||||||
|
fwrite(m_bytes, m_size, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
} else {
|
||||||
|
LOG_FMT("Path not found: %s\n", path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Data Data::hex_to_bytes() const {
|
Data Data::hex_to_bytes() const {
|
||||||
Data data(m_size / 2);
|
Data data(m_size / 2);
|
||||||
char byte_chars[3] = {'\0','\0','\0'};
|
char byte_chars[3] = {'\0','\0','\0'};
|
||||||
|
@ -105,6 +127,11 @@ Data Data::hex_to_bytes() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Data Data::hex() const {
|
Data Data::hex() const {
|
||||||
|
if (!m_size) {
|
||||||
|
char end = '\n';
|
||||||
|
return Data(&end, 1);
|
||||||
|
}
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
Data hex(m_size * 2);
|
Data hex(m_size * 2);
|
||||||
char fmt[3] = {'\0','\0','\0'};
|
char fmt[3] = {'\0','\0','\0'};
|
||||||
|
@ -116,9 +143,3 @@ Data Data::hex() const {
|
||||||
hex.m_bytes[m_size * 2] = '\0';
|
hex.m_bytes[m_size * 2] = '\0';
|
||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Data::write_to_file(std::string path) {
|
|
||||||
FILE *f = fopen(path.c_str(), "w");
|
|
||||||
fwrite(m_bytes, m_size, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
|
|
||||||
static Data random_bytes(size_t size);
|
static Data random_bytes(size_t size);
|
||||||
static Data read_from_file(std::string path);
|
static Data read_from_file(std::string path);
|
||||||
|
void write_to_file(std::string path);
|
||||||
|
|
||||||
Data hex_to_bytes() const;
|
Data hex_to_bytes() const;
|
||||||
Data hex() const;
|
Data hex() const;
|
||||||
|
@ -35,8 +36,6 @@ public:
|
||||||
return m_size == 0;
|
return m_size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_to_file(std::string path);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned char* m_bytes = nullptr;
|
unsigned char* m_bytes = nullptr;
|
||||||
size_t m_size = 0;
|
size_t m_size = 0;
|
||||||
|
|
258
src/crypto/MbedTLSCryptoManager.cpp
Normal file
258
src/crypto/MbedTLSCryptoManager.cpp
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
#include "MbedTLSCryptoManager.hpp"
|
||||||
|
#include "Settings.hpp"
|
||||||
|
#include "client.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <mbedtls/sha1.h>
|
||||||
|
#include <mbedtls/sha256.h>
|
||||||
|
#include <mbedtls/aes.h>
|
||||||
|
#include <mbedtls/entropy.h>
|
||||||
|
#include <mbedtls/ctr_drbg.h>
|
||||||
|
#include <mbedtls/x509.h>
|
||||||
|
#include <mbedtls/x509_crt.h>
|
||||||
|
#include <mbedtls/error.h>
|
||||||
|
|
||||||
|
static Data m_cert;
|
||||||
|
static Data m_key;
|
||||||
|
|
||||||
|
static bool _generate_new_cert_key_pair();
|
||||||
|
|
||||||
|
bool MbedTLSCryptoManager::load_cert_key_pair() {
|
||||||
|
if (m_key.is_empty() || m_cert.is_empty()) {
|
||||||
|
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
||||||
|
Data cert = Data::read_from_file(key_dir + CERTIFICATE_FILE_NAME);
|
||||||
|
Data key = Data::read_from_file(key_dir + KEY_FILE_NAME);
|
||||||
|
|
||||||
|
if (!cert.is_empty() && !key.is_empty()) {
|
||||||
|
m_cert = cert;
|
||||||
|
m_key = key;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MbedTLSCryptoManager::generate_new_cert_key_pair() {
|
||||||
|
if (_generate_new_cert_key_pair()) {
|
||||||
|
if (!m_cert.is_empty() && !m_key.is_empty()) {
|
||||||
|
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
||||||
|
mkdirtree(key_dir.c_str());
|
||||||
|
m_cert.write_to_file(key_dir + CERTIFICATE_FILE_NAME);
|
||||||
|
m_key.write_to_file(key_dir + KEY_FILE_NAME);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MbedTLSCryptoManager::remove_cert_key_pair() {
|
||||||
|
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
||||||
|
remove((key_dir + CERTIFICATE_FILE_NAME).c_str());
|
||||||
|
remove((key_dir + KEY_FILE_NAME).c_str());
|
||||||
|
m_cert = Data();
|
||||||
|
m_key = Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::cert_data() {
|
||||||
|
return m_cert;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::key_data() {
|
||||||
|
return m_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::SHA1_hash_data(Data data) {
|
||||||
|
mbedtls_sha1_context ctx;
|
||||||
|
unsigned char sha1[20];
|
||||||
|
mbedtls_sha1_init(&ctx);
|
||||||
|
mbedtls_sha1_ret(data.bytes(), data.size(), sha1);
|
||||||
|
mbedtls_sha1_free(&ctx);
|
||||||
|
return Data(sha1, sizeof(sha1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::SHA256_hash_data(Data data) {
|
||||||
|
mbedtls_sha256_context ctx;
|
||||||
|
unsigned char sha256[32];
|
||||||
|
mbedtls_sha256_init(&ctx);
|
||||||
|
mbedtls_sha256_ret(data.bytes(), data.size(), sha256, 0);
|
||||||
|
mbedtls_sha256_free(&ctx);
|
||||||
|
return Data(sha256, sizeof(sha256));
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::create_AES_key_from_salt_SHA1(Data salted_pin) {
|
||||||
|
return SHA1_hash_data(salted_pin).subdata(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::create_AES_key_from_salt_SHA256(Data salted_pin) {
|
||||||
|
return SHA256_hash_data(salted_pin).subdata(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_encrypt_size(Data data) {
|
||||||
|
// the size is the length of the data ceiling to the nearest 16 bytes
|
||||||
|
return (((int)data.size() + 15) / 16) * 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::aes_encrypt(Data data, Data key) {
|
||||||
|
mbedtls_aes_context ctx;
|
||||||
|
mbedtls_aes_init(&ctx);
|
||||||
|
mbedtls_aes_setkey_enc(&ctx, key.bytes(), 128);
|
||||||
|
|
||||||
|
int size = get_encrypt_size(data);
|
||||||
|
unsigned char* buffer = (unsigned char*)malloc(size);
|
||||||
|
unsigned char* block_rounded_buffer = (unsigned char*)calloc(1, size);
|
||||||
|
memcpy(block_rounded_buffer, data.bytes(), data.size());
|
||||||
|
|
||||||
|
int block_offset = 0;
|
||||||
|
while (block_offset < size) {
|
||||||
|
mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, block_rounded_buffer + block_offset, buffer + block_offset);
|
||||||
|
block_offset += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data encrypted_data = Data((char*)buffer, size);
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
free(buffer);
|
||||||
|
free(block_rounded_buffer);
|
||||||
|
return encrypted_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::aes_decrypt(Data data, Data key) {
|
||||||
|
mbedtls_aes_context ctx;
|
||||||
|
mbedtls_aes_init(&ctx);
|
||||||
|
mbedtls_aes_setkey_dec(&ctx, key.bytes(), 128);
|
||||||
|
unsigned char* buffer = (unsigned char*)malloc(data.size());
|
||||||
|
|
||||||
|
int block_offset = 0;
|
||||||
|
while (block_offset < data.size()) {
|
||||||
|
mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, data.bytes() + block_offset, buffer + block_offset);
|
||||||
|
block_offset += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data decrypted_data = Data(buffer, data.size());
|
||||||
|
mbedtls_aes_free(&ctx);
|
||||||
|
free(buffer);
|
||||||
|
return decrypted_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::signature(Data cert) {
|
||||||
|
mbedtls_x509_crt x509;
|
||||||
|
mbedtls_x509_crt_init(&x509);
|
||||||
|
|
||||||
|
mbedtls_x509_crt_parse(&x509, cert.bytes(), cert.size() + 1);
|
||||||
|
|
||||||
|
Data data(x509.sig.p, x509.sig.len);
|
||||||
|
mbedtls_x509_crt_free(&x509);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MbedTLSCryptoManager::verify_signature(Data data, Data signature, Data cert) {
|
||||||
|
// TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data MbedTLSCryptoManager::sign_data(Data data, Data key) {
|
||||||
|
mbedtls_pk_context pk;
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
|
||||||
|
unsigned char hash[32];
|
||||||
|
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
mbedtls_entropy_init(&entropy);
|
||||||
|
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||||
|
mbedtls_pk_init(&pk);
|
||||||
|
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
|
||||||
|
|
||||||
|
mbedtls_pk_parse_key(&pk, key.bytes(), key.size() + 1, NULL, 0);
|
||||||
|
mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), data.bytes(), data.size(), hash);
|
||||||
|
mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256, hash, 0, buf, &size, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||||
|
|
||||||
|
mbedtls_pk_free(&pk);
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
return Data(buf, size);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cert and key generator
|
||||||
|
|
||||||
|
static void _generate_key(mbedtls_pk_context* key) {
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
|
||||||
|
mbedtls_entropy_init(&entropy);
|
||||||
|
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||||
|
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
|
||||||
|
|
||||||
|
mbedtls_pk_init(key);
|
||||||
|
|
||||||
|
mbedtls_pk_setup(key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
|
||||||
|
mbedtls_rsa_gen_key(mbedtls_pk_rsa(*key), mbedtls_ctr_drbg_random, &ctr_drbg, 2048, 65537);
|
||||||
|
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _generate_cert(mbedtls_x509write_cert* cert, mbedtls_pk_context* key) {
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
mbedtls_mpi serial;
|
||||||
|
|
||||||
|
mbedtls_entropy_init(&entropy);
|
||||||
|
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||||
|
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
|
||||||
|
mbedtls_mpi_init(&serial);
|
||||||
|
mbedtls_mpi_lset(&serial, 1);
|
||||||
|
|
||||||
|
mbedtls_x509write_crt_init(cert);
|
||||||
|
|
||||||
|
mbedtls_x509write_crt_set_version(cert, MBEDTLS_X509_CRT_VERSION_3);
|
||||||
|
mbedtls_x509write_crt_set_subject_name(cert, "CN=NVIDIA GameStream Client");
|
||||||
|
mbedtls_x509write_crt_set_issuer_name(cert, "CN=NVIDIA GameStream Client");
|
||||||
|
mbedtls_x509write_crt_set_subject_key(cert, key);
|
||||||
|
mbedtls_x509write_crt_set_issuer_key(cert, key);
|
||||||
|
mbedtls_x509write_crt_set_md_alg(cert, MBEDTLS_MD_SHA256);
|
||||||
|
mbedtls_x509write_crt_set_validity(cert, "20200101000000", "20300101000000");
|
||||||
|
mbedtls_x509write_crt_set_serial(cert, &serial);
|
||||||
|
|
||||||
|
mbedtls_mpi_free(&serial);
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _generate_new_cert_key_pair() {
|
||||||
|
mbedtls_entropy_context entropy;
|
||||||
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
|
|
||||||
|
mbedtls_entropy_init(&entropy);
|
||||||
|
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||||
|
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
|
||||||
|
|
||||||
|
mbedtls_x509write_cert cert;
|
||||||
|
mbedtls_pk_context key;
|
||||||
|
|
||||||
|
_generate_key(&key);
|
||||||
|
_generate_cert(&cert, &key);
|
||||||
|
|
||||||
|
unsigned char tmp[4096];
|
||||||
|
memset(tmp, 0, 4096);
|
||||||
|
size_t len = 0;
|
||||||
|
int i = mbedtls_pk_write_key_pem(&key, tmp, 4096);
|
||||||
|
|
||||||
|
len = strlen((char *)tmp);
|
||||||
|
m_key = Data(tmp, len);
|
||||||
|
memset(tmp, 0, 4096);
|
||||||
|
|
||||||
|
i = mbedtls_x509write_crt_pem(&cert, tmp, 4096, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||||
|
len = strlen((char *)tmp);
|
||||||
|
m_cert = Data(tmp, len);
|
||||||
|
|
||||||
|
mbedtls_x509write_crt_free(&cert);
|
||||||
|
mbedtls_pk_free(&key);
|
||||||
|
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||||
|
mbedtls_entropy_free(&entropy);
|
||||||
|
return true;
|
||||||
|
}
|
28
src/crypto/MbedTLSCryptoManager.hpp
Normal file
28
src/crypto/MbedTLSCryptoManager.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "Data.hpp"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CERTIFICATE_FILE_NAME "client.pem"
|
||||||
|
#define KEY_FILE_NAME "key.pem"
|
||||||
|
|
||||||
|
class MbedTLSCryptoManager {
|
||||||
|
public:
|
||||||
|
static bool load_cert_key_pair();
|
||||||
|
static bool generate_new_cert_key_pair();
|
||||||
|
static void remove_cert_key_pair();
|
||||||
|
|
||||||
|
static Data cert_data();
|
||||||
|
static Data key_data();
|
||||||
|
|
||||||
|
static Data SHA1_hash_data(Data data);
|
||||||
|
static Data SHA256_hash_data(Data data);
|
||||||
|
static Data create_AES_key_from_salt_SHA1(Data salted_pin);
|
||||||
|
static Data create_AES_key_from_salt_SHA256(Data salted_pin);
|
||||||
|
static Data aes_encrypt(Data data, Data key);
|
||||||
|
static Data aes_decrypt(Data data, Data key);
|
||||||
|
|
||||||
|
static Data signature(Data cert);
|
||||||
|
static bool verify_signature(Data data, Data signature, Data cert);
|
||||||
|
static Data sign_data(Data data, Data key);
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
#include "CryptoManager.hpp"
|
#include "OpenSSLCryptoManager.hpp"
|
||||||
#include "Settings.hpp"
|
#include "Settings.hpp"
|
||||||
|
#include "client.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
|
@ -7,95 +8,80 @@
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/pkcs12.h>
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
static const int SHA1_HASH_LENGTH = 20;
|
|
||||||
static const int SHA256_HASH_LENGTH = 32;
|
|
||||||
|
|
||||||
static Data m_cert;
|
static Data m_cert;
|
||||||
static Data m_p12;
|
|
||||||
static Data m_key;
|
static Data m_key;
|
||||||
|
|
||||||
bool CryptoManager::certs_exists() {
|
static const int NUM_BITS = 2048;
|
||||||
if (load_certs()) {
|
static const int SERIAL = 0;
|
||||||
return true;
|
static const int NUM_YEARS = 10;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CryptoManager::load_certs() {
|
static bool _generate_new_cert_key_pair();
|
||||||
if (m_key.is_empty() || m_cert.is_empty() || m_p12.is_empty()) {
|
|
||||||
|
bool OpenSSLCryptoManager::load_cert_key_pair() {
|
||||||
|
if (m_key.is_empty() || m_cert.is_empty()) {
|
||||||
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
||||||
mkdirtree(key_dir.c_str());
|
|
||||||
|
|
||||||
Data cert = Data::read_from_file(key_dir + CERTIFICATE_FILE_NAME);
|
Data cert = Data::read_from_file(key_dir + CERTIFICATE_FILE_NAME);
|
||||||
Data p12 = Data::read_from_file(key_dir + P12_FILE_NAME);
|
|
||||||
Data key = Data::read_from_file(key_dir + KEY_FILE_NAME);
|
Data key = Data::read_from_file(key_dir + KEY_FILE_NAME);
|
||||||
|
|
||||||
if (!cert.is_empty() && !p12.is_empty() && !key.is_empty()) {
|
if (!cert.is_empty() && !key.is_empty()) {
|
||||||
m_cert = cert;
|
m_cert = cert;
|
||||||
m_p12 = p12;
|
|
||||||
m_key = key;
|
m_key = key;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CryptoManager::generate_certs() {
|
bool OpenSSLCryptoManager::generate_new_cert_key_pair() {
|
||||||
auto cert_key_pair = mkcert_generate();
|
if (_generate_new_cert_key_pair()) {
|
||||||
|
if (!m_cert.is_empty() && !m_key.is_empty()) {
|
||||||
Data cert = get_cert_from_cert_key_pair(&cert_key_pair);
|
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
||||||
Data p12 = get_p12_from_cert_key_pair(&cert_key_pair);
|
mkdirtree(key_dir.c_str());
|
||||||
Data key = get_key_from_cert_key_pair(&cert_key_pair);
|
m_cert.write_to_file(key_dir + CERTIFICATE_FILE_NAME);
|
||||||
|
m_key.write_to_file(key_dir + KEY_FILE_NAME);
|
||||||
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
return true;
|
||||||
mkdirtree(key_dir.c_str());
|
}
|
||||||
|
|
||||||
if (!cert.is_empty() && !p12.is_empty() && !key.is_empty()) {
|
|
||||||
cert.write_to_file(key_dir + CERTIFICATE_FILE_NAME);
|
|
||||||
p12.write_to_file(key_dir + P12_FILE_NAME);
|
|
||||||
key.write_to_file(key_dir + KEY_FILE_NAME);
|
|
||||||
m_cert = cert;
|
|
||||||
m_p12 = p12;
|
|
||||||
m_key = key;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::read_cert_from_file() {
|
void OpenSSLCryptoManager::remove_cert_key_pair() {
|
||||||
|
auto key_dir = Settings::settings()->working_dir() + "/key/";
|
||||||
|
remove((key_dir + CERTIFICATE_FILE_NAME).c_str());
|
||||||
|
remove((key_dir + KEY_FILE_NAME).c_str());
|
||||||
|
m_cert = Data();
|
||||||
|
m_key = Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
Data OpenSSLCryptoManager::cert_data() {
|
||||||
return m_cert;
|
return m_cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::read_p12_from_file() {
|
Data OpenSSLCryptoManager::key_data() {
|
||||||
return m_p12;
|
|
||||||
}
|
|
||||||
|
|
||||||
Data CryptoManager::read_key_from_file() {
|
|
||||||
return m_key;
|
return m_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::SHA1_hash_data(Data data) {
|
Data OpenSSLCryptoManager::SHA1_hash_data(Data data) {
|
||||||
unsigned char sha1[SHA1_HASH_LENGTH];
|
unsigned char sha1[20];
|
||||||
SHA1(data.bytes(), data.size(), sha1);
|
SHA1(data.bytes(), data.size(), sha1);
|
||||||
return Data(sha1, sizeof(sha1));
|
return Data(sha1, sizeof(sha1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::SHA256_hash_data(Data data) {
|
Data OpenSSLCryptoManager::SHA256_hash_data(Data data) {
|
||||||
unsigned char sha256[SHA256_HASH_LENGTH];
|
unsigned char sha256[32];
|
||||||
SHA256(data.bytes(), data.size(), sha256);
|
SHA256(data.bytes(), data.size(), sha256);
|
||||||
return Data(sha256, sizeof(sha256));
|
return Data(sha256, sizeof(sha256));
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::create_AES_key_from_salt_SHA1(Data salted_pin) {
|
Data OpenSSLCryptoManager::create_AES_key_from_salt_SHA1(Data salted_pin) {
|
||||||
return SHA1_hash_data(salted_pin).subdata(0, 16);
|
return SHA1_hash_data(salted_pin).subdata(0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::create_AES_key_from_salt_SHA256(Data salted_pin) {
|
Data OpenSSLCryptoManager::create_AES_key_from_salt_SHA256(Data salted_pin) {
|
||||||
return SHA256_hash_data(salted_pin).subdata(0, 16);
|
return SHA256_hash_data(salted_pin).subdata(0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +90,7 @@ static int get_encrypt_size(Data data) {
|
||||||
return (((int)data.size() + 15) / 16) * 16;
|
return (((int)data.size() + 15) / 16) * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::aes_encrypt(Data data, Data key) {
|
Data OpenSSLCryptoManager::aes_encrypt(Data data, Data key) {
|
||||||
AES_KEY aes_key;
|
AES_KEY aes_key;
|
||||||
AES_set_encrypt_key((unsigned char*)key.bytes(), 128, &aes_key);
|
AES_set_encrypt_key((unsigned char*)key.bytes(), 128, &aes_key);
|
||||||
int size = get_encrypt_size(data);
|
int size = get_encrypt_size(data);
|
||||||
|
@ -125,7 +111,7 @@ Data CryptoManager::aes_encrypt(Data data, Data key) {
|
||||||
return encrypted_data;
|
return encrypted_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::aes_decrypt(Data data, Data key) {
|
Data OpenSSLCryptoManager::aes_decrypt(Data data, Data key) {
|
||||||
AES_KEY aes_key;
|
AES_KEY aes_key;
|
||||||
AES_set_decrypt_key(key.bytes(), 128, &aes_key);
|
AES_set_decrypt_key(key.bytes(), 128, &aes_key);
|
||||||
unsigned char* buffer = (unsigned char*)malloc(data.size());
|
unsigned char* buffer = (unsigned char*)malloc(data.size());
|
||||||
|
@ -142,25 +128,31 @@ Data CryptoManager::aes_decrypt(Data data, Data key) {
|
||||||
return decrypted_data;
|
return decrypted_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::pem_to_der(Data pem_cert_bytes) {
|
Data OpenSSLCryptoManager::signature(Data cert) {
|
||||||
X509* x509;
|
BIO* bio = BIO_new_mem_buf(cert.bytes(), cert.size());
|
||||||
|
X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||||
|
|
||||||
BIO* bio = BIO_new_mem_buf(pem_cert_bytes.bytes(), pem_cert_bytes.size());
|
if (!x509) {
|
||||||
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
LOG("Unable to parse certificate in memory!\n");
|
||||||
BIO_free(bio);
|
return Data();
|
||||||
|
}
|
||||||
|
|
||||||
bio = BIO_new(BIO_s_mem());
|
#if (OPENSSL_VERSION_NUMBER < 0x10002000L)
|
||||||
i2d_X509_bio(bio, x509);
|
ASN1_BIT_STRING *asn_signature = x509->signature;
|
||||||
|
#elif (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||||
|
ASN1_BIT_STRING *asn_signature;
|
||||||
|
X509_get0_signature(&asn_signature, NULL, x509);
|
||||||
|
#else
|
||||||
|
const ASN1_BIT_STRING *asn_signature;
|
||||||
|
X509_get0_signature(&asn_signature, NULL, x509);
|
||||||
|
#endif
|
||||||
|
|
||||||
BUF_MEM* mem;
|
Data sig = Data(asn_signature->data, asn_signature->length);
|
||||||
BIO_get_mem_ptr(bio, &mem);
|
X509_free(x509);
|
||||||
|
return sig;
|
||||||
Data ret = Data(mem->data, mem->length);
|
|
||||||
BIO_free(bio);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CryptoManager::verify_signature(Data data, Data signature, Data cert) {
|
bool OpenSSLCryptoManager::verify_signature(Data data, Data signature, Data cert) {
|
||||||
BIO* bio = BIO_new_mem_buf(cert.bytes(), cert.size());
|
BIO* bio = BIO_new_mem_buf(cert.bytes(), cert.size());
|
||||||
X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
@ -184,14 +176,14 @@ bool CryptoManager::verify_signature(Data data, Data signature, Data cert) {
|
||||||
return result > 0;
|
return result > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::sign_data(Data data, Data key) {
|
Data OpenSSLCryptoManager::sign_data(Data data, Data key) {
|
||||||
BIO* bio = BIO_new_mem_buf(key.bytes(), key.size());
|
BIO* bio = BIO_new_mem_buf(key.bytes(), key.size());
|
||||||
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||||
|
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
|
|
||||||
if (!pkey) {
|
if (!pkey) {
|
||||||
LOG("Unable to parse private key in memory!");
|
LOG("Unable to parse private key in memory...\n");
|
||||||
return Data();
|
return Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,8 +200,8 @@ Data CryptoManager::sign_data(Data data, Data key) {
|
||||||
|
|
||||||
if (result <= 0) {
|
if (result <= 0) {
|
||||||
free(signature);
|
free(signature);
|
||||||
LOG("Unable to sign data!");
|
LOG("Unable to sign data...\n");
|
||||||
exit(-1);
|
Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
Data signed_data = Data(signature, slen);
|
Data signed_data = Data(signature, slen);
|
||||||
|
@ -217,37 +209,27 @@ Data CryptoManager::sign_data(Data data, Data key) {
|
||||||
return signed_data;
|
return signed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::get_signature_from_cert(Data cert) {
|
// Cert and key generator
|
||||||
BIO* bio = BIO_new_mem_buf(cert.bytes(), cert.size());
|
|
||||||
X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
static Data _cert_data(X509* cert) {
|
||||||
|
BIO* bio = BIO_new(BIO_s_mem());
|
||||||
|
|
||||||
if (!x509) {
|
PEM_write_bio_X509(bio, cert);
|
||||||
LOG("Unable to parse certificate in memory!\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER < 0x10002000L)
|
BUF_MEM* mem;
|
||||||
ASN1_BIT_STRING *asn_signature = x509->signature;
|
BIO_get_mem_ptr(bio, &mem);
|
||||||
#elif (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
Data data = Data(mem->data, mem->length);
|
||||||
ASN1_BIT_STRING *asn_signature;
|
BIO_free(bio);
|
||||||
X509_get0_signature(&asn_signature, NULL, x509);
|
return data;
|
||||||
#else
|
|
||||||
const ASN1_BIT_STRING *asn_signature;
|
|
||||||
X509_get0_signature(&asn_signature, NULL, x509);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Data sig = Data(asn_signature->data, asn_signature->length);
|
|
||||||
X509_free(x509);
|
|
||||||
return sig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::get_key_from_cert_key_pair(PCERT_KEY_PAIR cert_key_pair) {
|
static Data _key_data(EVP_PKEY* pk) {
|
||||||
BIO* bio = BIO_new(BIO_s_mem());
|
BIO* bio = BIO_new(BIO_s_mem());
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||||
PEM_write_bio_PrivateKey(bio, cert_key_pair->pkey, NULL, NULL, 0, NULL, NULL);
|
PEM_write_bio_PrivateKey(bio, pk, NULL, NULL, 0, NULL, NULL);
|
||||||
#else
|
#else
|
||||||
PEM_write_bio_PrivateKey_traditional(bio, cert_key_pair->pkey, NULL, NULL, 0, NULL, NULL);
|
PEM_write_bio_PrivateKey_traditional(bio, pk, NULL, NULL, 0, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BUF_MEM* mem;
|
BUF_MEM* mem;
|
||||||
|
@ -257,26 +239,55 @@ Data CryptoManager::get_key_from_cert_key_pair(PCERT_KEY_PAIR cert_key_pair) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data CryptoManager::get_p12_from_cert_key_pair(PCERT_KEY_PAIR cert_key_pair) {
|
static bool _generate_new_cert_key_pair() {
|
||||||
BIO* bio = BIO_new(BIO_s_mem());
|
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
||||||
|
BIO *bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||||
|
|
||||||
i2d_PKCS12_bio(bio, cert_key_pair->p12);
|
X509* cert = X509_new();
|
||||||
|
EVP_PKEY* pk = EVP_PKEY_new();
|
||||||
|
BIGNUM* bne = BN_new();
|
||||||
|
RSA* rsa = RSA_new();
|
||||||
|
|
||||||
BUF_MEM* mem;
|
BN_set_word(bne, RSA_F4);
|
||||||
BIO_get_mem_ptr(bio, &mem);
|
RSA_generate_key_ex(rsa, NUM_BITS, bne, NULL);
|
||||||
Data data = Data(mem->data, mem->length);
|
|
||||||
BIO_free(bio);
|
EVP_PKEY_assign_RSA(pk, rsa);
|
||||||
return data;
|
|
||||||
}
|
X509_set_version(cert, 2);
|
||||||
|
ASN1_INTEGER_set(X509_get_serialNumber(cert), SERIAL);
|
||||||
Data CryptoManager::get_cert_from_cert_key_pair(PCERT_KEY_PAIR cert_key_pair) {
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
BIO* bio = BIO_new(BIO_s_mem());
|
X509_gmtime_adj(X509_get_notBefore(cert), 0);
|
||||||
|
X509_gmtime_adj(X509_get_notAfter(cert), 60 * 60 * 24 * 365 * NUM_YEARS);
|
||||||
PEM_write_bio_X509(bio, cert_key_pair->x509);
|
#else
|
||||||
|
ASN1_TIME* before = ASN1_STRING_dup(X509_get0_notBefore(cert));
|
||||||
BUF_MEM* mem;
|
ASN1_TIME* after = ASN1_STRING_dup(X509_get0_notAfter(cert));
|
||||||
BIO_get_mem_ptr(bio, &mem);
|
|
||||||
Data data = Data(mem->data, mem->length);
|
X509_gmtime_adj(before, 0);
|
||||||
BIO_free(bio);
|
X509_gmtime_adj(after, 60 * 60 * 24 * 365 * NUM_YEARS);
|
||||||
return data;
|
|
||||||
|
X509_set1_notBefore(cert, before);
|
||||||
|
X509_set1_notAfter(cert, after);
|
||||||
|
|
||||||
|
ASN1_STRING_free(before);
|
||||||
|
ASN1_STRING_free(after);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
X509_set_pubkey(cert, pk);
|
||||||
|
|
||||||
|
X509_NAME* name = X509_get_subject_name(cert);
|
||||||
|
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const unsigned char*)"NVIDIA GameStream Client", -1, -1, 0);
|
||||||
|
X509_set_issuer_name(cert, name);
|
||||||
|
|
||||||
|
X509_sign(cert, pk, EVP_sha256());
|
||||||
|
|
||||||
|
BN_free(bne);
|
||||||
|
|
||||||
|
BIO_free(bio_err);
|
||||||
|
|
||||||
|
m_cert = _cert_data(cert);
|
||||||
|
m_key = _key_data(pk);
|
||||||
|
|
||||||
|
X509_free(cert);
|
||||||
|
EVP_PKEY_free(pk);
|
||||||
|
return true;
|
||||||
}
|
}
|
28
src/crypto/OpenSSLCryptoManager.hpp
Normal file
28
src/crypto/OpenSSLCryptoManager.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "Data.hpp"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CERTIFICATE_FILE_NAME "client.pem"
|
||||||
|
#define KEY_FILE_NAME "key.pem"
|
||||||
|
|
||||||
|
class OpenSSLCryptoManager {
|
||||||
|
public:
|
||||||
|
static bool load_cert_key_pair();
|
||||||
|
static bool generate_new_cert_key_pair();
|
||||||
|
static void remove_cert_key_pair();
|
||||||
|
|
||||||
|
static Data cert_data();
|
||||||
|
static Data key_data();
|
||||||
|
|
||||||
|
static Data SHA1_hash_data(Data data);
|
||||||
|
static Data SHA256_hash_data(Data data);
|
||||||
|
static Data create_AES_key_from_salt_SHA1(Data salted_pin);
|
||||||
|
static Data create_AES_key_from_salt_SHA256(Data salted_pin);
|
||||||
|
static Data aes_encrypt(Data data, Data key);
|
||||||
|
static Data aes_decrypt(Data data, Data key);
|
||||||
|
|
||||||
|
static Data signature(Data cert);
|
||||||
|
static bool verify_signature(Data data, Data signature, Data cert);
|
||||||
|
static Data sign_data(Data data, Data key);
|
||||||
|
};
|
|
@ -5,8 +5,6 @@
|
||||||
#include "Limelight.h"
|
#include "Limelight.h"
|
||||||
#include "libretro.h"
|
#include "libretro.h"
|
||||||
#include "InputController.hpp"
|
#include "InputController.hpp"
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
@ -55,12 +53,11 @@ static int16_t glfw_input_state_cb(unsigned port, unsigned device, unsigned inde
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "CryptoManager.hpp"
|
||||||
|
|
||||||
int main(int argc, const char * argv[]) {
|
int main(int argc, const char * argv[]) {
|
||||||
input_state_cb = glfw_input_state_cb;
|
input_state_cb = glfw_input_state_cb;
|
||||||
|
|
||||||
OpenSSL_add_all_algorithms();
|
|
||||||
curl_global_init(CURL_GLOBAL_ALL);
|
|
||||||
|
|
||||||
glfwInit();
|
glfwInit();
|
||||||
|
|
||||||
glfwSetErrorCallback([](int i, const char *error) {
|
glfwSetErrorCallback([](int i, const char *error) {
|
||||||
|
@ -140,6 +137,12 @@ int main(int argc, const char * argv[]) {
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
extern void terminate_gamestream_thread();
|
||||||
|
terminate_gamestream_thread();
|
||||||
|
#endif
|
||||||
|
//nanogui::shutdown();
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,22 @@ uint16_t ntohs(uint16_t netshort) {
|
||||||
return __builtin_bswap16(netshort);
|
return __builtin_bswap16(netshort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uid_t getuid() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uid_t geteuid() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gid_t getgid(void) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gid_t getegid(void) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int sigaction(int a, const struct sigaction* b, struct sigaction* c) {
|
int sigaction(int a, const struct sigaction* b, struct sigaction* c) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue