diff --git a/lib/fko_encryption.c b/lib/fko_encryption.c index 3f18cb58..1df8d3f1 100644 --- a/lib/fko_encryption.c +++ b/lib/fko_encryption.c @@ -49,6 +49,7 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) char *b64ciphertext; unsigned char *ciphertext; int cipher_len; + int pt_len; if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA); @@ -56,25 +57,29 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) if (! is_valid_digest_len(ctx->digest_len)) return(FKO_ERROR_INVALID_DATA); + pt_len = ctx->encoded_msg_len + ctx->digest_len + RIJNDAEL_BLOCKSIZE + 2; + /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ - plaintext = calloc(1, ctx->encoded_msg_len - + ctx->digest_len + RIJNDAEL_BLOCKSIZE + 2); + plaintext = calloc(1, pt_len); if(plaintext == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); - sprintf(plaintext, "%s:%s", ctx->encoded_msg, ctx->digest); + pt_len = snprintf(plaintext, pt_len+1, "%s:%s", ctx->encoded_msg, ctx->digest); + + if(! is_valid_pt_msg_len(pt_len)) + return(FKO_ERROR_INVALID_DATA); /* Make a bucket for the encrypted version and populate it. */ - ciphertext = calloc(1, strlen(plaintext) + 32); /* Plus padding for salt and Block */ + ciphertext = calloc(1, pt_len + 32); /* Plus padding for salt and Block */ if(ciphertext == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); cipher_len = rij_encrypt( - (unsigned char*)plaintext, strlen(plaintext), + (unsigned char*)plaintext, pt_len, (char*)enc_key, enc_key_len, ciphertext, ctx->encryption_mode ); @@ -214,6 +219,7 @@ gpg_encrypt(fko_ctx_t ctx, const char *enc_key) { int res; char *plain; + int pt_len; char *b64cipher; unsigned char *cipher = NULL; size_t cipher_len; @@ -230,6 +236,8 @@ gpg_encrypt(fko_ctx_t ctx, const char *enc_key) if(ctx->gpg_recipient == NULL) return(FKO_ERROR_MISSING_GPG_KEY_DATA); + pt_len = ctx->encoded_msg_len + ctx->digest_len + 2; + /* Make a bucket big enough to hold the enc msg + digest (plaintext) * and populate it appropriately. */ @@ -237,19 +245,20 @@ gpg_encrypt(fko_ctx_t ctx, const char *enc_key) if(plain == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); - sprintf(plain, "%s:%s", ctx->encoded_msg, ctx->digest); + pt_len = snprintf(plain, pt_len+1, "%s:%s", ctx->encoded_msg, ctx->digest); + + if(! is_valid_pt_msg_len(pt_len)) + return(FKO_ERROR_INVALID_DATA); if (enc_key != NULL) { - res = gpgme_encrypt(ctx, - (unsigned char*)plain, strlen(plain), + res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len, enc_key, &cipher, &cipher_len ); } else { - res = gpgme_encrypt(ctx, - (unsigned char*)plain, strlen(plain), + res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len, empty_key, &cipher, &cipher_len ); } diff --git a/lib/fko_limits.h b/lib/fko_limits.h index 7efba4b3..a5ff57a4 100644 --- a/lib/fko_limits.h +++ b/lib/fko_limits.h @@ -46,7 +46,11 @@ #define MAX_SPA_MESSAGE_TYPE_SIZE 2 #define MIN_SPA_ENCODED_MSG_SIZE 36 /* Somewhat arbitrary */ -#define MAX_SPA_ENCODED_MSG_SIZE MAX_SPA_ENCRYPTED_SIZE +#define MAX_SPA_ENCODED_MSG_SIZE MAX_SPA_ENCRYPTED_SIZE + +#define MIN_SPA_PLAINTEXT_MSG_SIZE MIN_SPA_ENCODED_MSG_SIZE +#define MAX_SPA_PLAINTEXT_MSG_SIZE MAX_SPA_ENCODED_MSG_SIZE + #define MIN_GNUPG_MSG_SIZE 400 #define MIN_SPA_FIELDS 6 #define MAX_SPA_FIELDS 10 diff --git a/lib/fko_util.c b/lib/fko_util.c index 2a4f3304..5b1fdd6c 100644 --- a/lib/fko_util.c +++ b/lib/fko_util.c @@ -42,6 +42,17 @@ is_valid_encoded_msg_len(const int len) return(1); } +/* Validate plaintext input size +*/ +int +is_valid_pt_msg_len(const int len) +{ + if(len < MIN_SPA_PLAINTEXT_MSG_SIZE || len >= MAX_SPA_PLAINTEXT_MSG_SIZE) + return(0); + + return(1); +} + /* Validate digest length */ int diff --git a/lib/fko_util.h b/lib/fko_util.h index 97aeddc8..5b980a05 100644 --- a/lib/fko_util.h +++ b/lib/fko_util.h @@ -36,6 +36,7 @@ /* Function prototypes */ int is_valid_encoded_msg_len(const int len); +int is_valid_pt_msg_len(const int len); int is_valid_digest_len(const int len); size_t strlcat(char *dst, const char *src, size_t siz);