diff --git a/plugins/serval-dna/crypto.c b/plugins/serval-dna/crypto.c
index 1d5f513..4a9547d 100644
--- a/plugins/serval-dna/crypto.c
+++ b/plugins/serval-dna/crypto.c
@@ -26,7 +26,7 @@
* You should have received a copy of the GNU General Public License
* along with Commotion. If not, see .
*
- * =====================================================================================
+ * ============================================================================
*/
#include
@@ -48,29 +48,40 @@
#include "serval-dna.h"
-extern struct subscriber *my_subscriber;
+/* libserval global for the primary keyring */
extern keyring_file *keyring;
-char *serval_path = NULL;
+/*
+ * libserval global identifying the subscriber corresponding
+ * to the primary identity in the primary keyring
+ */
+extern struct subscriber *my_subscriber;
+/* file path for the serval state/conf/keyring directory */
+char *serval_path = NULL;
+
+/* used to store error messages to pass in response to client commands */
co_obj_t *err_msg = NULL;
-static int serval_create_signature(unsigned char *key,
- const unsigned char *msg,
- const size_t msg_len,
- unsigned char *sig_buffer,
- const size_t sig_size) {
-
+/* Private */
+
+static int
+serval_create_signature(svl_crypto_ctx *ctx)
+{
+ CHECK(ctx && ctx->sas_private[0] && ctx->msg && ctx->msg_len,"Invalid ctx");
unsigned long long sig_length = SIGNATURE_BYTES;
-
- CHECK(sig_size >= msg_len + SIGNATURE_BYTES,"Signature buffer too small");
-
unsigned char hash[crypto_hash_sha512_BYTES];
- crypto_hash_sha512(hash, msg, msg_len); // create sha512 hash of message, which will then be signed
- memcpy(sig_buffer,msg,msg_len);
+ // create sha512 hash of message, which will then be signed
+ crypto_hash_sha512(hash, ctx->msg, ctx->msg_len);
- if (crypto_create_signature(key, hash, crypto_hash_sha512_BYTES, &sig_buffer[msg_len], &sig_length) != 0) // create signature of message hash, append it to end of message
+ // create signature of message hash, append it to end of message
+ int sig_ret = crypto_create_signature(ctx->sas_private,
+ hash,
+ crypto_hash_sha512_BYTES,
+ ctx->signature,
+ &sig_length);
+ if (sig_ret != 0)
return 0;
return 1;
@@ -78,311 +89,303 @@ static int serval_create_signature(unsigned char *key,
return 0;
}
-static int serval_extract_sas(unsigned char **key, int *key_len, keyring_file *_keyring, unsigned char *_sid) {
- *key=keyring_find_sas_private(_keyring, _sid, NULL); // get SAS key associated with our SID
- CHECK_ERR(*key,"Failed to fetch SAS key");
- if (key_len) *key_len = crypto_sign_edwards25519sha512batch_SECRETKEYBYTES;
- return 1;
-error:
- return 0;
-}
-
-int serval_open_keyring(const char *keyring_path,
- const size_t keyring_len,
- keyring_file **_keyring) {
-
- char keyring_path_str[PATH_MAX] = {0};
-
- if (keyring_path == NULL || keyring_len == 0) { // if no keyring specified, use default keyring
- strcpy(keyring_path_str,serval_path);
- if (serval_path[strlen(serval_path) - 1] != '/')
- strcat(keyring_path_str,"/");
- strcat(keyring_path_str,"serval.keyring");
- // Fetching SAS keys requires setting the SERVALINSTANCE_PATH environment variable
- CHECK_ERR(setenv("SERVALINSTANCE_PATH",serval_path,1) == 0,"Failed to set SERVALINSTANCE_PATH env variable");
- }
- else { // otherwise, use specified keyring (NOTE: if keyring does not exist, it will be created)
- CHECK(keyring_len < PATH_MAX,"Keyring length too long");
- strncpy(keyring_path_str,keyring_path,keyring_len);
- keyring_path_str[keyring_len] = '\0';
- }
-
- CHECK_ERR((*_keyring = keyring_open(keyring_path_str)),"Failed to open specified keyring file");
-
- if (keyring_enter_pin(*_keyring, KEYRING_PIN) <= 0) {
- /* put initial identity in if we don't have any visible */
- CHECK_ERR(keyring_seed(*_keyring) == 0,"Failed to seed keyring");
- }
-
- return 1;
-error:
- return 0;
-}
-
-int serval_init_keyring(unsigned char *sid,
- const size_t sid_len,
- const char *keyring_path,
- const size_t keyring_len,
- keyring_file **_keyring,
- unsigned char **key,
- int *key_len) {
- keyring_identity *new_ident;
-
- unsigned char *_sid = sid;
-
- if (sid) CHECK(sid_len == SID_SIZE,"Invalid SID");
-
- CHECK_ERR(serval_open_keyring(keyring_path,keyring_len,_keyring),"Failed to open keyring");
-
- if (!sid) {
- //create new sid
- int c;
- for(c = 0; c < (*_keyring)->context_count; c++) { // cycle through the keyring contexts until we find one with room for another identity
- new_ident = keyring_create_identity(*_keyring,(*_keyring)->contexts[c], KEYRING_PIN); // create new Serval identity
- if (new_ident)
- break;
- }
- CHECK_ERR(new_ident,"failed to create new SID");
-
- CHECK_ERR(keyring_commit(*_keyring) == 0,"Failed to save new SID into keyring"); // need to commit keyring or else new identity won't be saved (needs permissions)
-
- _sid = new_ident->subscriber->sid;
- }
-
- if (key)
- CHECK(serval_extract_sas(key,key_len, *_keyring, _sid),"Failed to fetch SAS key");
-
+static int
+serval_extract_sas(svl_crypto_ctx *ctx)
+{
+ CHECK(ctx,"Invalid ctx");
+ // get SAS key associated with our SID
+ unsigned char *sas_public = NULL;
+ unsigned char *sas_private = keyring_find_sas_private(ctx->keyring_file, ctx->sid, &sas_public);
+ CHECK(sas_private && sas_public,"Failed to fetch SAS private key");
+ memcpy(ctx->sas_private, sas_private, crypto_sign_SECRETKEYBYTES);
+ memcpy(ctx->sas_public, sas_public, crypto_sign_PUBLICKEYBYTES);
return 1;
error:
return 0;
}
-int cmd_serval_sign(const char *sid_str,
- const size_t sid_len,
- const unsigned char *msg,
- const size_t msg_len,
- char *sig_str_buf,
- const size_t sig_str_size,
- const char *keyring_path,
- const size_t keyring_len) {
-
+/* Used by serval-client */
+static int
+keyring_send_sas_request_client(struct subscriber *subscriber)
+{
int ret = 0;
- unsigned char signed_msg[msg_len + SIGNATURE_BYTES];
- keyring_file *_keyring = NULL;
- unsigned char *key = NULL;
- unsigned char packedSid[SID_SIZE] = {0};
-
- CHECK(sig_str_size >= 2*SIGNATURE_BYTES + 1,"Signature buffer too small");
-
- if (sid_str) {
- CHECK_ERR(sid_len == 2*SID_SIZE && str_is_subscriber_id(sid_str) == 1,"Invalid SID");
- stowSid(packedSid,0,sid_str);
- }
-
- if (keyring_path) {
- CHECK_ERR(serval_init_keyring(sid_str ? packedSid : NULL,
- sid_str ? SID_SIZE : 0,
- keyring_path,
- keyring_len,
- &_keyring,
- &key,
- NULL), "Failed to initialize Serval keyring");
- } else {
- CHECK_ERR(serval_extract_sas(&key,NULL,keyring,packedSid),"Failed to fetch SAS key");
- }
-
- CHECK_ERR(serval_create_signature(key, msg, msg_len, signed_msg, SIGNATURE_BYTES + msg_len),"Failed to create signature");
-
- strncpy(sig_str_buf,alloca_tohex(signed_msg + msg_len,SIGNATURE_BYTES),2*SIGNATURE_BYTES);
- sig_str_buf[2*SIGNATURE_BYTES] = '\0';
-
- ret = 1;
-error:
- if (_keyring) keyring_free(_keyring);
- return ret;
-}
-
-static int keyring_send_sas_request_client(struct subscriber *subscriber){
- int sent, client_port, found = 0, ret = 0;
- int siglen=SID_SIZE+crypto_sign_edwards25519sha512batch_BYTES;
- unsigned char *srcsid[SID_SIZE] = {0}, *plain = NULL;
- unsigned char signature[siglen];
+ unsigned char *srcsid[SID_SIZE] = {0};
time_ms_t now = gettime_ms();
- CHECK_ERR(overlay_mdp_getmyaddr(0,(sid_t *)srcsid) == 0,"Could not get local address");
-
+ CHECK_ERR(overlay_mdp_getmyaddr(0, (sid_t *)srcsid) == 0, "Could not get local address");
+
if (subscriber->sas_valid)
return 1;
- CHECK_ERR(now >= subscriber->sas_last_request + 100,"Too soon to ask for SAS mapping again");
+ CHECK_ERR(now >= subscriber->sas_last_request + 100, "Too soon to ask for SAS mapping again");
- CHECK_ERR(my_subscriber,"couldn't request SAS (I don't know who I am)");
+ CHECK_ERR(my_subscriber, "Couldn't request SAS (I don't know who I am)");
DEBUG("Requesting SAS mapping for SID=%s", alloca_tohex_sid(subscriber->sid));
- CHECK_ERR(overlay_mdp_bind((sid_t *)my_subscriber->sid,(client_port=32768+(random()&32767))) == 0,"Failed to bind to client socket");
-
-/* request mapping (send request auth-crypted). */
+ int client_port = 32768 + (random() & 32767);
+ CHECK_ERR(overlay_mdp_bind((sid_t *)my_subscriber->sid, client_port) == 0,
+ "Failed to bind to client socket");
+
+ /* request mapping (send request auth-crypted). */
overlay_mdp_frame mdp;
- memset(&mdp,0,sizeof(mdp));
-
- mdp.packetTypeAndFlags=MDP_TX;
- mdp.out.queue=OQ_MESH_MANAGEMENT;
- memmove(mdp.out.dst.sid,subscriber->sid,SID_SIZE);
- mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST;
- mdp.out.src.port=client_port;
- memmove(mdp.out.src.sid,srcsid,SID_SIZE);
- mdp.out.payload_length=1;
- mdp.out.payload[0]=KEYTYPE_CRYPTOSIGN;
-
- sent = overlay_mdp_send(&mdp, 0,0);
+ memset(&mdp, 0, sizeof(mdp));
+
+ mdp.packetTypeAndFlags = MDP_TX;
+ mdp.out.queue = OQ_MESH_MANAGEMENT;
+ memmove(mdp.out.dst.sid, subscriber->sid, SID_SIZE);
+ mdp.out.dst.port = MDP_PORT_KEYMAPREQUEST;
+ mdp.out.src.port = client_port;
+ memmove(mdp.out.src.sid, srcsid, SID_SIZE);
+ mdp.out.payload_length = 1;
+ mdp.out.payload[0] = KEYTYPE_CRYPTOSIGN;
+
+ int sent = overlay_mdp_send(&mdp, 0, 0);
if (sent) {
DEBUG("Failed to send SAS resolution request: %d", sent);
- CHECK_ERR(mdp.packetTypeAndFlags != MDP_ERROR,"MDP Server error #%d: '%s'",mdp.error.error,mdp.error.message);
+ CHECK_ERR(mdp.packetTypeAndFlags != MDP_ERROR, "MDP Server error #%d: '%s'", mdp.error.error, mdp.error.message);
}
time_ms_t timeout = now + 5000;
-
- while(now0) {
- int ttl=-1;
- if (overlay_mdp_recv(&mdp, client_port, &ttl)==0) {
- switch(mdp.packetTypeAndFlags&MDP_TYPE_MASK) {
+ if (result > 0) {
+ int ttl = -1;
+ if (overlay_mdp_recv(&mdp, client_port, &ttl) == 0) {
+ int found = 0;
+ switch(mdp.packetTypeAndFlags & MDP_TYPE_MASK) {
case MDP_ERROR:
ERROR("overlay_mdp_recv: %s (code %d)", mdp.error.message, mdp.error.error);
break;
case MDP_TX:
- {
DEBUG("Received SAS mapping response");
found = 1;
break;
- }
- break;
default:
DEBUG("overlay_mdp_recv: Unexpected MDP frame type 0x%x", mdp.packetTypeAndFlags);
break;
}
- if (found) break;
+ if (found)
+ break;
}
}
- now=gettime_ms();
+ now = gettime_ms();
if (servalShutdown)
break;
}
-
+
unsigned keytype = mdp.out.payload[0];
- CHECK_ERR(keytype == KEYTYPE_CRYPTOSIGN,"Ignoring SID:SAS mapping with unsupported key type %u", keytype);
+ CHECK_ERR(keytype == KEYTYPE_CRYPTOSIGN, "Ignoring SID:SAS mapping with unsupported key type %u", keytype);
- CHECK_ERR(mdp.out.payload_length >= 1 + SAS_SIZE,"Truncated key mapping announcement? payload_length: %d", mdp.out.payload_length);
+ CHECK_ERR(mdp.out.payload_length >= 1 + SAS_SIZE,
+ "Truncated key mapping announcement? payload_length: %d",
+ mdp.out.payload_length);
- plain = (unsigned char*)calloc(mdp.out.payload_length,sizeof(unsigned char));
- unsigned long long plain_len=0;
- unsigned char *sas_public=&mdp.out.payload[1];
- unsigned char *compactsignature = &mdp.out.payload[1+SAS_SIZE];
+ unsigned char *plain = (unsigned char*)calloc(mdp.out.payload_length,sizeof(unsigned char));
+ unsigned long long plain_len = 0;
+ unsigned char *sas_public = &mdp.out.payload[1];
+ unsigned char *compactsignature = &mdp.out.payload[SAS_SIZE + 1];
/* reconstitute signed SID for verification */
- memmove(&signature[0],&compactsignature[0],64);
- memmove(&signature[64],&mdp.out.src.sid[0],SID_SIZE);
+ unsigned char signature[SID_SIZE + crypto_sign_edwards25519sha512batch_BYTES];
+ memmove(&signature[0], &compactsignature[0], 64);
+ memmove(&signature[64], &mdp.out.src.sid[0], SID_SIZE);
+
+ int sign_ret = crypto_sign_edwards25519sha512batch_open(plain,
+ &plain_len,
+ signature,
+ SID_SIZE + crypto_sign_edwards25519sha512batch_BYTES,
+ sas_public);
+ CHECK_ERR(sign_ret == 0, "SID:SAS mapping verification signature does not verify");
- int r=crypto_sign_edwards25519sha512batch_open(plain,&plain_len,
- signature,siglen,
- sas_public);
- CHECK_ERR(r == 0,"SID:SAS mapping verification signature does not verify");
-
/* These next two tests should never be able to fail, but let's just check anyway. */
- CHECK_ERR(plain_len == SID_SIZE,"SID:SAS mapping signed block is wrong length");
- CHECK_ERR(memcmp(plain, mdp.out.src.sid, SID_SIZE) == 0,"SID:SAS mapping signed block is for wrong SID");
+ CHECK_ERR(plain_len == SID_SIZE, "SID:SAS mapping signed block is wrong length");
+ CHECK_ERR(memcmp(plain, mdp.out.src.sid, SID_SIZE) == 0, "SID:SAS mapping signed block is for wrong SID");
memmove(subscriber->sas_public, sas_public, SAS_SIZE);
- subscriber->sas_valid=1;
- subscriber->sas_last_request=now;
+ subscriber->sas_valid = 1;
+ subscriber->sas_last_request = now;
ret = 1;
-error:
- if (plain) free(plain);
+ error:
+ if (plain)
+ free(plain);
return ret;
}
-int cmd_serval_verify(const char *sas_key,
- const size_t sas_key_len,
- const unsigned char *msg,
- const size_t msg_len,
- const char *sig,
- const size_t sig_len) {
- int verdict = 0;
+/* Public */
+
+svl_crypto_ctx *
+svl_crypto_ctx_new(void)
+{
+ svl_crypto_ctx *ctx = h_calloc(1,sizeof(svl_crypto_ctx));
+ CHECK_MEM(ctx);
+ return ctx;
+error:
+ return NULL;
+}
+
+void
+svl_crypto_ctx_free(svl_crypto_ctx *ctx)
+{
+ if (!ctx)
+ return;
+ if (ctx->keyring_file)
+ keyring_free(ctx->keyring_file);
+ h_free(ctx);
+}
+
+int
+serval_open_keyring(svl_crypto_ctx *ctx)
+{
+ CHECK_ERR(ctx,"Invalid ctx");
+ if (ctx->keyring_len == 0) {
+ // if no keyring specified, use default keyring
+ CHECK(serval_path,"Default Serval path not initialized");
+ char keyring_path_str[PATH_MAX] = {0};
+ strcpy(keyring_path_str, serval_path);
+ if (serval_path[strlen(serval_path) - 1] != '/')
+ strcat(keyring_path_str, "/");
+ strcat(keyring_path_str, "serval.keyring");
+ // Fetching SAS keys requires setting the SERVALINSTANCE_PATH environment variable
+ CHECK_ERR(setenv("SERVALINSTANCE_PATH", serval_path, 1) == 0,
+ "Failed to set SERVALINSTANCE_PATH env variable");
+ ctx->keyring_len = strlen(keyring_path_str);
+ ctx->keyring_path = h_malloc(ctx->keyring_len + 1);
+ strcpy(ctx->keyring_path,keyring_path_str);
+ hattach(ctx->keyring_path,ctx);
+ } else {
+ // otherwise, use specified keyring (NOTE: if keyring does not exist, it will be created)
+ CHECK(ctx->keyring_len < PATH_MAX, "Keyring length too long");
+ }
+
+ ctx->keyring_file = keyring_open(ctx->keyring_path);
+ CHECK_ERR(ctx->keyring_file, "Failed to open specified keyring file");
+
+ if (keyring_enter_pin(ctx->keyring_file, KEYRING_PIN) <= 0) {
+ // put initial identity in if we don't have any visible
+ CHECK_ERR(keyring_seed(ctx->keyring_file) == 0, "Failed to seed keyring");
+ }
- unsigned char bin_sig[SIGNATURE_BYTES];
- unsigned char bin_sas[SAS_SIZE];
+ return 1;
+error:
+ return 0;
+}
+
+int
+serval_init_keyring(svl_crypto_ctx *ctx)
+{
+ keyring_identity *new_ident;
- CHECK_ERR(sig_len == 2*SIGNATURE_BYTES,"Invalid signature");
- CHECK_ERR(sas_key_len == 2*SAS_SIZE,"Invalid SAS key");
+ CHECK_ERR(ctx,"Invalid ctx");
- // convert signature from hex to binary
- CHECK_ERR(fromhexstr(bin_sig,sig,SIGNATURE_BYTES) == 0,"Invalid signature");
- CHECK_ERR(fromhexstr(bin_sas,sas_key,SAS_SIZE) == 0,"Invalid SAS key");
+ CHECK_ERR(serval_open_keyring(ctx), "Failed to open keyring");
- DEBUG("Message to verify:\n%s",msg);
+ if (!ctx->sid[0]) { //create new sid
+ // cycle through the keyring contexts until we find one with room for another identity
+ for(int c = 0; c < (ctx->keyring_file)->context_count; c++) {
+ // create new Serval identity
+ new_ident = keyring_create_identity(ctx->keyring_file,
+ (ctx->keyring_file)->contexts[c],
+ KEYRING_PIN);
+ if (new_ident)
+ break;
+ }
+ CHECK_ERR(new_ident, "Failed to create new SID");
+
+ // need to commit keyring or else new identity won't be saved (needs permissions)
+ CHECK_ERR(keyring_commit(ctx->keyring_file) == 0, "Failed to save new SID into keyring");
+
+ memcpy(ctx->sid,new_ident->subscriber->sid,SID_SIZE);
+ }
- unsigned char hash[crypto_hash_sha512_BYTES];
- crypto_hash_sha512(hash,msg,msg_len);
+ CHECK(serval_extract_sas(ctx), "Failed to fetch SAS keys");
- if (crypto_verify_signature(bin_sas, hash, crypto_hash_sha512_BYTES,
- &bin_sig[0], SIGNATURE_BYTES) == 0)
+ return 1;
+error:
+ return 0;
+}
+
+int
+cmd_serval_sign(svl_crypto_ctx *ctx)
+{
+ CHECK_ERR(ctx,"Invalid ctx");
+
+ /* If a non-default keyring path is given, and/or no SID is set,
+ * we need to initialize the keyring */
+ if (ctx->keyring_path || !ctx->sid[0]) {
+ CHECK_ERR(serval_init_keyring(ctx),
+ "Failed to initialize Serval keyring");
+ } else {
+ // or just use the default keyring
+ ctx->keyring_file = keyring; // serval global
+ CHECK_ERR(serval_extract_sas(ctx),
+ "Failed to fetch SAS keys");
+ }
+
+ CHECK_ERR(serval_create_signature(ctx),"Failed to create signature");
+
+ return 1;
+error:
+ return 0;
+}
+
+int
+cmd_serval_verify(svl_crypto_ctx *ctx)
+{
+ int verdict = 0;
+
+ CHECK_ERR(ctx && ctx->msg && ctx->signature[0] && ctx->sas_public[0],"Invalid ctx");
+
+ DEBUG("Message to verify:\n%s", ctx->msg);
+
+ unsigned char hash[crypto_hash_sha512_BYTES];
+ crypto_hash_sha512(hash, ctx->msg, ctx->msg_len);
+
+ int sig_ret = crypto_verify_signature(ctx->sas_public,
+ hash,
+ crypto_hash_sha512_BYTES,
+ ctx->signature,
+ SIGNATURE_BYTES);
+ if (sig_ret == 0)
verdict = 1; // successfully verified
error:
return verdict;
}
-int serval_verify_client(const char *sid_str,
- const size_t sid_len,
- const unsigned char *msg,
- const size_t msg_len,
- const char *sig,
- const size_t sig_len,
- const char *keyring_path,
- const size_t keyring_len) {
-
- int verdict = 0;
- char sas_str[2*SAS_SIZE+1] = {0};
- unsigned char packedSid[SID_SIZE] = {0};
-
- CHECK(sid_len == 2*SID_SIZE,"Invalid SID length");
- CHECK(sig_len == 2*SIGNATURE_BYTES,"Invalid signature length");
-
- CHECK(str_is_subscriber_id(sid_str) != 0,"Invalid SID");
- stowSid(packedSid,0,sid_str);
-
- CHECK(serval_init_keyring(packedSid,
- SID_SIZE,
- keyring_path,
- keyring_len,
- &keyring,
- NULL,
- NULL), "Failed to initialize Serval keyring");
+/* Used by serval-client */
+int
+serval_verify_client(svl_crypto_ctx *ctx)
+{
+ CHECK(ctx && ctx->sid[0] && ctx->msg && ctx->signature[0] && ctx->keyring_path,
+ "Invalid ctx");
+
+ CHECK(serval_init_keyring(ctx), "Failed to initialize Serval keyring");
- struct subscriber *sub = find_subscriber(packedSid, SID_SIZE, 1); // get Serval identity described by given SID
+ struct subscriber *sub = find_subscriber(ctx->sid, SID_SIZE, 1); // get Serval identity described by given SID
- CHECK(sub,"Failed to fetch Serval subscriber");
+ CHECK(sub, "Failed to fetch Serval subscriber");
- CHECK(keyring_send_sas_request_client(sub),"SAS request failed");
+ CHECK(keyring_send_sas_request_client(sub), "SAS request failed");
- CHECK(sub->sas_valid,"Could not validate the signing key!");
- CHECK(sub->sas_public[0],"Could not validate the signing key!");
- CHECK(tohex(sas_str,sub->sas_public,SAS_SIZE),"Failed to convert signing key");
+ CHECK(sub->sas_valid, "Could not validate the signing key!");
+ CHECK(sub->sas_public[0], "Could not validate the signing key!");
- verdict = cmd_serval_verify(sas_str,2*SAS_SIZE,
- msg,msg_len,sig,sig_len);
+ memcpy(ctx->sas_public,sub->sas_public,crypto_sign_PUBLICKEYBYTES);
+ return cmd_serval_verify(ctx);
error:
- return verdict;
+ return 0;
}
-int serval_crypto_register(void) {
+int
+serval_crypto_register(void)
+{
/** name: serval-crypto
* param[0] - param[3]: (co_str?_t)
*/
@@ -390,35 +393,46 @@ int serval_crypto_register(void) {
const char name[] = "serval-crypto",
usage[] = "serval-crypto sign [] [--keyring=]\n"
"serval-crypto verify ",
- desc[] = "Serval-crypto utilizes Serval's crypto API to:\n"
- " * Sign any arbitrary text using a Serval key. If no Serval key ID (SID) is given,\n"
- " a new key will be created on the default Serval keyring.\n"
- " * Verify any arbitrary text, a signature, and a Serval signing key (SAS), and will\n"
- " determine if the signature is valid.";
-
- CHECK(co_cmd_register(name,sizeof(name),usage,sizeof(usage),desc,sizeof(desc),serval_crypto_handler),"Failed to register commands");
+ desc[] = "Serval-crypto utilizes Serval's crypto API to:\n"
+ " * Sign any arbitrary text using a Serval key. If no Serval key ID (SID) is given,\n"
+ " a new key will be created on the default Serval keyring.\n"
+ " * Verify any arbitrary text, a signature, and a Serval signing key (SAS), and will\n"
+ " determine if the signature is valid.";
+
+ int reg_ret = co_cmd_register(name,
+ sizeof(name),
+ usage,
+ sizeof(usage),
+ desc,
+ sizeof(desc),
+ serval_crypto_handler);
+ CHECK(reg_ret, "Failed to register commands");
return 1;
error:
return 0;
}
-int olsrd_mdp_register(void) {
+int
+olsrd_mdp_register(void)
+{
/**
* name: mdp-init
- * param[0] : (co_str8_t)
- * param[1] : (co_str16_t)
+ * param[0] : (co_str16_t)
+ * param[1] : (co_str8_t)
*/
const char name[] = "mdp-init";
- CHECK(co_cmd_register(name,sizeof(name),"",1,"",1,olsrd_mdp_init),"Failed to register command");
+ CHECK(co_cmd_register(name, sizeof(name), "", 1, "", 1, olsrd_mdp_init), "Failed to register command");
return 1;
error:
return 0;
}
-int olsrd_mdp_sign_register(void) {
+int
+olsrd_mdp_sign_register(void)
+{
/**
* name: mdp-sign
* param[0] : key (co_bin8_t)
@@ -427,68 +441,92 @@ int olsrd_mdp_sign_register(void) {
const char name[] = "mdp-sign";
- CHECK(co_cmd_register(name,sizeof(name),"",1,"",1,olsrd_mdp_sign),"Failed to register command");
+ CHECK(co_cmd_register(name, sizeof(name), "", 1, "", 1, olsrd_mdp_sign), "Failed to register command");
return 1;
error:
return 0;
}
-int serval_crypto_handler(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
+int
+serval_crypto_handler(co_obj_t *self, co_obj_t **output, co_obj_t *params)
+{
CLEAR_ERR();
- int list_len = co_list_length(params), keypath = 0;
+ svl_crypto_ctx *ctx = NULL;
+ int list_len = co_list_length(params);
+ int keypath = 0;
- CHECK_ERR(IS_LIST(params) && list_len >= 2,"Invalid params");
+ CHECK_ERR(IS_LIST(params) && list_len >= 2, "Invalid params");
- if (!strncmp("--keyring=",co_obj_data_ptr(co_list_get_last(params)),10)) {
+ if (!strncmp("--keyring=", co_obj_data_ptr(co_list_get_last(params)), 10)) {
keypath = 1;
--list_len;
}
- if (co_str_cmp_str(co_list_element(params,0),"sign") == 0) {
+ ctx = svl_crypto_ctx_new();
+
+ if (co_str_cmp_str(co_list_element(params, 0), "sign") == 0) {
+
+ CHECK_ERR(list_len == 2 || list_len == 3, "Invalid arguments");
- CHECK_ERR(list_len == 2 || list_len == 3,"Invalid arguments");
- char sig_buf[2*SIGNATURE_BYTES + 1] = {0};
if (list_len == 3) {
- CHECK_ERR(cmd_serval_sign(_LIST_ELEMENT(params,1),
- co_str_len(co_list_element(params,1)) - 1,
- (unsigned char*)_LIST_ELEMENT(params,2),
- co_str_len(co_list_element(params,2)) - 1,
- sig_buf,
- 2*SIGNATURE_BYTES + 1,
- keypath ? _LIST_ELEMENT(params,3) + 10 : NULL, // strlen("--length=") == 10
- keypath ? co_str_len(co_list_element(params,3)) - 11 : 0),"Failed to create signature");
+ char *sid_str = _LIST_ELEMENT(params, 1);
+ size_t sid_len = co_str_len(co_list_element(params, 1)) - 1;
+ CHECK_ERR(sid_len == (2 * SID_SIZE) && str_is_subscriber_id(sid_str) == 1,
+ "Invalid SID");
+ stowSid(ctx->sid, 0, sid_str);
+ ctx->msg = (unsigned char*)_LIST_ELEMENT(params, 2);
+ ctx->msg_len = co_str_len(co_list_element(params, 2)) - 1;
+ if (keypath) {
+ ctx->keyring_path = _LIST_ELEMENT(params, 3) + 10;
+ ctx->keyring_len = co_str_len(co_list_element(params, 3)) - 11;
+ CHECK_ERR(ctx->keyring_len < PATH_MAX,"Keyring path too long");
+ }
+
} else if (list_len == 2) {
- CHECK_ERR(cmd_serval_sign(NULL,
- 0,
- (unsigned char*)_LIST_ELEMENT(params,1),
- co_str_len(co_list_element(params,1)) - 1,
- sig_buf,
- 2*SIGNATURE_BYTES + 1,
- keypath ? _LIST_ELEMENT(params,2) + 10 : NULL, // strlen("--length=") == 10
- keypath ? co_str_len(co_list_element(params,2)) - 11 : 0),"Failed to create signature");
+
+ ctx->msg = (unsigned char*)_LIST_ELEMENT(params, 1);
+ ctx->msg_len = co_str_len(co_list_element(params, 1)) - 1;
+ if (keypath) {
+ ctx->keyring_path = _LIST_ELEMENT(params, 2) + 10;
+ ctx->keyring_len = co_str_len(co_list_element(params, 2)) - 11;
+ CHECK_ERR(ctx->keyring_len < PATH_MAX,"Keyring path too long");
+ }
+
}
- CMD_OUTPUT("result",co_str8_create(sig_buf,2*SIGNATURE_BYTES+1,0));
+ CHECK_ERR(cmd_serval_sign(ctx), "Failed to create signature");
- } else if (co_str_cmp_str(co_list_element(params,0),"verify") == 0) {
+ // convert ctx->signature, ctx->sas_public, and ctx->sid to hex:
+ char sid_str[(2 * SID_SIZE) + 1] = {0};
+ strncpy(sid_str, alloca_tohex(ctx->sid, SID_SIZE), 2 * SID_SIZE);
+ char sas_str[(2 * crypto_sign_PUBLICKEYBYTES) + 1] = {0};
+ strncpy(sas_str, alloca_tohex(ctx->sas_public, crypto_sign_PUBLICKEYBYTES), 2 * crypto_sign_PUBLICKEYBYTES);
+ char sig_str[(2 * SIGNATURE_BYTES) + 1] = {0};
+ strncpy(sig_str, alloca_tohex(ctx->signature, SIGNATURE_BYTES), 2 * SIGNATURE_BYTES);
+ CMD_OUTPUT("SID", co_str8_create(sid_str, (2 * SID_SIZE) + 1, 0));
+ CMD_OUTPUT("SAS", co_str8_create(sas_str, (2 * crypto_sign_PUBLICKEYBYTES) + 1, 0));
+ CMD_OUTPUT("signature", co_str8_create(sig_str, (2 * SIGNATURE_BYTES) + 1, 0));
- CHECK_ERR(!keypath,"Keyring option not available for verification");
- CHECK_ERR(list_len == 4,"Invalid arguments");
- int verdict = cmd_serval_verify(_LIST_ELEMENT(params,1),
- co_str_len(co_list_element(params,1)) - 1,
- (unsigned char*)_LIST_ELEMENT(params,3),
- co_str_len(co_list_element(params,3)) - 1,
- _LIST_ELEMENT(params,2),
- co_str_len(co_list_element(params,2)) - 1);
-// keypath ? _LIST_ELEMENT(params,4) + 10 : NULL, // strlen("--length=") == 10
-// keypath ? co_str_len(co_list_element(params,4)) - 10 : 0);
+ } else if (co_str_cmp_str(co_list_element(params, 0), "verify") == 0) {
+
+ CHECK_ERR(!keypath, "Keyring option not available for verification");
+ CHECK_ERR(list_len == 4, "Invalid arguments");
+ // convert SAS and signature from hex to bin
+ CHECK_ERR(fromhexstr(ctx->signature, _LIST_ELEMENT(params, 2), SIGNATURE_BYTES) == 0, "Invalid signature");
+ CHECK_ERR(fromhexstr(ctx->sas_public, _LIST_ELEMENT(params, 1), crypto_sign_PUBLICKEYBYTES) == 0, "Invalid SAS key");
+ ctx->msg = (unsigned char*)_LIST_ELEMENT(params, 3);
+ ctx->msg_len = co_str_len(co_list_element(params, 3)) - 1;
+
+ int verdict = cmd_serval_verify(ctx);
if (verdict == 1) {
DEBUG("signature verified");
- CMD_OUTPUT("result",co_bool_create(true,0)); // successfully verified
+ CMD_OUTPUT("result", co_bool_create(true, 0)); // successfully verified
+ CMD_OUTPUT("verified",co_str8_create("true",sizeof("true"),0));
} else if (verdict == 0) {
DEBUG("signature NOT verified");
- CMD_OUTPUT("result",co_bool_create(false,0));
+ CMD_OUTPUT("result", co_bool_create(false, 0));
+ CMD_OUTPUT("verified",co_str8_create("false",sizeof("false"),0));
}
}
@@ -496,60 +534,61 @@ int serval_crypto_handler(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
return 1;
error:
INS_ERROR();
+ if (ctx)
+ svl_crypto_ctx_free(ctx);
return 0;
}
-int olsrd_mdp_init(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
- keyring_file *mdp_keyring = NULL;
- unsigned char *mdp_key = NULL;
- int mdp_key_len = 0;
- unsigned char packedSid[SID_SIZE] = {0};
+int
+olsrd_mdp_init(co_obj_t *self, co_obj_t **output, co_obj_t *params)
+{
+ svl_crypto_ctx *ctx = NULL;
+ CHECK(IS_LIST(params) && co_list_length(params) == 2, "Invalid params");
- CHECK(IS_LIST(params) && co_list_length(params) == 2,"Invalid params");
+ size_t sid_len = co_str_len(co_list_element(params, 1));
+ char *sid_str = _LIST_ELEMENT(params, 1);
- size_t sid_len = co_str_len(co_list_element(params,1));
- char *sid_str = _LIST_ELEMENT(params,1);
+ CHECK(sid_len == (2 * SID_SIZE) + 1 && str_is_subscriber_id(sid_str) == 1, "Invalid SID");
- CHECK(sid_len == 2*SID_SIZE + 1 && str_is_subscriber_id(sid_str) == 1,"Invalid SID");
- stowSid(packedSid,0,sid_str);
+ ctx = svl_crypto_ctx_new();
- CHECK(serval_init_keyring(packedSid,
- SID_SIZE,
- _LIST_ELEMENT(params,0),
- co_str_len(co_list_element(params,0)),
- &mdp_keyring,
- &mdp_key,
- &mdp_key_len), "Failed to initialize Serval keyring");
+ stowSid(ctx->sid, 0, sid_str);
- CMD_OUTPUT("key",co_bin8_create((char*)mdp_key,mdp_key_len,0));
+ ctx->keyring_path = _LIST_ELEMENT(params, 0);
+ ctx->keyring_len = co_str_len(co_list_element(params, 0)) - 1;
+ CHECK_ERR(ctx->keyring_len < PATH_MAX,"Keyring path too long");
+
+ CHECK(serval_init_keyring(ctx), "Failed to initialize Serval keyring");
+
+ CMD_OUTPUT("key", co_bin8_create((char*)ctx->sas_private, crypto_sign_SECRETKEYBYTES, 0));
return 1;
error:
+ if (ctx)
+ svl_crypto_ctx_free(ctx);
return 0;
}
-int olsrd_mdp_sign(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
- int msg_len = 0, ret = 0, sig_buf_len;
- unsigned char *msg = NULL, *sig_buf = NULL;
+int
+olsrd_mdp_sign(co_obj_t *self, co_obj_t **output, co_obj_t *params)
+{
+ int ret = 0;
+ svl_crypto_ctx *ctx = svl_crypto_ctx_new();
/** skipping some error checking for performance reasons */
-// CHECK(IS_LIST(params) && co_list_length(params) == 2,"Invalid params");
+// CHECK(IS_LIST(params) && co_list_length(params) == 2, "Invalid params");
+
+ ctx->msg_len = co_obj_data((char**)&ctx->msg, co_list_element(params, 1));
- msg_len = co_obj_data((char**)&msg,co_list_element(params,1));
- sig_buf_len = SIGNATURE_BYTES + msg_len + 1;
- sig_buf = calloc(sig_buf_len,sizeof(unsigned char));
+ memcpy(ctx->sas_private,_LIST_ELEMENT(params, 0),crypto_sign_SECRETKEYBYTES);
- CHECK(serval_create_signature((unsigned char*)_LIST_ELEMENT(params,0),
- msg,
- msg_len,
- sig_buf,
- sig_buf_len),"Failed to sign OLSRd packet");
+ CHECK(serval_create_signature(ctx), "Failed to sign OLSRd packet");
- CMD_OUTPUT("sig",co_bin8_create((char*)(sig_buf+msg_len),SIGNATURE_BYTES,0));
+ CMD_OUTPUT("sig", co_bin8_create((char*)ctx->signature, SIGNATURE_BYTES, 0));
ret = 1;
error:
- if (sig_buf) free(sig_buf);
+ svl_crypto_ctx_free(ctx);
return ret;
}
diff --git a/plugins/serval-dna/crypto.h b/plugins/serval-dna/crypto.h
index 07a503b..a92b42d 100644
--- a/plugins/serval-dna/crypto.h
+++ b/plugins/serval-dna/crypto.h
@@ -38,6 +38,25 @@
#define KEYRING_PIN NULL
#define BUF_SIZE 1024
+#define crypto_sign_PUBLICKEYBYTES crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES
+#define crypto_sign_SECRETKEYBYTES crypto_sign_edwards25519sha512batch_SECRETKEYBYTES
+#define SIGNATURE_BYTES crypto_sign_edwards25519sha512batch_BYTES
+
+struct svl_crypto_ctx {
+ char *keyring_path;
+ size_t keyring_len;
+ keyring_file *keyring_file;
+ unsigned char sid[SID_SIZE]; // SID public key
+ unsigned char sas_public[crypto_sign_PUBLICKEYBYTES]; // SAS public key
+ unsigned char sas_private[crypto_sign_SECRETKEYBYTES]; // SAS private key
+ unsigned char signature[SIGNATURE_BYTES];
+ unsigned char *msg; // byte array used to create signature
+ size_t msg_len;
+};
+typedef struct svl_crypto_ctx svl_crypto_ctx;
+
+svl_crypto_ctx *svl_crypto_ctx_new(void);
+void svl_crypto_ctx_free(svl_crypto_ctx *ctx);
int serval_crypto_register(void);
@@ -51,41 +70,14 @@ int olsrd_mdp_init(co_obj_t *self, co_obj_t **output, co_obj_t *params);
int olsrd_mdp_sign(co_obj_t *self, co_obj_t **output, co_obj_t *params);
-int serval_open_keyring(const char *keyring_path,
- const size_t keyring_len,
- keyring_file **_keyring);
-
-int serval_init_keyring(unsigned char *sid,
- const size_t sid_len,
- const char *keyring_path,
- const size_t keyring_len,
- keyring_file **_keyring,
- unsigned char **key,
- int *key_len);
-
-int cmd_serval_sign(const char *sid_str,
- const size_t sid_len,
- const unsigned char *msg,
- const size_t msg_len,
- char *sig_str_buf,
- const size_t sig_str_size,
- const char *keyring_path,
- const size_t keyring_len);
-
-int cmd_serval_verify(const char *sas_key,
- const size_t sas_key_len,
- const unsigned char *msg,
- const size_t msg_len,
- const char *sig,
- const size_t sig_len);
-
-int serval_verify_client(const char *sid_str,
- const size_t sid_len,
- const unsigned char *msg,
- const size_t msg_len,
- const char *sig,
- const size_t sig_len,
- const char *keyring_path,
- const size_t keyring_len);
+int serval_open_keyring(svl_crypto_ctx *ctx);
+
+int serval_init_keyring(svl_crypto_ctx *ctx);
+
+int cmd_serval_sign(svl_crypto_ctx *ctx);
+
+int cmd_serval_verify(svl_crypto_ctx *ctx);
+
+int serval_verify_client(svl_crypto_ctx *ctx);
#endif
\ No newline at end of file
diff --git a/plugins/serval-dna/serval-client.c b/plugins/serval-dna/serval-client.c
index bfd473a..068997a 100644
--- a/plugins/serval-dna/serval-client.c
+++ b/plugins/serval-dna/serval-client.c
@@ -31,7 +31,6 @@
#include
#include
-#include
#include
#include
#include
@@ -57,7 +56,7 @@ typedef enum {
SERVAL_SIGN = 0,
SERVAL_VERIFY = 1,
SERVAL_CRYPTO = 2
-} serval_cmd;
+} serval_client_cmd;
#define _DECLARE_SERVAL(F) extern int F(const struct cli_parsed *parsed, void *context);
_DECLARE_SERVAL(commandline_usage);
@@ -204,7 +203,7 @@ static struct cli_schema command_line_options[]={
{NULL,{NULL}}
};
-static int print_usage(serval_cmd cmd) {
+static int print_usage(serval_client_cmd cmd) {
printf("Serval client\n");
printf("Usage:\n");
if (cmd == SERVAL_SIGN || cmd == SERVAL_CRYPTO) {
@@ -218,124 +217,117 @@ static int print_usage(serval_cmd cmd) {
return 1;
}
-int main(int argc, char *argv[]) {
- int ret = 1, opt = 0, opt_index = 0, keypath = 0;
- char keyring_path[PATH_MAX] = {0};
- char *keyring_opt = NULL;
- static const char *opt_string = "k:h";
-
- static struct option long_opts[] = {
- {"keyring", required_argument, NULL, 'k'},
- {"help", no_argument, NULL, 'h'}
- };
-
- opt = getopt_long(argc, argv, opt_string, long_opts, &opt_index);
-
- while(opt != -1) {
- switch(opt) {
- case 'k':
- keyring_opt = optarg;
- break;
- case 'h':
- default:
- print_usage(SERVAL_CRYPTO);
- return 0;
- break;
- }
- opt = getopt_long(argc, argv, opt_string, long_opts, &opt_index);
+static int serval_cmd(int argc, char *argv[]) {
+ struct cli_parsed parsed;
+ int result = cli_parse(argc, (const char*const*)argv, command_line_options, &parsed);
+ switch (result) {
+ case 0:
+ // Do not run the command if the configuration does not load ok.
+ if (((parsed.commands[parsed.cmdi].flags & CLIFLAG_PERMISSIVE_CONFIG) ? cf_reload_permissive() : cf_reload()) != -1) {
+ if (cli_invoke(&parsed, NULL) == 0) {
+ return 0;
+ }
+ }
+ break;
+ case 1:
+ case 2:
+ // Load configuration so that log messages can get out.
+ cf_reload_permissive();
+ // NOWHENCE(HINTF("Run \"%s help\" for more information.", argv0 ? argv0 : "servald"));
+ break;
+ default:
+ // Load configuration so that log error messages can get out.
+ cf_reload_permissive();
+ break;
}
+ return 1;
+}
+
+int main(int argc, char *argv[]) {
+ int ret = 1;
+ char *instance_path = NULL;
+ svl_crypto_ctx *ctx = svl_crypto_ctx_new();
+ CHECK_MEM(ctx);
- if (keyring_opt) {
- CHECK(strlen(keyring_opt) < PATH_MAX,"keyring path too long");
- strcpy(keyring_path,keyring_opt);
+ // Run the Serval command
+
+ if (!strncmp("--keyring=",argv[argc-1],10)) {
+ CHECK(strlen(argv[argc-1] + 10) < PATH_MAX,"keyring path too long");
+ ctx->keyring_path = argv[argc-1] + 10;
+ argc--;
} else {
- strcpy(keyring_path,DEFAULT_SERVAL_PATH);
- strcpy(keyring_path,"/");
- strcpy(keyring_path,"serval.keyring");
+ // add default path to ctx->keyring_path
+ ctx->keyring_path = h_malloc(strlen(DEFAULT_SERVAL_PATH) + strlen("/serval.keyring"));
+ hattach(ctx->keyring_path,ctx);
+ strcpy(ctx->keyring_path,DEFAULT_SERVAL_PATH);
+ strcat(ctx->keyring_path,"/serval.keyring");
}
+ ctx->keyring_len = strlen(ctx->keyring_path);
- // Run the Serval command
-
- if (!strcmp(argv[optind],"sign")) {
- if (argc - optind <= 2 || argc - optind >= 4) {
+ argc--;
+ argv++;
+ if (!strcmp(argv[0],"sign")) {
+ if (argc < 2 || argc > 3) {
print_usage(SERVAL_SIGN);
goto error;
}
char sig_buf[2*SIGNATURE_BYTES + 1] = {0};
- if (!strncmp("--keyring=",argv[argc-1],10)) {
- keypath = 1;
- argc--;
- }
- char keyring_path[PATH_MAX] = {0};
- FORM_SERVAL_INSTANCE_PATH(keyring_path, "serval.keyring");
- if (argc - optind == 3) {
- CHECK(cmd_serval_sign(argv[optind+1],
- strlen(argv[optind+1]),
- (unsigned char*)argv[optind+2],
- strlen(argv[optind+2]),
- sig_buf,
- 2*SIGNATURE_BYTES + 1,
- keypath ? argv[optind+3] + 10 : keyring_path, // strlen("--length=") == 10
- keypath ? strlen(argv[optind+3] + 10) : strlen(keyring_path)),"Failed to create signature");
- } else if (argc - optind == 2) {
- CHECK(cmd_serval_sign(NULL,
- 0,
- (unsigned char*)argv[optind+1],
- strlen(argv[optind+1]),
- sig_buf,
- 2*SIGNATURE_BYTES + 1,
- keypath ? argv[optind+2] + 10 : keyring_path, // strlen("--length=") == 10
- keypath ? strlen(argv[optind+2] + 10) : strlen(keyring_path)),"Failed to create signature");
+ if (argc == 3) {
+ char *sid_str = argv[1];
+ CHECK(strlen(sid_str) == (2 * SID_SIZE) && str_is_subscriber_id(sid_str) == 1,
+ "Invalid SID");
+ stowSid(ctx->sid, 0, sid_str);
+ ctx->msg = (unsigned char*)argv[2];
+ ctx->msg_len = strlen(argv[2]);
+ } else if (argc == 2) {
+ ctx->msg = (unsigned char*)argv[1];
+ ctx->msg_len = strlen(argv[1]);
}
+ CHECK(cmd_serval_sign(ctx), "Failed to create signature");
+ // convert ctx->signature to hex:
+ strncpy(sig_buf, alloca_tohex(ctx->signature, SIGNATURE_BYTES), 2 * SIGNATURE_BYTES);
+ sig_buf[2 * SIGNATURE_BYTES] = '\0';
printf("%s\n",sig_buf);
- } else if (!strcmp(argv[optind],"verify")) {
- if (argc - optind != 4) {
+ } else if (!strcmp(argv[0],"verify")) {
+ if (argc != 4) {
print_usage(SERVAL_VERIFY);
goto error;
}
- int verdict = serval_verify_client(argv[optind+1],
- strlen(argv[optind+1]),
- (unsigned char*)argv[optind+3],
- strlen(argv[optind+3]),
- argv[optind+2],
- strlen(argv[optind+2]),
- keyring_path,
- strlen(keyring_path));
+
+ // Set SERVALINSTANCE_PATH environment variable
+ char *last_slash = strrchr(ctx->keyring_path,(int)'/');
+ instance_path = calloc(last_slash - ctx->keyring_path + 1,sizeof(char));
+ strncpy(instance_path,ctx->keyring_path,last_slash - ctx->keyring_path);
+ CHECK(setenv("SERVALINSTANCE_PATH", instance_path, 1) == 0,
+ "Failed to set SERVALINSTANCE_PATH env variable");
+
+ char *sid_str = argv[1];
+ CHECK(strlen(sid_str) == (2 * SID_SIZE) && str_is_subscriber_id(sid_str) == 1,
+ "Invalid SID");
+ stowSid(ctx->sid, 0, sid_str);
+ CHECK(fromhexstr(ctx->signature, argv[2], SIGNATURE_BYTES) == 0, "Invalid signature");
+ ctx->msg = (unsigned char*)argv[3];
+ ctx->msg_len = strlen(argv[3]);
+ int verdict = serval_verify_client(ctx);
if (verdict == 1)
printf("Message verified!\n");
else
printf("Message NOT verified!\n");
} else { // Serval built-in commands
- struct cli_parsed parsed;
- int result = cli_parse(argc - optind, (const char*const*)(argv + optind), command_line_options, &parsed);
- switch (result) {
- case 0:
- // Do not run the command if the configuration does not load ok.
- if (((parsed.commands[parsed.cmdi].flags & CLIFLAG_PERMISSIVE_CONFIG) ? cf_reload_permissive() : cf_reload()) != -1) {
- if (cli_invoke(&parsed, NULL) == 0) {
- ret = 0;
- }
- }
- break;
- case 1:
- case 2:
- // Load configuration so that log messages can get out.
- cf_reload_permissive();
- // NOWHENCE(HINTF("Run \"%s help\" for more information.", argv0 ? argv0 : "servald"));
- break;
- default:
- // Load configuration so that log error messages can get out.
- cf_reload_permissive();
- break;
- }
+ ret = serval_cmd(argc, argv);
}
/* clean up after ourselves */
overlay_mdp_client_done();
rhizome_close_db();
+ ret = 0;
error:
+ if (instance_path)
+ free(instance_path);
+ if (ctx)
+ svl_crypto_ctx_free(ctx);
return ret;
}
diff --git a/plugins/serval-dna/serval-dna.c b/plugins/serval-dna/serval-dna.c
index 766d1b8..d148519 100644
--- a/plugins/serval-dna/serval-dna.c
+++ b/plugins/serval-dna/serval-dna.c
@@ -395,6 +395,7 @@ static int serval_load_config(void) {
int co_plugin_init(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
char *enabled = NULL;
+ svl_crypto_ctx *ctx = NULL;
co_profile_get_str(co_profile_global(),&enabled,"servald",sizeof("servald"));
if (strcmp(enabled,"disabled") == 0) return 1;
@@ -403,7 +404,9 @@ int co_plugin_init(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
srandomdev();
CHECK(serval_load_config(),"Failed to load Serval config parameters");
- CHECK(serval_open_keyring(NULL,0,&keyring),"Failed to open keyring");
+ ctx = svl_crypto_ctx_new();
+ CHECK(serval_open_keyring(ctx),"Failed to open keyring");
+ keyring = ctx->keyring_file;
if (!serval_registered) {
// CHECK(serval_register(),"Failed to register Serval commands");
@@ -433,6 +436,8 @@ int co_plugin_init(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
return 1;
error:
+ if (ctx)
+ svl_crypto_ctx_free(ctx);
return 0;
}
@@ -488,6 +493,8 @@ static int serval_daemon_register(void) {
}
int serval_daemon_handler(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
+ svl_crypto_ctx *ctx = NULL;
+
CLEAR_ERR();
CHECK_ERR(IS_LIST(params) && co_list_length(params) == 1,"Invalid parameters");
@@ -500,13 +507,17 @@ int serval_daemon_handler(co_obj_t *self, co_obj_t **output, co_obj_t *params) {
CHECK_ERR(co_plugin_shutdown(NULL,NULL,NULL),"Failed to stop daemon");
} else*/ if (co_str_cmp_str(co_list_element(params,0),"reload") == 0) {
keyring_free(keyring);
- CHECK_ERR(serval_open_keyring(NULL,0,&keyring),"Failed to open keyring");
+ ctx = svl_crypto_ctx_new();
+ CHECK_ERR(serval_open_keyring(ctx),"Failed to open keyring");
+ keyring = ctx->keyring_file;
}
CMD_OUTPUT("result",co_str8_create("success",sizeof("success"),0));
return 1;
error:
+ if (ctx)
+ svl_crypto_ctx_free(ctx);
INS_ERROR();
return 0;
}
\ No newline at end of file