mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Added user challenge generation and verification.
This commit is contained in:
@@ -20,7 +20,7 @@ void sign(const unsigned char *msg, unsigned long long msg_len, unsigned char *s
|
||||
crypto_sign_detached(sig, NULL, msg, msg_len, conf::cfg.seckey);
|
||||
}
|
||||
|
||||
string sign_b64(string msg)
|
||||
string sign_b64(string &msg)
|
||||
{
|
||||
unsigned char sig[crypto_sign_BYTES];
|
||||
crypto_sign_detached(sig, NULL, (unsigned char *)msg.data(), msg.size() + 1, conf::cfg.seckey);
|
||||
@@ -33,7 +33,7 @@ bool verify(const unsigned char *msg, unsigned long long msg_len, const unsigned
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
bool verify_b64(string msg, string sigb64, string pubkeyb64)
|
||||
bool verify_b64(string &msg, string &sigb64, string &pubkeyb64)
|
||||
{
|
||||
unsigned char decoded_pubkey[crypto_sign_PUBLICKEYBYTES];
|
||||
shared::base64_decode(pubkeyb64, decoded_pubkey, crypto_sign_PUBLICKEYBYTES);
|
||||
|
||||
@@ -16,7 +16,7 @@ void sign(const unsigned char *msg, unsigned long long msg_len, unsigned char *s
|
||||
/**
|
||||
* Returns the base64 signature for the given message using the contract's secret key.
|
||||
*/
|
||||
string sign_b64(string msg);
|
||||
string sign_b64(string &msg);
|
||||
|
||||
/**
|
||||
* Verifies the given signature with the message using the provided public key.
|
||||
@@ -26,7 +26,7 @@ bool verify(const unsigned char *msg, unsigned long long msg_len, const unsigned
|
||||
/**
|
||||
* Verifies the given base64 signature with the message using the provided base64 public key.
|
||||
*/
|
||||
bool verify_b64(string msg, string sigb64, string pubkeyb64);
|
||||
bool verify_b64(string &msg, string &sigb64, string &pubkeyb64);
|
||||
|
||||
} // namespace crypto
|
||||
|
||||
|
||||
11
src/main.cpp
11
src/main.cpp
@@ -35,16 +35,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (conf::ctx.command == "run")
|
||||
{
|
||||
//TODO
|
||||
|
||||
usr::add_user("pku1");
|
||||
usr::add_user("pku2");
|
||||
usr::add_user("pku3");
|
||||
|
||||
proc::ContractExecArgs ctargs;
|
||||
ctargs.users = &usr::users;
|
||||
|
||||
proc::exec_contract(ctargs);
|
||||
usr::init();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <rapidjson/document.h>
|
||||
#include "rapidjson/stringbuffer.h"
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include "proc.h"
|
||||
#include "conf.h"
|
||||
@@ -65,7 +65,7 @@ int exec_contract(ContractExecArgs &args)
|
||||
* "version":"0.1",
|
||||
* "usrfd":{ "pk1":[fd0, fd1], "pk2":[fd0, fd1] }
|
||||
* }
|
||||
*/
|
||||
*/
|
||||
void write_to_stdin(ContractExecArgs &args)
|
||||
{
|
||||
Document d;
|
||||
@@ -74,7 +74,7 @@ void write_to_stdin(ContractExecArgs &args)
|
||||
d.AddMember("version", StringRef(_HP_VERSION_), allocator);
|
||||
|
||||
Value users(kObjectType);
|
||||
for (auto& [pk, user] : (*args.users))
|
||||
for (auto &[pk, user] : (*args.users))
|
||||
{
|
||||
Value fdlist(kArrayType);
|
||||
fdlist.PushBack(user.inpipe[0], allocator);
|
||||
@@ -104,9 +104,9 @@ bool is_contract_running()
|
||||
int status = 0;
|
||||
if (!waitpid(contract_pid, &status, WNOHANG))
|
||||
return true;
|
||||
contract_pid = 0;
|
||||
}
|
||||
|
||||
contract_pid = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,18 +3,87 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/schema.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <sodium.h>
|
||||
#include "../shared.h"
|
||||
#include "../conf.h"
|
||||
#include "../crypto.h"
|
||||
#include "usr.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace shared;
|
||||
using namespace rapidjson;
|
||||
|
||||
namespace usr
|
||||
{
|
||||
|
||||
map<string, ContractUser> users;
|
||||
Document challenge_response_schemadoc;
|
||||
|
||||
void add_user(string pubkeyb64)
|
||||
void create_user_challenge(string &msg, string &challenge)
|
||||
{
|
||||
unsigned char challenge_bytes[USER_CHALLENGE_LEN];
|
||||
randombytes_buf(challenge_bytes, USER_CHALLENGE_LEN);
|
||||
|
||||
challenge = base64_encode(challenge_bytes, USER_CHALLENGE_LEN);
|
||||
|
||||
Document d;
|
||||
d.SetObject();
|
||||
Document::AllocatorType &allocator = d.GetAllocator();
|
||||
d.AddMember("version", StringRef(_HP_VERSION_), allocator);
|
||||
d.AddMember("type", "public_challenge", allocator);
|
||||
d.AddMember("challenge", StringRef(challenge.data()), allocator);
|
||||
|
||||
StringBuffer buffer;
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
d.Accept(writer);
|
||||
msg = buffer.GetString();
|
||||
}
|
||||
|
||||
bool verify_user_challenge_response(string &response, string &original_challenge, string &extracted_pubkeyb64)
|
||||
{
|
||||
Document d;
|
||||
d.Parse(response.data());
|
||||
|
||||
SchemaDocument schema(challenge_response_schemadoc);
|
||||
SchemaValidator validator(schema);
|
||||
if (!d.Accept(validator))
|
||||
{
|
||||
cerr << "User challenge resposne schema invalid.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
string type = d["type"].GetString();
|
||||
if (type != "challenge_response")
|
||||
{
|
||||
cerr << "User challenge response type invalid. 'challenge_response' expeced.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
string challenge = d["challenge"].GetString();
|
||||
string sigb64 = d["sig"].GetString();
|
||||
string pubkeyb64 = d["pubkey"].GetString();
|
||||
|
||||
if (challenge != original_challenge)
|
||||
{
|
||||
cerr << "User challenge resposne: challenge mismatch.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!crypto::verify_b64(original_challenge, sigb64, pubkeyb64))
|
||||
{
|
||||
cerr << "User challenge response signature verification failed.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
extracted_pubkeyb64 = pubkeyb64;
|
||||
return true;
|
||||
}
|
||||
|
||||
void add_user(string &pubkeyb64)
|
||||
{
|
||||
if (users.count(pubkeyb64) == 1)
|
||||
{
|
||||
@@ -24,7 +93,8 @@ void add_user(string pubkeyb64)
|
||||
|
||||
int inpipe[2];
|
||||
int outpipe[2];
|
||||
if (pipe(inpipe) != 0 || pipe(outpipe) != 0) {
|
||||
if (pipe(inpipe) != 0 || pipe(outpipe) != 0)
|
||||
{
|
||||
cerr << "User pipe creation failed. pubkey:" << pubkeyb64 << endl;
|
||||
return;
|
||||
}
|
||||
@@ -32,7 +102,7 @@ void add_user(string pubkeyb64)
|
||||
users.insert(pair<string, ContractUser>(pubkeyb64, ContractUser(pubkeyb64, inpipe, outpipe)));
|
||||
}
|
||||
|
||||
void remove_user(string pubkeyb64)
|
||||
void remove_user(string &pubkeyb64)
|
||||
{
|
||||
if (users.count(pubkeyb64) == 0)
|
||||
{
|
||||
@@ -53,7 +123,7 @@ void remove_user(string pubkeyb64)
|
||||
//Read per-user outputs produced by the contract process.
|
||||
int read_contract_user_outputs()
|
||||
{
|
||||
for (auto& [pk, user] : users)
|
||||
for (auto &[pk, user] : users)
|
||||
{
|
||||
int fdout = user.outpipe[0];
|
||||
int bytes_available = 0;
|
||||
@@ -75,4 +145,23 @@ int read_contract_user_outputs()
|
||||
return 1;
|
||||
}
|
||||
|
||||
int init()
|
||||
{
|
||||
const char *challenge_response_schema =
|
||||
"{"
|
||||
"\"type\": \"object\","
|
||||
"\"required\": [ \"type\", \"challenge\", \"sig\", \"pubkey\" ],"
|
||||
"\"properties\": {"
|
||||
"\"type\": { \"type\": \"string\" },"
|
||||
"\"challenge\": { \"type\": \"string\" },"
|
||||
"\"sig\": { \"type\": \"string\" },"
|
||||
"\"pubkey\": { \"type\": \"string\" }"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
challenge_response_schemadoc.Parse(challenge_response_schema);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace usr
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _HP_USR_H_
|
||||
#define _HP_USR_H_
|
||||
|
||||
#define USER_CHALLENGE_LEN 16
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
@@ -12,8 +14,12 @@ using namespace shared;
|
||||
namespace usr
|
||||
{
|
||||
extern map<string, ContractUser> users;
|
||||
void add_user(string pubkeyb64);
|
||||
void remove_user(string pubkeyb64);
|
||||
|
||||
int init();
|
||||
void create_user_challenge(string &msg, string &challenge);
|
||||
bool verify_user_challenge_response(string &response, string &original_challenge, string &extracted_pubkey);
|
||||
void add_user(string &pubkeyb64);
|
||||
void remove_user(string &pubkeyb64);
|
||||
|
||||
} // namespace usr
|
||||
|
||||
|
||||
Reference in New Issue
Block a user