Files
m241Neelima/components/ip_net2-6.9/ipcom/src/ipcom_key_db.c
T

1292 lines
32 KiB
C

/*
******************************************************************************
* 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 <roger.boden@windriver.com>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipcom_config.h"
#ifdef IPCOM_USE_KEY_DB
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_sysvar.h>
#include <ipcom_syslog.h>
#include <ipcom_err.h>
#include <ipcom_file.h>
#include <ipcom_key_db.h>
#ifdef IPCRYPTO
#include <openssl/aes.h>
#include <ipcrypto.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/sha.h>
#endif /* IPCRYPTO */
#if defined(IP_PORT_OSE5)
#include <openssl/aes.h>
#include <openssl/sha.h>
#elif defined(IPMCRYPTO)
#include <ip/openssl/aes.h>
#include <ip/openssl/sha.h>
#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<i && slash_ptr; j++)
{
if (*slash_ptr == '/')
slash_ptr++;
slash_ptr = ipcom_strchr(slash_ptr, '/');
}
if (!slash_ptr)
{
ipcom_free(tmp_path);
break;
}
*slash_ptr = 0;
/* If we have an absolute path it will start with a slash */
if (ipcom_strlen(tmp_path) > 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+pad_len; i++)
in_ptr[i] = (Ip_u8)pad_len;
(void)AES_set_encrypt_key(key, 256, &aes_key);
encr_len = (unsigned long)*outl;
(void)AES_cbc_encrypt(in_ptr, out, encr_len, &aes_key, iv, 1);
ipcom_free(in_ptr);
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_buf_decrypt
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_err
ipcom_key_db_buf_decrypt(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];
ip_assert((inl % AES_BLOCK_SIZE) == 0);
ip_assert(*outl >= 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
****************************************************************************
*/