Merge remote-tracking branch 'origin/master'
This commit is contained in:
+117
@@ -66,6 +66,123 @@ namespace nvhttp {
|
||||
std::shared_ptr<rtsp_stream::launch_session_t>
|
||||
make_launch_session(bool host_audio, int appid, const args_t &args, const crypto::named_cert_t* named_cert_p);
|
||||
|
||||
/**
|
||||
* @brief Setup the nvhttp server.
|
||||
* @param pkey
|
||||
* @param cert
|
||||
*/
|
||||
void
|
||||
setup(const std::string &pkey, const std::string &cert);
|
||||
|
||||
class SunshineHTTPS: public SimpleWeb::HTTPS {
|
||||
public:
|
||||
SunshineHTTPS(boost::asio::io_context &io_context, boost::asio::ssl::context &ctx):
|
||||
SimpleWeb::HTTPS(io_context, ctx) {}
|
||||
|
||||
virtual ~SunshineHTTPS() {
|
||||
// Gracefully shutdown the TLS connection
|
||||
SimpleWeb::error_code ec;
|
||||
shutdown(ec);
|
||||
}
|
||||
};
|
||||
|
||||
enum class PAIR_PHASE {
|
||||
NONE, ///< Sunshine is not in a pairing phase
|
||||
GETSERVERCERT, ///< Sunshine is in the get server certificate phase
|
||||
CLIENTCHALLENGE, ///< Sunshine is in the client challenge phase
|
||||
SERVERCHALLENGERESP, ///< Sunshine is in the server challenge response phase
|
||||
CLIENTPAIRINGSECRET ///< Sunshine is in the client pairing secret phase
|
||||
};
|
||||
|
||||
struct pair_session_t {
|
||||
struct {
|
||||
std::string uniqueID = {};
|
||||
std::string cert = {};
|
||||
std::string name = {};
|
||||
} client;
|
||||
|
||||
std::unique_ptr<crypto::aes_t> cipher_key = {};
|
||||
std::vector<uint8_t> clienthash = {};
|
||||
|
||||
std::string serversecret = {};
|
||||
std::string serverchallenge = {};
|
||||
|
||||
struct {
|
||||
util::Either<
|
||||
std::shared_ptr<typename SimpleWeb::ServerBase<SimpleWeb::HTTP>::Response>,
|
||||
std::shared_ptr<typename SimpleWeb::ServerBase<SunshineHTTPS>::Response>>
|
||||
response;
|
||||
std::string salt = {};
|
||||
} async_insert_pin;
|
||||
|
||||
/**
|
||||
* @brief used as a security measure to prevent out of order calls
|
||||
*/
|
||||
PAIR_PHASE last_phase = PAIR_PHASE::NONE;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief removes the temporary pairing session
|
||||
* @param sess
|
||||
*/
|
||||
void
|
||||
remove_session(const pair_session_t &sess);
|
||||
|
||||
/**
|
||||
* @brief Pair, phase 1
|
||||
*
|
||||
* Moonlight will send a salt and client certificate, we'll also need the user provided pin.
|
||||
*
|
||||
* PIN and SALT will be used to derive a shared AES key that needs to be stored
|
||||
* in order to be used to decrypt_symmetric in the next phases.
|
||||
*
|
||||
* At this stage we only have to send back our public certificate.
|
||||
*/
|
||||
void
|
||||
getservercert(pair_session_t &sess, boost::property_tree::ptree &tree, const std::string &pin);
|
||||
|
||||
/**
|
||||
* @brief Pair, phase 2
|
||||
*
|
||||
* Using the AES key that we generated in phase 1 we have to decrypt the client challenge,
|
||||
*
|
||||
* We generate a SHA256 hash with the following:
|
||||
* - Decrypted challenge
|
||||
* - Server certificate signature
|
||||
* - Server secret: a randomly generated secret
|
||||
*
|
||||
* The hash + server_challenge will then be AES encrypted and sent as the `challengeresponse` in the returned XML
|
||||
*/
|
||||
void
|
||||
clientchallenge(pair_session_t &sess, boost::property_tree::ptree &tree, const std::string &challenge);
|
||||
|
||||
/**
|
||||
* @brief Pair, phase 3
|
||||
*
|
||||
* Moonlight will send back a `serverchallengeresp`: an AES encrypted client hash,
|
||||
* we have to send back the `pairingsecret`:
|
||||
* using our private key we have to sign the certificate_signature + server_secret (generated in phase 2)
|
||||
*/
|
||||
void
|
||||
serverchallengeresp(pair_session_t &sess, boost::property_tree::ptree &tree, const std::string &encrypted_response);
|
||||
|
||||
/**
|
||||
* @brief Pair, phase 4 (final)
|
||||
*
|
||||
* We now have to use everything we exchanged before in order to verify and finally pair the clients
|
||||
*
|
||||
* We'll check the client_hash obtained at phase 3, it should contain the following:
|
||||
* - The original server_challenge
|
||||
* - The signature of the X509 client_cert
|
||||
* - The unencrypted client_pairing_secret
|
||||
* We'll check that SHA256(server_challenge + client_public_cert_signature + client_secret) == client_hash
|
||||
*
|
||||
* Then using the client certificate public key we should be able to verify that
|
||||
* the client secret has been signed by Moonlight
|
||||
*/
|
||||
void
|
||||
clientpairingsecret(pair_session_t &sess, std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, boost::property_tree::ptree &tree, const std::string &client_pairing_secret);
|
||||
|
||||
/**
|
||||
* @brief Compare the user supplied pin to the Moonlight pin.
|
||||
* @param pin The user supplied pin.
|
||||
|
||||
Reference in New Issue
Block a user