diff options
-rw-r--r-- | include/signer/noscrypt_signer.hpp | 21 | ||||
-rw-r--r-- | src/signer/noscrypt_signer.cpp | 74 |
2 files changed, 94 insertions, 1 deletions
diff --git a/include/signer/noscrypt_signer.hpp b/include/signer/noscrypt_signer.hpp index d2135da..606438e 100644 --- a/include/signer/noscrypt_signer.hpp +++ b/include/signer/noscrypt_signer.hpp @@ -40,6 +40,9 @@ private: std::string _localPrivateKey; std::string _localPublicKey; + std::string _remotePublicKey; + std::string _bunkerSecret; + ///< A list of relays that will be used to connect to the remote signer. std::vector<std::string> _relays; @@ -58,6 +61,24 @@ private: */ std::tuple<std::string, std::string> _createLocalKeypair(); + /** + * @brief Parses the remote signer npub from a connection token provided by the signer. + * @param connectionToken A connection token beginning with `bunker://`. + * @returns The index of the first character of the connection token's query string, or -1 if + * no valid public key could be parsed. + * @remark This function updates the `_remotePublicKey` string in its class instance by side + * effect. + */ + int _parseRemotePublicKey(std::string connectionToken); + + /** + * @brief Parses a single query param from a connection token provided by a remote signer. + * @param param A single query param from the connection token of the form `key=value`. + * @remark This function updates the `_relays` vector and the `_bunkerSecret` string in its + * class instance by side effect. + */ + void _handleConnectionTokenParam(std::string param); + #pragma region Logging void _logNoscryptInitResult(NCResult initResult); diff --git a/src/signer/noscrypt_signer.cpp b/src/signer/noscrypt_signer.cpp index 2b00cca..d02aa93 100644 --- a/src/signer/noscrypt_signer.cpp +++ b/src/signer/noscrypt_signer.cpp @@ -32,7 +32,30 @@ NoscryptSigner::~NoscryptSigner() void NoscryptSigner::receiveConnection(string connectionToken) { - // Receive the connection token here. + if (connectionToken.empty()) + { + PLOG_ERROR << "No connection token was provided - unable to connect to a remote signer."; + return; + } + + int queryStart = this->_parseRemotePublicKey(connectionToken); + if (queryStart == -1) + { + return; + } + + string remainingToken = connectionToken.substr(queryStart); + int splitIndex = remainingToken.find('&'); + do + { + string param = remainingToken.substr(0, splitIndex); + this->_handleConnectionTokenParam(param); + + remainingToken = remainingToken.substr(splitIndex + 1); + splitIndex = remainingToken.find('&'); + } while (splitIndex != string::npos); + + // TODO: Handle any messaging with the remote signer. }; string NoscryptSigner::initiateConnection( @@ -73,6 +96,8 @@ string NoscryptSigner::initiateConnection( ss << "}"; return ss.str(); + + // TODO: Handle any messaging with the remote signer. }; void NoscryptSigner::sign(shared_ptr<data::Event> event) @@ -176,6 +201,53 @@ tuple<string, string> NoscryptSigner::_createLocalKeypair() return make_tuple(privateKey, publicKey); }; +int NoscryptSigner::_parseRemotePublicKey(string connectionToken) +{ + int queryStart = connectionToken.find('?'); + if (queryStart == string::npos) + { + PLOG_ERROR << "The connection token is invalid - no query string was found."; + return -1; + } + + const int pubkeyStart = 9; + string prefix = connectionToken.substr(0, pubkeyStart); + if (prefix != "bunker://") + { + PLOG_ERROR << "The connection token is invalid - the token must begin with 'bunker://'."; + return -1; + } + + string remotePubkey = connectionToken.substr(pubkeyStart, queryStart); + this->_remotePublicKey = remotePubkey; + + return queryStart + 1; +}; + +void NoscryptSigner::_handleConnectionTokenParam(string param) +{ + // Parse the query param into a key-value pair. + int splitIndex = param.find('='); + if (splitIndex == string::npos) + { + PLOG_ERROR << "The connection token query param is invalid - it is not of the form 'key=value'."; + return; + } + + string key = param.substr(0, splitIndex); + string value = param.substr(splitIndex + 1); + + // Handle the key-value pair. + if (key == "relay") + { + this->_relays.push_back(value); + } + else if (key == "secret") + { + this->_bunkerSecret = value; + } +}; + #pragma region Logging void NoscryptSigner::_logNoscryptInitResult(NCResult initResult) |