diff --git a/dap-sdk/core/include/dap_common.h b/dap-sdk/core/include/dap_common.h index 164121dd11fe57bf04f86571482f2bfcc3217589..a5460b55f1b16422a19924985ac53fcf5b34aa2d 100755 --- a/dap-sdk/core/include/dap_common.h +++ b/dap-sdk/core/include/dap_common.h @@ -508,7 +508,10 @@ static inline void * dap_mempcpy(void * a_dest,const void * a_src,size_t n) return ((byte_t*) memcpy(a_dest,a_src,n))+n; } - +int dap_is_alpha_and_(char e); +int dap_is_alpha(char e); +int dap_is_digit(char e); +char **dap_parse_items(const char *a_str, char a_delimiter, int *a_count, const int a_only_digit); #ifdef __MINGW32__ int exec_silent(const char *a_cmd); diff --git a/dap-sdk/core/src/dap_common.c b/dap-sdk/core/src/dap_common.c index 2789fec964794a738da7f5df3c47f67aea44ddfb..f15e6cb0a91a5d1fe6c09ea96ca8c8c5a176a2cf 100755 --- a/dap-sdk/core/src/dap_common.c +++ b/dap-sdk/core/src/dap_common.c @@ -1097,3 +1097,83 @@ char* dap_ctime_r(time_t *a_time, char* a_buf){ return "(null)\r\n"; } +int dap_is_alpha_and_(char e) +{ + if ((e >= '0' && e <= '9')||(e >= 'a' && e <= 'z')||(e >= 'A' && e <= 'Z')||(e == '_')) return 1; + return 0; +} + +int dap_is_alpha(char e) +{ + if ((e >= '0' && e <= '9')||(e >= 'a' && e <= 'z')||(e >= 'A' && e <= 'Z')) return 1; + return 0; +} +int dap_is_digit(char e) +{ + if ((e >= '0' && e <= '9')) return 1; + return 0; +} +char **dap_parse_items(const char *a_str, char a_delimiter, int *a_count, const int a_only_digit) +{ + int l_count_temp = *a_count = 0; + int l_len_str = strlen(a_str); + if (l_len_str == 0) return NULL; + char *s, *l_temp_str; + s = l_temp_str = dap_strdup(a_str); + + int l_buf = 0; + for (int i = 0; i < l_len_str; i++) { + if (s[i] == a_delimiter && !l_buf) { + s[i] = 0; + continue; + } + if (s[i] == a_delimiter && l_buf) { + s[i] = 0; + l_buf = 0; + continue; + } + if (!dap_is_alpha(s[i]) && l_buf) { + s[i] = 0; + l_buf = 0; + continue; + } + if (!dap_is_alpha(s[i]) && !l_buf) { + s[i] = 0; + continue; + } + if (a_only_digit) { + if (dap_is_digit(s[i])) { + l_buf++; + if (l_buf == 1) l_count_temp++; + continue; + } + } else if (dap_is_alpha(s[i])) { + l_buf++; + if (l_buf == 1) l_count_temp++; + continue; + } + if (!dap_is_alpha(s[i])) { + l_buf = 0; + s[i] = 0; + continue; + } + } + + s = l_temp_str; + if (l_count_temp == 0) { + free (l_temp_str); + return NULL; + } + + char **lines = DAP_CALLOC(l_count_temp, sizeof (void *)); + for (int i = 0; i < l_count_temp; i++) { + while (*s == 0) s++; + lines[i] = strdup(s); + s = strchr(s, '\0'); + s++; + } + + free (l_temp_str); + *a_count = l_count_temp; + return lines; +} diff --git a/dap-sdk/crypto/src/dap_cert.c b/dap-sdk/crypto/src/dap_cert.c index f813c276d6c9b3d1b66f57a20bc04ca374bf1bd2..8e77a4649d4d2e773c569adc4e32168d8cb2a6a1 100755 --- a/dap-sdk/crypto/src/dap_cert.c +++ b/dap-sdk/crypto/src/dap_cert.c @@ -848,4 +848,4 @@ void *dap_cert_get_meta_custom(dap_cert_t *a_cert, const char *a_field, size_t * void dap_cert_deinit() { -} \ No newline at end of file +} diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index edda63085b9aa08e4508c50ef460ee9ffd2a5bfa..c118458f8a59b37f6c30fd7fc04dca6443d8a6ae 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -266,6 +266,9 @@ static dap_chain_type_t s_chain_type_from_str(const char *a_type_str) if(!dap_strcmp(a_type_str, "ca")) { return CHAIN_TYPE_CA; } + if(!dap_strcmp(a_type_str, "signer")) { + return CHAIN_TYPE_SIGNER; + } return CHAIN_TYPE_LAST; } @@ -295,6 +298,9 @@ static uint16_t s_datum_type_from_str(const char *a_type_str) if(!dap_strcmp(a_type_str, "transaction")) { return DAP_CHAIN_DATUM_256_TX; } + if (!dap_strcmp(a_type_str, "signer")) { + return DAP_CHAIN_DATUM_SIGNER; + } return DAP_CHAIN_DATUM_CUSTOM; } diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index 6925d627291f1202e534e3f0040bdb36412dec0a..65d3b5840f3d8a6dbd66b95dc4af3abd0ce1f566 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -95,6 +95,7 @@ typedef enum dap_chain_type CHAIN_TYPE_EMISSION, CHAIN_TYPE_TX, CHAIN_TYPE_CA, + CHAIN_TYPE_SIGNER, CHAIN_TYPE_LAST // CHAIN_TYPE_256_TOKEN, // 256 // CHAIN_TYPE_256_EMISSION, // 256 diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index 3ccaaf44e17095818053103ef450859feab6cbca..042789f2d47e2a2863e822494942eaa774343243 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -55,6 +55,7 @@ /// CA with public key and self signed metadata #define DAP_CHAIN_DATUM_CA 0x0c00 +#define DAP_CHAIN_DATUM_SIGNER 0x0c01 /// Token /// Simple token decl @@ -84,6 +85,8 @@ s = "DATUM_EVM_DATA"; break; \ case DAP_CHAIN_DATUM_CA: \ s = "DATUM_CA"; break; \ + case DAP_CHAIN_DATUM_SIGNER: \ + s = "DATUM_SIGNER"; break; \ case DAP_CHAIN_DATUM_CUSTOM: \ s = "DATUM_CUSTOM"; break; \ case DAP_CHAIN_DATUM_TOKEN_DECL: \ diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c index 6b763948e957d283f07c21107deffb15819687d2..a71a7f79b6142b5e1a60dcb85bd6ebf35d933c61 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -302,7 +302,6 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c const char * l_events_sign_cert = NULL; if ( ( l_events_sign_cert = dap_config_get_item_str(a_chain_net_cfg,"dag-poa","events-sign-cert") ) != NULL ) { - if ( ( PVT(l_poa)->events_sign_cert = dap_cert_find_by_name(l_events_sign_cert)) == NULL ){ log_it(L_ERROR,"Can't load events sign certificate, name \"%s\" is wrong",l_events_sign_cert); }else diff --git a/modules/consensus/none/dap_chain_cs_none.c b/modules/consensus/none/dap_chain_cs_none.c index 415910ef4d43c9b4cb2e4f153d464d3d13cec7c3..2cc6f6d04ed91ce54ee5913da1571cc65598c343 100644 --- a/modules/consensus/none/dap_chain_cs_none.c +++ b/modules/consensus/none/dap_chain_cs_none.c @@ -368,6 +368,8 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha if ( dap_cert_chain_file_save(l_datum, a_chain->net_name) < 0 ) return ATOM_REJECT; }break; + case DAP_CHAIN_DATUM_SIGNER: + break; default: return ATOM_REJECT; } diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index e72a1242c09f04606ce71c772202e3d60b03ae63..8834d39989aaf83202bff19f6b2f6bd546b9444d 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -93,6 +93,7 @@ char *dap_chain_mempool_datum_add(dap_chain_datum_t * a_datum, dap_chain_t * a_c } else { log_it(L_WARNING, "Can't place data's hash %s was placed in mempool", l_key_str); DAP_DELETE(l_key_str); + l_key_str = NULL; } DAP_DELETE(l_gdb_group); return l_key_str; diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 09745c70f49314a71740572eead1de2d47bfb82c..c3ed8698873fde589373462351ff00ef44043f4f 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -928,7 +928,10 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "global_db flush \n\n" // "global_db wallet_info set -addr <wallet address> -cell <cell id> \n\n" ); - + dap_chain_node_cli_cmd_item_create("mempool", com_signer, "Sign operations", + "mempool sign -net <net name> -chain <chain name> -file <filename> [-mime <(SIGNER_FILENAME,SIGNER_FILENAME_SHORT,SIGNER_FILESIZE,SIGNER_DATE,SIGNER_MIME_MAGIC) or (SIGNER_ALL_FLAGS)>]\n" + "mempool check -net <net name> ((-file <filename>) or (-hash <hash>)) [-mime <(SIGNER_FILENAME,SIGNER_FILENAME_SHORT,SIGNER_FILESIZE,SIGNER_DATE,SIGNER_MIME_MAGIC) or (SIGNER_ALL_FLAGS)>]\n" + ); dap_chain_node_cli_cmd_item_create("node", com_node, "Work with node", "node add -net <net name> -addr {<node address> | -alias <node alias>} {-port <port>} -cell <cell id> {-ipv4 <ipv4 external address> | -ipv6 <ipv6 external address>}\n\n" "node del -net <net name> -addr <node address> | -alias <node alias>\n\n" diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 1501362a3e9153ccbd704a5cd70863da455f243a..55b797a4dcfc9b1111faf886d161c957e435affe 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -35,6 +35,8 @@ #include <assert.h> #include <ctype.h> #include <dirent.h> +#include <magic.h> +#include <sys/stat.h> #ifdef WIN32 #include <winsock2.h> @@ -4516,3 +4518,556 @@ int cmd_gdb_import(int argc, char ** argv, char ** a_str_reply) json_object_put(l_json); return 0; } + +/* + * block code signer + */ +/* + * enum for dap_chain_sign_file + */ +typedef enum { + SIGNER_ALL_FLAGS = 0x1f, + SIGNER_FILENAME = 1 << 0, // flag - full filename + SIGNER_FILENAME_SHORT = 1 << 1, // flag - filename without extension + SIGNER_FILESIZE = 1 << 2, // flag - size of file + SIGNER_DATE = 1 << 3, // flag - date + SIGNER_MIME_MAGIC = 1 << 4, // flag - mime magic + SIGNER_COUNT = 5 // count flags +} dap_sign_signer_file_t; + +static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, const char *a_cert_name, + dap_sign_t **a_signed, dap_chain_hash_fast_t *a_hash); +static int s_signer_cmd(int a_arg_index, int a_argc, char **a_argv, char **a_str_reply); +static int s_check_cmd(int a_arg_index, int a_argc, char **a_argv, char **a_str_reply); +static uint8_t *s_byte_to_hex(const char *a_line, size_t *a_size); +static uint8_t s_get_num(uint8_t a_byte, int a_pp); +struct opts { + char *name; + uint32_t cmd; +}; + +#define BUILD_BUG(condition) ((void)sizeof(char[1-2*!!(condition)])) + +int com_signer(int a_argc, char **a_argv, char **a_str_reply) +{ + enum { + CMD_NONE, CMD_SIGN, CMD_CHECK + }; + + int arg_index = 1; + int cmd_num = CMD_NONE; + + struct opts l_opts[] = { + { "sign", CMD_SIGN }, + { "check", CMD_CHECK } + }; + + size_t l_len_opts = sizeof(l_opts) / sizeof(struct opts); + for (int i = 0; i < l_len_opts; i++) { + if (dap_chain_node_cli_find_option_val(a_argv, arg_index, min(a_argc, arg_index + 1), l_opts[i].name, NULL)) { + cmd_num = l_opts[i].cmd; + break; + } + } + + if(cmd_num == CMD_NONE) { + dap_chain_node_cli_set_reply_text(a_str_reply, "command %s not recognized", a_argv[1]); + return -1; + } + switch (cmd_num) { + case CMD_SIGN: + return s_signer_cmd(arg_index, a_argc, a_argv, a_str_reply); + break; + case CMD_CHECK: + return s_check_cmd(arg_index, a_argc, a_argv, a_str_reply); + break; + } + + return -1; +} + +static int s_get_key_from_file(const char *a_file, const char *a_mime, const char *a_cert_name, dap_sign_t **a_sign); + +static int s_check_cmd(int a_arg_index, int a_argc, char **a_argv, char **a_str_reply) +{ + int l_ret = 0; + enum {OPT_FILE, OPT_HASH, OPT_NET, OPT_MIME, OPT_CERT, + OPT_COUNT}; + struct opts l_opts_check[] = { + { "-file", OPT_FILE }, + { "-hash", OPT_HASH }, + { "-net", OPT_NET }, + { "-mime", OPT_MIME }, + { "-cert", OPT_CERT } + }; + + BUILD_BUG((sizeof(l_opts_check)/sizeof(struct opts)) != OPT_COUNT); + + char *l_str_opts_check[OPT_COUNT] = {0}; + for (int i = 0; i < OPT_COUNT; i++) { + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, l_opts_check[i].name, (const char **) &l_str_opts_check[i]); + } + + if (!l_str_opts_check[OPT_CERT]) { + dap_chain_node_cli_set_reply_text(a_str_reply, "%s need to be selected", l_opts_check[OPT_CERT].name); + return -1; + } + if (l_str_opts_check[OPT_HASH] && l_str_opts_check[OPT_FILE]) { + dap_chain_node_cli_set_reply_text(a_str_reply, "you can select is only one from (file or hash)"); + return -1; + } + + dap_chain_net_t *l_network = dap_chain_net_by_name(l_str_opts_check[OPT_NET]); + if (!l_network) { + dap_chain_node_cli_set_reply_text(a_str_reply, "%s network not found", l_str_opts_check[OPT_NET]); + return -1; + } + + + dap_chain_t *l_chain = dap_chain_net_get_chain_by_chain_type(l_network, CHAIN_TYPE_SIGNER); + if (!l_chain) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Not found datum signer in network %s", l_str_opts_check[OPT_NET]); + return -1; + } + + dap_sign_t *l_sign = NULL; + dap_chain_datum_t *l_datum = NULL; + dap_global_db_obj_t *l_objs = NULL; + char *l_gdb_group = NULL; + + l_gdb_group = dap_chain_net_get_gdb_group_mempool(l_chain); + if (!l_gdb_group) { + l_ret = -1; + goto end; + } + + printf("....%p\n", l_chain->cells); + + if (l_str_opts_check[OPT_HASH]) { +#if 0 + size_t l_size_store_datum = 0; + dap_store_obj_t *l_store_datum = dap_chain_global_db_obj_gr_get(l_str_opts_check[OPT_HASH], &l_size_store_datum, l_gdb_group); + dap_chain_node_cli_set_reply_text(a_str_reply, "%s datum by hash: %s", + l_size_store_datum ? "found" : "not found", + l_str_opts_check[OPT_HASH]); +#endif + + } + + if (l_str_opts_check[OPT_FILE]) { + l_ret = s_get_key_from_file(l_str_opts_check[OPT_FILE], l_str_opts_check[OPT_MIME], l_str_opts_check[OPT_CERT], &l_sign); + if (!l_ret) { + l_ret = -1; + goto end; + } +#if 0 + dap_chain_hash_fast_t l_key_hash; + dap_hash_fast(l_sign->pkey_n_sign, l_sign->header.sign_size, &l_key_hash); + char *l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); + if (l_key_str) { + size_t l_size_store_datum = 0; + dap_store_obj_t *l_store_datum = dap_chain_global_db_obj_gr_get(l_key_str, &l_size_store_datum, l_gdb_group); + dap_chain_node_cli_set_reply_text(a_str_reply, "%s datum by file: %s", + l_size_store_datum ? "found" : "not found", + l_str_opts_check[OPT_FILE]); + DAP_FREE(l_key_str); + } +#endif +#if 0 + dap_chain_cell_id_t l_cell_id = {0}; + dap_chain_atom_iter_t *l_iter = NULL; + for (uint64_t i = 0; i >= 0; i++) { + l_iter = l_chain->callback_atom_iter_create(l_chain, l_cell_id); + if (l_iter) { + size_t l_size = 0; + dap_chain_datum_t *l_datum = l_chain->callback_atom_iter_get_next(l_iter, &l_size); + if (l_datum) { + printf("l_size: %ld\n", l_size); + for (size_t i = 0; i < l_size; i++) { + + dap_hash_fast_t l_hash; + dap_chain_hash_fast_from_str(l_datum[i].data, &l_hash); + char *l_key = dap_hash_fast_to_str_new(&l_hash); + printf("key: %s\n", l_key); + } + + + } + } else break; + l_cell_id.uint64++; + } +#endif + } + + +end: + + if (l_gdb_group) DAP_FREE(l_gdb_group); + + + return 0; +} + +static int s_get_key_from_file(const char *a_file, const char *a_mime, const char *a_cert_name, dap_sign_t **a_sign) +{ + char **l_items_mime = NULL; + int l_items_mime_count = 0; + uint32_t l_flags_mime = 0; + + + + if (a_mime) { + l_items_mime = dap_parse_items(a_mime, ',', &l_items_mime_count, 0); + } + + if (l_items_mime && l_items_mime_count > 0) { + struct opts l_opts_flags[] = { + { "SIGNER_ALL_FLAGS", SIGNER_ALL_FLAGS }, + { "SIGNER_FILENAME", SIGNER_FILENAME }, + { "SIGNER_FILENAME_SHORT", SIGNER_FILENAME_SHORT }, + { "SIGNER_FILESIZE", SIGNER_FILESIZE }, + { "SIGNER_DATE", SIGNER_DATE }, + { "SIGNER_MIME_MAGIC", SIGNER_MIME_MAGIC } + }; + int l_len_opts_flags = sizeof(l_opts_flags) / sizeof (struct opts); + for (int i = 0; i < l_len_opts_flags; i++) { + for (int isub = 0; isub < l_items_mime_count; isub++) { + if (!strncmp (l_opts_flags[i].name, l_items_mime[isub], strlen(l_items_mime[isub]) + 1)) { + l_flags_mime |= l_opts_flags[i].cmd; + break; + } + } + + } + + /* free l_items_mime */ + for (int i = 0; i < l_items_mime_count; i++) { + if (l_items_mime[i]) DAP_FREE(l_items_mime[i]); + } + DAP_FREE(l_items_mime); + l_items_mime_count = 0; + } + if (l_flags_mime == 0) l_flags_mime = SIGNER_ALL_FLAGS; + + dap_chain_hash_fast_t l_hash; + + + int l_ret = s_sign_file(a_file, l_flags_mime, a_cert_name, a_sign, &l_hash); + + return l_ret; +} + +static int s_signer_cmd(int a_arg_index, int a_argc, char **a_argv, char **a_str_reply) +{ + enum { + OPT_FILE, OPT_MIME, OPT_NET, OPT_CHAIN, OPT_CERT, + OPT_COUNT + }; + struct opts l_opts_signer[] = { + { "-file", OPT_FILE }, + { "-mime", OPT_MIME }, + { "-net", OPT_NET }, + { "-chain", OPT_CHAIN }, + { "-cert", OPT_CERT } + }; + + BUILD_BUG((sizeof(l_opts_signer)/sizeof(struct opts)) != OPT_COUNT); + + a_arg_index++; + + char *l_opts_sign[OPT_COUNT] = {0}; + for (int i = 0; i < OPT_COUNT; i++) { + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, l_opts_signer[i].name, (const char **) &l_opts_sign[i]); + } + + if (!l_opts_sign[OPT_CERT]) { + dap_chain_node_cli_set_reply_text(a_str_reply, "%s need to be selected", l_opts_signer[OPT_CERT].name); + return -1; + } + + + dap_chain_net_t *l_network = dap_chain_net_by_name(l_opts_sign[OPT_NET]); + if (!l_network) { + dap_chain_node_cli_set_reply_text(a_str_reply, "%s network not found", l_opts_sign[OPT_NET]); + return -1; + } + + dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_network, l_opts_sign[OPT_CHAIN]); + if (!l_chain) { + dap_chain_node_cli_set_reply_text(a_str_reply, "%s chain not found", l_opts_sign[OPT_CHAIN]); + return -1; + } + + int l_ret = 0; + dap_sign_t *l_sign = NULL; + dap_chain_datum_t *l_datum = NULL; + dap_global_db_obj_t *l_objs = NULL; + + printf("#\n"); + l_ret = s_get_key_from_file(l_opts_sign[OPT_FILE], l_opts_sign[OPT_MIME], l_opts_sign[OPT_CERT], &l_sign); + if (!l_ret) { + dap_chain_node_cli_set_reply_text(a_str_reply, "%s cert not found", l_opts_sign[OPT_CERT]); + l_ret = -1; + goto end; + } + + + printf("##\n"); + + l_datum = dap_chain_datum_create(DAP_CHAIN_DATUM_SIGNER, l_sign->pkey_n_sign, l_sign->header.sign_size); + if (!l_datum) { + dap_chain_node_cli_set_reply_text(a_str_reply, "not created datum"); + l_ret = -1; + goto end; + } + + printf("###\n"); + +#if 0 + char *l_hash_str = dap_chain_mempool_datum_add(l_datum, l_chain); + dap_chain_node_cli_set_reply_text(a_str_reply, "%s by certificate is signed %s", l_opts_sign[OPT_FILE], + l_hash_str ? "successfull": "not successfull"); + + if (l_hash_str) { + l_ret = 0; + DAP_FREE(l_hash_str); + } + printf("####\n"); +#endif + dap_chain_cell_id_t l_cell_id = {0}; + dap_chain_cell_create_fill(l_chain, l_cell_id); + l_ret = l_chain->callback_add_datums(l_chain, &l_datum, 1); + printf("l_ret datum: %d\n", l_ret); + +end: + + if (l_datum) DAP_FREE(l_datum); + + return l_ret; +} + + + +/* +SIGNER_ALL_FLAGS = 0 << 0, +SIGNER_FILENAME = 1 << 0, // flag - full filename +SIGNER_FILENAME_SHORT = 1 << 1, // flag - filename without extension +SIGNER_FILESIZE = 1 << 2, // flag - size of file +SIGNER_DATE = 1 << 3, // flag - date +SIGNER_MIME_MAGIC = 1 << 4, // flag - mime magic +SIGNER_COUNT +*/ + +static char *s_strdup_by_index (const char *a_file, const int a_index); +static dap_tsd_t *s_alloc_metadata (const char *a_file, const int a_meta); +static uint8_t *s_concat_hash_and_mimetypes (dap_chain_hash_fast_t *a_chain, dap_list_t *a_meta_list, int a_index_meta, size_t *a_fullsize); + +/* + * dap_sign_file - sign a file with flags. + * flags - (SIGNER_FILENAME, SIGNER_FILENAME_SHORT, SIGNER_FILESIZE, SIGNER_DATE, SIGNER_MIME_MAGIC) or SIGNER_ALL_FLAGS + * example + * int ret = dap_sign_file ("void.png", SIGNER_ALL_FLAGS); it's sign file with all mime types. + * example + * int ret = dap_sign_file ("void.png", SIGNER_FILENAME | SIGNER_FILESIZE | SIGNER_DATE); + */ +/** + * @brief dap_chain_sign_file + * @param a_chain + * @param a_filename + * @param a_flags + * @return + */ +static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, const char *a_cert_name, + dap_sign_t **a_signed, dap_chain_hash_fast_t *a_hash) +{ + uint32_t l_shift = 1; + int l_count_meta = 0; + int l_index_meta = 0; + char *l_buffer = NULL; + + if (a_flags == SIGNER_ALL_FLAGS) { + l_count_meta = SIGNER_COUNT; + a_flags = SIGNER_FILENAME | SIGNER_FILENAME_SHORT | SIGNER_FILESIZE | SIGNER_DATE | SIGNER_MIME_MAGIC; + } + + do { + if (a_flags <= 0) break; + + for (int i = 0; i < SIGNER_COUNT; i++) { + if (l_shift | a_flags) l_count_meta++; + l_shift <<= 1; + } + } while (0); + + size_t l_file_content_size; + if (!dap_file_get_contents(a_filename, &l_buffer, &l_file_content_size)) return 0; + + l_shift = 1; + dap_list_t *l_std_list = NULL; + + + for (int i = 0; i < l_count_meta; i++) { + if (l_shift | a_flags) { + dap_tsd_t *l_item = s_alloc_metadata(a_filename, l_shift & a_flags); + if (l_item) { + l_std_list = dap_list_append(l_std_list, l_item); + l_index_meta++; + } + } + l_shift <<= 1; + } + + int l_ret = 0; + + dap_cert_t *l_cert = dap_cert_find_by_name(a_cert_name); + if (!l_cert) { + DAP_FREE(l_buffer); + return 0; + } + + if (!dap_hash_fast(l_buffer, l_file_content_size, a_hash)) { + DAP_FREE(l_buffer); + return 0; + } + + size_t l_full_size_for_sign; + uint8_t *l_data = s_concat_hash_and_mimetypes (a_hash, l_std_list, l_index_meta, &l_full_size_for_sign); + if (!l_data) { + DAP_FREE(l_buffer); + return 0; + } + *a_signed = dap_sign_create(l_cert->enc_key, l_data, l_full_size_for_sign, 0); + if (*a_signed == NULL) { + DAP_FREE(l_buffer); + return 0; + } + + + DAP_FREE(l_buffer); + return 1; +} + +static byte_t *s_concat_meta (dap_list_t *a_meta, int a_index_meta, size_t *a_fullsize) +{ + if (a_fullsize) + *a_fullsize = 0; + + int l_len = 0; + int l_n; + int l_part = 256; + int l_power = 1; + byte_t *l_buf = DAP_CALLOC(l_part * l_power++, 1); + int l_total = l_part; + int l_counter = 0; + int l_part_power = l_part; + int l_index = 0; + + for ( dap_list_t* l_iter = dap_list_first(a_meta); l_iter; l_iter = l_iter->next){ + if (!l_iter->data) continue; + dap_tsd_t * l_tsd = (dap_tsd_t *) l_iter->data; + size_t l_tsd_size = dap_tsd_size(l_tsd); + l_index = l_counter; + l_counter += l_tsd_size; + if (l_counter >= l_part_power) { + l_part_power = l_part * l_power++; + l_buf = (byte_t *) DAP_REALLOC(l_buf, l_part_power); + + } + memcpy (&l_buf[l_index], l_tsd->data, l_tsd_size); + } + + if (a_fullsize) + *a_fullsize = l_counter; + + return l_buf; +} + +static uint8_t *s_concat_hash_and_mimetypes (dap_chain_hash_fast_t *a_chain_hash, dap_list_t *a_meta_list, int a_index_meta, size_t *a_fullsize) +{ + if (!a_fullsize) return NULL; + byte_t *l_buf = s_concat_meta (a_meta_list, a_index_meta, a_fullsize); + if (!l_buf) return (uint8_t *) l_buf; + + size_t l_len_meta_buf = *a_fullsize; + *a_fullsize += sizeof (a_chain_hash->raw) + 1; + uint8_t *l_fullbuf = DAP_CALLOC(*a_fullsize, 1); + uint8_t *l_s = l_fullbuf; + + memcpy(l_s, a_chain_hash->raw, sizeof(a_chain_hash->raw)); + l_s += sizeof (a_chain_hash->raw); + memcpy(l_s, l_buf, l_len_meta_buf); + DAP_FREE(l_buf); + + return l_fullbuf; +} + + +static char *s_strdup_by_index (const char *a_file, const int a_index) +{ + char *l_buf = DAP_CALLOC(a_index + 1, 1); + strncpy (l_buf, a_file, a_index); + return l_buf; +} + +static dap_tsd_t *s_alloc_metadata (const char *a_file, const int a_meta) +{ + switch (a_meta) { + case SIGNER_FILENAME: + return dap_tsd_create_string(SIGNER_FILENAME, a_file); + break; + case SIGNER_FILENAME_SHORT: + { + char *l_filename_short = NULL; + if (l_filename_short = strrchr(a_file, '.')) { + int l_index_of_latest_point = l_filename_short - a_file; + l_filename_short = s_strdup_by_index (a_file, l_index_of_latest_point); + if (!l_filename_short) return NULL; + dap_tsd_t *l_ret = dap_tsd_create_string(SIGNER_FILENAME_SHORT, l_filename_short); + free (l_filename_short); + return l_ret; + } + } + break; + case SIGNER_FILESIZE: + { + struct stat l_st; + stat (a_file, &l_st); + return dap_tsd_create_scalar(SIGNER_FILESIZE, l_st.st_size); + } + break; + case SIGNER_DATE: + { + struct stat l_st; + stat (a_file, &l_st); + char *l_ctime = ctime(&l_st.st_ctime); + char *l = NULL; + if (l = strchr(l_ctime, '\n')) *l = 0; + return dap_tsd_create_string(SIGNER_DATE, l_ctime); + } + break; + case SIGNER_MIME_MAGIC: + { + magic_t l_magic = magic_open(MAGIC_MIME); + if (l_magic == NULL) return NULL; + if (magic_load (l_magic, NULL)) { + magic_close(l_magic); + return NULL; + } + const char *l_str_magic_file = NULL; + dap_tsd_t *l_ret = NULL; + do { + l_str_magic_file = magic_file (l_magic, a_file); + if (!l_str_magic_file) break; + l_ret = dap_tsd_create_string(SIGNER_MIME_MAGIC, l_str_magic_file); + } while (0); + magic_close (l_magic); + return l_ret; + + } + break; + default: + return NULL; + } + + return NULL; +} diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index 0a35ddba34ef04ff885eb20ea877e1980f7d207d..4ac0d989e399f6214028df72a42f0043cdd13e4e 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -146,4 +146,4 @@ int com_mempool_proc(int argc, char ** argv, char ** a_str_reply); int com_mempool_add_ca( int a_argc, char ** a_argv, char ** a_str_reply); int com_chain_ca_pub( int a_argc, char ** a_argv, char ** a_str_reply); int com_chain_ca_copy( int a_argc, char ** a_argv, char ** a_str_reply); - +int com_signer(int a_argc, char **a_argv, char **a_str_reply); diff --git a/modules/service/stake/dap_chain_net_srv_stake.c b/modules/service/stake/dap_chain_net_srv_stake.c index 62f1e2522a39545a5ea08ddf00ad37c73f195e56..89f9534e1988fc9fc4ef7b7df5f772270b76a6c7 100644 --- a/modules/service/stake/dap_chain_net_srv_stake.c +++ b/modules/service/stake/dap_chain_net_srv_stake.c @@ -397,7 +397,8 @@ static bool s_stake_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_net) return false; } // Processing will be made according to autoprocess policy - if (!dap_chain_mempool_datum_add(l_datum, l_chain)) { + char *l_ret = NULL; + if ((l_ret = dap_chain_mempool_datum_add(l_datum, l_chain)) == NULL) { DAP_DELETE(l_datum); return false; } diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index e38168e51a839f904d87819a86c4899d8bc28dff..45662257bd4190e85330d488f3b1963fa0b1f055 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -329,7 +329,8 @@ static bool s_xchange_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_net) return false; } // Processing will be made according to autoprocess policy - if (!dap_chain_mempool_datum_add(l_datum, l_chain)) { + char *l_ret = NULL; + if ((l_ret = dap_chain_mempool_datum_add(l_datum, l_chain)) == NULL) { DAP_DELETE(l_datum); return false; } diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index c9b8a95cbe473211080b0d48e85cb415eda38ac2..e46648a74c18018bc198c1beeccfed11059353c6 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -330,6 +330,9 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger return DAP_CHAIN_DATUM_CA; } break; + case DAP_CHAIN_DATUM_SIGNER: { + return DAP_CHAIN_DATUM_SIGNER; + } default: return -1; } @@ -443,6 +446,9 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha if(s_debug_more) log_it(L_DEBUG, "... DATUM_CA"); break; + case DAP_CHAIN_DATUM_SIGNER: + ret = ATOM_ACCEPT; + break; default: if (s_debug_more) { l_event_hash_str = dap_chain_hash_fast_to_str_new(&l_event_item->hash); @@ -574,12 +580,12 @@ static size_t s_chain_callback_datums_pool_proc(dap_chain_t * a_chain, dap_chain } pthread_rwlock_unlock(&PVT(l_dag)->events_rwlock); } - if (l_hashes_linked || s_seed_mode ) { dap_chain_cs_dag_event_t * l_event = NULL; size_t l_event_size = 0; - if(l_dag->callback_cs_event_create) + if(l_dag->callback_cs_event_create) { l_event = l_dag->callback_cs_event_create(l_dag,l_datum,l_hashes,l_hashes_linked,&l_event_size); + } if ( l_event&&l_event_size){ // Event is created if (l_dag->is_add_directy) { l_cell = a_chain->cells;