Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48ecf5f934 | ||
|
|
d6221f019b | ||
|
|
1630a872b1 |
12
build.sh
12
build.sh
@@ -152,14 +152,10 @@ chmod +x "$BUILD_DIR/$OUTPUT_NAME"
|
||||
|
||||
print_status "Verifying binary with ldd/file"
|
||||
LDD_OK=false
|
||||
if LDD_OUTPUT=$(ldd "$BUILD_DIR/$OUTPUT_NAME" 2>&1); then
|
||||
echo "$LDD_OUTPUT" >&2
|
||||
if echo "$LDD_OUTPUT" | grep -q "not a dynamic executable\|statically linked"; then
|
||||
LDD_OK=true
|
||||
fi
|
||||
else
|
||||
print_warning "ldd check failed (this can happen for foreign-arch binaries)"
|
||||
echo "$LDD_OUTPUT" >&2
|
||||
LDD_OUTPUT=$(ldd "$BUILD_DIR/$OUTPUT_NAME" 2>&1 || true)
|
||||
echo "$LDD_OUTPUT" >&2
|
||||
if echo "$LDD_OUTPUT" | grep -q "not a dynamic executable\|statically linked"; then
|
||||
LDD_OK=true
|
||||
fi
|
||||
|
||||
FILE_OUTPUT=$(file "$BUILD_DIR/$OUTPUT_NAME" 2>&1 || true)
|
||||
|
||||
@@ -56,4 +56,69 @@ int nsigner_nip44_encrypt(const char *socket_name, const char *role,
|
||||
int nsigner_nip44_decrypt(const char *socket_name, const char *role,
|
||||
const char *peer_pub_hex, const char *ciphertext, char **plain_out);
|
||||
|
||||
/*
|
||||
* URL helpers for FIPS/TCP transport.
|
||||
* URL format: http://host:port (path/query ignored if present).
|
||||
*/
|
||||
int nsigner_get_public_key_url(const char *url, const char *role, char *out_hex_65);
|
||||
|
||||
int nsigner_sign_event_url(const char *url, const char *role,
|
||||
const char *unsigned_event_json, char **signed_event_json_out);
|
||||
|
||||
int nsigner_nip04_encrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *plaintext, char **cipher_out);
|
||||
|
||||
int nsigner_nip04_decrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *ciphertext, char **plain_out);
|
||||
|
||||
int nsigner_nip44_encrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *plaintext, char **cipher_out);
|
||||
|
||||
int nsigner_nip44_decrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *ciphertext, char **plain_out);
|
||||
|
||||
/*
|
||||
* qrexec helpers for cross-qube n_signer transport.
|
||||
* target_qube: destination signer qube (e.g. "nsigner-vault").
|
||||
* service_name: qrexec service name (e.g. "qubes.NsignerRpc").
|
||||
*/
|
||||
int nsigner_qrexec_get_public_key(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
char *out_hex_65);
|
||||
|
||||
int nsigner_qrexec_sign_event(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *unsigned_event_json,
|
||||
char **signed_event_json_out);
|
||||
|
||||
int nsigner_qrexec_nip04_encrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *plaintext,
|
||||
char **cipher_out);
|
||||
|
||||
int nsigner_qrexec_nip04_decrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *ciphertext,
|
||||
char **plain_out);
|
||||
|
||||
int nsigner_qrexec_nip44_encrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *plaintext,
|
||||
char **cipher_out);
|
||||
|
||||
int nsigner_qrexec_nip44_decrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *ciphertext,
|
||||
char **plain_out);
|
||||
|
||||
#endif /* NSIGNER_CLIENT_H */
|
||||
|
||||
@@ -7,12 +7,17 @@
|
||||
|
||||
typedef enum {
|
||||
NT_SIGNER_LOCAL = 0,
|
||||
NT_SIGNER_NSIGNER = 1
|
||||
NT_SIGNER_NSIGNER = 1,
|
||||
NT_SIGNER_NSIGNER_QREXEC = 2,
|
||||
NT_SIGNER_NSIGNER_URL = 3
|
||||
} nt_signer_kind_t;
|
||||
|
||||
typedef struct {
|
||||
nt_signer_kind_t kind;
|
||||
char socket_name[128];
|
||||
char qrexec_target[128];
|
||||
char qrexec_service[128];
|
||||
char endpoint_url[256];
|
||||
char role[64];
|
||||
} nt_signer_t;
|
||||
|
||||
@@ -21,6 +26,8 @@ extern nt_signer_t g_signer;
|
||||
void signer_init(void);
|
||||
int signer_init_local(void);
|
||||
int signer_init_nsigner(const char *socket_name);
|
||||
int signer_init_nsigner_qrexec(const char *target_qube, const char *service_name);
|
||||
int signer_init_nsigner_url(const char *endpoint_url);
|
||||
|
||||
int signer_create_and_sign(int kind,
|
||||
const char *content,
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
*/
|
||||
#define NT_VERSION_MAJOR 0
|
||||
#define NT_VERSION_MINOR 0
|
||||
#define NT_VERSION_PATCH 6
|
||||
#define NT_VERSION "v0.0.6"
|
||||
#define NT_VERSION_PATCH 9
|
||||
#define NT_VERSION "v0.0.9"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
146
src/menu_login.c
146
src/menu_login.c
@@ -1,6 +1,7 @@
|
||||
#include "tui.h"
|
||||
#include "state.h"
|
||||
#include "net.h"
|
||||
#include "db.h"
|
||||
|
||||
#include "publish.h"
|
||||
#include "signer.h"
|
||||
@@ -160,7 +161,14 @@ void menu_login(void) {
|
||||
unsigned char pub[32];
|
||||
|
||||
tui_clear_screen();
|
||||
tui_print("LOGIN");
|
||||
tui_print("LOGIN\n");
|
||||
tui_print("^_E^:nter test/dev seed fallback");
|
||||
tui_print("^_P^:rivate key (nsec or 64-hex)");
|
||||
tui_print("^_M^:nemonic (12 words)");
|
||||
tui_print("^_S^:igner local (same qube)");
|
||||
tui_print("^_U^:RL signer (FIPS/web address)");
|
||||
tui_print("^_N^:ew account");
|
||||
tui_print("^_Q^:uit");
|
||||
|
||||
tui_get_line(">", input, (int)sizeof(input));
|
||||
|
||||
@@ -169,6 +177,20 @@ void menu_login(void) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (input[0] == 'e' || input[0] == 'E') {
|
||||
input[0] = '\0';
|
||||
} else if (input[0] == 'p' || input[0] == 'P') {
|
||||
tui_get_line("Private key (nsec or 64-hex) >", input, (int)sizeof(input));
|
||||
if (input[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
} else if (input[0] == 'm' || input[0] == 'M') {
|
||||
tui_get_line("Seed phrase (12 words) >", input, (int)sizeof(input));
|
||||
if (input[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(input, "s") == 0 || strcmp(input, "S") == 0) {
|
||||
char **names = NULL;
|
||||
int name_count = 0;
|
||||
@@ -247,6 +269,126 @@ void menu_login(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(input, "u") == 0 || strcmp(input, "U") == 0) {
|
||||
char pubkey_hex[65] = {0};
|
||||
char endpoint_url[256];
|
||||
const char *saved_endpoint = db_get_local("nsigner_url_endpoint");
|
||||
|
||||
snprintf(endpoint_url, sizeof(endpoint_url), "%s", (saved_endpoint && saved_endpoint[0] != '\0') ? saved_endpoint : "");
|
||||
tui_get_line("Signer URL (http://<npub>.fips:8080) >", endpoint_url, (int)sizeof(endpoint_url));
|
||||
if (endpoint_url[0] == '\0') {
|
||||
if (saved_endpoint && saved_endpoint[0] != '\0') {
|
||||
snprintf(endpoint_url, sizeof(endpoint_url), "%s", saved_endpoint);
|
||||
} else {
|
||||
tui_print("No URL provided.");
|
||||
tui_get_line(">", input, (int)sizeof(input));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
tui_print("Connecting to n_signer URL: %s", endpoint_url);
|
||||
tui_print("Waiting for n_signer approval...");
|
||||
|
||||
if (nsigner_get_public_key_url(endpoint_url, "main", pubkey_hex) != 0) {
|
||||
tui_print("Failed to get public key from n_signer URL (denied or error).");
|
||||
tui_get_line(">", input, (int)sizeof(input));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (signer_init_nsigner_url(endpoint_url) != 0) {
|
||||
tui_print("Failed to initialize URL signer mode.");
|
||||
tui_get_line(">", input, (int)sizeof(input));
|
||||
continue;
|
||||
}
|
||||
|
||||
(void)db_set_local("nsigner_url_endpoint", endpoint_url);
|
||||
|
||||
snprintf(g_state.npub_hex, sizeof(g_state.npub_hex), "%s", pubkey_hex);
|
||||
{
|
||||
unsigned char pub_bytes[32];
|
||||
nostr_hex_to_bytes(pubkey_hex, pub_bytes, 32);
|
||||
nostr_key_to_bech32(pub_bytes, "npub", g_state.npub_bech32);
|
||||
}
|
||||
g_state.nsec_hex[0] = '\0';
|
||||
g_state.nsec_bech32[0] = '\0';
|
||||
g_state.seed_phrase[0] = '\0';
|
||||
g_state.logged_in = 1;
|
||||
|
||||
tui_print("Signed in via n_signer URL (%s)", endpoint_url);
|
||||
tui_print("npub: %s", g_state.npub_bech32);
|
||||
|
||||
(void)state_load_user_info();
|
||||
|
||||
if (g_state.kind0_json && strcmp(g_state.kind0_json, "{}") == 0) {
|
||||
tui_print("No profile found on relays. Setting up new user...");
|
||||
menu_add_new_user();
|
||||
(void)state_load_user_info();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(input, "S") == 0) {
|
||||
char pubkey_hex[65] = {0};
|
||||
char target_qube[128];
|
||||
char service_name[128];
|
||||
const char *saved_target = db_get_local("nsigner_qrexec_target");
|
||||
|
||||
snprintf(target_qube, sizeof(target_qube), "%s", (saved_target && saved_target[0] != '\0') ? saved_target : "nsigner-vault");
|
||||
snprintf(service_name, sizeof(service_name), "%s", "qubes.NsignerRpc");
|
||||
|
||||
tui_get_line("Target signer qube (nsigner-vault) >", target_qube, (int)sizeof(target_qube));
|
||||
if (target_qube[0] == '\0') {
|
||||
snprintf(target_qube, sizeof(target_qube), "%s", (saved_target && saved_target[0] != '\0') ? saved_target : "nsigner-vault");
|
||||
}
|
||||
|
||||
tui_get_line("Qrexec service (qubes.NsignerRpc) >", service_name, (int)sizeof(service_name));
|
||||
if (service_name[0] == '\0') {
|
||||
snprintf(service_name, sizeof(service_name), "%s", "qubes.NsignerRpc");
|
||||
}
|
||||
|
||||
tui_print("Calling qrexec service %s in %s...", service_name, target_qube);
|
||||
tui_print("Waiting for n_signer approval...");
|
||||
|
||||
if (nsigner_qrexec_get_public_key(target_qube, service_name, "main", pubkey_hex) != 0) {
|
||||
tui_print("Failed to get public key via qrexec (denied or error).");
|
||||
tui_get_line(">", input, (int)sizeof(input));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (signer_init_nsigner_qrexec(target_qube, service_name) != 0) {
|
||||
tui_print("Failed to initialize qrexec signer mode.");
|
||||
tui_get_line(">", input, (int)sizeof(input));
|
||||
continue;
|
||||
}
|
||||
|
||||
(void)db_set_local("nsigner_qrexec_target", target_qube);
|
||||
|
||||
snprintf(g_state.npub_hex, sizeof(g_state.npub_hex), "%s", pubkey_hex);
|
||||
{
|
||||
unsigned char pub_bytes[32];
|
||||
nostr_hex_to_bytes(pubkey_hex, pub_bytes, 32);
|
||||
nostr_key_to_bech32(pub_bytes, "npub", g_state.npub_bech32);
|
||||
}
|
||||
g_state.nsec_hex[0] = '\0';
|
||||
g_state.nsec_bech32[0] = '\0';
|
||||
g_state.seed_phrase[0] = '\0';
|
||||
g_state.logged_in = 1;
|
||||
|
||||
tui_print("Signed in via qrexec n_signer (%s:%s)", target_qube, service_name);
|
||||
tui_print("npub: %s", g_state.npub_bech32);
|
||||
|
||||
(void)state_load_user_info();
|
||||
|
||||
if (g_state.kind0_json && strcmp(g_state.kind0_json, "{}") == 0) {
|
||||
tui_print("No profile found on relays. Setting up new user...");
|
||||
menu_add_new_user();
|
||||
(void)state_load_user_info();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(input, "n") == 0) {
|
||||
char mnemonic[256];
|
||||
char idxbuf[32];
|
||||
@@ -382,7 +524,7 @@ void menu_login(void) {
|
||||
}
|
||||
}
|
||||
|
||||
tui_print("Invalid login input. Enter 12 words, nsec, 64-hex, [s], [n], or [q].");
|
||||
tui_print("Invalid login input. Choose a menu command or enter valid key/mnemonic data.");
|
||||
tui_get_line(">", input, (int)sizeof(input));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,13 @@ void menu_profile(void) {
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER) {
|
||||
tui_print("Signer: n_signer (@%s)", g_signer.socket_name);
|
||||
} else if (g_signer.kind == NT_SIGNER_NSIGNER_QREXEC) {
|
||||
tui_print("Signer: n_signer qrexec");
|
||||
tui_print("Signer target: %s", g_signer.qrexec_target);
|
||||
tui_print("Signer service: %s", g_signer.qrexec_service);
|
||||
} else if (g_signer.kind == NT_SIGNER_NSIGNER_URL) {
|
||||
tui_print("Signer: n_signer URL");
|
||||
tui_print("Signer endpoint: %s", g_signer.endpoint_url);
|
||||
} else {
|
||||
tui_print("nsecHex: %s", g_state.nsec_hex);
|
||||
tui_print("nsec: %s", g_state.nsec_bech32);
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
|
||||
static int write_all(int fd, const void *buf, size_t len) {
|
||||
const unsigned char *p = (const unsigned char *)buf;
|
||||
@@ -223,6 +225,152 @@ int nsigner_connect(const char *name) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int nsigner_parse_url(const char *url, char *host_out, size_t host_out_sz, int *port_out) {
|
||||
const char *p;
|
||||
const char *end;
|
||||
const char *authority_end;
|
||||
const char *port_sep = NULL;
|
||||
int port = 8080;
|
||||
size_t host_len;
|
||||
|
||||
if (!url || !host_out || host_out_sz == 0 || !port_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
p = url;
|
||||
if (strncmp(p, "http://", 7) == 0) {
|
||||
p += 7;
|
||||
} else if (strncmp(p, "https://", 8) == 0) {
|
||||
p += 8;
|
||||
}
|
||||
|
||||
end = p;
|
||||
while (*end && *end != '/' && *end != '?' && *end != '#') {
|
||||
end++;
|
||||
}
|
||||
authority_end = end;
|
||||
|
||||
if (p == authority_end) {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
if (*p == '[') {
|
||||
const char *rb = p + 1;
|
||||
while (rb < authority_end && *rb != ']') {
|
||||
rb++;
|
||||
}
|
||||
if (rb >= authority_end || *rb != ']') {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
host_len = (size_t)(rb - (p + 1));
|
||||
if (host_len == 0 || host_len >= host_out_sz) {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
memcpy(host_out, p + 1, host_len);
|
||||
host_out[host_len] = '\0';
|
||||
|
||||
if ((rb + 1) < authority_end) {
|
||||
if (*(rb + 1) != ':') {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
port_sep = rb + 1;
|
||||
}
|
||||
} else {
|
||||
const char *c = authority_end;
|
||||
while (c > p) {
|
||||
c--;
|
||||
if (*c == ':') {
|
||||
port_sep = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (port_sep) {
|
||||
host_len = (size_t)(port_sep - p);
|
||||
} else {
|
||||
host_len = (size_t)(authority_end - p);
|
||||
}
|
||||
|
||||
if (host_len == 0 || host_len >= host_out_sz) {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
memcpy(host_out, p, host_len);
|
||||
host_out[host_len] = '\0';
|
||||
}
|
||||
|
||||
if (port_sep && (port_sep + 1) < authority_end) {
|
||||
char port_buf[16];
|
||||
size_t port_len = (size_t)(authority_end - (port_sep + 1));
|
||||
char *endptr = NULL;
|
||||
long parsed;
|
||||
|
||||
if (port_len == 0 || port_len >= sizeof(port_buf)) {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
memcpy(port_buf, port_sep + 1, port_len);
|
||||
port_buf[port_len] = '\0';
|
||||
|
||||
parsed = strtol(port_buf, &endptr, 10);
|
||||
if (!endptr || *endptr != '\0' || parsed <= 0 || parsed > 65535) {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
port = (int)parsed;
|
||||
} else if (port_sep) {
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
*port_out = port;
|
||||
return NT_NSIGNER_OK;
|
||||
}
|
||||
|
||||
static int nsigner_connect_url(const char *url) {
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res = NULL;
|
||||
struct addrinfo *ai;
|
||||
char host[256];
|
||||
int port;
|
||||
char port_str[16];
|
||||
int fd = -1;
|
||||
|
||||
if (nsigner_parse_url(url, host, sizeof(host), &port) != NT_NSIGNER_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
snprintf(port_str, sizeof(port_str), "%d", port);
|
||||
if (getaddrinfo(host, port_str, &hints, &res) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ai = res; ai; ai = ai->ai_next) {
|
||||
struct timeval tv;
|
||||
|
||||
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (fd < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
(void)setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
|
||||
if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
return fd;
|
||||
}
|
||||
|
||||
int nsigner_rpc(int fd, const cJSON *request, cJSON **response_out, int read_timeout_ms) {
|
||||
char *req_json = NULL;
|
||||
uint32_t req_len;
|
||||
@@ -377,6 +525,274 @@ static int nsigner_call_string_method(const char *socket_name,
|
||||
return *result_out ? NT_NSIGNER_OK : NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
static int nsigner_call_string_method_url(const char *url,
|
||||
const char *role,
|
||||
const char *method,
|
||||
const char **args,
|
||||
int arg_count,
|
||||
char **result_out) {
|
||||
int fd = -1;
|
||||
cJSON *request = NULL;
|
||||
cJSON *params = NULL;
|
||||
cJSON *response = NULL;
|
||||
cJSON *result_item;
|
||||
int rc;
|
||||
|
||||
if (!url || !method || !result_out || arg_count < 0) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
(void)role;
|
||||
*result_out = NULL;
|
||||
|
||||
fd = nsigner_connect_url(url);
|
||||
if (fd < 0) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
request = cJSON_CreateObject();
|
||||
params = cJSON_CreateArray();
|
||||
if (!request || !params) {
|
||||
cJSON_Delete(request);
|
||||
cJSON_Delete(params);
|
||||
close(fd);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
cJSON_AddStringToObject(request, "id", "1");
|
||||
cJSON_AddStringToObject(request, "method", method);
|
||||
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
if (!args || !args[i]) {
|
||||
cJSON_Delete(request);
|
||||
cJSON_Delete(params);
|
||||
close(fd);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
cJSON_AddItemToArray(params, cJSON_CreateString(args[i]));
|
||||
}
|
||||
|
||||
cJSON_AddItemToObject(request, "params", params);
|
||||
|
||||
rc = nsigner_rpc(fd, request, &response, 60000);
|
||||
cJSON_Delete(request);
|
||||
close(fd);
|
||||
if (rc != NT_NSIGNER_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
result_item = cJSON_GetObjectItemCaseSensitive(response, "result");
|
||||
if (!cJSON_IsString(result_item) || !result_item->valuestring) {
|
||||
cJSON_Delete(response);
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
*result_out = strdup(result_item->valuestring);
|
||||
cJSON_Delete(response);
|
||||
|
||||
return *result_out ? NT_NSIGNER_OK : NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
static int nsigner_qrexec_rpc(const char *target_qube,
|
||||
const char *service_name,
|
||||
const cJSON *request,
|
||||
cJSON **response_out) {
|
||||
int in_pipe[2] = {-1, -1};
|
||||
int out_pipe[2] = {-1, -1};
|
||||
pid_t pid;
|
||||
char *req_json = NULL;
|
||||
uint32_t req_len;
|
||||
uint32_t req_be;
|
||||
uint32_t resp_be;
|
||||
uint32_t resp_len;
|
||||
char *resp_buf = NULL;
|
||||
cJSON *response = NULL;
|
||||
int err_code;
|
||||
int status = 0;
|
||||
|
||||
if (!target_qube || !*target_qube || !service_name || !*service_name || !request || !response_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
*response_out = NULL;
|
||||
|
||||
if (pipe(in_pipe) != 0 || pipe(out_pipe) != 0) {
|
||||
if (in_pipe[0] >= 0) close(in_pipe[0]);
|
||||
if (in_pipe[1] >= 0) close(in_pipe[1]);
|
||||
if (out_pipe[0] >= 0) close(out_pipe[0]);
|
||||
if (out_pipe[1] >= 0) close(out_pipe[1]);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
close(in_pipe[0]);
|
||||
close(in_pipe[1]);
|
||||
close(out_pipe[0]);
|
||||
close(out_pipe[1]);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
dup2(in_pipe[0], STDIN_FILENO);
|
||||
dup2(out_pipe[1], STDOUT_FILENO);
|
||||
|
||||
close(in_pipe[0]);
|
||||
close(in_pipe[1]);
|
||||
close(out_pipe[0]);
|
||||
close(out_pipe[1]);
|
||||
|
||||
execlp("qrexec-client-vm", "qrexec-client-vm", target_qube, service_name, (char *)NULL);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
close(in_pipe[0]);
|
||||
close(out_pipe[1]);
|
||||
|
||||
req_json = cJSON_PrintUnformatted((cJSON *)request);
|
||||
if (!req_json) {
|
||||
close(in_pipe[1]);
|
||||
close(out_pipe[0]);
|
||||
waitpid(pid, NULL, 0);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
req_len = (uint32_t)strlen(req_json);
|
||||
req_be = htonl(req_len);
|
||||
|
||||
if (write_all(in_pipe[1], &req_be, sizeof(req_be)) != 0 ||
|
||||
write_all(in_pipe[1], req_json, req_len) != 0) {
|
||||
free(req_json);
|
||||
close(in_pipe[1]);
|
||||
close(out_pipe[0]);
|
||||
waitpid(pid, NULL, 0);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
free(req_json);
|
||||
close(in_pipe[1]);
|
||||
|
||||
if (read_all(out_pipe[0], &resp_be, sizeof(resp_be)) != 0) {
|
||||
close(out_pipe[0]);
|
||||
waitpid(pid, NULL, 0);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
resp_len = ntohl(resp_be);
|
||||
if (resp_len == 0 || resp_len > (16U * 1024U * 1024U)) {
|
||||
close(out_pipe[0]);
|
||||
waitpid(pid, NULL, 0);
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
resp_buf = (char *)malloc((size_t)resp_len + 1U);
|
||||
if (!resp_buf) {
|
||||
close(out_pipe[0]);
|
||||
waitpid(pid, NULL, 0);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
if (read_all(out_pipe[0], resp_buf, resp_len) != 0) {
|
||||
free(resp_buf);
|
||||
close(out_pipe[0]);
|
||||
waitpid(pid, NULL, 0);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
resp_buf[resp_len] = '\0';
|
||||
close(out_pipe[0]);
|
||||
|
||||
if (waitpid(pid, &status, 0) < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
free(resp_buf);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
response = cJSON_Parse(resp_buf);
|
||||
free(resp_buf);
|
||||
if (!response || !cJSON_IsObject(response)) {
|
||||
cJSON_Delete(response);
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
err_code = nsigner_error_code_from_response(response);
|
||||
if (err_code != NT_NSIGNER_OK) {
|
||||
cJSON_Delete(response);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
if (!cJSON_GetObjectItemCaseSensitive(response, "result")) {
|
||||
cJSON_Delete(response);
|
||||
return NT_NSIGNER_E_ERROR;
|
||||
}
|
||||
|
||||
*response_out = response;
|
||||
return NT_NSIGNER_OK;
|
||||
}
|
||||
|
||||
static int nsigner_qrexec_call_string_method(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *method,
|
||||
const char **args,
|
||||
int arg_count,
|
||||
char **result_out) {
|
||||
cJSON *request = NULL;
|
||||
cJSON *params = NULL;
|
||||
cJSON *role_obj = NULL;
|
||||
cJSON *response = NULL;
|
||||
cJSON *result_item;
|
||||
int rc;
|
||||
|
||||
if (!target_qube || !service_name || !method || !result_out || arg_count < 0) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
*result_out = NULL;
|
||||
|
||||
request = cJSON_CreateObject();
|
||||
params = cJSON_CreateArray();
|
||||
if (!request || !params) {
|
||||
cJSON_Delete(request);
|
||||
cJSON_Delete(params);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
cJSON_AddStringToObject(request, "id", "1");
|
||||
cJSON_AddStringToObject(request, "method", method);
|
||||
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
if (!args || !args[i]) {
|
||||
cJSON_Delete(request);
|
||||
cJSON_Delete(params);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
cJSON_AddItemToArray(params, cJSON_CreateString(args[i]));
|
||||
}
|
||||
|
||||
role_obj = cJSON_CreateObject();
|
||||
if (!role_obj) {
|
||||
cJSON_Delete(request);
|
||||
cJSON_Delete(params);
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
cJSON_AddStringToObject(role_obj, "role", (role && *role) ? role : "main");
|
||||
cJSON_AddItemToArray(params, role_obj);
|
||||
|
||||
cJSON_AddItemToObject(request, "params", params);
|
||||
|
||||
rc = nsigner_qrexec_rpc(target_qube, service_name, request, &response);
|
||||
cJSON_Delete(request);
|
||||
if (rc != NT_NSIGNER_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
result_item = cJSON_GetObjectItemCaseSensitive(response, "result");
|
||||
if (!cJSON_IsString(result_item) || !result_item->valuestring) {
|
||||
cJSON_Delete(response);
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
*result_out = strdup(result_item->valuestring);
|
||||
cJSON_Delete(response);
|
||||
|
||||
return *result_out ? NT_NSIGNER_OK : NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
int nsigner_get_public_key(const char *socket_name, const char *role, char *out_hex_65) {
|
||||
char *result = NULL;
|
||||
int rc;
|
||||
@@ -465,3 +881,209 @@ int nsigner_nip44_decrypt(const char *socket_name, const char *role,
|
||||
args[1] = ciphertext;
|
||||
return nsigner_call_string_method(socket_name, role, "nip44_decrypt", args, 2, plain_out);
|
||||
}
|
||||
|
||||
int nsigner_get_public_key_url(const char *url, const char *role, char *out_hex_65) {
|
||||
char *result = NULL;
|
||||
int rc;
|
||||
size_t len;
|
||||
|
||||
if (!out_hex_65) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
rc = nsigner_call_string_method_url(url, role, "get_public_key", NULL, 0, &result);
|
||||
if (rc != NT_NSIGNER_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
len = strlen(result);
|
||||
if (len != 64) {
|
||||
free(result);
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
memcpy(out_hex_65, result, len + 1);
|
||||
free(result);
|
||||
return NT_NSIGNER_OK;
|
||||
}
|
||||
|
||||
int nsigner_sign_event_url(const char *url, const char *role,
|
||||
const char *unsigned_event_json, char **signed_event_json_out) {
|
||||
const char *args[1];
|
||||
|
||||
if (!unsigned_event_json || !signed_event_json_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = unsigned_event_json;
|
||||
return nsigner_call_string_method_url(url, role, "sign_event", args, 1, signed_event_json_out);
|
||||
}
|
||||
|
||||
int nsigner_nip04_encrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *plaintext, char **cipher_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !plaintext || !cipher_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = plaintext;
|
||||
return nsigner_call_string_method_url(url, role, "nip04_encrypt", args, 2, cipher_out);
|
||||
}
|
||||
|
||||
int nsigner_nip04_decrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *ciphertext, char **plain_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !ciphertext || !plain_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = ciphertext;
|
||||
return nsigner_call_string_method_url(url, role, "nip04_decrypt", args, 2, plain_out);
|
||||
}
|
||||
|
||||
int nsigner_nip44_encrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *plaintext, char **cipher_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !plaintext || !cipher_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = plaintext;
|
||||
return nsigner_call_string_method_url(url, role, "nip44_encrypt", args, 2, cipher_out);
|
||||
}
|
||||
|
||||
int nsigner_nip44_decrypt_url(const char *url, const char *role,
|
||||
const char *peer_pub_hex, const char *ciphertext, char **plain_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !ciphertext || !plain_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = ciphertext;
|
||||
return nsigner_call_string_method_url(url, role, "nip44_decrypt", args, 2, plain_out);
|
||||
}
|
||||
|
||||
int nsigner_qrexec_get_public_key(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
char *out_hex_65) {
|
||||
char *result = NULL;
|
||||
int rc;
|
||||
size_t len;
|
||||
|
||||
if (!out_hex_65) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
rc = nsigner_qrexec_call_string_method(target_qube, service_name, role,
|
||||
"get_public_key", NULL, 0, &result);
|
||||
if (rc != NT_NSIGNER_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
len = strlen(result);
|
||||
if (len != 64) {
|
||||
free(result);
|
||||
return NT_NSIGNER_E_PARSE;
|
||||
}
|
||||
|
||||
memcpy(out_hex_65, result, len + 1);
|
||||
free(result);
|
||||
return NT_NSIGNER_OK;
|
||||
}
|
||||
|
||||
int nsigner_qrexec_sign_event(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *unsigned_event_json,
|
||||
char **signed_event_json_out) {
|
||||
const char *args[1];
|
||||
|
||||
if (!unsigned_event_json || !signed_event_json_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = unsigned_event_json;
|
||||
return nsigner_qrexec_call_string_method(target_qube, service_name, role,
|
||||
"sign_event", args, 1, signed_event_json_out);
|
||||
}
|
||||
|
||||
int nsigner_qrexec_nip04_encrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *plaintext,
|
||||
char **cipher_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !plaintext || !cipher_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = plaintext;
|
||||
return nsigner_qrexec_call_string_method(target_qube, service_name, role,
|
||||
"nip04_encrypt", args, 2, cipher_out);
|
||||
}
|
||||
|
||||
int nsigner_qrexec_nip04_decrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *ciphertext,
|
||||
char **plain_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !ciphertext || !plain_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = ciphertext;
|
||||
return nsigner_qrexec_call_string_method(target_qube, service_name, role,
|
||||
"nip04_decrypt", args, 2, plain_out);
|
||||
}
|
||||
|
||||
int nsigner_qrexec_nip44_encrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *plaintext,
|
||||
char **cipher_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !plaintext || !cipher_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = plaintext;
|
||||
return nsigner_qrexec_call_string_method(target_qube, service_name, role,
|
||||
"nip44_encrypt", args, 2, cipher_out);
|
||||
}
|
||||
|
||||
int nsigner_qrexec_nip44_decrypt(const char *target_qube,
|
||||
const char *service_name,
|
||||
const char *role,
|
||||
const char *peer_pub_hex,
|
||||
const char *ciphertext,
|
||||
char **plain_out) {
|
||||
const char *args[2];
|
||||
|
||||
if (!peer_pub_hex || !ciphertext || !plain_out) {
|
||||
return NT_NSIGNER_E_IO;
|
||||
}
|
||||
|
||||
args[0] = peer_pub_hex;
|
||||
args[1] = ciphertext;
|
||||
return nsigner_qrexec_call_string_method(target_qube, service_name, role,
|
||||
"nip44_decrypt", args, 2, plain_out);
|
||||
}
|
||||
|
||||
218
src/signer.c
218
src/signer.c
@@ -15,6 +15,7 @@
|
||||
nt_signer_t g_signer = {
|
||||
.kind = NT_SIGNER_LOCAL,
|
||||
.socket_name = {0},
|
||||
.endpoint_url = {0},
|
||||
.role = "main",
|
||||
};
|
||||
|
||||
@@ -31,6 +32,9 @@ static int signer_local_private_key(unsigned char out_priv[32]) {
|
||||
void signer_init(void) {
|
||||
g_signer.kind = NT_SIGNER_LOCAL;
|
||||
g_signer.socket_name[0] = '\0';
|
||||
g_signer.qrexec_target[0] = '\0';
|
||||
g_signer.qrexec_service[0] = '\0';
|
||||
g_signer.endpoint_url[0] = '\0';
|
||||
snprintf(g_signer.role, sizeof(g_signer.role), "%s", "main");
|
||||
}
|
||||
|
||||
@@ -45,6 +49,36 @@ int signer_init_nsigner(const char *socket_name) {
|
||||
}
|
||||
g_signer.kind = NT_SIGNER_NSIGNER;
|
||||
snprintf(g_signer.socket_name, sizeof(g_signer.socket_name), "%s", socket_name);
|
||||
g_signer.qrexec_target[0] = '\0';
|
||||
g_signer.qrexec_service[0] = '\0';
|
||||
g_signer.endpoint_url[0] = '\0';
|
||||
snprintf(g_signer.role, sizeof(g_signer.role), "%s", "main");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int signer_init_nsigner_qrexec(const char *target_qube, const char *service_name) {
|
||||
if (!target_qube || target_qube[0] == '\0' || !service_name || service_name[0] == '\0') {
|
||||
return -1;
|
||||
}
|
||||
g_signer.kind = NT_SIGNER_NSIGNER_QREXEC;
|
||||
g_signer.socket_name[0] = '\0';
|
||||
snprintf(g_signer.qrexec_target, sizeof(g_signer.qrexec_target), "%s", target_qube);
|
||||
snprintf(g_signer.qrexec_service, sizeof(g_signer.qrexec_service), "%s", service_name);
|
||||
g_signer.endpoint_url[0] = '\0';
|
||||
snprintf(g_signer.role, sizeof(g_signer.role), "%s", "main");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int signer_init_nsigner_url(const char *endpoint_url) {
|
||||
if (!endpoint_url || endpoint_url[0] == '\0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_signer.kind = NT_SIGNER_NSIGNER_URL;
|
||||
g_signer.socket_name[0] = '\0';
|
||||
g_signer.qrexec_target[0] = '\0';
|
||||
g_signer.qrexec_service[0] = '\0';
|
||||
snprintf(g_signer.endpoint_url, sizeof(g_signer.endpoint_url), "%s", endpoint_url);
|
||||
snprintf(g_signer.role, sizeof(g_signer.role), "%s", "main");
|
||||
return 0;
|
||||
}
|
||||
@@ -123,6 +157,107 @@ int signer_create_and_sign(int kind,
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_QREXEC) {
|
||||
cJSON *unsigned_event = NULL;
|
||||
cJSON *tags_copy = NULL;
|
||||
char *unsigned_json = NULL;
|
||||
int rc = -1;
|
||||
|
||||
unsigned_event = cJSON_CreateObject();
|
||||
if (!unsigned_event) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cJSON_AddNumberToObject(unsigned_event, "kind", kind) ||
|
||||
!cJSON_AddStringToObject(unsigned_event, "content", content ? content : "")) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tags_copy = tags ? cJSON_Duplicate(tags, 1) : cJSON_CreateArray();
|
||||
if (!tags_copy) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
if (!cJSON_AddItemToObject(unsigned_event, "tags", tags_copy)) {
|
||||
cJSON_Delete(tags_copy);
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cJSON_AddNumberToObject(unsigned_event, "created_at", (double)timestamp) ||
|
||||
!cJSON_AddStringToObject(unsigned_event, "pubkey", g_state.npub_hex)) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned_json = cJSON_PrintUnformatted(unsigned_event);
|
||||
if (!unsigned_json) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = nsigner_qrexec_sign_event(g_signer.qrexec_target,
|
||||
g_signer.qrexec_service,
|
||||
g_signer.role,
|
||||
unsigned_json,
|
||||
signed_event_json_out);
|
||||
|
||||
free(unsigned_json);
|
||||
cJSON_Delete(unsigned_event);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_URL) {
|
||||
cJSON *unsigned_event = NULL;
|
||||
cJSON *tags_copy = NULL;
|
||||
char *unsigned_json = NULL;
|
||||
int rc = -1;
|
||||
|
||||
unsigned_event = cJSON_CreateObject();
|
||||
if (!unsigned_event) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cJSON_AddNumberToObject(unsigned_event, "kind", kind) ||
|
||||
!cJSON_AddStringToObject(unsigned_event, "content", content ? content : "")) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tags_copy = tags ? cJSON_Duplicate(tags, 1) : cJSON_CreateArray();
|
||||
if (!tags_copy) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
if (!cJSON_AddItemToObject(unsigned_event, "tags", tags_copy)) {
|
||||
cJSON_Delete(tags_copy);
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cJSON_AddNumberToObject(unsigned_event, "created_at", (double)timestamp) ||
|
||||
!cJSON_AddStringToObject(unsigned_event, "pubkey", g_state.npub_hex)) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned_json = cJSON_PrintUnformatted(unsigned_event);
|
||||
if (!unsigned_json) {
|
||||
cJSON_Delete(unsigned_event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = nsigner_sign_event_url(g_signer.endpoint_url,
|
||||
g_signer.role,
|
||||
unsigned_json,
|
||||
signed_event_json_out);
|
||||
|
||||
free(unsigned_json);
|
||||
cJSON_Delete(unsigned_event);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (g_signer.kind != NT_SIGNER_LOCAL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -177,6 +312,21 @@ int signer_sign_event_json(const char *unsigned_event_json, char **signed_event_
|
||||
signed_event_json_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_QREXEC) {
|
||||
return nsigner_qrexec_sign_event(g_signer.qrexec_target,
|
||||
g_signer.qrexec_service,
|
||||
g_signer.role,
|
||||
unsigned_event_json,
|
||||
signed_event_json_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_URL) {
|
||||
return nsigner_sign_event_url(g_signer.endpoint_url,
|
||||
g_signer.role,
|
||||
unsigned_event_json,
|
||||
signed_event_json_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind != NT_SIGNER_LOCAL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -241,6 +391,23 @@ int signer_nip04_encrypt(const char *peer_pub_hex, const char *plaintext, char *
|
||||
cipher_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_QREXEC) {
|
||||
return nsigner_qrexec_nip04_encrypt(g_signer.qrexec_target,
|
||||
g_signer.qrexec_service,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
plaintext,
|
||||
cipher_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_URL) {
|
||||
return nsigner_nip04_encrypt_url(g_signer.endpoint_url,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
plaintext,
|
||||
cipher_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind != NT_SIGNER_LOCAL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -283,6 +450,23 @@ int signer_nip04_decrypt(const char *peer_pub_hex, const char *ciphertext, char
|
||||
plain_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_QREXEC) {
|
||||
return nsigner_qrexec_nip04_decrypt(g_signer.qrexec_target,
|
||||
g_signer.qrexec_service,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
ciphertext,
|
||||
plain_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_URL) {
|
||||
return nsigner_nip04_decrypt_url(g_signer.endpoint_url,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
ciphertext,
|
||||
plain_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind != NT_SIGNER_LOCAL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -325,6 +509,23 @@ int signer_nip44_encrypt(const char *peer_pub_hex, const char *plaintext, char *
|
||||
cipher_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_QREXEC) {
|
||||
return nsigner_qrexec_nip44_encrypt(g_signer.qrexec_target,
|
||||
g_signer.qrexec_service,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
plaintext,
|
||||
cipher_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_URL) {
|
||||
return nsigner_nip44_encrypt_url(g_signer.endpoint_url,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
plaintext,
|
||||
cipher_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind != NT_SIGNER_LOCAL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -367,6 +568,23 @@ int signer_nip44_decrypt(const char *peer_pub_hex, const char *ciphertext, char
|
||||
plain_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_QREXEC) {
|
||||
return nsigner_qrexec_nip44_decrypt(g_signer.qrexec_target,
|
||||
g_signer.qrexec_service,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
ciphertext,
|
||||
plain_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind == NT_SIGNER_NSIGNER_URL) {
|
||||
return nsigner_nip44_decrypt_url(g_signer.endpoint_url,
|
||||
g_signer.role,
|
||||
peer_pub_hex,
|
||||
ciphertext,
|
||||
plain_out);
|
||||
}
|
||||
|
||||
if (g_signer.kind != NT_SIGNER_LOCAL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user