From 838829f2bb91758d87137d4344aa7a1ad25bc0d3 Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Thu, 26 Jul 2012 00:10:28 -0400 Subject: [PATCH] added a new encoded_msg_len to cut down on strlen() calls within libfko --- lib/fko_context.h | 1 + lib/fko_decode.c | 27 +++++++++++++-------------- lib/fko_digest.c | 16 +++++++++++----- lib/fko_encode.c | 5 +++++ lib/fko_encryption.c | 28 ++++++++++++++++++++-------- 5 files changed, 50 insertions(+), 27 deletions(-) diff --git a/lib/fko_context.h b/lib/fko_context.h index 630f61d8..26466257 100644 --- a/lib/fko_context.h +++ b/lib/fko_context.h @@ -79,6 +79,7 @@ struct fko_context { /* Computed processed data (encodings, etc.) */ char *encoded_msg; + int encoded_msg_len; char *encrypted_msg; char *msg_hmac; diff --git a/lib/fko_decode.c b/lib/fko_decode.c index 6dfc14d6..e4642ccf 100644 --- a/lib/fko_decode.c +++ b/lib/fko_decode.c @@ -42,14 +42,8 @@ fko_decode_spa_data(fko_ctx_t ctx) char *tbuf, *ndx, *tmp; int t_size, i; - /* Check for required data. - */ - if(ctx->encoded_msg == NULL || strnlen(ctx->encoded_msg, - MAX_SPA_ENCODED_MSG_SIZE) < MIN_SPA_ENCODED_MSG_SIZE) - return(FKO_ERROR_INVALID_DATA); - - if(strnlen(ctx->encoded_msg, - MAX_SPA_ENCODED_MSG_SIZE) == MAX_SPA_ENCODED_MSG_SIZE) + if (ctx->encoded_msg_len < MIN_SPA_ENCODED_MSG_SIZE + || ctx->encoded_msg_len > MAX_SPA_ENCODED_MSG_SIZE) return(FKO_ERROR_INVALID_DATA); /* Make sure there are enough fields in the SPA packet @@ -68,7 +62,7 @@ fko_decode_spa_data(fko_ctx_t ctx) if (i < MIN_SPA_FIELDS) return(FKO_ERROR_INVALID_DATA); - t_size = strlen(ndx); + t_size = strnlen(ndx, SHA512_B64_LENGTH+1); switch(t_size) { @@ -96,6 +90,9 @@ fko_decode_spa_data(fko_ctx_t ctx) return(FKO_ERROR_INVALID_DIGEST_TYPE); } + if (ctx->encoded_msg_len - t_size < 0) + return(FKO_ERROR_INVALID_DATA); + /* Copy the digest into the context and terminate the encoded data * at that point so the original digest is not part of the * encoded string. @@ -108,6 +105,8 @@ fko_decode_spa_data(fko_ctx_t ctx) */ bzero((ndx-1), t_size); + ctx->encoded_msg_len -= t_size+1; + /* Make a tmp bucket for processing base64 encoded data and * other general use. */ @@ -120,23 +119,23 @@ fko_decode_spa_data(fko_ctx_t ctx) switch(ctx->digest_type) { case FKO_DIGEST_MD5: - md5_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + md5_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA1: - sha1_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + sha1_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA256: - sha256_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + sha256_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA384: - sha384_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + sha384_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; case FKO_DIGEST_SHA512: - sha512_base64(tbuf, (unsigned char*)ctx->encoded_msg, strlen(ctx->encoded_msg)); + sha512_base64(tbuf, (unsigned char*)ctx->encoded_msg, ctx->encoded_msg_len); break; } diff --git a/lib/fko_digest.c b/lib/fko_digest.c index f2e2577b..6d6015cb 100644 --- a/lib/fko_digest.c +++ b/lib/fko_digest.c @@ -101,6 +101,12 @@ static int set_digest(char *data, char **digest, short digest_type) { char *md = NULL; + int data_len; + + data_len = strnlen(data, MAX_SPA_ENCODED_MSG_SIZE); + + if(data_len == MAX_SPA_ENCODED_MSG_SIZE) + return(FKO_ERROR_INVALID_DATA); switch(digest_type) { @@ -110,7 +116,7 @@ set_digest(char *data, char **digest, short digest_type) return(FKO_ERROR_MEMORY_ALLOCATION); md5_base64(md, - (unsigned char*)data, strlen(data)); + (unsigned char*)data, data_len); break; case FKO_DIGEST_SHA1: @@ -119,7 +125,7 @@ set_digest(char *data, char **digest, short digest_type) return(FKO_ERROR_MEMORY_ALLOCATION); sha1_base64(md, - (unsigned char*)data, strlen(data)); + (unsigned char*)data, data_len); break; case FKO_DIGEST_SHA256: @@ -128,7 +134,7 @@ set_digest(char *data, char **digest, short digest_type) return(FKO_ERROR_MEMORY_ALLOCATION); sha256_base64(md, - (unsigned char*)data, strlen(data)); + (unsigned char*)data, data_len); break; case FKO_DIGEST_SHA384: @@ -137,7 +143,7 @@ set_digest(char *data, char **digest, short digest_type) return(FKO_ERROR_MEMORY_ALLOCATION); sha384_base64(md, - (unsigned char*)data, strlen(data)); + (unsigned char*)data, data_len); break; case FKO_DIGEST_SHA512: @@ -146,7 +152,7 @@ set_digest(char *data, char **digest, short digest_type) return(FKO_ERROR_MEMORY_ALLOCATION); sha512_base64(md, - (unsigned char*)data, strlen(data)); + (unsigned char*)data, data_len); break; default: diff --git a/lib/fko_encode.c b/lib/fko_encode.c index b0f09d4b..8c1417bb 100644 --- a/lib/fko_encode.c +++ b/lib/fko_encode.c @@ -195,6 +195,11 @@ fko_encode_spa_data(fko_ctx_t ctx) return(FKO_ERROR_MEMORY_ALLOCATION); } + ctx->encoded_msg_len = strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE); + + if(ctx->encoded_msg_len == MAX_SPA_ENCODED_MSG_SIZE) + return(FKO_ERROR_INVALID_DATA); + /* At this point we can compute the digest for this SPA data. */ if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS) diff --git a/lib/fko_encryption.c b/lib/fko_encryption.c index 130612d7..a4d20d60 100644 --- a/lib/fko_encryption.c +++ b/lib/fko_encryption.c @@ -170,6 +170,14 @@ _rijndael_decrypt(fko_ctx_t ctx, if(pt_len < (cipher_len - 32)) return(FKO_ERROR_DECRYPTION_SIZE); + if(ctx->encoded_msg == NULL || pt_len < MIN_SPA_ENCODED_MSG_SIZE) + return(FKO_ERROR_INVALID_DATA); + + if(pt_len == MAX_SPA_ENCODED_MSG_SIZE) + return(FKO_ERROR_INVALID_DATA); + + ctx->encoded_msg_len = pt_len; + /* At this point we can check the data to see if we have a good * decryption by ensuring the first field (16-digit random decimal * value) is valid and is followed by a colon. Additional checks @@ -275,7 +283,7 @@ gpg_decrypt(fko_ctx_t ctx, const char *dec_key) char *tbuf; unsigned char *cipher; size_t cipher_len; - int res; + int res, pt_len; int b64_len = strlen(ctx->encrypted_msg); @@ -322,7 +330,7 @@ gpg_decrypt(fko_ctx_t ctx, const char *dec_key) */ res = gpgme_decrypt(ctx, cipher, cipher_len, - dec_key, (unsigned char**)&ctx->encoded_msg, &cipher_len + dec_key, (unsigned char**)&ctx->encoded_msg, &cipher_len ); /* Done with cipher... @@ -332,9 +340,15 @@ gpg_decrypt(fko_ctx_t ctx, const char *dec_key) if(res != FKO_SUCCESS) return(res); - /* XXX: We could put some kind of sanity check of the decrypted - * data here - */ + pt_len = strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE); + + if(ctx->encoded_msg == NULL || pt_len < MIN_SPA_ENCODED_MSG_SIZE) + return(FKO_ERROR_INVALID_DATA); + + if(pt_len == MAX_SPA_ENCODED_MSG_SIZE) + return(FKO_ERROR_INVALID_DATA); + + ctx->encoded_msg_len = pt_len; /* Call fko_decode and return the results. */ @@ -440,10 +454,8 @@ fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key, const int enc_key_len) * check for a somewhat arbitrary minimum length for the encoded * data. */ - if(strlen(ctx->encoded_msg) < MIN_SPA_ENCODED_MSG_SIZE) - { + if(ctx->encoded_msg_len < MIN_SPA_ENCODED_MSG_SIZE) return(FKO_ERROR_MISSING_ENCODED_DATA); - } /* Encrypt according to type and return... */