Blob Blame History Raw
commit 71dcbcda4692922360fe6222bd6556cce89d98e4
Author: John Dennis <jdennis@redhat.com>
Date:   Thu Mar 31 16:09:11 2016 -0400

    apr_jwe_decrypt_content_aesgcm() null terminate string
    
    Also fixes unit test failure.
    
    The test test_jwt_decrypt_gcm() in test.c would sometimes fail. The
    failure was caused by extra garbage appearing in the decrypted string
    after the expected string. This is due to the failure of
    apr_jwe_decrypt_content_aesgcm() to null terminate the string as is
    similarity done in apr_jwe_decrypt_content_aescbc().
    
    This patch copies the logic from apr_jwe_decrypt_content_aescbc()
    regarding the decryption output length (p_len) and the final output
    length (f_len) which are then used to compute the end of the data in
    the output buffer, the next octet after the decrypted data in the
    output buffer is then assigned a null terminator.
    
    Signed-off-by: John Dennis <jdennis@redhat.com>

diff --git a/src/jose/apr_jwe.c b/src/jose/apr_jwe.c
index 6800033..d4b64cb 100644
--- a/src/jose/apr_jwe.c
+++ b/src/jose/apr_jwe.c
@@ -382,7 +382,7 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
 		apr_jwt_error_t *err) {
 
 	EVP_CIPHER_CTX *ctx;
-	int outlen, rv;
+	int rv;
 
 	ctx = EVP_CIPHER_CTX_new();
 	if (!EVP_DecryptInit_ex(ctx, apr_jwe_enc_to_openssl_cipher(header->enc),
@@ -391,8 +391,9 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
 		return FALSE;
 	}
 
+	int p_len = cipher_text->len, f_len = 0;
 	unsigned char *plaintext = apr_palloc(pool,
-			cipher_text->len
+			p_len
 			+ EVP_CIPHER_block_size(
 					apr_jwe_enc_to_openssl_cipher(header->enc)));
 
@@ -407,13 +408,13 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
 		return FALSE;
 	}
 	/* zero or more calls to specify any AAD */
-	if (!EVP_DecryptUpdate(ctx, NULL, &outlen, (unsigned char *) aad,
+	if (!EVP_DecryptUpdate(ctx, NULL, &p_len, (unsigned char *) aad,
 			aad_len)) {
 		apr_jwt_error_openssl(err, "EVP_DecryptUpdate (aad)");
 		return FALSE;
 	}
 	/* decrypt plaintext */
-	if (!EVP_DecryptUpdate(ctx, plaintext, &outlen,
+	if (!EVP_DecryptUpdate(ctx, plaintext, &p_len,
 			(unsigned char *) cipher_text->value, cipher_text->len)) {
 		apr_jwt_error_openssl(err, "EVP_DecryptUpdate (ciphertext)");
 		return FALSE;
@@ -425,7 +426,8 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
 	}
 
 	/* finalise: note get no output for GCM */
-	rv = EVP_DecryptFinal_ex(ctx, plaintext, &outlen);
+	rv = EVP_DecryptFinal_ex(ctx, plaintext, &f_len);
+	plaintext[p_len + f_len] = '\0';
 
 	EVP_CIPHER_CTX_free(ctx);