8c02ed
commit 71dcbcda4692922360fe6222bd6556cce89d98e4
8c02ed
Author: John Dennis <jdennis@redhat.com>
8c02ed
Date:   Thu Mar 31 16:09:11 2016 -0400
8c02ed
8c02ed
    apr_jwe_decrypt_content_aesgcm() null terminate string
8c02ed
    
8c02ed
    Also fixes unit test failure.
8c02ed
    
8c02ed
    The test test_jwt_decrypt_gcm() in test.c would sometimes fail. The
8c02ed
    failure was caused by extra garbage appearing in the decrypted string
8c02ed
    after the expected string. This is due to the failure of
8c02ed
    apr_jwe_decrypt_content_aesgcm() to null terminate the string as is
8c02ed
    similarity done in apr_jwe_decrypt_content_aescbc().
8c02ed
    
8c02ed
    This patch copies the logic from apr_jwe_decrypt_content_aescbc()
8c02ed
    regarding the decryption output length (p_len) and the final output
8c02ed
    length (f_len) which are then used to compute the end of the data in
8c02ed
    the output buffer, the next octet after the decrypted data in the
8c02ed
    output buffer is then assigned a null terminator.
8c02ed
    
8c02ed
    Signed-off-by: John Dennis <jdennis@redhat.com>
8c02ed
8c02ed
diff --git a/src/jose/apr_jwe.c b/src/jose/apr_jwe.c
8c02ed
index 6800033..d4b64cb 100644
8c02ed
--- a/src/jose/apr_jwe.c
8c02ed
+++ b/src/jose/apr_jwe.c
8c02ed
@@ -382,7 +382,7 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
8c02ed
 		apr_jwt_error_t *err) {
8c02ed
 
8c02ed
 	EVP_CIPHER_CTX *ctx;
8c02ed
-	int outlen, rv;
8c02ed
+	int rv;
8c02ed
 
8c02ed
 	ctx = EVP_CIPHER_CTX_new();
8c02ed
 	if (!EVP_DecryptInit_ex(ctx, apr_jwe_enc_to_openssl_cipher(header->enc),
8c02ed
@@ -391,8 +391,9 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
8c02ed
 		return FALSE;
8c02ed
 	}
8c02ed
 
8c02ed
+	int p_len = cipher_text->len, f_len = 0;
8c02ed
 	unsigned char *plaintext = apr_palloc(pool,
8c02ed
-			cipher_text->len
8c02ed
+			p_len
8c02ed
 			+ EVP_CIPHER_block_size(
8c02ed
 					apr_jwe_enc_to_openssl_cipher(header->enc)));
8c02ed
 
8c02ed
@@ -407,13 +408,13 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
8c02ed
 		return FALSE;
8c02ed
 	}
8c02ed
 	/* zero or more calls to specify any AAD */
8c02ed
-	if (!EVP_DecryptUpdate(ctx, NULL, &outlen, (unsigned char *) aad,
8c02ed
+	if (!EVP_DecryptUpdate(ctx, NULL, &p_len, (unsigned char *) aad,
8c02ed
 			aad_len)) {
8c02ed
 		apr_jwt_error_openssl(err, "EVP_DecryptUpdate (aad)");
8c02ed
 		return FALSE;
8c02ed
 	}
8c02ed
 	/* decrypt plaintext */
8c02ed
-	if (!EVP_DecryptUpdate(ctx, plaintext, &outlen,
8c02ed
+	if (!EVP_DecryptUpdate(ctx, plaintext, &p_len,
8c02ed
 			(unsigned char *) cipher_text->value, cipher_text->len)) {
8c02ed
 		apr_jwt_error_openssl(err, "EVP_DecryptUpdate (ciphertext)");
8c02ed
 		return FALSE;
8c02ed
@@ -425,7 +426,8 @@ apr_byte_t apr_jwe_decrypt_content_aesgcm(apr_pool_t *pool,
8c02ed
 	}
8c02ed
 
8c02ed
 	/* finalise: note get no output for GCM */
8c02ed
-	rv = EVP_DecryptFinal_ex(ctx, plaintext, &outlen);
8c02ed
+	rv = EVP_DecryptFinal_ex(ctx, plaintext, &f_len);
8c02ed
+	plaintext[p_len + f_len] = '\0';
8c02ed
 
8c02ed
 	EVP_CIPHER_CTX_free(ctx);
8c02ed