From 0b189192d12ad484b720bc06a1cf3a9b1156d68c Mon Sep 17 00:00:00 2001 From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net> Date: Tue, 22 Jan 2019 20:15:08 +0700 Subject: [PATCH] [+] Certificate object with data save on disk and load [+] PKey and Sign serialization structures operations --- dap_chain_cert.c | 54 +++++++++++++---- dap_chain_cert.h | 6 ++ dap_chain_cert_file.c | 131 +++++++++++++++++++++++++++++++++++++++++- dap_chain_cert_file.h | 20 +++++-- dap_chain_pkey.c | 59 +++++++++---------- dap_chain_pkey.h | 4 +- dap_chain_sign.c | 95 +++++++++++++++++++++++++++++- dap_chain_sign.h | 14 ++++- 8 files changed, 330 insertions(+), 53 deletions(-) diff --git a/dap_chain_cert.c b/dap_chain_cert.c index 47d8962..c638406 100644 --- a/dap_chain_cert.c +++ b/dap_chain_cert.c @@ -23,6 +23,7 @@ */ #include <string.h> #include <stdio.h> +#include <unistd.h> #include "uthash.h" #include "dap_common.h" #include "dap_chain_cert.h" @@ -62,18 +63,29 @@ dap_chain_cert_t * dap_chain_cert_generate(const char * a_cert_name, const char { dap_chain_cert_t * l_cert = s_cert_new(); l_cert->key_private = dap_enc_key_new_generate(a_key_type, NULL, 0, NULL, 0, 0); + if ( l_cert->key_private ){ + log_it(L_DEBUG,"Certificate generated"); + dap_chain_cert_item_t * l_cert_item = DAP_NEW_Z(dap_chain_cert_item_t); + snprintf(l_cert_item->name,sizeof(l_cert_item->name),"%s",a_cert_name); + HASH_ADD_STR(s_certs,name,l_cert_item); + log_it(L_DEBUG,"Certificate name %s recorded", a_cert_name); + if ( dap_chain_cert_file_save(l_cert, a_file_path) == 0 ){ + return l_cert; + } else{ + s_cert_delete(l_cert); + log_it(L_ERROR, "Can't save certificate to the file!"); + return NULL; + } + } else { + log_it(L_ERROR,"Can't generate certificat in memory!"); + } +} - dap_chain_cert_item_t * l_cert_item = DAP_NEW_Z(dap_chain_cert_item_t); - snprintf(l_cert_item->name,sizeof(l_cert_item->name),"%s",a_cert_name); - HASH_ADD_STR(s_certs,name,l_cert_item); - if ( dap_chain_cert_file_save(l_cert, a_file_path) == 0 ){ - return l_cert; - } else{ - s_cert_delete(l_cert); - log_it(L_ERROR, "Can't save certificate to the file!"); - return NULL; - } + +void dap_chain_cert_delete(const char * a_cert_name) +{ + } /** @@ -104,10 +116,32 @@ void s_cert_delete(dap_chain_cert_t * a_cert) * @return */ dap_chain_cert_t * dap_chain_cert_add_file(const char * a_cert_name,const char *a_file_path) +{ + size_t l_cert_path_length = strlen(a_cert_name)+8+strlen(a_file_path); + char * l_cert_path = DAP_NEW_Z_SIZE(char,l_cert_path_length); + snprintf(l_cert_path,l_cert_path_length,"%s/%s.dcert",a_file_path,a_cert_name); + if( access( l_cert_path, F_OK ) == -1 ) { + log_it (L_ERROR, "File %s is not exists! ", l_cert_path); + exit(-701); + } + dap_chain_cert_t * l_cert; + l_cert = dap_chain_cert_file_load(l_cert_path); + if (l_cert == NULL){ + log_it (L_ERROR, "File %s is corrupted or wrong format ", l_cert_path); + } + return l_cert; +} + +/** + * @brief dap_chain_cert_dump + * @param a_cert + */ +void dap_chain_cert_dump(dap_chain_cert_t * a_cert) { } + /** * @brief dap_chain_cert_add_folder * @param a_cert_name_prefix diff --git a/dap_chain_cert.h b/dap_chain_cert.h index 5da6ecf..a64414c 100644 --- a/dap_chain_cert.h +++ b/dap_chain_cert.h @@ -34,8 +34,14 @@ typedef struct dap_chain_cert { } dap_chain_cert_t; int dap_chain_cert_init(); + + dap_chain_cert_t * dap_chain_cert_generate(const char * a_cert_name,const char * a_file_path,dap_enc_key_type_t a_key_type ); dap_chain_cert_t * dap_chain_cert_add_file(const char * a_cert_name,const char *a_file_path); void dap_chain_cert_add_folder(const char* a_cert_name_prefix,const char *a_folder_path); +void dap_chain_cert_dump(dap_chain_cert_t * a_cert); + void dap_chain_cert_deinit(); + +void dap_chain_cert_delete(const char * a_cert_name); diff --git a/dap_chain_cert_file.c b/dap_chain_cert_file.c index 6dfbfd2..561398b 100644 --- a/dap_chain_cert_file.c +++ b/dap_chain_cert_file.c @@ -21,8 +21,13 @@ You should have received a copy of the GNU General Public License along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. */ - +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> #include "dap_common.h" +#include "dap_enc.h" +#include "dap_enc_key.h" #include "dap_chain_cert_file.h" #define LOG_TAG "dap_chain_cert_file" @@ -35,7 +40,63 @@ */ int dap_chain_cert_file_save(dap_chain_cert_t * a_cert, const char * a_cert_file_path) { - return 0; + dap_chain_cert_file_hdr_t l_hdr={0}; + dap_enc_key_t * l_key = a_cert->key_private; + int ret = 0; + + l_hdr.sign = DAP_CHAIN_CERT_FILE_HDR_SIGN; + l_hdr.type = DAP_CHAIN_CERT_FILE_TYPE_PUBLIC; + if ( l_key->priv_key_data ){ + l_hdr.type = DAP_CHAIN_CERT_FILE_TYPE_PRIVATE; + log_it(L_DEBUG,"Private key size %u",l_key->priv_key_data_size); + } + if (l_key->pub_key_data){ + log_it(L_DEBUG,"Public key size %u",l_key->pub_key_data_size); + }else{ + log_it(L_ERROR,"No public or private key in certificate, nothing to save"); + ret = -1; + goto lb_exit; + } + log_it(L_DEBUG,"Metadata size %u",l_key->_inheritor_size); + + l_hdr.version = DAP_CHAIN_CERT_FILE_VERSION; + l_hdr.data_size = l_key->pub_key_data_size; + l_hdr.data_pvt_size = l_key->priv_key_data_size; + l_hdr.inheritor_size = l_key->_inheritor_size; + + l_hdr.ts_last_used = l_key->last_used_timestamp; + l_hdr.sign_type = dap_chain_sign_type_from_key_type ( l_key->type ); + FILE * l_file = fopen(a_cert_file_path,"w"); + if( l_file ){ + size_t l_retbytes=0; + if ( (l_retbytes = fwrite(&l_hdr,1,sizeof(l_hdr),l_file )) != sizeof(l_hdr) ){ + log_it(L_ERROR, "Can't write %u bytes on disk (processed only %u)!", sizeof(l_hdr),l_retbytes); + ret = -3; + } + if ( ( l_retbytes = fwrite(l_key->pub_key_data,1,l_key->pub_key_data_size,l_file )) != l_key->pub_key_data_size ){ + log_it(L_ERROR, "Can't write %u bytes of public key to file (processed only %u)!", l_key->pub_key_data_size,l_retbytes); + ret = -4; + } + if ( ( l_retbytes = fwrite(l_key->priv_key_data,1,l_key->priv_key_data_size,l_file )) != l_key->priv_key_data_size ){ + log_it(L_ERROR, "Can't write %u bytes of private key to file (processed only %u)!", l_key->priv_key_data_size,l_retbytes); + ret = -4; + } + if ( ( l_retbytes = fwrite(l_key->_inheritor,1,l_key->_inheritor_size,l_file )) != l_key->_inheritor_size ){ + log_it(L_ERROR, "Can't write %u bytes if metadata to file (processed only %u)!", l_key->_inheritor_size,l_retbytes); + ret = -1; + } + }else{ + log_it(L_ERROR, "Can't open file for write: %s", strerror(errno)); + return -2; + } +lb_exit: + if (l_file) + fclose(l_file); + + if (ret == 0) + log_it(L_NOTICE,"Certificate sucsessfully saved to %s",a_cert_file_path); + + return ret; } /** @@ -46,5 +107,71 @@ int dap_chain_cert_file_save(dap_chain_cert_t * a_cert, const char * a_cert_file dap_chain_cert_t* dap_chain_cert_file_load(const char * a_cert_file_path) { dap_chain_cert_t * l_ret = NULL; + FILE * l_file = fopen(a_cert_file_path,"r"); + dap_chain_cert_file_hdr_t l_hdr={0}; + if( l_file ){ + fseek(l_file, 0L, SEEK_END); + uint64_t l_file_size = ftell(l_file); + rewind(l_file); + + if ( fread(&l_hdr,1,sizeof(l_hdr),l_file ) != sizeof(l_hdr) ){ + log_it(L_ERROR, "Can't read %u bytes from the disk!", sizeof(l_hdr)); + goto l_exit; + } + if (l_hdr.sign != DAP_CHAIN_CERT_FILE_HDR_SIGN ){ + log_it(L_ERROR, "Wrong file signature, corrupted header!"); + goto l_exit; + } + if (l_hdr.version >= 1 ){ + if ( (l_hdr.data_size+l_hdr.data_pvt_size +l_hdr.inheritor_size) > l_file_size ){ + log_it(L_ERROR,"Corrupted file, data sections size is smaller than exists on the disk! (%llu expected, %llu on disk)", + l_hdr.data_pvt_size+l_hdr.data_size+l_hdr.inheritor_size, l_file_size); + goto l_exit; + } + + + l_ret = DAP_NEW_Z(dap_chain_cert_t); + l_ret->key_private = dap_enc_key_new( dap_chain_sign_type_to_key_type( l_hdr.sign_type )); + l_ret->key_private->last_used_timestamp = l_hdr.ts_last_used; + if ( l_hdr.data_size > 0 ){ + l_ret->key_private->pub_key_data_size = l_hdr.data_size; + l_ret->key_private->pub_key_data = DAP_NEW_SIZE (void,l_hdr.data_size); + if ( fread(l_ret->key_private->pub_key_data , 1, l_hdr.data_size, l_file ) != l_hdr.data_size ){ + log_it(L_ERROR, "Can't read %u bytes of public key from the file!", l_hdr.data_size); + goto l_exit; + } + } + l_ret->key_private->priv_key_data_size = l_hdr.data_size; + if ( l_hdr.data_pvt_size > 0 ){ + l_ret->key_private->priv_key_data = DAP_NEW_SIZE (void,l_ret->key_private->priv_key_data_size); + if ( fread(l_ret->key_private->priv_key_data , 1, l_ret->key_private->priv_key_data_size,l_file ) + != l_ret->key_private->priv_key_data_size ){ + log_it(L_ERROR, "Can't read %u bytes of private key from the file!", l_ret->key_private->priv_key_data_size); + goto l_exit; + } + } + + l_ret->key_private->_inheritor_size = l_hdr.inheritor_size; + if ( l_hdr.inheritor_size > 0 ){ + l_ret->key_private->_inheritor = DAP_NEW_SIZE (void,l_hdr.inheritor_size); + if ( fread(l_ret->key_private->_inheritor , 1, l_hdr.inheritor_size, l_file ) != l_hdr.inheritor_size ){ + log_it(L_ERROR, "Can't read %u bytes of inheritor part to the file!", l_hdr.inheritor_size); + goto l_exit; + } + + } + + + log_it(L_NOTICE,"Successfuly loaded certificate from the file %s",a_cert_file_path); + }else + log_it(L_ERROR,"Unrecognizable certificate version, corrupted file or you have too old software"); + }else{ + log_it(L_ERROR, "Can't open file for reading: %s", strerror(errno)); + goto l_exit; + } +l_exit: + if( l_file ) + fclose(l_file); + return l_ret; } diff --git a/dap_chain_cert_file.h b/dap_chain_cert_file.h index c3b5da5..e90329b 100644 --- a/dap_chain_cert_file.h +++ b/dap_chain_cert_file.h @@ -28,18 +28,30 @@ // Magic .dapcert signature #define DAP_CHAIN_CERT_FILE_HDR_SIGN 0x0F300C4711E29380 +#define DAP_CHAIN_CERT_FILE_VERSION 1 // Default certificate with private key and optionaly some signs -#define DAP_CHAIN_CERT_TYPE_PRIVATE 0x00 +#define DAP_CHAIN_CERT_FILE_TYPE_PRIVATE 0x00 // Default certificate with public key and optionaly some signs -#define DAP_CHAIN_CERT_TYPE_PUBLIC 0xf0 +#define DAP_CHAIN_CERT_FILE_TYPE_PUBLIC 0xf0 + typedef struct dap_chain_cert_file_hdr { uint64_t sign; + int version; uint8_t type; - uint64_t section_number; -} dap_chain_sert_file_hdr_t; + dap_chain_sign_type_t sign_type; + uint64_t data_size; + uint64_t data_pvt_size; + uint64_t inheritor_size; + time_t ts_last_used; +} DAP_ALIGN_PACKED dap_chain_cert_file_hdr_t; + +typedef struct dap_chain_cert_file{ + dap_chain_cert_file_hdr_t hdr; + uint8_t data[]; +}DAP_ALIGN_PACKED dap_chain_cert_file_t; int dap_chain_cert_file_save(dap_chain_cert_t * a_cert, const char * a_cert_file_path); dap_chain_cert_t* dap_chain_cert_file_load(const char * a_cert_file_path); diff --git a/dap_chain_pkey.c b/dap_chain_pkey.c index 61f9ff9..1d89c58 100644 --- a/dap_chain_pkey.c +++ b/dap_chain_pkey.c @@ -26,59 +26,56 @@ #include "dap_chain_pkey.h" #define LOG_TAG "chain_key" -dap_chain_pkey_t m_dap_chain_pkey_null={0}; // For sizeof nothing more +static dap_chain_pkey_t m_dap_chain_pkey_null={0}; // For sizeof nothing more /** - * @brief dap_chain_pkey_enc_get_buf_out_size - * @param a_pkey + * @brief dap_chain_pkey_from_enc_key + * @param a_key * @return */ -size_t dap_chain_pkey_enc_get_buf_out_size(dap_chain_pkey_t * a_pkey) +dap_chain_pkey_t* dap_chain_pkey_from_enc_key(dap_enc_key_t *a_key) { - log_it(L_WARNING,"NOT DEFINED:dap_chain_pkey_enc_get_buf_out_size"); - return 0; -} + if (a_key->pub_key_data_size > 0 ){ + dap_chain_pkey_t * l_ret = NULL; + l_ret = DAP_NEW_Z_SIZE(dap_chain_pkey_t,dap_chain_pkey_from_enc_key_output_calc(a_key)); + if( dap_chain_pkey_from_enc_key_output(a_key,l_ret) != 0 ) { + DAP_DELETE(l_ret); + return NULL; + }else + return l_ret; + } -/** - * @brief dap_chain_pkey_enc - * @param a_type - * @param a_buf_in - * @param a_buf_in_size - * @param a_buf_out - * @return - */ -int dap_chain_pkey_enc(dap_chain_pkey_t * a_pkey,const void * a_buf_in, uint32_t a_buf_in_size, void * a_buf_out) // 0 if success -{ - log_it(L_WARNING,"NOT DEFINED: dap_chain_pkey_enc"); - return -1; + return NULL; } /** - * @brief dap_chain_pkey_from_enc_key + * @brief dap_chain_pkey_from_enc_key_output * @param a_key + * @param a_output * @return */ -dap_chain_pkey_t* dap_chain_pkey_from_enc_key(dap_enc_key_t *a_key) +int dap_chain_pkey_from_enc_key_output(dap_enc_key_t *a_key, void * a_output) { - dap_chain_pkey_t * l_ret = NULL; + dap_chain_pkey_t * l_output = (dap_chain_pkey_t *) a_output; if (a_key->pub_key_data_size > 0 ){ - l_ret = DAP_NEW_Z_SIZE(dap_chain_pkey_t,sizeof(l_ret->header)+ a_key->pub_key_data_size); switch (a_key->type) { case DAP_ENC_KEY_TYPE_SIG_BLISS: - l_ret->header.type.type = PKEY_TYPE_SIGN_BLISS ; + l_output->header.type.type = PKEY_TYPE_SIGN_BLISS ; break; case DAP_ENC_KEY_TYPE_SIG_PICNIC: - l_ret->header.type.type = PKEY_TYPE_SIGN_PICNIC ; + l_output->header.type.type = PKEY_TYPE_SIGN_PICNIC ; break; default: log_it(L_WARNING,"No serialization preset"); - DAP_DELETE(l_ret); - return NULL; + return -1; } - l_ret->header.size = a_key->pub_key_data_size; - memcpy(l_ret->pkey,a_key->pub_key_data,a_key->pub_key_data_size); - }else + l_output->header.size = a_key->pub_key_data_size; + memcpy(l_output->pkey,a_key->pub_key_data,a_key->pub_key_data_size); + return 0; + }else{ log_it(L_WARNING, "No public key in the input enc_key object"); - return l_ret; + return -2; + } + return -3; } diff --git a/dap_chain_pkey.h b/dap_chain_pkey.h index 05450b7..8637891 100644 --- a/dap_chain_pkey.h +++ b/dap_chain_pkey.h @@ -49,10 +49,10 @@ typedef struct dap_chain_pkey{ uint8_t pkey[]; /// @param pkey @brief raw pkey dat } DAP_ALIGN_PACKED dap_chain_pkey_t; -extern dap_chain_pkey_t m_dap_chain_pkey_null; // For sizeof nothing more +static dap_chain_pkey_t m_dap_chain_pkey_null; // For sizeof nothing more dap_chain_pkey_t *dap_chain_pkey_from_enc_key(dap_enc_key_t *a_key); -inline size_t dap_chain_pkey_from_enc_key_output_calc(dap_enc_key_t *a_key) +static inline size_t dap_chain_pkey_from_enc_key_output_calc(dap_enc_key_t *a_key) { return sizeof(m_dap_chain_pkey_null.header)+ a_key->pub_key_data_size; } diff --git a/dap_chain_sign.c b/dap_chain_sign.c index 1868e47..49dbd34 100644 --- a/dap_chain_sign.c +++ b/dap_chain_sign.c @@ -32,7 +32,7 @@ dap_chain_sign_t * s_sign_null = NULL; bliss_signature_t s_sign_bliss_null = {0}; -size_t dap_chain_sign_cals_size(dap_enc_key_t * a_key) +size_t dap_chain_sign_create_output_cals_size(dap_enc_key_t * a_key, size_t a_output_wish_size ) { size_t l_sign_size = 0; switch (a_key->type){ @@ -44,7 +44,98 @@ size_t dap_chain_sign_cals_size(dap_enc_key_t * a_key) return sizeof(s_sign_null->header)+ a_key->pub_key_data_size + l_sign_size; } -int dap_chain_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, void * a_output ) +/** + * @brief dap_chain_sign_type_from_key_type + * @param a_key_type + * @return + */ +dap_chain_sign_type_t dap_chain_sign_type_from_key_type( dap_enc_key_type_t a_key_type) { + dap_chain_sign_type_t l_sign_type={0}; + switch (a_key_type){ + case DAP_ENC_KEY_TYPE_SIG_BLISS: l_sign_type.type = SIG_TYPE_BLISS; break; + case DAP_ENC_KEY_TYPE_SIG_PICNIC: l_sign_type.type = SIG_TYPE_PICNIC; break; + case DAP_ENC_KEY_TYPE_SIG_TESLA: l_sign_type.type = SIG_TYPE_TESLA; break; + } + return l_sign_type; + +} + +/** + * @brief dap_chain_sign_type_to_key_type + * @param a_chain_sign_type + * @return + */ +dap_enc_key_type_t dap_chain_sign_type_to_key_type(dap_chain_sign_type_t a_chain_sign_type) +{ + switch (a_chain_sign_type.type) { + case SIG_TYPE_BLISS: return DAP_ENC_KEY_TYPE_SIG_BLISS; + case SIG_TYPE_TESLA: return DAP_ENC_KEY_TYPE_SIG_TESLA; + case SIG_TYPE_PICNIC: return DAP_ENC_KEY_TYPE_SIG_PICNIC; + default: return DAP_ENC_KEY_TYPE_NULL; + } +} + +/** + * @brief dap_chain_sign_create + * @param a_key + * @param a_data + * @param a_data_size + * @param a_output_wish_size + * @return + */ +dap_chain_sign_t * dap_chain_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, + size_t a_output_wish_size ) +{ + size_t l_ret_size = dap_chain_sign_create_output_cals_size(a_key,a_output_wish_size); + if (l_ret_size > 0 ) { + dap_chain_sign_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_sign_t, + l_ret_size ); + if (l_ret){ + if ( dap_chain_sign_create_output(a_key,a_data,a_data_size,l_ret,l_ret_size) !=0 ){ + DAP_DELETE(l_ret); + return NULL; + }else + return l_ret; + } + }else + return NULL; + +} + +/** + * @brief dap_chain_sign_create_output + * @param a_key + * @param a_data + * @param a_data_size + * @param a_output + * @return + */ +int dap_chain_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, void * a_output + ,size_t a_output_size) +{ + switch (a_key->type){ + default: return -1; + } return 0; } + +/** + * @brief dap_chain_sign_to_enc_key + * @param a_chain_sign + * @return + */ +dap_enc_key_t *dap_chain_sign_to_enc_key(dap_chain_sign_t * a_chain_sign) +{ + +} + +/** + * @brief dap_chain_sign_verify + * @param a_chain_sign + * @return + */ +int dap_chain_sign_verify (dap_chain_sign_t * a_chain_sign) +{ + +} diff --git a/dap_chain_sign.h b/dap_chain_sign.h index 4210902..1b08da7 100644 --- a/dap_chain_sign.h +++ b/dap_chain_sign.h @@ -53,5 +53,15 @@ typedef struct dap_chain_sign{ uint8_t pkey_n_sign[]; /// @param sig @brief raw signature data } DAP_ALIGN_PACKED dap_chain_sign_t; -size_t dap_chain_sign_cals_size(dap_enc_key_t * a_key); -int dap_chain_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size, void * a_output ); +int dap_chain_sign_verify (dap_chain_sign_t * a_chain_sign); + +dap_chain_sign_t * dap_chain_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size + , size_t a_output_wish_size ); + +dap_chain_sign_type_t dap_chain_sign_type_from_key_type( dap_enc_key_type_t a_key_type); +dap_enc_key_type_t dap_chain_sign_type_to_key_type(dap_chain_sign_type_t a_chain_sign_type); + +dap_enc_key_t *dap_chain_sign_to_enc_key(dap_chain_sign_t * a_chain_sign); +size_t dap_chain_sign_create_output_cals_size(dap_enc_key_t * a_key,size_t a_output_wish_size ); +int dap_chain_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size + , void * a_output, size_t a_output_size ); -- GitLab