246 lines
8.1 KiB
C
246 lines
8.1 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2009, 2011 Fidelity Information Services, Inc *
|
|
* *
|
|
* This source code contains the intellectual property *
|
|
* of its copyright holder(s), and is made available *
|
|
* under a license. If you do not know the terms of *
|
|
* the license, please stop and do not read further. *
|
|
* *
|
|
****************************************************************/
|
|
#ifndef GTMCRYPT_REF_H
|
|
#define GTMCRYPT_REF_H
|
|
|
|
#ifdef USE_OPENSSL
|
|
# include <openssl/blowfish.h>
|
|
# include <openssl/sha.h>
|
|
# include <openssl/evp.h>
|
|
#elif defined USE_GCRYPT
|
|
# include <gcrypt.h>
|
|
#else
|
|
# error "Unsupported encryption library. Reference implementation currently supports openssl and gcrypt"
|
|
#endif
|
|
|
|
#ifndef DEBUG
|
|
#undef assert
|
|
#define assert(x)
|
|
#endif
|
|
|
|
/* Any change done to the below macro should be reflected in mdef.h and vice versa */
|
|
/* Note: sizeof returns a "unsigned long" type by default. In expressions involving 32-bit quantities,
|
|
* using sizeof causes a compiler warning for every 64->32 bit auto cast (zOS compiler for now).
|
|
* Hence typecasting the return to "int" on zOS (to avoid warning) in most common sizeof usages.
|
|
* Whenever SIZEOF needs to be used in expressions involving 64-bit pointer quantities, use ((INTPTR_T)SIZEOF(...)).
|
|
* Whenever SIZEOF needs to be used in expressions involving 64-bit integer quantities, use ((long)SIZEOF(...)).
|
|
*/
|
|
#if defined(__MVS__)
|
|
# define SIZEOF(X) ((int)(sizeof(X))) /* BYPASSOK */
|
|
#else
|
|
# define SIZEOF(X) ((long)sizeof(X)) /* BYPASSOK */
|
|
#endif
|
|
|
|
typedef enum
|
|
{
|
|
ERROR_LINE_INFO = -1,
|
|
DAT_LINE_INFO,
|
|
KEY_LINE_INFO
|
|
} dbkeyfile_line_type;
|
|
|
|
typedef enum
|
|
{
|
|
LOOKING_FOR_DAT_ENTRY = 1,
|
|
LOOKING_FOR_KEY_ENTRY,
|
|
NUM_STATES
|
|
} dbkeyfile_states;
|
|
#ifdef USE_OPENSSL
|
|
typedef EVP_CIPHER_CTX crypt_key_t;
|
|
#else
|
|
typedef gcry_cipher_hd_t crypt_key_t;
|
|
#endif
|
|
|
|
#define TAB_NAME_MAX 512
|
|
#define GTM_PASSPHRASE_MAX 512
|
|
#define GC_ENCRYPT 1
|
|
#define GC_DECRYPT 0
|
|
#define GC_FAILURE 1
|
|
#define GC_SUCCESS 0
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define GNUPGHOME "GNUPGHOME"
|
|
#define DOT_GNUPG ".gnupg"
|
|
#define GTM_PASSWD "gtm_passwd"
|
|
#define GTM_DBKEYS "gtm_dbkeys"
|
|
#define DOT_GTM_DBKEYS "."GTM_DBKEYS
|
|
#define PASSWD_EMPTY "Environment variable gtm_passwd set to empty string. Password prompting not allowed for utilities"
|
|
#define GTM_PATH_MAX 1024
|
|
#define GTM_KEY_MAX 32
|
|
#define GTMCRYPT_HASH_LEN 64
|
|
#define GTMCRYPT_HASH_HEX_LEN GTMCRYPT_HASH_LEN * 2
|
|
#define DAT_LINE_INDICATOR "dat "
|
|
#define KEY_LINE_INDICATOR "key "
|
|
#define DAT_LINE_INDICATOR_SIZE (SIZEOF(DAT_LINE_INDICATOR) - 1)
|
|
#define KEY_LINE_INDICATOR_SIZE (SIZEOF(KEY_LINE_INDICATOR) - 1)
|
|
#define INVALID_HANDLE -1
|
|
#define GTMCI "GTMCI"
|
|
#define ERR_STRLEN 2048
|
|
|
|
#ifdef USE_GCRYPT
|
|
#define IV_LEN 16
|
|
#define ALGO GCRY_CIPHER_AES256
|
|
#define MODE GCRY_CIPHER_MODE_CFB
|
|
/* This string uniquely identifies the encryption algorithm and its parameters.
|
|
* It will be appended to the encryption key and the combination will be hashed (with SHA512).
|
|
* This hash will be used verify that the same algorithm (including parameters) and key are used to
|
|
* open the database file as were used to create the database file. */
|
|
#define UNIQ_ENC_PARAM_STRING "AES256CFB"
|
|
#define FLAGS 0
|
|
static char iv[IV_LEN];
|
|
static int gcry_already_inited = FALSE;
|
|
#else
|
|
#define ALGO EVP_bf_cfb64()
|
|
#define UNIQ_ENC_PARAM_STRING "BLOWFISHCFB"
|
|
#endif
|
|
#define UNIQ_ENC_PARAM_LEN SIZEOF(UNIQ_ENC_PARAM_STRING) - 1
|
|
#define HASH_INPUT_BUFF_LEN UNIQ_ENC_PARAM_LEN + GTM_KEY_MAX
|
|
|
|
|
|
/* ==================================================================================== */
|
|
/* Legend to namespaces used -
|
|
* gc_XXXXX - All functions start with the gc_ namespace
|
|
* gc_dbk_XXX - All functions related to db key mapping and internal book keeping
|
|
* gc_sym_XXX - All functions related to usages of symmetric enc/dec activities, primarily using libgcrypt or libcrypto
|
|
* gc_pk_XXX - All functions related to usages of public/private key enc/dec activities, primarily using libgpgme
|
|
*/
|
|
/* ==================================================================================== */
|
|
|
|
/* ==================================================================================== */
|
|
/* Generic macros and functions related to this plugin */
|
|
/* ==================================================================================== */
|
|
|
|
#define GC_MIN_STATIC_BLOCK_SIZE 4096 /* Have a good size block, so that we dont keep reallocating */
|
|
#define GC_ROUNDUP(x, y) ((x / y) * y) + ((x % y) ? y : 0)
|
|
#define GC_FLAGS (RTLD_NOW | RTLD_GLOBAL)
|
|
|
|
#define GTM_MALLOC_FUNC "gtm_malloc"
|
|
#define GTM_FREE_FUNC "gtm_free"
|
|
#define GTM_FILENAME_TO_ID_FUNC "gtm_filename_to_id"
|
|
#define GTM_CI_FUNC "gtm_ci"
|
|
#define GTM_ZSTATUS_FUNC "gtm_zstatus"
|
|
#define GTM_IS_FILE_IDENTICAL_FUNC "gtm_is_file_identical"
|
|
#define GTM_XCFILEID_FREE_FUNC "gtm_xcfileid_free"
|
|
|
|
xc_status_t gc_init_interface(int prompt_passwd);
|
|
|
|
typedef void * (*gtm_malloc_fptr_t)(size_t);
|
|
typedef void (*gtm_free_fptr_t)(void *);
|
|
typedef xc_status_t (*gtm_filename_to_id_fptr_t)(xc_string_t *, xc_fileid_ptr_t *);
|
|
typedef xc_status_t (*gtm_ci_fptr_t)(const char *c_rtn_name, ...);
|
|
typedef void (*gtm_zstatus_fptr_t)(char *msg, int len);
|
|
typedef xc_status_t (*gtm_is_file_identical_fptr_t)(xc_fileid_ptr_t, xc_fileid_ptr_t);
|
|
typedef void (*gtm_xcfileid_free_fptr_t)(xc_fileid_ptr_t);
|
|
|
|
gtm_malloc_fptr_t gtm_malloc_fptr;
|
|
gtm_free_fptr_t gtm_free_fptr;
|
|
gtm_filename_to_id_fptr_t gtm_filename_to_id_fptr;
|
|
gtm_ci_fptr_t gtm_ci_fptr;
|
|
gtm_zstatus_fptr_t gtm_zstatus_fptr;
|
|
gtm_is_file_identical_fptr_t gtm_is_file_identical_fptr;
|
|
gtm_xcfileid_free_fptr_t gtm_xcfileid_free_fptr;
|
|
|
|
#define DLSYM_ERR_AND_EXIT(fptr_type, fptr, func_name) \
|
|
{ \
|
|
fptr = (fptr_type)dlsym(handle, func_name); \
|
|
if (NULL == fptr) \
|
|
{ \
|
|
snprintf(err_string, ERR_STRLEN, "Enable to resolve %s ", func_name); /* BYPASSOK */ \
|
|
return GC_FAILURE; \
|
|
} \
|
|
}
|
|
|
|
#define GC_MALLOC(blk, len, type) \
|
|
{ \
|
|
blk = (type *)gtm_malloc_fptr(len); \
|
|
assert (blk); \
|
|
}
|
|
|
|
#define GC_FREE(blk) gtm_free_fptr(blk)
|
|
|
|
|
|
#define GC_COPY_TO_XC_STRING(X, STR, N) \
|
|
{ \
|
|
memcpy((X)->address, STR, N); \
|
|
(X)->length = N; \
|
|
}
|
|
|
|
|
|
/* Following makes sure that at no point we are in the encryption library without gtmcrypt_init getting called
|
|
* prior to the current call
|
|
*/
|
|
#define GC_VERIFY_INITED \
|
|
{ \
|
|
if (!gtmcrypt_inited) \
|
|
{ \
|
|
snprintf(err_string, ERR_STRLEN, "%s", "Encryption library has not been initialized"); /* BYPASSOK */ \
|
|
return GC_FAILURE; \
|
|
} \
|
|
}
|
|
|
|
#define GC_IF_INITED_RETURN \
|
|
{ \
|
|
/* Check if init has happened already */ \
|
|
if (gtmcrypt_inited) \
|
|
return GC_SUCCESS; \
|
|
}
|
|
|
|
#define GC_SET_INITED gtmcrypt_inited = TRUE;
|
|
|
|
#define GC_CLEAR_INITED gtmcrypt_inited = FALSE;
|
|
|
|
#define GC_INT(H) ((H >= 'A' && H <= 'F') ? ((H - 'A') + 10) : (H - '0'))
|
|
|
|
#define GC_UNHEX(a, b, len) \
|
|
{ \
|
|
int i; \
|
|
for (i = 0; i < len; i+=2) \
|
|
b[i/2] = (unsigned char)(GC_INT(a[i]) * 16 + GC_INT(a[i + 1])); \
|
|
}
|
|
|
|
#define GC_HEX(a, b, len) \
|
|
{ \
|
|
int i; \
|
|
for (i = 0; i < len; i+=2) \
|
|
sprintf(b + i, "%02X", (unsigned char)a[i/2]); /* BYPASSOK */ \
|
|
}
|
|
|
|
#define GC_GETENV(ptr, key, RC) \
|
|
{ \
|
|
RC = GC_SUCCESS; \
|
|
if (NULL == (ptr = (char *)getenv(key))) \
|
|
RC = GC_FAILURE; \
|
|
}
|
|
|
|
#define GC_ENV_UNSET_ERROR(key) \
|
|
{ \
|
|
snprintf(err_string, ERR_STRLEN, "Environment variable %s not set", key); /* BYPASSOK */ \
|
|
}
|
|
|
|
/* Allocate a single block, and try reusing the same everytime this macro is called */
|
|
#ifdef USE_OPENSSL
|
|
#define GC_GET_STATIC_BLOCK(out, block_len) \
|
|
{ \
|
|
static char *blk = (char *)NULL; \
|
|
static int allocated_len = GC_MIN_STATIC_BLOCK_SIZE; \
|
|
if (blk == NULL || (block_len > allocated_len)) \
|
|
{ \
|
|
if (blk) \
|
|
GC_FREE(blk); \
|
|
allocated_len = (block_len > allocated_len) ? \
|
|
GC_ROUNDUP(block_len, GC_MIN_STATIC_BLOCK_SIZE) : \
|
|
allocated_len; \
|
|
GC_MALLOC(blk, allocated_len, char); \
|
|
} \
|
|
out = blk; \
|
|
}
|
|
#endif
|
|
#endif /* GTMCRYPT_REF_H */
|