From 0249ce70438c0c3c9ef3122d752958f8d942de55 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 28 Apr 2018 23:29:45 -0700 Subject: [PATCH] working identity --- identitymanager.cpp | 42 ++++++++++++++++++++++++++++++++++++------ nvhttp.cpp | 15 ++++++++++++--- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/identitymanager.cpp b/identitymanager.cpp index 1779fb8a..bd8220dd 100644 --- a/identitymanager.cpp +++ b/identitymanager.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include @@ -40,10 +42,19 @@ IdentityManager::IdentityManager(QDir directory) m_CachedPemCert = certificateFile.readAll(); m_CachedPrivateKey = privateKeyFile.readAll(); - qDebug() << "Loaded cached identity credentials from disk"; - return; + // Make sure it really loads + if (!QSslKey(m_CachedPrivateKey, QSsl::Rsa).isNull() && !QSslCertificate(m_CachedPemCert).isNull()) + { + qDebug() << "Loaded cached identity key pair from disk"; + return; + } + + qDebug() << "Regenerating corrupted local key pair"; } + privateKeyFile.close(); + certificateFile.close(); + X509* cert = X509_new(); THROW_BAD_ALLOC_IF_NULL(cert); @@ -62,6 +73,7 @@ IdentityManager::IdentityManager(QDir directory) EVP_PKEY_assign_RSA(pk, rsa); X509_set_version(cert, 2); + ASN1_INTEGER_set(X509_get_serialNumber(cert), 0); X509_gmtime_adj(X509_get_notBefore(cert), 0); X509_gmtime_adj(X509_get_notAfter(cert), 60 * 60 * 24 * 365 * 20); // 20 yrs X509_set_pubkey(cert, pk); @@ -70,15 +82,33 @@ IdentityManager::IdentityManager(QDir directory) X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast(const_cast("NVIDIA GameStream Client")), -1, -1, 0); X509_set_issuer_name(cert, name); - privateKeyFile.open(QIODevice::ReadWrite); - PEM_write_PrivateKey(fdopen(privateKeyFile.handle(), "w"), pk, nullptr, nullptr, 0, nullptr, nullptr); + X509_sign(cert, pk, EVP_sha1()); - certificateFile.open(QIODevice::ReadWrite); - PEM_write_X509(fdopen(certificateFile.handle(), "w"), cert); + BIO* biokey = BIO_new(BIO_s_mem()); + THROW_BAD_ALLOC_IF_NULL(biokey); + PEM_write_bio_PrivateKey(biokey, pk, NULL, NULL, 0, NULL, NULL); + + BIO* biocert = BIO_new(BIO_s_mem()); + THROW_BAD_ALLOC_IF_NULL(biocert); + PEM_write_bio_X509(biocert, cert); + + privateKeyFile.open(QIODevice::WriteOnly); + certificateFile.open(QIODevice::WriteOnly); + + BUF_MEM* mem; + BIO_get_mem_ptr(biokey, &mem); + m_CachedPrivateKey = QByteArray(mem->data, mem->length); + QTextStream(&privateKeyFile) << m_CachedPrivateKey; + + BIO_get_mem_ptr(biocert, &mem); + m_CachedPemCert = QByteArray(mem->data, mem->length); + QTextStream(&certificateFile) << m_CachedPemCert; X509_free(cert); EVP_PKEY_free(pk); BN_free(bne); + BIO_free(biokey); + BIO_free(biocert); qDebug() << "Wrote new identity credentials to disk"; } diff --git a/nvhttp.cpp b/nvhttp.cpp index 025fd306..34d43610 100644 --- a/nvhttp.cpp +++ b/nvhttp.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #define REQUEST_TIMEOUT_MS 5000 @@ -112,7 +113,7 @@ NvHTTP::getServerInfo() if (e.getStatusCode() == 401) { // Certificate validation error, fallback to HTTP - serverInfo = openConnectionToString(m_BaseUrlHttps, + serverInfo = openConnectionToString(m_BaseUrlHttp, "serverinfo", nullptr, true); @@ -198,10 +199,18 @@ NvHTTP::openConnection(QUrl baseUrl, "&uuid=" + QUuid::createUuid().toRfc4122().toHex() + ((arguments != nullptr) ? ("&" + arguments) : "")); - QNetworkReply* reply = m_Nam.get(QNetworkRequest(url)); + QNetworkRequest request = QNetworkRequest(url); + + // Add our client certificate + QSslConfiguration sslConfig(QSslConfiguration::defaultConfiguration()); + sslConfig.setLocalCertificate(QSslCertificate(m_Im.getCertificate())); + sslConfig.setPrivateKey(QSslKey(m_Im.getPrivateKey(), QSsl::Rsa)); + request.setSslConfiguration(sslConfig); + + QNetworkReply* reply = m_Nam.get(request); // Ignore self-signed certificate errors (since GFE uses them) - reply->ignoreSslErrors(QList{ QSslError::SelfSignedCertificate }); + reply->ignoreSslErrors(); // Run the request with a timeout if requested QEventLoop loop;