Make encrypt/decrypt code accept integer key lengths instead of using strlen()
Now that encryptions keys and hmac keys may be acquired from /dev/random with --key-gen (and base64 encoded), they may contain NULL bytes. This emphasizes the need to not leverage code that assumes C-style strings when making use of key information.
This commit is contained in:
parent
92e403a242
commit
47e39272ed
@ -37,7 +37,8 @@
|
||||
/* prototypes
|
||||
*/
|
||||
static void get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
char *key, char *hmac_key, const int crypt_op);
|
||||
char *key, int *key_len, char *hmac_key,
|
||||
int *hmac_key_len, const int crypt_op);
|
||||
static void display_ctx(fko_ctx_t ctx);
|
||||
static void errmsg(const char *msg, const int err);
|
||||
static void show_last_command(void);
|
||||
@ -59,6 +60,7 @@ main(int argc, char **argv)
|
||||
char access_buf[MAX_LINE_LEN] = {0};
|
||||
char key[MAX_KEY_LEN+1] = {0};
|
||||
char hmac_key[MAX_KEY_LEN+1] = {0};
|
||||
int key_len = 0, hmac_key_len = 0;
|
||||
|
||||
fko_cli_options_t options;
|
||||
|
||||
@ -301,11 +303,12 @@ main(int argc, char **argv)
|
||||
|
||||
/* Acquire the necessary encryption/hmac keys
|
||||
*/
|
||||
get_keys(ctx, &options, key, hmac_key, CRYPT_OP_ENCRYPT);
|
||||
get_keys(ctx, &options, key, &key_len,
|
||||
hmac_key, &hmac_key_len, CRYPT_OP_ENCRYPT);
|
||||
|
||||
/* Finalize the context data (encrypt and encode the SPA data)
|
||||
*/
|
||||
res = fko_spa_data_final(ctx, key, hmac_key);
|
||||
res = fko_spa_data_final(ctx, key, key_len, hmac_key, hmac_key_len);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
errmsg("fko_spa_data_final", res);
|
||||
@ -366,7 +369,7 @@ main(int argc, char **argv)
|
||||
* options, then decode it.
|
||||
*/
|
||||
res = fko_new_with_data(&ctx2, spa_data, NULL,
|
||||
ctx->encryption_mode, hmac_key);
|
||||
0, ctx->encryption_mode, hmac_key, hmac_key_len);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
errmsg("fko_new_with_data", res);
|
||||
@ -395,12 +398,13 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
get_keys(ctx2, &options, key, hmac_key, CRYPT_OP_DECRYPT);
|
||||
get_keys(ctx2, &options, key, &key_len,
|
||||
hmac_key, &hmac_key_len, CRYPT_OP_DECRYPT);
|
||||
|
||||
/* Verify HMAC first
|
||||
*/
|
||||
if(options.use_hmac)
|
||||
res = fko_verify_hmac(ctx2, hmac_key);
|
||||
res = fko_verify_hmac(ctx2, hmac_key, hmac_key_len);
|
||||
|
||||
/* Decrypt
|
||||
*/
|
||||
@ -409,7 +413,7 @@ main(int argc, char **argv)
|
||||
/* check fko_verify_hmac() return value */
|
||||
}
|
||||
else
|
||||
res = fko_decrypt_spa_data(ctx2, key);
|
||||
res = fko_decrypt_spa_data(ctx2, key, key_len);
|
||||
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
@ -751,7 +755,8 @@ set_message_type(fko_ctx_t ctx, fko_cli_options_t *options)
|
||||
*/
|
||||
static void
|
||||
get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
char *key, char *hmac_key, const int crypt_op)
|
||||
char *key, int *key_len, char *hmac_key,
|
||||
int *hmac_key_len, const int crypt_op)
|
||||
{
|
||||
int use_hmac = 0, res = 0;
|
||||
|
||||
@ -767,10 +772,14 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
return;
|
||||
|
||||
if (options->have_key)
|
||||
{
|
||||
strlcpy(key, options->key, MAX_KEY_LEN+1);
|
||||
*key_len = strlen(key);
|
||||
}
|
||||
else if (options->have_base64_key)
|
||||
{
|
||||
fko_base64_decode(options->key_base64, (unsigned char *) options->key);
|
||||
*key_len = fko_base64_decode(options->key_base64,
|
||||
(unsigned char *) options->key);
|
||||
memcpy(key, options->key, RIJNDAEL_MAX_KEYSIZE);
|
||||
}
|
||||
else
|
||||
@ -781,15 +790,22 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
{
|
||||
strlcpy(key, getpasswd_file(options->get_key_file,
|
||||
options->spa_server_str), MAX_KEY_LEN+1);
|
||||
*key_len = strlen(key);
|
||||
}
|
||||
else if (options->use_gpg)
|
||||
{
|
||||
if(crypt_op == CRYPT_OP_DECRYPT)
|
||||
{
|
||||
strlcpy(key, getpasswd("Enter passphrase for secret key: "),
|
||||
MAX_KEY_LEN+1);
|
||||
*key_len = strlen(key);
|
||||
}
|
||||
else if(options->gpg_signer_key && strlen(options->gpg_signer_key))
|
||||
{
|
||||
strlcpy(key, getpasswd("Enter passphrase for signing: "),
|
||||
MAX_KEY_LEN+1);
|
||||
*key_len = strlen(key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -802,6 +818,7 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
else
|
||||
strlcpy(key, getpasswd("Enter key: "),
|
||||
MAX_KEY_LEN+1);
|
||||
*key_len = strlen(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -809,11 +826,13 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
if (options->have_hmac_key)
|
||||
{
|
||||
strlcpy(hmac_key, options->hmac_key, MAX_KEY_LEN+1);
|
||||
*hmac_key_len = strlen(hmac_key);
|
||||
use_hmac = 1;
|
||||
}
|
||||
else if (options->have_hmac_base64_key)
|
||||
{
|
||||
fko_base64_decode(options->hmac_key_base64, (unsigned char *) options->hmac_key);
|
||||
*hmac_key_len = fko_base64_decode(options->hmac_key_base64,
|
||||
(unsigned char *) options->hmac_key);
|
||||
memcpy(hmac_key, options->hmac_key, SHA256_BLOCK_LENGTH);
|
||||
use_hmac = 1;
|
||||
}
|
||||
@ -830,6 +849,7 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
|
||||
{
|
||||
#endif
|
||||
strlcpy(hmac_key, getpasswd("Enter HMAC key: "), MAX_KEY_LEN+1);
|
||||
*hmac_key_len = strlen(hmac_key);
|
||||
use_hmac = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -115,27 +115,27 @@ get_random_data(unsigned char *data, const size_t len)
|
||||
* the Perl Crypt::CBC module's use of Rijndael.
|
||||
*/
|
||||
static void
|
||||
rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, const unsigned char *data)
|
||||
rij_salt_and_iv(RIJNDAEL_context *ctx, const char *key,
|
||||
const int key_len, const unsigned char *data)
|
||||
{
|
||||
char pw_buf[16];
|
||||
char pw_buf[RIJNDAEL_MIN_KEYSIZE];
|
||||
unsigned char tmp_buf[64]; /* How big does this need to be? */
|
||||
unsigned char kiv_buf[48]; /* Key and IV buffer */
|
||||
unsigned char md5_buf[16]; /* Buffer for computed md5 hash */
|
||||
|
||||
size_t kiv_len = 0;
|
||||
size_t plen = strlen(pass);
|
||||
|
||||
/* First make pw 16 bytes (pad with "0" (ascii 0x30)) or truncate.
|
||||
/* First make pw 32 bytes (pad with "0" (ascii 0x30)) or truncate.
|
||||
* Note: pw_buf was initialized with '0' chars (again, not the value
|
||||
* 0, but the digit '0' character).
|
||||
*/
|
||||
if(plen < 16)
|
||||
if(key_len < RIJNDAEL_MIN_KEYSIZE)
|
||||
{
|
||||
memcpy(pw_buf, pass, plen);
|
||||
memset(pw_buf+plen, '0', 16 - plen);
|
||||
memcpy(pw_buf, key, key_len);
|
||||
memset(pw_buf+key_len, '0', RIJNDAEL_MIN_KEYSIZE - key_len);
|
||||
}
|
||||
else
|
||||
strncpy(pw_buf, pass, 16);
|
||||
memcpy(pw_buf, key, RIJNDAEL_MIN_KEYSIZE);
|
||||
|
||||
/* If we are decrypting, data will contain the salt. Otherwise,
|
||||
* for encryption, we generate a random salt.
|
||||
@ -157,7 +157,7 @@ rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, const unsigned char *da
|
||||
* (again it is the perl Crypt::CBC way, with a touch of
|
||||
* fwknop).
|
||||
*/
|
||||
memcpy(tmp_buf+16, pw_buf, 16);
|
||||
memcpy(tmp_buf+RIJNDAEL_MIN_KEYSIZE, pw_buf, RIJNDAEL_MIN_KEYSIZE);
|
||||
memcpy(tmp_buf+32, ctx->salt, 8);
|
||||
|
||||
while(kiv_len < sizeof(kiv_buf))
|
||||
@ -181,8 +181,9 @@ rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, const unsigned char *da
|
||||
/* Initialization entry point.
|
||||
*/
|
||||
static void
|
||||
rijndael_init(RIJNDAEL_context *ctx, const char *pass,
|
||||
const unsigned char *data, int encryption_mode)
|
||||
rijndael_init(RIJNDAEL_context *ctx, const char *key,
|
||||
const int key_len, const unsigned char *data,
|
||||
int encryption_mode)
|
||||
{
|
||||
|
||||
/* The default (set in fko.h) is ECB mode to be compatible with the
|
||||
@ -192,11 +193,11 @@ rijndael_init(RIJNDAEL_context *ctx, const char *pass,
|
||||
|
||||
/* Generate the salt and initialization vector.
|
||||
*/
|
||||
rij_salt_and_iv(ctx, pass, data);
|
||||
rij_salt_and_iv(ctx, key, key_len, data);
|
||||
|
||||
/* Intialize our rinjdael context.
|
||||
/* Intialize our Rijndael context.
|
||||
*/
|
||||
rijndael_setup(ctx, 32, ctx->key);
|
||||
rijndael_setup(ctx, RIJNDAEL_MAX_KEYSIZE, ctx->key);
|
||||
}
|
||||
|
||||
/* Take a chunk of data, encrypt it in the same way the perl Crypt::CBC
|
||||
@ -204,13 +205,14 @@ rijndael_init(RIJNDAEL_context *ctx, const char *pass,
|
||||
*/
|
||||
size_t
|
||||
rij_encrypt(unsigned char *in, size_t in_len,
|
||||
const char *pass, unsigned char *out, int encryption_mode)
|
||||
const char *key, const int key_len,
|
||||
unsigned char *out, int encryption_mode)
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
int i, pad_val;
|
||||
unsigned char *ondx = out;
|
||||
|
||||
rijndael_init(&ctx, pass, NULL, encryption_mode);
|
||||
rijndael_init(&ctx, key, key_len, NULL, encryption_mode);
|
||||
|
||||
/* Prepend the salt to the ciphertext...
|
||||
*/
|
||||
@ -237,14 +239,15 @@ rij_encrypt(unsigned char *in, size_t in_len,
|
||||
*/
|
||||
size_t
|
||||
rij_decrypt(unsigned char *in, size_t in_len,
|
||||
const char *pass, unsigned char *out, int encryption_mode)
|
||||
const char *key, const int key_len,
|
||||
unsigned char *out, int encryption_mode)
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
int i, pad_val, pad_err = 0;
|
||||
unsigned char *pad_s;
|
||||
unsigned char *ondx = out;
|
||||
|
||||
rijndael_init(&ctx, pass, in, encryption_mode);
|
||||
rijndael_init(&ctx, key, key_len, in, encryption_mode);
|
||||
|
||||
/* Remove the first block since it contains the salt (it was consumed
|
||||
* by the rijndael_init() function above).
|
||||
|
||||
@ -49,9 +49,11 @@
|
||||
|
||||
void get_random_data(unsigned char *data, const size_t len);
|
||||
size_t rij_encrypt(unsigned char *in, size_t len,
|
||||
const char *key, unsigned char *out, int encryption_mode);
|
||||
const char *key, const int key_len,
|
||||
unsigned char *out, int encryption_mode);
|
||||
size_t rij_decrypt(unsigned char *in, size_t len,
|
||||
const char *key, unsigned char *out, int encryption_mode);
|
||||
const char *key, const int key_len,
|
||||
unsigned char *out, int encryption_mode);
|
||||
|
||||
#endif /* CIPHER_FUNCS_H */
|
||||
|
||||
|
||||
35
lib/fko.h
35
lib/fko.h
@ -222,10 +222,11 @@ enum {
|
||||
*/
|
||||
DLL_API int fko_new(fko_ctx_t *ctx);
|
||||
DLL_API int fko_new_with_data(fko_ctx_t *ctx, const char *enc_msg,
|
||||
const char *dec_key, int encryption_mode, const char *hmac_key);
|
||||
const char *dec_key, const int dec_key_len, int encryption_mode,
|
||||
const char *hmac_key, const int hmac_key_len);
|
||||
DLL_API void fko_destroy(fko_ctx_t ctx);
|
||||
DLL_API int fko_spa_data_final(fko_ctx_t ctx, const char *enc_key,
|
||||
const char *hmac_key);
|
||||
const int enc_key_len, const char *hmac_key, const int hmac_key_len);
|
||||
|
||||
|
||||
/* Set context data functions
|
||||
@ -255,10 +256,14 @@ DLL_API int fko_base64_decode(const char *in, unsigned char *out);
|
||||
|
||||
DLL_API int fko_encode_spa_data(fko_ctx_t ctx);
|
||||
DLL_API int fko_decode_spa_data(fko_ctx_t ctx);
|
||||
DLL_API int fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key);
|
||||
DLL_API int fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key);
|
||||
DLL_API int fko_verify_hmac(fko_ctx_t ctx, const char *hmac_key);
|
||||
DLL_API int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key);
|
||||
DLL_API int fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key,
|
||||
const int enc_key_len);
|
||||
DLL_API int fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key,
|
||||
const int dec_key_len);
|
||||
DLL_API int fko_verify_hmac(fko_ctx_t ctx, const char *hmac_key,
|
||||
const int hmac_key_len);
|
||||
DLL_API int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key,
|
||||
const int hmac_key_len);
|
||||
DLL_API int fko_get_hmac_data(fko_ctx_t ctx, char **enc_data);
|
||||
|
||||
DLL_API int fko_get_encoded_data(fko_ctx_t ctx, char **enc_data);
|
||||
@ -295,18 +300,24 @@ DLL_API int fko_get_gpg_home_dir(fko_ctx_t ctx, char **gpg_home_dir);
|
||||
|
||||
DLL_API const char* fko_gpg_errstr(fko_ctx_t ctx);
|
||||
|
||||
DLL_API int fko_set_gpg_signature_verify(fko_ctx_t ctx, const unsigned char val);
|
||||
DLL_API int fko_get_gpg_signature_verify(fko_ctx_t ctx, unsigned char *val);
|
||||
DLL_API int fko_set_gpg_ignore_verify_error(fko_ctx_t ctx, const unsigned char val);
|
||||
DLL_API int fko_get_gpg_ignore_verify_error(fko_ctx_t ctx, unsigned char *val);
|
||||
DLL_API int fko_set_gpg_signature_verify(fko_ctx_t ctx,
|
||||
const unsigned char val);
|
||||
DLL_API int fko_get_gpg_signature_verify(fko_ctx_t ctx,
|
||||
unsigned char *val);
|
||||
DLL_API int fko_set_gpg_ignore_verify_error(fko_ctx_t ctx,
|
||||
const unsigned char val);
|
||||
DLL_API int fko_get_gpg_ignore_verify_error(fko_ctx_t ctx,
|
||||
unsigned char *val);
|
||||
|
||||
DLL_API int fko_get_gpg_signature_id(fko_ctx_t ctx, char **sig_id);
|
||||
DLL_API int fko_get_gpg_signature_fpr(fko_ctx_t ctx, char **sig_fpr);
|
||||
DLL_API int fko_get_gpg_signature_summary(fko_ctx_t ctx, int *sigsum);
|
||||
DLL_API int fko_get_gpg_signature_status(fko_ctx_t ctx, int *sigstat);
|
||||
|
||||
DLL_API int fko_gpg_signature_id_match(fko_ctx_t ctx, const char *id, unsigned char *result);
|
||||
DLL_API int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char *fpr, unsigned char *result);
|
||||
DLL_API int fko_gpg_signature_id_match(fko_ctx_t ctx, const char *id,
|
||||
unsigned char *result);
|
||||
DLL_API int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char *fpr,
|
||||
unsigned char *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
/* Prep and encrypt using Rijndael
|
||||
*/
|
||||
static int
|
||||
_rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
_rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len)
|
||||
{
|
||||
char *plaintext;
|
||||
char *b64ciphertext;
|
||||
@ -68,8 +68,9 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
cipher_len = rij_encrypt(
|
||||
(unsigned char*)plaintext, strlen(plaintext), (char*)enc_key, ciphertext,
|
||||
ctx->encryption_mode
|
||||
(unsigned char*)plaintext, strlen(plaintext),
|
||||
(char*)enc_key, enc_key_len,
|
||||
ciphertext, ctx->encryption_mode
|
||||
);
|
||||
|
||||
/* Now make a bucket for the base64-encoded version and populate it.
|
||||
@ -98,7 +99,8 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
/* Decode, decrypt, and parse SPA data into the context.
|
||||
*/
|
||||
static int
|
||||
_rijndael_decrypt(fko_ctx_t ctx, const char *dec_key, int encryption_mode)
|
||||
_rijndael_decrypt(fko_ctx_t ctx,
|
||||
const char *dec_key, const int key_len, int encryption_mode)
|
||||
{
|
||||
char *tbuf;
|
||||
unsigned char *ndx;
|
||||
@ -155,7 +157,7 @@ _rijndael_decrypt(fko_ctx_t ctx, const char *dec_key, int encryption_mode)
|
||||
if(ctx->encoded_msg == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
pt_len = rij_decrypt(cipher, cipher_len, dec_key,
|
||||
pt_len = rij_decrypt(cipher, cipher_len, dec_key, key_len,
|
||||
(unsigned char*)ctx->encoded_msg, encryption_mode);
|
||||
|
||||
/* Done with cipher...
|
||||
@ -413,7 +415,7 @@ fko_get_spa_encryption_mode(fko_ctx_t ctx, int *enc_mode)
|
||||
/* Encrypt the encoded SPA data.
|
||||
*/
|
||||
int
|
||||
fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key)
|
||||
fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key, const int enc_key_len)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
@ -445,7 +447,7 @@ fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key)
|
||||
/* Encrypt according to type and return...
|
||||
*/
|
||||
if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL)
|
||||
res = _rijndael_encrypt(ctx, enc_key);
|
||||
res = _rijndael_encrypt(ctx, enc_key, enc_key_len);
|
||||
else if(ctx->encryption_type == FKO_ENCRYPTION_GPG)
|
||||
#if HAVE_LIBGPGME
|
||||
res = gpg_encrypt(ctx, enc_key);
|
||||
@ -461,7 +463,7 @@ fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key)
|
||||
/* Decode, decrypt, and parse SPA data into the context.
|
||||
*/
|
||||
int
|
||||
fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key)
|
||||
fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key, const int key_len)
|
||||
{
|
||||
int enc_type, res;
|
||||
|
||||
@ -484,7 +486,8 @@ fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key)
|
||||
else if(enc_type == FKO_ENCRYPTION_RIJNDAEL)
|
||||
{
|
||||
ctx->encryption_type = FKO_ENCRYPTION_RIJNDAEL;
|
||||
res = _rijndael_decrypt(ctx, dec_key, ctx->encryption_mode);
|
||||
res = _rijndael_decrypt(ctx,
|
||||
dec_key, key_len, ctx->encryption_mode);
|
||||
}
|
||||
else
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
|
||||
@ -171,7 +171,9 @@ fko_new(fko_ctx_t *r_ctx)
|
||||
*/
|
||||
int
|
||||
fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg,
|
||||
const char *dec_key, int encryption_mode, const char *hmac_key)
|
||||
const char *dec_key, const int dec_key_len,
|
||||
int encryption_mode, const char *hmac_key,
|
||||
const int hmac_key_len)
|
||||
{
|
||||
fko_ctx_t ctx;
|
||||
int res = FKO_SUCCESS; /* Are we optimistic or what? */
|
||||
@ -204,7 +206,7 @@ fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg,
|
||||
*/
|
||||
ctx->initval = FKO_CTX_INITIALIZED;
|
||||
if(hmac_key != NULL)
|
||||
res = fko_verify_hmac(ctx, hmac_key);
|
||||
res = fko_verify_hmac(ctx, hmac_key, hmac_key_len);
|
||||
ctx->initval = 0;
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
@ -221,7 +223,7 @@ fko_new_with_data(fko_ctx_t *r_ctx, const char *enc_msg,
|
||||
*/
|
||||
if(dec_key != NULL)
|
||||
{
|
||||
res = fko_decrypt_spa_data(ctx, dec_key);
|
||||
res = fko_decrypt_spa_data(ctx, dec_key, dec_key_len);
|
||||
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
@ -330,7 +332,7 @@ fko_destroy(fko_ctx_t ctx)
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
/* Generate Rijndael and HMAC keys from /dev/random and base-64
|
||||
/* Generate Rijndael and HMAC keys from /dev/random and base64
|
||||
* encode them
|
||||
*/
|
||||
int
|
||||
@ -353,15 +355,13 @@ fko_key_gen(char *key_base64, char *hmac_key_base64)
|
||||
int
|
||||
fko_base64_encode(unsigned char *in, char *out, int in_len)
|
||||
{
|
||||
b64_encode(in, out, in_len);
|
||||
return(FKO_SUCCESS);
|
||||
return b64_encode(in, out, in_len);
|
||||
}
|
||||
|
||||
int
|
||||
fko_base64_decode(const char *in, unsigned char *out)
|
||||
{
|
||||
b64_decode(in, out);
|
||||
return(FKO_SUCCESS);
|
||||
return b64_decode(in, out);
|
||||
}
|
||||
|
||||
/* Return the fko version
|
||||
@ -384,7 +384,9 @@ fko_get_version(fko_ctx_t ctx, char **version)
|
||||
* set.
|
||||
*/
|
||||
int
|
||||
fko_spa_data_final(fko_ctx_t ctx, const char *enc_key, const char *hmac_key)
|
||||
fko_spa_data_final(fko_ctx_t ctx,
|
||||
const char *enc_key, const int enc_key_len,
|
||||
const char *hmac_key, const int hmac_key_len)
|
||||
{
|
||||
char *tbuf;
|
||||
int res = 0, data_with_hmac_len = 0;
|
||||
@ -394,14 +396,14 @@ fko_spa_data_final(fko_ctx_t ctx, const char *enc_key, const char *hmac_key)
|
||||
if(!CTX_INITIALIZED(ctx))
|
||||
return(FKO_ERROR_CTX_NOT_INITIALIZED);
|
||||
|
||||
res = fko_encrypt_spa_data(ctx, enc_key);
|
||||
res = fko_encrypt_spa_data(ctx, enc_key, enc_key_len);
|
||||
|
||||
/* Now calculate hmac if so configured
|
||||
*/
|
||||
if (res == FKO_SUCCESS &&
|
||||
ctx->hmac_mode != FKO_HMAC_UNKNOWN && hmac_key != NULL)
|
||||
{
|
||||
res = fko_calculate_hmac(ctx, hmac_key);
|
||||
res = fko_calculate_hmac(ctx, hmac_key, hmac_key_len);
|
||||
|
||||
if (res == FKO_SUCCESS)
|
||||
{
|
||||
|
||||
@ -33,7 +33,8 @@
|
||||
#include "hmac.h"
|
||||
#include "base64.h"
|
||||
|
||||
int fko_verify_hmac(fko_ctx_t ctx, const char *hmac_key)
|
||||
int fko_verify_hmac(fko_ctx_t ctx,
|
||||
const char *hmac_key, const int hmac_key_len)
|
||||
{
|
||||
/* Must be initialized
|
||||
*/
|
||||
@ -80,7 +81,8 @@ fko_set_hmac_mode(fko_ctx_t ctx, const short hmac_mode)
|
||||
return(FKO_SUCCESS);
|
||||
}
|
||||
|
||||
int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key)
|
||||
int fko_calculate_hmac(fko_ctx_t ctx,
|
||||
const char *hmac_key, const int hmac_key_len)
|
||||
{
|
||||
unsigned char hmac[SHA256_DIGEST_STRING_LENGTH] = {0};
|
||||
char *hmac_base64 = NULL;
|
||||
@ -99,7 +101,8 @@ int fko_calculate_hmac(fko_ctx_t ctx, const char *hmac_key)
|
||||
if (hmac_base64 == NULL)
|
||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||
|
||||
hmac_sha256(ctx->encrypted_msg, strlen(ctx->encrypted_msg), hmac, hmac_key);
|
||||
hmac_sha256(ctx->encrypted_msg,
|
||||
strlen(ctx->encrypted_msg), hmac, hmac_key);
|
||||
|
||||
b64_encode(hmac, hmac_base64, SHA256_DIGEST_LENGTH);
|
||||
strip_b64_eq(hmac_base64);
|
||||
|
||||
@ -303,13 +303,13 @@ inv_mix_column(uint32_t *a, uint32_t *b)
|
||||
}
|
||||
|
||||
void
|
||||
rijndael_setup(RIJNDAEL_context *ctx, size_t keysize, const uint8_t *key)
|
||||
rijndael_setup(RIJNDAEL_context *ctx, const size_t keysize, const uint8_t *key)
|
||||
{
|
||||
int nk, nr, i, lastkey;
|
||||
uint32_t temp, rcon;
|
||||
|
||||
/* Truncate keysizes to the valid key sizes provided by Rijndael */
|
||||
if (keysize >= 32) {
|
||||
if (keysize >= RIJNDAEL_MAX_KEYSIZE) {
|
||||
nk = 8;
|
||||
nr = 14;
|
||||
} else if (keysize >= 24) {
|
||||
|
||||
@ -63,7 +63,7 @@ typedef struct {
|
||||
int nrounds; /* number of rounds to use for our key size */
|
||||
int mode; /* encryption mode */
|
||||
/* Added by DSS */
|
||||
uint8_t key[32];
|
||||
uint8_t key[RIJNDAEL_MAX_KEYSIZE];
|
||||
uint8_t iv[16];
|
||||
uint8_t salt[8];
|
||||
} RIJNDAEL_context;
|
||||
@ -77,7 +77,8 @@ typedef struct {
|
||||
* PASS A VALUE LESS THAN 16 TO KEYSIZE!
|
||||
*/
|
||||
void
|
||||
rijndael_setup(RIJNDAEL_context *ctx, size_t keysize, const uint8_t *key);
|
||||
rijndael_setup(RIJNDAEL_context *ctx,
|
||||
const size_t keysize, const uint8_t *key);
|
||||
|
||||
/*
|
||||
* rijndael_encrypt()
|
||||
|
||||
@ -49,7 +49,31 @@ add_acc_string(char **var, const char *val)
|
||||
if((*var = strdup(val)) == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal memory allocation error adding access list entry: %s", var
|
||||
"Fatal memory allocation error adding access list entry: %s", *var
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Decode base64 encoded string into access entry
|
||||
*/
|
||||
static void
|
||||
add_acc_b64_string(char **var, int *len, const char *val)
|
||||
{
|
||||
if((*var = strdup(val)) == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal memory allocation error adding access list entry: %s", *var
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(*var, 0x0, strlen(val));
|
||||
*len = fko_base64_decode(val, (unsigned char *) *var);
|
||||
|
||||
if (*len < 0)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"base64 decoding returned error for: %s", *var
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -752,9 +776,8 @@ set_acc_defaults(fko_srv_options_t *opts)
|
||||
static int
|
||||
acc_data_is_valid(const acc_stanza_t *acc)
|
||||
{
|
||||
if((acc->key == NULL || !strlen(acc->key))
|
||||
&& (acc->key_base64 == NULL || !strlen(acc->key_base64))
|
||||
&& (acc->gpg_decrypt_pw == NULL || !strlen(acc->gpg_decrypt_pw)))
|
||||
if(acc->key_len < 0 || ((acc->key == NULL && acc->key_base64 == NULL)
|
||||
&& (acc->gpg_decrypt_pw == NULL || !strlen(acc->gpg_decrypt_pw))))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[*] No keys found for access stanza source: '%s'\n", acc->source
|
||||
@ -904,6 +927,7 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
add_acc_string(&(curr_acc->key), val);
|
||||
curr_acc->key_len = strlen(curr_acc->key);
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "KEY_BASE64"))
|
||||
{
|
||||
@ -922,6 +946,8 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
add_acc_string(&(curr_acc->key_base64), val);
|
||||
add_acc_b64_string(&(curr_acc->key),
|
||||
&(curr_acc->key_len), curr_acc->key_base64);
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "HMAC_KEY_BASE64"))
|
||||
{
|
||||
@ -940,6 +966,8 @@ parse_access_file(fko_srv_options_t *opts)
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
add_acc_string(&(curr_acc->hmac_key_base64), val);
|
||||
add_acc_b64_string(&(curr_acc->hmac_key),
|
||||
&curr_acc->hmac_key_len, curr_acc->hmac_key_base64);
|
||||
}
|
||||
else if(CONF_VAR_IS(var, "FW_ACCESS_TIMEOUT"))
|
||||
{
|
||||
|
||||
@ -267,8 +267,10 @@ typedef struct acc_stanza
|
||||
char *restrict_ports;
|
||||
acc_port_list_t *rport_list;
|
||||
char *key;
|
||||
int key_len;
|
||||
char *key_base64;
|
||||
char *hmac_key;
|
||||
int hmac_key_len;
|
||||
char *hmac_key_base64;
|
||||
int fw_access_timeout;
|
||||
unsigned char enable_cmd_exec;
|
||||
|
||||
@ -241,19 +241,6 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
|
||||
if(enc_type == FKO_ENCRYPTION_RIJNDAEL)
|
||||
{
|
||||
if (acc->key_base64 != NULL)
|
||||
{
|
||||
if ((acc->key = strdup(acc->key_base64)) == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal memory allocation error copying key_base64 -> key: %s",
|
||||
acc->key_base64
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(acc->key, 0x0, strlen(acc->key_base64));
|
||||
fko_base64_decode(acc->key_base64, (unsigned char *) acc->key);
|
||||
}
|
||||
if (acc->key == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
@ -264,22 +251,9 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (acc->hmac_key_base64 != NULL)
|
||||
{
|
||||
if ((acc->hmac_key = strdup(acc->hmac_key_base64)) == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"Fatal memory allocation error copying hmac_key_base64 -> hmac_key: %s",
|
||||
acc->hmac_key_base64
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(acc->hmac_key, 0x0, strlen(acc->hmac_key_base64));
|
||||
fko_base64_decode(acc->hmac_key_base64, (unsigned char *) acc->hmac_key);
|
||||
}
|
||||
|
||||
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data,
|
||||
acc->key, acc->encryption_mode, acc->hmac_key);
|
||||
acc->key, acc->key_len, acc->encryption_mode, acc->hmac_key,
|
||||
acc->hmac_key_len);
|
||||
}
|
||||
else if(enc_type == FKO_ENCRYPTION_GPG)
|
||||
{
|
||||
@ -289,7 +263,7 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
if(acc->gpg_decrypt_pw != NULL)
|
||||
{
|
||||
res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, NULL,
|
||||
acc->encryption_mode, NULL);
|
||||
0, acc->encryption_mode, NULL, 0);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
log_msg(LOG_WARNING,
|
||||
@ -338,7 +312,7 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
|
||||
/* Now decrypt the data.
|
||||
*/
|
||||
res = fko_decrypt_spa_data(ctx, acc->gpg_decrypt_pw);
|
||||
res = fko_decrypt_spa_data(ctx, acc->gpg_decrypt_pw, 0);
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user