Sunshine master
Self-hosted game stream host for Moonlight.
crypto.h
Go to the documentation of this file.
1
5#pragma once
6
7// standard includes
8#include <array>
9
10// lib includes
11#include <openssl/evp.h>
12#include <openssl/rand.h>
13#include <openssl/sha.h>
14#include <openssl/x509.h>
15
16// local includes
17#include "utility.h"
18
19namespace crypto {
23 struct creds_t {
24 std::string x509;
25 std::string pkey;
26 };
27
33 void md_ctx_destroy(EVP_MD_CTX *ctx);
34
38 using sha256_t = std::array<std::uint8_t, SHA256_DIGEST_LENGTH>;
39
43 using aes_t = std::vector<std::uint8_t>;
80
86 sha256_t hash(const std::string_view &plaintext);
87
95 aes_t gen_aes_key(const std::array<uint8_t, 16> &salt, const std::string_view &pin);
102 x509_t x509(const std::string_view &x);
109 pkey_t pkey(const std::string_view &k);
116 std::string pem(x509_t &x509);
123 std::string pem(pkey_t &pkey);
124
132 std::vector<uint8_t> sign256(const pkey_t &pkey, const std::string_view &data);
141 bool verify256(const x509_t &x509, const std::string_view &data, const std::string_view &signature);
142
150 creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits);
151
158 std::string_view signature(const x509_t &x);
159
166 std::string rand(std::size_t bytes);
174 std::string rand_alphabet(std::size_t bytes, const std::string_view &alphabet = std::string_view {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!%&()=-"});
175
180 public:
182
183
188 void add(x509_t &&cert);
189
193 void clear();
194
195 const char *verify(x509_t::element_type *cert);
196
197 private:
198 std::vector<std::pair<x509_t, x509_store_t>> _certs;
199 x509_store_ctx_t _cert_ctx;
200 };
201
202 namespace cipher {
203 constexpr std::size_t tag_size = 16;
204
211 constexpr std::size_t round_to_pkcs7_padded(std::size_t size) {
212 return ((size + 15) / 16) * 16;
213 }
214
227
231 class ecb_t: public cipher_t {
232 public:
233 ecb_t() = default;
237 ecb_t(ecb_t &&) noexcept = default;
243 ecb_t &operator=(ecb_t &&) noexcept = default;
244
251 ecb_t(const aes_t &key, bool padding = true);
252
260 int encrypt(const std::string_view &plaintext, std::vector<std::uint8_t> &cipher);
268 int decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext);
269 };
270
274 class gcm_t: public cipher_t {
275 public:
276 gcm_t() = default;
280 gcm_t(gcm_t &&) noexcept = default;
286 gcm_t &operator=(gcm_t &&) noexcept = default;
287
294 gcm_t(const crypto::aes_t &key, bool padding = true);
295
304 int encrypt(const std::string_view &plaintext, std::uint8_t *tag, std::uint8_t *ciphertext, aes_t *iv);
305
314 int encrypt(const std::string_view &plaintext, std::uint8_t *tagged_cipher, aes_t *iv);
315
324 int decrypt(const std::string_view &cipher, std::vector<std::uint8_t> &plaintext, aes_t *iv);
325 };
326
330 class cbc_t: public cipher_t {
331 public:
332 cbc_t() = default;
336 cbc_t(cbc_t &&) noexcept = default;
342 cbc_t &operator=(cbc_t &&) noexcept = default;
343
350 cbc_t(const crypto::aes_t &key, bool padding = true);
351
360 int encrypt(const std::string_view &plaintext, std::uint8_t *cipher, aes_t *iv);
361 };
362 } // namespace cipher
363} // namespace crypto
Owns the certificate chain returned by Sunshine's TLS certificate loader.
Definition crypto.h:179
void add(x509_t &&cert)
Add a certificate to the verification chain.
Definition crypto.cpp:27
const char * verify(x509_t::element_type *cert)
Verify the certificate chain. When certificates from two or more instances of Moonlight have been add...
Definition crypto.cpp:64
void clear()
Remove all certificates from the verification chain.
Definition crypto.cpp:34
AES-CBC cipher helper used for block-mode encryption and decryption.
Definition crypto.h:330
cbc_t(cbc_t &&) noexcept=default
Construct an AES-CBC cipher helper with key material and IV state.
AES-GCM encrypt/decrypt context pair used for GameStream messages.
Definition crypto.h:218
cipher_ctx_t decrypt_ctx
Decrypt ctx.
Definition crypto.h:220
bool padding
Enables block padding for the cipher.
Definition crypto.h:225
aes_t key
AES key used by the cipher context.
Definition crypto.h:223
cipher_ctx_t encrypt_ctx
Encrypt ctx.
Definition crypto.h:221
AES-ECB cipher helper used by pairing and stream encryption code.
Definition crypto.h:231
int decrypt(const std::string_view &cipher, std::vector< std::uint8_t > &plaintext)
Decrypt ciphertext into the supplied plaintext buffer.
Definition crypto.cpp:229
ecb_t(ecb_t &&) noexcept=default
Construct an AES-ECB cipher helper with key material.
int encrypt(const std::string_view &plaintext, std::vector< std::uint8_t > &cipher)
Encrypt plaintext into the supplied ciphertext buffer.
Definition crypto.cpp:257
AES-GCM cipher helper that encrypts and authenticates payloads.
Definition crypto.h:274
gcm_t(gcm_t &&) noexcept=default
Construct an AES-GCM cipher helper with key material and IV state.
Unique pointer wrapper with customizable pointer and deleter types.
Definition utility.h:820
T element_type
Object type managed by the unique pointer wrapper.
Definition utility.h:825
std::string_view signature(const x509_t &x)
Return the certificate signature bytes.
Definition crypto.cpp:413
aes_t gen_aes_key(const std::array< uint8_t, 16 > &salt, const std::string_view &pin)
Derive the AES key used by the pairing protocol.
Definition crypto.cpp:334
std::string rand(std::size_t bytes)
Generate cryptographically secure random bytes.
Definition crypto.cpp:428
void md_ctx_destroy(EVP_MD_CTX *ctx)
Destroy an OpenSSL message digest context.
Definition crypto.cpp:562
bool verify256(const x509_t &x509, const std::string_view &data, const std::string_view &signature)
Verify a SHA-256 signature with the certificate public key.
Definition crypto.cpp:555
x509_t x509(const std::string_view &x)
Parse PEM text into an X.509 certificate object.
Definition crypto.cpp:359
std::string rand_alphabet(std::size_t bytes, const std::string_view &alphabet)
Generate random text from the supplied alphabet.
Definition crypto.cpp:569
sha256_t hash(const std::string_view &plaintext)
Hashes the given plaintext using SHA-256.
Definition crypto.cpp:350
pkey_t pkey(const std::string_view &k)
Parse PEM text into an OpenSSL private key object.
Definition crypto.cpp:373
std::vector< uint8_t > sign256(const pkey_t &pkey, const std::string_view &data)
Sign data with SHA-256.
Definition crypto.cpp:519
std::string pem(x509_t &x509)
Serialize an OpenSSL object to PEM text.
Definition crypto.cpp:387
creds_t gen_creds(const std::string_view &cn, std::uint32_t key_bits)
Generate a self-signed certificate and private key for Sunshine pairing.
Definition crypto.cpp:472
std::vector< std::uint8_t > aes_t
Byte buffer containing AES key material.
Definition crypto.h:43
std::array< std::uint8_t, SHA256_DIGEST_LENGTH > sha256_t
Fixed-size SHA-256 digest byte array.
Definition crypto.h:38
constexpr std::size_t round_to_pkcs7_padded(std::size_t size)
Round a byte count up to the next PKCS#7 padding boundary.
Definition crypto.h:211
constexpr std::size_t tag_size
Tag size.
Definition crypto.h:203
PEM-encoded certificate and private key pair.
Definition crypto.h:23
std::string x509
PEM-encoded X.509 certificate.
Definition crypto.h:24
std::string pkey
Private key PEM string or path.
Definition crypto.h:25
Declarations for utility functions.
#define KITTY_DECL_CONSTR(x)
Declare the standard move operations and out-of-line default constructor for a type.
Definition utility.h:108