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; CHECK_ERR(IS_LIST(params) && list_len >= 2,"Invalid params"); 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) { 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"); } 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"); } CMD_OUTPUT("result",co_str8_create(sig_buf,2*SIGNATURE_BYTES+1,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"); 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); if (verdict == 1) { DEBUG("signature verified"); CMD_OUTPUT("result",co_bool_create(true,0)); // successfully verified } else if (verdict == 0) { DEBUG("signature NOT verified"); CMD_OUTPUT("result",co_bool_create(false,0)); } } return 1; error: INS_ERROR(); return 0; }
int serval_crypto_handler(co_obj_t *self, co_obj_t **output, co_obj_t *params) { CLEAR_ERR(); 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"); if (!strncmp("--keyring=", co_obj_data_ptr(co_list_get_last(params)), 10)) { keypath = 1; --list_len; } 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"); if (list_len == 3) { 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) { 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"); } } CHECK_ERR(cmd_serval_sign(ctx), "Failed to create signature"); // 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)); } 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("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("verified",co_str8_create("false",sizeof("false"),0)); } } error: INS_ERROR(); if (ctx) svl_crypto_ctx_free(ctx); return 1; }