mirror of
https://github.com/LizardByte/Sunshine.git
synced 2024-12-29 12:16:08 +00:00
Generate Private Key and Certificate if none exist
This commit is contained in:
parent
1b49a9661e
commit
f06f5dde2f
@ -1,22 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDsTCCApmgAwIBAgIULnRRHDUzdg4a9dwWi0/yV5LADLIwDQYJKoZIhvcNAQEL
|
||||
BQAwaDELMAkGA1UEBhMCTkwxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEhMB8GCSqGSIb3DQEJARYSbG9raUBm
|
||||
YWtlZW1haWwuY29tMB4XDTE5MDYwMzEwMzY0N1oXDTI5MDUzMTEwMzY0N1owaDEL
|
||||
MAkGA1UEBhMCTkwxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVy
|
||||
bmV0IFdpZGdpdHMgUHR5IEx0ZDEhMB8GCSqGSIb3DQEJARYSbG9raUBmYWtlZW1h
|
||||
aWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4cyNQ7uH6tAE
|
||||
EAD99oxR1CVYlOgRDEUqJCjkpIoVF5uE3/kfuvEJ+l7/WL51lqbq35uL5ta7EbJH
|
||||
BvVyNH00FN2D/Yl0n/X+TlhRP88MS5F0d0rwyQEAh4wEGcUhdSoW9TfybmLaHeCC
|
||||
bZlxC3kBWxr0e6YDlV9deM6j+OjCerQwkiiGwgE9dVrVCj1dLyzBhWnYGpYBvY+3
|
||||
6kEy0Vmf2spGCB6meCAMrAMz75fUDuk8YRF0umb+SLA44AB/U6d6GXU2EjpTuPww
|
||||
OMkUr8EmdbAI3l1tmWJTAkhFQ7681AyIWYOspc1biXZdBrvNBTV8kbDGlomNj19V
|
||||
QhhN44d4ywIDAQABo1MwUTAdBgNVHQ4EFgQUFRktN33zyW4MR9Cy1Vcn+B+EdYAw
|
||||
HwYDVR0jBBgwFoAUFRktN33zyW4MR9Cy1Vcn+B+EdYAwDwYDVR0TAQH/BAUwAwEB
|
||||
/zANBgkqhkiG9w0BAQsFAAOCAQEAkpU+ALElNz+5jOnVAPyYXYsJKfevmKK9uK4v
|
||||
V+l7GrFLIEhC2qr26S8Nd2pLkrgesCD4xfoOONiVOceU5igh9acFA3+NyOSFLdRN
|
||||
bSdy0jvCuoiK46ieDAagQtdt0G7HGV4u+jWz0jaKUQI9zJqznOHdJV6RZFIqTYLG
|
||||
KHnGP+mtXjW3E1djU9vFreYcB6UY+Ai1KB33dnBK9Es2fIQhikKZUPTh6BYsRZT6
|
||||
U7c6fh+01fRhRPo/SCFmY993857NtoOHMeP0M2V65CG4VjpAPR0msChVQVv7csca
|
||||
TvBvB23dFRTLbo5PUSWC9bhBrMjzJ7yylt1CNBBHv7ycw8yIPw==
|
||||
-----END CERTIFICATE-----
|
@ -1,28 +0,0 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDhzI1Du4fq0AQQ
|
||||
AP32jFHUJViU6BEMRSokKOSkihUXm4Tf+R+68Qn6Xv9YvnWWpurfm4vm1rsRskcG
|
||||
9XI0fTQU3YP9iXSf9f5OWFE/zwxLkXR3SvDJAQCHjAQZxSF1Khb1N/JuYtod4IJt
|
||||
mXELeQFbGvR7pgOVX114zqP46MJ6tDCSKIbCAT11WtUKPV0vLMGFadgalgG9j7fq
|
||||
QTLRWZ/aykYIHqZ4IAysAzPvl9QO6TxhEXS6Zv5IsDjgAH9Tp3oZdTYSOlO4/DA4
|
||||
yRSvwSZ1sAjeXW2ZYlMCSEVDvrzUDIhZg6ylzVuJdl0Gu80FNXyRsMaWiY2PX1VC
|
||||
GE3jh3jLAgMBAAECggEAdnHgoGkc8RXRK7v5fH0653f3sZTSbIdThchVt+IfElUo
|
||||
LHz4Ig4S191BQQIXmMFSb52ek6aMVsoX7BSQpewPh+pzNGoIXWiiz+IQLNKldnaE
|
||||
i5cqG6aE6pWOCR6ZYGaFyHhimXkNRaLhiDB3VjdReML5AGujcZWm6Jos9YLTkZ07
|
||||
pYXs2S+/5oNbfDdAE8dgdD7vD9lNGrbtmJ9+J+VvgPOYM/4LaEAfZU0ALDm2Hl3n
|
||||
CqkZCp+eWbQK3MC2+6Y4yS+jo7e5/nKX1De9StkX6KumAEIpxkHPZF2EnWXW64oD
|
||||
k40tKXT+oMXF1RLb4scnv+J+uR4bdl+Xq/VTzKrtsQKBgQDyoOjrv+g5l0s0KKDJ
|
||||
qPkLQNRCJpzU7Km3CjPuk8DOlmBCr4KUeVfjbYPxQQMkeNL9zFz/QYBmabTCE6Ih
|
||||
E8BbzT/RQzVPSOOh//Hh4eN4umrYaOIkY4Bv2R2X3H0ELFq+G7pKdvTAkusGHcWu
|
||||
OAUb2HO5rTiRYq8DvHy8b+qH7wKBgQDuPjR+DCVtkBXmBNf0FZkl7OW/EUQBq4+T
|
||||
WoaYleq8Gd7ubJgz2Gud+0+L41VjFD9W3hkJAb/3wkASseQ+2hk3Sv/BzpAIdS9e
|
||||
tN/xxp/8NK7tJGL63m6tAfX+Hi/kSDEp45Zp3PoOD08MEK0yIrpf7S8uJ++u49K4
|
||||
tKXkGCIg5QKBgFujvPW2AQ8nfqcPpVMleBLxBHqLvPaLALr6poy4z7z3fRoS0j4j
|
||||
6rcimRAZHwe6fu6PLpzWb5m+2R/obHcTz7acujreqJbuj9OTKRfIyrLBrjNYwfk+
|
||||
f7c/CPdftvRJkGh3bpBLh7vogc5Ilm5sCDnxMhxyOYhn/nRpz68YkjuPAoGBAOQX
|
||||
6DfZtyfLcDvV3U/SMdsOkPO6OwsCTya73+tMdP18I2TP0XSpunb5ebIrh7+hTfcE
|
||||
EqH96+XwM1nyuNy4ALZgdrb95gZC84RP1axsBxX29pcSZDVdKkc3fmW6Tw3XVEKP
|
||||
o51dNIarf3nEqZ07hIZ81dPx5lbhxgiS49SaimpFAoGBAKamKZFAfUHlaHV/Na1C
|
||||
3SZji7PaDSj1EFmRkCySK9VqD7Tbh1abrpC2ImdhYHn5TcQQE2eidB+F0Nf6IhKN
|
||||
upBTofg0ebaslo+BYAqAsRKnUQGDToGIIIdXJ6DnO3wxWu9GY4nKdl3jxqAv2A2x
|
||||
d8SETw4wqlFFRO33opycuFS5
|
||||
-----END PRIVATE KEY-----
|
@ -8,9 +8,9 @@
|
||||
#include "utility.h"
|
||||
#include "config.h"
|
||||
|
||||
#define CA_DIR SUNSHINE_ASSETS_DIR "/demoCA"
|
||||
#define PRIVATE_KEY_FILE CA_DIR "/cakey.pem"
|
||||
#define CERTIFICATE_FILE CA_DIR "/cacert.pem"
|
||||
#define CA_DIR "credentials"
|
||||
#define PRIVATE_KEY_FILE CA_DIR "/cakey.pem"
|
||||
#define CERTIFICATE_FILE CA_DIR "/cacert.pem"
|
||||
|
||||
#define APPS_JSON_PATH SUNSHINE_ASSETS_DIR "/" APPS_JSON
|
||||
namespace config {
|
||||
|
@ -5,6 +5,10 @@
|
||||
#include <openssl/pem.h>
|
||||
#include "crypto.h"
|
||||
namespace crypto {
|
||||
using big_num_t = util::safe_ptr<BIGNUM, BN_free>;
|
||||
//using rsa_t = util::safe_ptr<RSA, RSA_free>;
|
||||
using asn1_string_t = util::safe_ptr<ASN1_STRING, ASN1_STRING_free>;
|
||||
|
||||
cert_chain_t::cert_chain_t() : _certs {}, _cert_ctx {X509_STORE_CTX_new() } {}
|
||||
void cert_chain_t::add(x509_t &&cert) {
|
||||
x509_store_t x509_store { X509_STORE_new() };
|
||||
@ -200,6 +204,25 @@ pkey_t pkey(const std::string_view &k) {
|
||||
return pkey_t { p };
|
||||
}
|
||||
|
||||
std::string pem(x509_t &x509) {
|
||||
bio_t bio { BIO_new(BIO_s_mem()) };
|
||||
|
||||
PEM_write_bio_X509(bio.get(), x509.get());
|
||||
BUF_MEM *mem_ptr;
|
||||
BIO_get_mem_ptr(bio.get(), &mem_ptr);
|
||||
|
||||
return { mem_ptr->data, mem_ptr->length };
|
||||
}
|
||||
|
||||
std::string pem(pkey_t &pkey) {
|
||||
bio_t bio { BIO_new(BIO_s_mem()) };
|
||||
|
||||
PEM_write_bio_PrivateKey(bio.get(), pkey.get(), nullptr, nullptr, 0, nullptr, nullptr);
|
||||
BUF_MEM *mem_ptr;
|
||||
BIO_get_mem_ptr(bio.get(), &mem_ptr);
|
||||
|
||||
return { mem_ptr->data, mem_ptr->length };
|
||||
}
|
||||
|
||||
std::string_view signature(const x509_t &x) {
|
||||
// X509_ALGOR *_ = nullptr;
|
||||
@ -242,6 +265,48 @@ std::vector<uint8_t> sign(const pkey_t &pkey, const std::string_view &data, cons
|
||||
return digest;
|
||||
}
|
||||
|
||||
creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits) {
|
||||
x509_t x509 { X509_new() };
|
||||
pkey_t pkey { EVP_PKEY_new() };
|
||||
|
||||
big_num_t big_num { BN_new() };
|
||||
BN_set_word(big_num.get(), RSA_F4);
|
||||
|
||||
auto rsa = RSA_new();
|
||||
RSA_generate_key_ex(rsa, key_bits, big_num.get(), nullptr);
|
||||
EVP_PKEY_assign_RSA(pkey.get(), rsa);
|
||||
|
||||
X509_set_version(x509.get(), 2);
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), 0);
|
||||
|
||||
constexpr auto year = 60 * 60 * 24 * 365;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
X509_gmtime_adj(X509_get_notBefore(x509.get()), 0);
|
||||
X509_gmtime_adj(X509_get_notAfter(x509.get()), 20 * year);
|
||||
#else
|
||||
asn1_string_t not_before { ASN1_STRING_dup(X509_get0_notBefore(x509.get())) };
|
||||
asn1_string_t not_after { ASN1_STRING_dup(X509_get0_notAfter(x509.get())) };
|
||||
|
||||
X509_gmtime_adj(not_before.get(), 0);
|
||||
X509_gmtime_adj(not_after.get(), 20 * year);
|
||||
|
||||
X509_set1_notBefore(x509.get(), not_before.get());
|
||||
X509_set1_notAfter(x509.get(), not_after.get());
|
||||
#endif
|
||||
|
||||
X509_set_pubkey(x509.get(), pkey.get());
|
||||
|
||||
auto name = X509_get_subject_name(x509.get());
|
||||
X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC,
|
||||
(const std::uint8_t*)cn.data(), cn.size(),
|
||||
-1, 0);
|
||||
|
||||
X509_set_issuer_name(x509.get(), name);
|
||||
X509_sign(x509.get(), pkey.get(), EVP_sha256());
|
||||
|
||||
return { pem(x509), pem(pkey) };
|
||||
}
|
||||
|
||||
std::vector<uint8_t> sign256(const pkey_t &pkey, const std::string_view &data) {
|
||||
return sign(pkey, data, EVP_sha256());
|
||||
}
|
||||
|
@ -15,6 +15,10 @@
|
||||
#include "utility.h"
|
||||
|
||||
namespace crypto {
|
||||
struct creds_t {
|
||||
std::string x509;
|
||||
std::string pkey;
|
||||
};
|
||||
constexpr std::size_t digest_size = 256;
|
||||
|
||||
void md_ctx_destroy(EVP_MD_CTX *);
|
||||
@ -35,10 +39,13 @@ aes_t gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &p
|
||||
|
||||
x509_t x509(const std::string_view &x);
|
||||
pkey_t pkey(const std::string_view &k);
|
||||
std::string pem(x509_t &x509);
|
||||
std::string pem(pkey_t &pkey);
|
||||
|
||||
std::vector<uint8_t> sign256(const pkey_t &pkey, const std::string_view &data);
|
||||
bool verify256(const x509_t &x509, const std::string_view &data, const std::string_view &signature);
|
||||
|
||||
creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits);
|
||||
|
||||
std::string_view signature(const x509_t &x);
|
||||
|
||||
|
@ -38,6 +38,7 @@ namespace fs = std::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
std::string read_file(const char *path);
|
||||
int write_file(const char *path, const std::string_view &contents);
|
||||
|
||||
using https_server_t = SimpleWeb::Server<SimpleWeb::HTTPS>;
|
||||
using http_server_t = SimpleWeb::Server<SimpleWeb::HTTP>;
|
||||
@ -652,7 +653,69 @@ void appasset(resp_https_t response, req_https_t request) {
|
||||
response->write(SimpleWeb::StatusCode::success_ok, in);
|
||||
}
|
||||
|
||||
int create_creds(const std::string &pkey, const std::string &cert) {
|
||||
fs::path pkey_path = pkey;
|
||||
fs::path cert_path = cert;
|
||||
|
||||
auto creds = crypto::gen_creds("Sunshine Gamestream Host"sv, 2048);
|
||||
|
||||
auto pkey_dir = pkey_path;
|
||||
auto cert_dir = cert_path;
|
||||
pkey_dir.remove_filename();
|
||||
cert_dir.remove_filename();
|
||||
|
||||
std::error_code err_code{};
|
||||
fs::create_directories(pkey_dir, err_code);
|
||||
if (err_code) {
|
||||
BOOST_LOG(fatal) << "Couldn't create directory ["sv << pkey_dir << "] :"sv << err_code.message();
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs::create_directories(cert_dir, err_code);
|
||||
if (err_code) {
|
||||
BOOST_LOG(fatal) << "Couldn't create directory ["sv << cert_dir << "] :"sv << err_code.message();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write_file(pkey.c_str(), creds.pkey)) {
|
||||
BOOST_LOG(fatal) << "Couldn't open ["sv << config::nvhttp.pkey << ']';
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write_file(cert.c_str(), creds.x509)) {
|
||||
BOOST_LOG(fatal) << "Couldn't open ["sv << config::nvhttp.cert << ']';
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs::permissions(pkey_path,
|
||||
fs::perms::owner_read | fs::perms::owner_write,
|
||||
fs::perm_options::replace, err_code);
|
||||
|
||||
if (err_code) {
|
||||
BOOST_LOG(fatal) << "Couldn't change permissions of ["sv << config::nvhttp.pkey << "] :"sv << err_code.message();
|
||||
return -1;
|
||||
}
|
||||
|
||||
fs::permissions(cert_path,
|
||||
fs::perms::owner_read | fs::perms::group_read | fs::perms::others_read | fs::perms::owner_write,
|
||||
fs::perm_options::replace, err_code);
|
||||
|
||||
if (err_code) {
|
||||
BOOST_LOG(fatal) << "Couldn't change permissions of ["sv << config::nvhttp.cert << "] :"sv << err_code.message();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void start(std::shared_ptr<safe::event_t<bool>> shutdown_event) {
|
||||
if(!fs::exists(config::nvhttp.pkey) || !fs::exists(config::nvhttp.cert)) {
|
||||
if(create_creds(config::nvhttp.pkey, config::nvhttp.cert)) {
|
||||
shutdown_event->raise(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
origin_pin_allowed = net::from_enum_string(config::nvhttp.origin_pin_allowed);
|
||||
load_state();
|
||||
|
||||
@ -748,6 +811,18 @@ void start(std::shared_ptr<safe::event_t<bool>> shutdown_event) {
|
||||
tcp.join();
|
||||
}
|
||||
|
||||
int write_file(const char *path, const std::string_view &contents) {
|
||||
std::ofstream out(path);
|
||||
|
||||
if(!out.is_open()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
out << contents;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string read_file(const char *path) {
|
||||
std::ifstream in(path);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user