/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcom_key_db.c,v $ $Revision: 1.8.10.4 $ * $Source: /home/interpeak/CVSRoot/ipcom/src/ipcom_key_db.c,v $ * $Author: hxie $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Roger Boden ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipcom_config.h" #ifdef IPCOM_USE_KEY_DB /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #ifdef IPCRYPTO #include #include #include #include #include #include #include #endif /* IPCRYPTO */ #if defined(IP_PORT_OSE5) #include #include #elif defined(IPMCRYPTO) #include #include #endif /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #ifndef IPCOM_KEY_DB_MAX_PATH #define IPCOM_KEY_DB_MAX_PATH 128 #endif #ifndef IPCOM_KEY_DB_MAX_SECRET #define IPCOM_KEY_DB_MAX_SECRET 32 #endif #define IPCOM_KEY_DB_TYPE_PKEY 1 #define IPCOM_KEY_DB_TYPE_BUF 2 #define IPCOM_KEY_DB_MODE_READ 1 #define IPCOM_KEY_DB_MODE_WRITE 2 #define IPCOM_SYSLOG_PRIORITY IPCOM_SYSLOG_IPCOM_PRIORITY #define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPCOM_KEY_DB #define MAX_BLOCK_SIZE 16 #ifdef EVP_MAX_KEY_LENGTH #define IPCOM_KEY_DB_MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH #else #define IPCOM_KEY_DB_MAX_KEY_LENGTH 32 #endif #ifdef EVP_MAX_IV_LENGTH #define IPCOM_KEY_DB_MAX_IV_LENGTH EVP_MAX_IV_LENGTH #else #define IPCOM_KEY_DB_MAX_IV_LENGTH 16 #endif /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ IP_STATIC Ip_err ipcom_key_db_init(void *unused); IP_STATIC int ipcom_key_db_get_kek_iv(unsigned char* key, int key_len, unsigned char* iv, int iv_len); IP_STATIC Ip_err ipcom_key_db_get_dir_name(char* dir, Ip_size_t len, int mode); IP_GLOBAL int ipcom_key_db_cb(char *buf, int size, int rwflag, void *userdata); IP_GLOBAL char ipcom_key_db_get_char(int in_chr); /* **************************************************************************** * 8 DATA **************************************************************************** */ IP_STATIC Ipcom_once_t ipcom_key_db_once = IPCOM_ONCE_INIT; IP_STATIC Ipcom_mutex ipcom_key_db_mutex; extern const char* ipcom_key_db_file_root; /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipcom_key_db_strcatn *=========================================================================== * Description: A variant of strncat. This function takes a length argument * of the dest buffer and ensures that the destination buffer is * not overrun. * Parameters: * Returns: * */ IP_STATIC Ip_err ipcom_key_db_strcatn(char* dest, Ip_size_t n, const char* src) { if (ipcom_strlen(dest)+ipcom_strlen(src)+1>= n) return IPCOM_ERR_FAILED; ipcom_strcat(dest, src); return IPCOM_SUCCESS; } /* *=========================================================================== * ipcom_key_db_init *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_err ipcom_key_db_init(void *unused) { Ip_err retval; (void)unused; retval = ipcom_mutex_create(&ipcom_key_db_mutex); ip_assert(retval == IPCOM_SUCCESS); if (retval != IPCOM_SUCCESS) return retval; return IPCOM_SUCCESS; } /* *=========================================================================== * ipcom_key_db_opendb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC void* ipcom_key_db_opendb(int mode) { IP_DIR* dir; char dir_path[IPCOM_KEY_DB_MAX_PATH] = {0}; if (ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL) != IPCOM_SUCCESS) return IP_NULL; ipcom_mutex_lock(ipcom_key_db_mutex); if (ipcom_key_db_get_dir_name(dir_path, sizeof(dir_path), mode) != IPCOM_SUCCESS) { ipcom_mutex_unlock(ipcom_key_db_mutex); return IP_NULL; } dir = ipcom_opendir(dir_path); ipcom_mutex_unlock(ipcom_key_db_mutex); return dir; } /* *=========================================================================== * ipcom_key_db_readdb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_err ipcom_key_db_readdb(void* handle, char* name, int name_len) { IP_DIR* dir; struct Ip_dirent* dirent; if (ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL) != IPCOM_SUCCESS) return IPCOM_ERR_FAILED; ipcom_mutex_lock(ipcom_key_db_mutex); dir = handle; while (1) { dirent = ipcom_readdir(dir); if (!dirent) { ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_END; } /* ipcom Ip_dirent struct gives no way to tell if its a real file or directory (due to restrictions in VxWorks file API). */ if (ipcom_strcmp(dirent->d_name, ".") == 0 || ipcom_strcmp(dirent->d_name, "..") == 0) { continue; } if ((int)ipcom_strlen(dirent->d_name) > name_len + 1) { ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_INVALID_ARG; } break; } ipcom_strcpy(name, dirent->d_name); ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_SUCCESS; } /* *=========================================================================== * ipcom_key_db_closedb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_err ipcom_key_db_closedb(void* handle) { IP_DIR* dir; dir = handle; return ipcom_closedir(dir); } /* *=========================================================================== * ipcom_key_db_create_dirs *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC void ipcom_key_db_create_dirs(const char* path) { char* tmp_path; char* slash_ptr; int i; int j; if (!path) { IPCOM_LOG0(ERR, "ipcom_key_db_create_dirs :: invalid path"); return; } if (!ipcom_strchr(path, '/')) { /* No slashes in path => path is a relative 'leaf' path */ ipcom_mkdir(path, 0744); return; } /* Create intermediate directories */ for (i=1;; i++) { tmp_path = ipcom_strdup(path); if (!tmp_path) { IPCOM_LOG0(ERR, "ipcom_key_db_create_dirs :: out of memory"); return; } for (j=0, slash_ptr = tmp_path; j 0 && ipcom_strcmp(tmp_path, ".") != 0) ipcom_mkdir(tmp_path, 0744); ipcom_free(tmp_path); } /* Create the final 'leaf' directory */ if (path[ipcom_strlen(path)-1] != '/') ipcom_mkdir(path, 0744); } /* *=========================================================================== * ipcom_key_db_get_dir_name *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_err ipcom_key_db_get_dir_name(char* dir, Ip_size_t len, int mode) { ip_assert(mode == IPCOM_KEY_DB_TYPE_PKEY || mode == IPCOM_KEY_DB_TYPE_BUF); if (ipcom_key_db_strcatn(dir, len, ipcom_key_db_file_root) != IPCOM_SUCCESS) return IPCOM_ERR_FAILED; if (dir[ipcom_strlen(dir)-1] != '/') if (ipcom_key_db_strcatn(dir, len, "/") != IPCOM_SUCCESS) return IPCOM_ERR_FAILED; switch (mode) { case IPCOM_KEY_DB_TYPE_PKEY: if (ipcom_key_db_strcatn(dir, len, "pkey_db/") != IPCOM_SUCCESS) return IPCOM_ERR_FAILED; break; case IPCOM_KEY_DB_TYPE_BUF: if (ipcom_key_db_strcatn(dir, len, "buf_db/") != IPCOM_SUCCESS) return IPCOM_ERR_FAILED; break; default: IP_PANIC(); } if (ipcom_strlen(dir) == len-1) return IPCOM_ERR_FAILED; ipcom_key_db_create_dirs(dir); return IPCOM_SUCCESS; } /* *=========================================================================== * ipcom_key_db_get_file_name *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_err ipcom_key_db_get_file_name(const char* key_id, char* file_path, Ip_size_t size, int type) { if (ipcom_key_db_get_dir_name(file_path, size, type) != IPCOM_SUCCESS) { IPCOM_LOG2(ERR, "ipcom_key_db_get_dir_name failed for path=%s, type=%d", file_path, type); return IPCOM_ERR_FAILED; } (void)ipcom_key_db_strcatn(file_path, size, key_id); if (ipcom_strlen(file_path) == (size-1)) { IPCOM_LOG2(ERR, "Failed to create sec key db file name for key_id=%s, type=%d", key_id, type); return IPCOM_ERR_FAILED; } return IPCOM_SUCCESS; } #ifdef IPCRYPTO /* *=========================================================================== * ipcom_key_db_get_bio *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC BIO* ipcom_key_db_get_bio(const char* key_id, int key_type, int mode) { char file_path[IPCOM_KEY_DB_MAX_PATH] = {0}; Ip_size_t size = sizeof(file_path); BIO *bio = IP_NULL; if (ipcom_key_db_get_file_name(key_id, file_path, size, key_type) != IPCOM_SUCCESS) return IP_NULL; bio = BIO_new(BIO_s_file()); if (!bio) { IPCOM_LOG0(ERR, "ipcom_key_db_get_bio :: out of memory"); goto cleanup; } switch (mode) { case IPCOM_KEY_DB_MODE_READ: if (!BIO_read_filename(bio, file_path)) { IPCOM_LOG1(DEBUG, "ipcom_key_db_get_bio :: failed to open %s", file_path); goto cleanup; } break; case IPCOM_KEY_DB_MODE_WRITE: if (!BIO_write_filename(bio, file_path)) { IPCOM_LOG1(ERR, "ipcom_key_db_get_bio :: failed to open %s", file_path); goto cleanup; } break; default: IP_PANIC(); goto cleanup; } ERR_clear_error(); ERR_remove_state(0); return bio; cleanup: if (bio) BIO_free(bio); ERR_clear_error(); ERR_remove_state(0); return IP_NULL; } #endif /* *=========================================================================== * ipcom_key_db_get_fp *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC IP_FILE* ipcom_key_db_get_fp(const char* key_id, int key_type, int mode) { char file_path[IPCOM_KEY_DB_MAX_PATH] = {0}; Ip_size_t size = sizeof(file_path); char* mode_str = ""; if (ipcom_key_db_get_file_name(key_id, file_path, size, key_type) != IPCOM_SUCCESS) return IP_NULL; switch (mode) { case IPCOM_KEY_DB_MODE_READ: mode_str = "r"; break; case IPCOM_KEY_DB_MODE_WRITE: mode_str = "w"; break; default: IP_PANIC(); break; } return ipcom_fopen(file_path, mode_str); } /* *=========================================================================== * ipcom_key_db_get_kek_iv *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int ipcom_key_db_get_kek_iv(unsigned char* key, int key_len, unsigned char* iv, int iv_len) { char pw[IPCOM_KEY_DB_MAX_SECRET]; unsigned char md_buf[20]; int addmd=0; unsigned int mds=20; unsigned int i; SHA_CTX ctx; if (ipcom_key_db_cb(pw, sizeof(pw), 0, IP_NULL) <= 0) return IPCOM_ERR_FAILED; for (;;) { (void)SHA1_Init(&ctx); if (addmd++) SHA1_Update(&ctx,&(md_buf[0]),mds); SHA1_Update(&ctx,pw,ipcom_strlen(pw)); SHA1_Final(md_buf,&ctx); i=0; mds=20; if (key_len) { for (;;) { if (key_len == 0) break; if (i == mds) break; if (key != IP_NULL) *(key++) = md_buf[i]; key_len--; i++; } } if (iv_len && (i != mds)) { for (;;) { if (iv_len == 0) break; if (i == mds) break; if (iv != IP_NULL) *(iv++)=md_buf[i]; iv_len--; i++; } } if ((key_len == 0) && (iv_len == 0)) break; } ipcom_memset(md_buf, 0, sizeof(md_buf)); return IPCOM_SUCCESS; } /* *=========================================================================== * ipcom_key_db_buf_encrypt *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC Ip_err ipcom_key_db_buf_encrypt(const Ip_u8* in, const int inl, Ip_u8* out, int* outl) { int pad_len; AES_KEY aes_key; unsigned char key[IPCOM_KEY_DB_MAX_KEY_LENGTH]; unsigned char iv[IPCOM_KEY_DB_MAX_IV_LENGTH]; int i; unsigned long encr_len; Ip_u8* in_ptr; pad_len = AES_BLOCK_SIZE - (inl % AES_BLOCK_SIZE); if (*outl < inl + pad_len) { *outl = inl + pad_len; return IPCOM_ERR_INVALID_ARG; } ipcom_key_db_get_kek_iv(key, sizeof(key), iv, sizeof(iv)); in_ptr = ipcom_malloc((Ip_size_t) (inl + AES_BLOCK_SIZE)); if (in_ptr == IP_NULL) return IPCOM_ERR_NO_MEMORY; ipcom_memcpy(in_ptr, in, (Ip_size_t)inl); *outl = inl + pad_len; for (i=inl; i= inl); ipcom_key_db_get_kek_iv(key, sizeof(key), iv, sizeof(iv)); (void)AES_set_decrypt_key(key, 256, &aes_key); (void)AES_cbc_encrypt(in, out, (unsigned long)inl, &aes_key, iv, 0); if (out[inl-1] > MAX_BLOCK_SIZE) { IPCOM_LOG1(ERR, "ipcom_key_db_buf_decrypt :: invalid padding, stated pad len=%d", out[inl-1]); return IPCOM_ERR_FAILED; } pad_len = out[inl-1]; *outl = inl - pad_len; return IPCOM_SUCCESS; } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipcom_key_db_get_char *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL char ipcom_key_db_get_char(int in_chr) { char ret; ret = (char)(in_chr % 126); if (ret < 32) ret = (char)(ret + 32); return ret; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ #ifdef IPCRYPTO /* *=========================================================================== * ipcom_key_db_pkey_get *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC EVP_PKEY* ipcom_key_db_pkey_get(const char* key_id) { BIO *bio = IP_NULL; EVP_PKEY* evp_pkey = IP_NULL; if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID) return IP_NULL; if (ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL) != IPCOM_SUCCESS) return IP_NULL; ipcom_mutex_lock(ipcom_key_db_mutex); bio = ipcom_key_db_get_bio(key_id, IPCOM_KEY_DB_TYPE_PKEY, IPCOM_KEY_DB_MODE_READ); if (!bio) { IPCOM_LOG1(ERR, "ipcom_key_db_get :: key_id %s does not exist", key_id); goto cleanup; } evp_pkey = PEM_read_bio_PrivateKey(bio, IP_NULL, ipcom_key_db_cb, IP_NULL); if (!evp_pkey) { IPCOM_LOG1(ERR, "ipcom_key_db_get :: failed to load key (%s) from file", key_id); } cleanup: if (bio) BIO_free(bio); ipcom_mutex_unlock(ipcom_key_db_mutex); return evp_pkey; } /* *=========================================================================== * ipcom_key_db_pkey_import *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_pkey_import(const char* key_id, const EVP_PKEY* key) { BIO *bio = IP_NULL; Ip_err rc = IPCOM_ERR_FAILED; if (!key || !key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID) return IPCOM_ERR_INVALID_ARG; rc = ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL); if (rc != IPCOM_SUCCESS) return rc; rc = IPCOM_ERR_FAILED; ipcom_mutex_lock(ipcom_key_db_mutex); /* Check if key_id already exists */ bio = ipcom_key_db_get_bio(key_id, IPCOM_KEY_DB_TYPE_PKEY, IPCOM_KEY_DB_MODE_READ); if (bio) { BIO_free(bio); ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_ALREADY_INSTALLED; } bio = ipcom_key_db_get_bio(key_id, IPCOM_KEY_DB_TYPE_PKEY, IPCOM_KEY_DB_MODE_WRITE); if (!bio) { BIO_free(bio); ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_FAILED; } /* Write key */ if (!PEM_write_bio_PrivateKey(bio, (EVP_PKEY*)key, EVP_aes_256_cbc(), IP_NULL, IP_NULL, ipcom_key_db_cb, IP_NULL)) { IPCOM_LOG1(ERR, "ipcom_key_db_pkey_import :: PEM_write_bio_PrivateKey failed for key_id: %s", key_id); goto cleanup; } rc = IPCOM_SUCCESS; cleanup: if (bio) BIO_free(bio); ipcom_mutex_unlock(ipcom_key_db_mutex); return rc; } /* *=========================================================================== * ipcom_key_db_pkey_get2 *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC EVP_PKEY* ipcom_key_db_pkey_get2(struct x509_st* x509, char* key_id, int* key_id_len) { EVP_PKEY* pkey = IP_NULL; char int_key_id[IPCOM_KEY_DB_MAX_PATH] = {0}; EVP_PKEY* cert_pub_key = IP_NULL; void* handle; if (!x509) return IP_NULL; if (ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL) != IPCOM_SUCCESS) return IP_NULL; ipcom_mutex_lock(ipcom_key_db_mutex); handle = ipcom_key_db_pkey_opendb(); if (!handle) goto cleanup; cert_pub_key=X509_get_pubkey(x509); if (!cert_pub_key) { goto cleanup; } /* Iterate over all keys in the DB and see if any of them match the X509 certificate */ while (1) { if (ipcom_key_db_pkey_readdb(handle, int_key_id, (int)sizeof(int_key_id)) != IPCOM_SUCCESS) goto cleanup; pkey = ipcom_key_db_pkey_get(int_key_id); if (!pkey) goto cleanup; if (EVP_PKEY_cmp(pkey, cert_pub_key) == 1) { if (key_id && key_id_len) { if ((int)ipcom_strlen(int_key_id) < *key_id_len) ipcom_strcpy(key_id, int_key_id); else *key_id = 0; *key_id_len = (int)ipcom_strlen(int_key_id); } break; } EVP_PKEY_free(pkey); pkey = IP_NULL; } cleanup: if (handle) ipcom_key_db_pkey_closedb(handle); if (cert_pub_key) EVP_PKEY_free(cert_pub_key); ipcom_mutex_unlock(ipcom_key_db_mutex); return pkey; } /* *=========================================================================== * ipcom_key_db_pkey_opendb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC void* ipcom_key_db_pkey_opendb(void) { return ipcom_key_db_opendb(IPCOM_KEY_DB_TYPE_PKEY); } /* *=========================================================================== * ipcom_key_db_pkey_readdb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_pkey_readdb(void* handle, char* name, int name_len) { if (!handle || !name) return IPCOM_ERR_INVALID_ARG; return ipcom_key_db_readdb(handle, name, name_len); } /* *=========================================================================== * ipcom_key_db_pkey_closedb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_pkey_closedb(void* handle) { return ipcom_key_db_closedb(handle); } #endif /* IPCRYPTO */ /* *=========================================================================== * ipcom_key_db_buf_import *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_buf_import(const char* key_id, const Ip_u8* key, int key_len) { IP_FILE* fp; Ip_err rc; unsigned char* encr_key; int encr_len; if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID || !key || key_len > IPCOM_KEY_DB_MAX_BUF) return IPCOM_ERR_INVALID_ARG; rc = ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL); if (rc != IPCOM_SUCCESS) return rc; rc = IPCOM_ERR_FAILED; ipcom_mutex_lock(ipcom_key_db_mutex); fp = ipcom_key_db_get_fp(key_id, IPCOM_KEY_DB_TYPE_BUF, IPCOM_KEY_DB_MODE_READ); if (fp) { ipcom_fclose(fp); ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_ALREADY_INSTALLED; } fp = ipcom_key_db_get_fp(key_id, IPCOM_KEY_DB_TYPE_BUF, IPCOM_KEY_DB_MODE_WRITE); if (!fp) { ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_FAILED; } encr_len = key_len+MAX_BLOCK_SIZE; encr_key = ipcom_malloc((Ip_size_t)encr_len); if (!encr_key) { IPCOM_LOG0(ERR, "ipcom_key_db_import_buf :: out of memory"); goto cleanup; } if (ipcom_key_db_buf_encrypt(key, key_len, encr_key, &encr_len) != IPCOM_SUCCESS) { IPCOM_LOG0(ERR, "ipcom_key_db_import_buf :: ipcom_key_db_buf_encrypt failed"); goto cleanup; } if (ipcom_fwrite(encr_key, (Ip_size_t)encr_len, 1, fp) != 1) { IPCOM_LOG1(ERR, "ipcom_key_db_import_buf :: ipcom_fwrite() failed, errno: %d", ipcom_errno); goto cleanup; } rc = IPCOM_SUCCESS; cleanup: if (fp) ipcom_fclose(fp); if (encr_key) ipcom_free(encr_key); ipcom_mutex_unlock(ipcom_key_db_mutex); return rc; } /* *=========================================================================== * ipcom_key_db_pkey_del *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_pkey_del(const char* key_id) { Ip_err err; char path[IPCOM_KEY_DB_MAX_PATH] = {0}; IP_FILE* fp; if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID) return IPCOM_ERR_INVALID_ARG; err = ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL); if (err != IPCOM_SUCCESS) return err; ipcom_mutex_lock(ipcom_key_db_mutex); fp = ipcom_key_db_get_fp(key_id, IPCOM_KEY_DB_TYPE_PKEY, IPCOM_KEY_DB_MODE_READ); if (!fp) { ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_NOT_FOUND; } ipcom_fclose(fp); if (ipcom_key_db_get_dir_name(path, sizeof(path), IPCOM_KEY_DB_TYPE_PKEY) != IPCOM_SUCCESS) { ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_FAILED; } (void)ipcom_key_db_strcatn(path, sizeof(path), key_id); if (ipcom_unlink(path)) err = IPCOM_ERR_FAILED; else err= IPCOM_SUCCESS; ipcom_mutex_unlock(ipcom_key_db_mutex); return err; } /* *=========================================================================== * ipcom_key_db_buf_get *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_buf_get(const char* key_id, Ip_u8* buf, int* buf_len) { IP_FILE* fp; unsigned char* encr_key = IP_NULL; unsigned char* clear_text_key = IP_NULL; int encr_len; int clear_text_len; Ip_err rc; if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID || !buf_len) { return IPCOM_ERR_INVALID_ARG; } rc = ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL); if (rc != IPCOM_SUCCESS) return rc; rc = IPCOM_ERR_FAILED; ipcom_mutex_lock(ipcom_key_db_mutex); fp = ipcom_key_db_get_fp(key_id, IPCOM_KEY_DB_TYPE_BUF, IPCOM_KEY_DB_MODE_READ); if (!fp) { rc = IPCOM_ERR_NOT_FOUND; goto cleanup; } encr_key = ipcom_malloc(IPCOM_KEY_DB_MAX_BUF+MAX_BLOCK_SIZE); clear_text_key = ipcom_malloc(IPCOM_KEY_DB_MAX_BUF+MAX_BLOCK_SIZE); clear_text_len = IPCOM_KEY_DB_MAX_BUF+MAX_BLOCK_SIZE; if (!encr_key || !clear_text_key) { IPCOM_LOG0(ERR, "ipcom_key_db_get_buf :: out of memory"); rc = IPCOM_ERR_NO_MEMORY; goto cleanup; } encr_len = (int)ipcom_fread(encr_key, 1, IPCOM_KEY_DB_MAX_BUF+MAX_BLOCK_SIZE, fp); if (encr_len <= 0) { IPCOM_LOG1(ERR, "ipcom_key_db_get_buf :: failed to read key_id %s", key_id); goto cleanup; } if (ipcom_key_db_buf_decrypt(encr_key, encr_len, clear_text_key, &clear_text_len) == IPCOM_SUCCESS) { rc = IPCOM_SUCCESS; if (buf) { if (*buf_len >= clear_text_len) ipcom_memcpy(buf, clear_text_key, (Ip_size_t)clear_text_len); else rc = IPCOM_ERR_INVALID_ARG; } *buf_len = clear_text_len; } else { IPCOM_LOG0(ERR, "ipcom_key_db_get_buf :: ipcom_key_db_buf_decrypt failed"); goto cleanup; } cleanup: if (fp) ipcom_fclose(fp); if (encr_key) ipcom_free(encr_key); if (clear_text_key) ipcom_free(clear_text_key); ipcom_mutex_unlock(ipcom_key_db_mutex); return rc; } /* *=========================================================================== * ipcom_key_db_buf_del *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_buf_del(const char* key_id) { Ip_err err; char path[IPCOM_KEY_DB_MAX_PATH] = {0}; if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID) { return IPCOM_ERR_INVALID_ARG; } err = ipcom_once(&ipcom_key_db_once, ipcom_key_db_init, IP_NULL); if (err != IPCOM_SUCCESS) return err; ipcom_mutex_lock(ipcom_key_db_mutex); if (ipcom_key_db_get_dir_name(path, sizeof(path), IPCOM_KEY_DB_TYPE_BUF) != IPCOM_SUCCESS) { ipcom_mutex_unlock(ipcom_key_db_mutex); return IPCOM_ERR_FAILED; } if (ipcom_key_db_strcatn(path, sizeof(path), key_id) == IPCOM_SUCCESS) { if (ipcom_unlink(path)) err = IPCOM_ERR_FAILED; else err= IPCOM_SUCCESS; } else err= IPCOM_SUCCESS; ipcom_mutex_unlock(ipcom_key_db_mutex); return err; } /* *=========================================================================== * ipcom_key_db_buf_opendb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC void* ipcom_key_db_buf_opendb(void) { return ipcom_key_db_opendb(IPCOM_KEY_DB_TYPE_BUF); } /* *=========================================================================== * ipcom_key_db_buf_readdb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_buf_readdb(void* handle, char* name, int name_len) { return ipcom_key_db_readdb(handle, name, name_len); } /* *=========================================================================== * ipcom_key_db_buf_closedb *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC Ip_err ipcom_key_db_buf_closedb(void* handle) { return ipcom_key_db_closedb(handle); } #else int ipcom_key_db_empty_file; #endif /* **************************************************************************** * END OF FILE **************************************************************************** */