You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by yl...@apache.org on 2023/03/20 17:12:45 UTC
svn commit: r1908581 - in /apr/apr-util/branches/1.7.x: ./ build/crypto.m4 crypto/ crypto/apr_crypto_openssl.c test/testcrypto.c
Author: ylavic
Date: Mon Mar 20 17:12:44 2023
New Revision: 1908581
URL: http://svn.apache.org/viewvc?rev=1908581&view=rev
Log:
apr_crypto_openssl: Compatibility with OpenSSL 3+
crypto: Follow up to r1908433: Fix EVP_MAC usage w/ openssl < 3.0.
crypto: Follow up to r1908433: streamline cleanups.
The crypto_*_init() functions can be called multiple times with the returned
structure already allocated/initialized, or not. So rather than cleaning up
after each operation (which was removed in r1908433 but is now leaky), let's
instead either allocate+register or cleanup existing structure in _init().
crypto: Follow up to r1908433: OPENSSL_API_COMPAT to 1.1.1.
crypto_openssl: Fix configure/detection of OPENSSL_init_crypto()
Merges r1908433, r1908448, r1908453, r1908455, r1908503 from ^/apr/apr/trunk.
Submitted by: ylavic
Modified:
apr/apr-util/branches/1.7.x/ (props changed)
apr/apr-util/branches/1.7.x/build/crypto.m4
apr/apr-util/branches/1.7.x/crypto/ (props changed)
apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c
apr/apr-util/branches/1.7.x/test/testcrypto.c
Propchange: apr/apr-util/branches/1.7.x/
------------------------------------------------------------------------------
Merged /apr/apr/trunk:r1908433,1908448,1908453,1908455,1908503
Modified: apr/apr-util/branches/1.7.x/build/crypto.m4
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/build/crypto.m4?rev=1908581&r1=1908580&r2=1908581&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/build/crypto.m4 (original)
+++ apr/apr-util/branches/1.7.x/build/crypto.m4 Mon Mar 20 17:12:44 2023
@@ -54,11 +54,11 @@ AC_DEFUN([APU_CHECK_CRYPTO], [
crypto_library_enabled=1
fi
done
- if test "$crypto_library_enabled" = "1"; then
+ if test "$crypto_library_enabled" = "1"; then
AC_MSG_NOTICE([Crypto was requested but no crypto library was found; autodetecting possible libraries])
else
AC_ERROR([Crypto was requested but all possible crypto libraries were disabled.])
- fi
+ fi
fi
APU_CHECK_CRYPTO_OPENSSL
@@ -97,15 +97,14 @@ AC_DEFUN([APU_CHECK_CRYPTO_OPENSSL], [
if test "$withval" = "yes"; then
AC_CHECK_HEADERS(openssl/x509.h, [openssl_have_headers=1])
AC_CHECK_LIB(crypto, EVP_CIPHER_CTX_new, openssl_have_libs=1)
- if test "$openssl_have_headers" != "0" && test "$openssl_have_libs" != "0"; then
+ if test "$openssl_have_headers" = "1" && test "$openssl_have_libs" = "1"; then
apu_have_openssl=1
fi
elif test "$withval" = "no"; then
apu_have_openssl=0
else
-
openssl_CPPFLAGS="-I$withval/include"
- openssl_LDFLAGS="-L$withval/lib "
+ openssl_LDFLAGS="-L$withval/lib -L$withval/lib64"
APR_ADDTO(CPPFLAGS, [$openssl_CPPFLAGS])
APR_ADDTO(LDFLAGS, [$openssl_LDFLAGS])
@@ -113,15 +112,15 @@ AC_DEFUN([APU_CHECK_CRYPTO_OPENSSL], [
AC_MSG_NOTICE(checking for openssl in $withval)
AC_CHECK_HEADERS(openssl/x509.h, [openssl_have_headers=1])
AC_CHECK_LIB(crypto, EVP_CIPHER_CTX_new, openssl_have_libs=1)
- if test "$openssl_have_headers" != "0" && test "$openssl_have_libs" != "0"; then
+ if test "$openssl_have_headers" = "1" && test "$openssl_have_libs" = "1"; then
apu_have_openssl=1
- APR_ADDTO(APRUTIL_LDFLAGS, [-L$withval/lib])
- APR_ADDTO(APRUTIL_INCLUDES, [-I$withval/include])
+ APR_ADDTO(APRUTIL_INCLUDES, [$openssl_CPPFLAGS])
+ APR_ADDTO(APRUTIL_LDFLAGS, [$openssl_LDFLAGS])
fi
-
- AC_CHECK_DECLS([EVP_PKEY_CTX_new, OPENSSL_init_crypto], [], [],
- [#include <openssl/evp.h>])
-
+ fi
+ if test "$apu_have_openssl" = "1"; then
+ AC_CHECK_LIB(crypto, OPENSSL_init_crypto)
+ AC_CHECK_FUNCS([OPENSSL_init_crypto])
fi
], [
apu_have_openssl=0
@@ -136,18 +135,12 @@ AC_DEFUN([APU_CHECK_CRYPTO_OPENSSL], [
apu_have_crypto=1
AC_MSG_CHECKING([for const input buffers in OpenSSL])
- AC_TRY_COMPILE([#include <openssl/rsa.h>],
- [ const unsigned char * buf;
- unsigned char * outbuf;
- RSA rsa;
-
- RSA_private_decrypt(1,
- buf,
- outbuf,
- &rsa,
- RSA_PKCS1_PADDING);
-
- ],
+ AC_TRY_COMPILE(
+ [#include <openssl/evp.h>],
+ [ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+ const unsigned char key[128] = {0}, iv[128] = {0};
+ EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
+ EVP_CIPHER_CTX_free(ctx); ],
[AC_MSG_RESULT([yes])]
[AC_DEFINE([CRYPTO_OPENSSL_CONST_BUFFERS], 1, [Define that OpenSSL uses const buffers])],
[AC_MSG_RESULT([no])])
Propchange: apr/apr-util/branches/1.7.x/crypto/
------------------------------------------------------------------------------
Merged /apr/apr/trunk/crypto:r1908433,1908448,1908453,1908455,1908503
Modified: apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c?rev=1908581&r1=1908580&r2=1908581&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c (original)
+++ apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c Mon Mar 20 17:12:44 2023
@@ -17,6 +17,7 @@
#include "apr_lib.h"
#include "apu.h"
#include "apu_errno.h"
+#include "apu_config.h"
#include <ctype.h>
#include <assert.h>
@@ -30,29 +31,70 @@
#if APU_HAVE_CRYPTO
+#ifndef OPENSSL_API_COMPAT
+#define OPENSSL_API_COMPAT 0x10101000L /* for ENGINE API */
+#endif
+
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/engine.h>
#include <openssl/obj_mac.h> /* for NID_* */
+#include <openssl/opensslv.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000
+#include <openssl/macros.h>
+#include <openssl/core_names.h>
+#endif
-#define LOG_PREFIX "apr_crypto_openssl: "
-
-#ifndef APR_USE_OPENSSL_PRE_1_1_API
#if defined(LIBRESSL_VERSION_NUMBER)
+
/* LibreSSL declares OPENSSL_VERSION_NUMBER == 2.0 but does not include most
* changes from OpenSSL >= 1.1 (new functions, macros, deprecations, ...), so
* we have to work around this...
*/
-#define APR_USE_OPENSSL_PRE_1_1_API (1)
-#define APR_USE_OPENSSL_PRE_1_1_1_API (1)
-#define APR_USE_OPENSSL_PRE_1_0_API (0)
-#else
-#define APR_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
-#define APR_USE_OPENSSL_PRE_1_1_1_API (OPENSSL_VERSION_NUMBER < 0x10101000L)
-#define APR_USE_OPENSSL_PRE_1_0_API (OPENSSL_VERSION_NUMBER < 0x10000000L)
+#define APR_USE_OPENSSL_PRE_1_0_API 0
+#if LIBRESSL_VERSION_NUMBER < 0x2070000f
+#define APR_USE_OPENSSL_PRE_1_1_API 1
+#else
+#define APR_USE_OPENSSL_PRE_1_1_API 0
+#endif
+/* TODO: keep up with LibreSSL latest versions */
+#define APR_USE_OPENSSL_PRE_1_1_1_API 1
+#define APR_USE_OPENSSL_PRE_3_0_API 1
+
+#else /* defined(LIBRESSL_VERSION_NUMBER) */
+
+#if OPENSSL_VERSION_NUMBER < 0x10000000L
+#define APR_USE_OPENSSL_PRE_1_0_API 1
+#else
+#define APR_USE_OPENSSL_PRE_1_0_API 0
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define APR_USE_OPENSSL_PRE_1_1_API 1
+#else
+#define APR_USE_OPENSSL_PRE_1_1_API 0
+#endif
+#if OPENSSL_VERSION_NUMBER < 0x10101000L
+#define APR_USE_OPENSSL_PRE_1_1_1_API 1
+#else
+#define APR_USE_OPENSSL_PRE_1_1_1_API 0
#endif
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+#define APR_USE_OPENSSL_PRE_3_0_API 1
+#else
+#define APR_USE_OPENSSL_PRE_3_0_API 0
#endif
+#endif /* defined(LIBRESSL_VERSION_NUMBER) */
+
+#if APR_USE_OPENSSL_PRE_3_0_API \
+ || (defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL < 30000)
+#define APR_USE_OPENSSL_ENGINE_API 1
+#else
+#define APR_USE_OPENSSL_ENGINE_API 0
+#endif
+
+#define LOG_PREFIX "apr_crypto_openssl: "
+
struct apr_crypto_t {
apr_pool_t *pool;
const apr_crypto_driver_t *provider;
@@ -64,7 +106,11 @@ struct apr_crypto_t {
};
struct apr_crypto_config_t {
+#if APR_USE_OPENSSL_ENGINE_API
ENGINE *engine;
+#else
+ void *engine;
+#endif
};
struct apr_crypto_key_t {
@@ -73,8 +119,11 @@ struct apr_crypto_key_t {
const apr_crypto_t *f;
const apr_crypto_key_rec_t *rec;
const EVP_CIPHER *cipher;
- const EVP_MD *hmac;
+ const EVP_MD *md;
EVP_PKEY *pkey;
+#if !APR_USE_OPENSSL_PRE_3_0_API
+ EVP_MAC *mac;
+#endif
unsigned char *key;
int keyLen;
int doPad;
@@ -87,7 +136,6 @@ struct apr_crypto_block_t {
const apr_crypto_t *f;
const apr_crypto_key_t *key;
EVP_CIPHER_CTX *cipherCtx;
- int initialised;
int ivSize;
int blockSize;
int doPad;
@@ -100,7 +148,9 @@ struct apr_crypto_digest_t {
const apr_crypto_key_t *key;
apr_crypto_digest_rec_t *rec;
EVP_MD_CTX *mdCtx;
- int initialised;
+#if !APR_USE_OPENSSL_PRE_3_0_API
+ EVP_MAC_CTX *macCtx;
+#endif
int digestSize;
};
@@ -148,7 +198,7 @@ static apr_status_t crypto_error(const a
*/
static apr_status_t crypto_shutdown(void)
{
-#if HAVE_DECL_OPENSSL_INIT_CRYPTO
+#if HAVE_OPENSSL_INIT_CRYPTO
/* Openssl v1.1+ handles all termination automatically. Do
* nothing in this case.
*/
@@ -177,7 +227,7 @@ static apr_status_t crypto_shutdown_help
static apr_status_t crypto_init(apr_pool_t *pool, const char *params,
const apu_err_t **result)
{
-#if HAVE_DECL_OPENSSL_INIT_CRYPTO
+#if HAVE_OPENSSL_INIT_CRYPTO
/* Openssl v1.1+ handles all initialisation automatically, apart
* from hints as to how we want to use the library.
*
@@ -246,7 +296,14 @@ static apr_status_t crypto_key_cleanup(a
{
if (key->pkey) {
EVP_PKEY_free(key->pkey);
+ key->pkey = NULL;
+ }
+#if !APR_USE_OPENSSL_PRE_3_0_API
+ if (key->mac) {
+ EVP_MAC_free(key->mac);
+ key->mac = NULL;
}
+#endif
return APR_SUCCESS;
}
@@ -266,17 +323,14 @@ static apr_status_t crypto_key_cleanup_h
static apr_status_t crypto_block_cleanup(apr_crypto_block_t *ctx)
{
- if (ctx->initialised) {
- if (ctx->cipherCtx) {
+ if (ctx->cipherCtx) {
#if APR_USE_OPENSSL_PRE_1_1_API
- EVP_CIPHER_CTX_cleanup(ctx->cipherCtx);
+ EVP_CIPHER_CTX_cleanup(ctx->cipherCtx);
#else
- EVP_CIPHER_CTX_reset(ctx->cipherCtx);
- EVP_CIPHER_CTX_free(ctx->cipherCtx);
+ EVP_CIPHER_CTX_reset(ctx->cipherCtx);
+ EVP_CIPHER_CTX_free(ctx->cipherCtx);
#endif
- ctx->cipherCtx = NULL;
- }
- ctx->initialised = 0;
+ ctx->cipherCtx = NULL;
}
return APR_SUCCESS;
@@ -297,14 +351,16 @@ static apr_status_t crypto_block_cleanup
*/
static apr_status_t crypto_digest_cleanup(apr_crypto_digest_t *ctx)
{
-
- if (ctx->initialised) {
- if (ctx->mdCtx) {
- EVP_MD_CTX_free(ctx->mdCtx);
- ctx->mdCtx = NULL;
- }
- ctx->initialised = 0;
+ if (ctx->mdCtx) {
+ EVP_MD_CTX_free(ctx->mdCtx);
+ ctx->mdCtx = NULL;
+ }
+#if !APR_USE_OPENSSL_PRE_3_0_API
+ if (ctx->macCtx) {
+ EVP_MAC_CTX_free(ctx->macCtx);
+ ctx->macCtx = NULL;
}
+#endif
return APR_SUCCESS;
@@ -324,12 +380,13 @@ static apr_status_t crypto_digest_cleanu
*/
static apr_status_t crypto_cleanup(apr_crypto_t *f)
{
-
+#if APR_USE_OPENSSL_ENGINE_API
if (f->config->engine) {
ENGINE_finish(f->config->engine);
ENGINE_free(f->config->engine);
f->config->engine = NULL;
}
+#endif
return APR_SUCCESS;
}
@@ -356,11 +413,10 @@ static apr_status_t crypto_make(apr_cryp
const apr_crypto_driver_t *provider, const char *params,
apr_pool_t *pool)
{
- apr_crypto_config_t *config = NULL;
- apr_crypto_t *f = apr_pcalloc(pool, sizeof(apr_crypto_t));
-
+ apr_crypto_t *f;
+ apr_crypto_config_t *config;
const char *engine = NULL;
-
+ apr_status_t status = APR_SUCCESS;
struct {
const char *field;
const char *value;
@@ -374,7 +430,8 @@ static apr_status_t crypto_make(apr_cryp
char **elts = NULL;
char *elt;
int i = 0, j;
- apr_status_t status;
+
+ *ff = NULL;
if (params) {
if (APR_SUCCESS != (status = apr_tokenize_to_argv(params, &elts, pool))) {
@@ -408,25 +465,45 @@ static apr_status_t crypto_make(apr_cryp
engine = fields[0].value;
}
+ f = apr_pcalloc(pool, sizeof(apr_crypto_t));
if (!f) {
return APR_ENOMEM;
}
- *ff = f;
- f->pool = pool;
- f->provider = provider;
- config = f->config = apr_pcalloc(pool, sizeof(apr_crypto_config_t));
+ f->config = config = apr_pcalloc(pool, sizeof(apr_crypto_config_t));
if (!config) {
return APR_ENOMEM;
}
+ f->pool = pool;
+ f->provider = provider;
+
+ /* The default/builtin "openssl" engine is the same as NULL though with
+ * openssl-3+ it's called something else, keep NULL for that name.
+ */
+ if (engine && strcasecmp(engine, "openssl") != 0) {
+#if APR_USE_OPENSSL_ENGINE_API
+ config->engine = ENGINE_by_id(engine);
+ if (!config->engine) {
+ return APR_ENOENGINE;
+ }
+ if (!ENGINE_init(config->engine)) {
+ status = APR_EINITENGINE;
+ goto cleanup;
+ }
+#else
+ return APR_ENOTIMPL;
+#endif
+ }
f->result = apr_pcalloc(pool, sizeof(apu_err_t));
if (!f->result) {
- return APR_ENOMEM;
+ status = APR_ENOMEM;
+ goto cleanup;
}
f->digests = apr_hash_make(pool);
if (!f->digests) {
- return APR_ENOMEM;
+ status = APR_ENOMEM;
+ goto cleanup;
}
apr_hash_set(f->digests, "md5", APR_HASH_KEY_STRING, &(key_digests[i = 0]));
apr_hash_set(f->digests, "sha1", APR_HASH_KEY_STRING, &(key_digests[++i]));
@@ -437,7 +514,8 @@ static apr_status_t crypto_make(apr_cryp
f->types = apr_hash_make(pool);
if (!f->types) {
- return APR_ENOMEM;
+ status = APR_ENOMEM;
+ goto cleanup;
}
apr_hash_set(f->types, "3des192", APR_HASH_KEY_STRING, &(key_types[i = 0]));
apr_hash_set(f->types, "aes128", APR_HASH_KEY_STRING, &(key_types[++i]));
@@ -446,33 +524,26 @@ static apr_status_t crypto_make(apr_cryp
f->modes = apr_hash_make(pool);
if (!f->modes) {
- return APR_ENOMEM;
+ status = APR_ENOMEM;
+ goto cleanup;
}
apr_hash_set(f->modes, "ecb", APR_HASH_KEY_STRING, &(key_modes[i = 0]));
apr_hash_set(f->modes, "cbc", APR_HASH_KEY_STRING, &(key_modes[++i]));
f->digests = apr_hash_make(pool);
if (!f->digests) {
- return APR_ENOMEM;
+ status = APR_ENOMEM;
+ goto cleanup;
}
+ *ff = f;
apr_pool_cleanup_register(pool, f, crypto_cleanup_helper,
- apr_pool_cleanup_null);
-
- if (engine) {
- config->engine = ENGINE_by_id(engine);
- if (!config->engine) {
- return APR_ENOENGINE;
- }
- if (!ENGINE_init(config->engine)) {
- ENGINE_free(config->engine);
- config->engine = NULL;
- return APR_EINITENGINE;
- }
- }
-
+ apr_pool_cleanup_null);
return APR_SUCCESS;
+cleanup:
+ crypto_cleanup(f);
+ return status;
}
/**
@@ -586,7 +657,6 @@ static apr_status_t crypto_cipher_mechan
if (!key->key) {
return APR_ENOMEM;
}
- apr_crypto_clear(p, key->key, key->keyLen);
return APR_SUCCESS;
}
@@ -618,11 +688,12 @@ static apr_status_t crypto_key(apr_crypt
if (!key) {
return APR_ENOMEM;
}
+ apr_pool_cleanup_register(p, key, crypto_key_cleanup_helper,
+ apr_pool_cleanup_null);
+ }
+ else {
+ crypto_key_cleanup(key);
}
-
- apr_pool_cleanup_register(p, key, crypto_key_cleanup_helper,
- apr_pool_cleanup_null);
-
key->pool = p;
key->f = f;
key->provider = f->provider;
@@ -672,22 +743,22 @@ static apr_status_t crypto_key(apr_crypt
switch (rec->k.hash.digest) {
case APR_CRYPTO_DIGEST_MD5:
- key->hmac = EVP_md5();
+ key->md = EVP_md5();
break;
case APR_CRYPTO_DIGEST_SHA1:
- key->hmac = EVP_sha1();
+ key->md = EVP_sha1();
break;
case APR_CRYPTO_DIGEST_SHA224:
- key->hmac = EVP_sha224();
+ key->md = EVP_sha224();
break;
case APR_CRYPTO_DIGEST_SHA256:
- key->hmac = EVP_sha256();
+ key->md = EVP_sha256();
break;
case APR_CRYPTO_DIGEST_SHA384:
- key->hmac = EVP_sha384();
+ key->md = EVP_sha384();
break;
case APR_CRYPTO_DIGEST_SHA512:
- key->hmac = EVP_sha512();
+ key->md = EVP_sha512();
break;
default:
return APR_ENODIGEST;
@@ -695,84 +766,70 @@ static apr_status_t crypto_key(apr_crypt
break;
}
- case APR_CRYPTO_KTYPE_HMAC: {
-
- apr_crypto_config_t *config = f->config;
-
- /* create hmac key */
- if (!(key->pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, config->engine,
- rec->k.hmac.secret, rec->k.hmac.secretLen))) {
- return APR_ENOKEY;
- }
+ case APR_CRYPTO_KTYPE_HMAC:
+ case APR_CRYPTO_KTYPE_CMAC: {
switch (rec->k.hmac.digest) {
case APR_CRYPTO_DIGEST_MD5:
- key->hmac = EVP_md5();
+ key->md = EVP_md5();
break;
case APR_CRYPTO_DIGEST_SHA1:
- key->hmac = EVP_sha1();
+ key->md = EVP_sha1();
break;
case APR_CRYPTO_DIGEST_SHA224:
- key->hmac = EVP_sha224();
+ key->md = EVP_sha224();
break;
case APR_CRYPTO_DIGEST_SHA256:
- key->hmac = EVP_sha256();
+ key->md = EVP_sha256();
break;
case APR_CRYPTO_DIGEST_SHA384:
- key->hmac = EVP_sha384();
+ key->md = EVP_sha384();
break;
case APR_CRYPTO_DIGEST_SHA512:
- key->hmac = EVP_sha512();
+ key->md = EVP_sha512();
break;
default:
return APR_ENODIGEST;
}
- break;
- }
-
- case APR_CRYPTO_KTYPE_CMAC: {
-
+ /* create hmac key */
+#if APR_USE_OPENSSL_PRE_3_0_API
+ if (rec->ktype == APR_CRYPTO_KTYPE_HMAC) {
+ apr_crypto_config_t *config = f->config;
+ key->pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC,
+ config->engine,
+ rec->k.hmac.secret,
+ rec->k.hmac.secretLen);
+ }
+ else {
#if !APR_USE_OPENSSL_PRE_1_1_1_API
- apr_crypto_config_t *config = f->config;
-
- /* decide on what cipher mechanism we will be using */
- rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad, p);
- if (APR_SUCCESS != rv) {
- return rv;
+ apr_crypto_config_t *config = f->config;
+ /* decide on what cipher mechanism we will be using */
+ rv = crypto_cipher_mechanism(key, rec->type, rec->mode, rec->pad, p);
+ if (APR_SUCCESS != rv) {
+ return rv;
+ }
+ key->pkey = EVP_PKEY_new_CMAC_key(config->engine,
+ rec->k.cmac.secret,
+ rec->k.cmac.secretLen,
+ key->cipher);
+#else
+ return APR_ENOTIMPL;
+#endif
}
-
- /* create cmac key */
- if (!(key->pkey = EVP_PKEY_new_CMAC_key(config->engine,
- rec->k.cmac.secret, rec->k.cmac.secretLen, key->cipher))) {
+ if (!key->pkey) {
return APR_ENOKEY;
}
-
- switch (rec->k.hmac.digest) {
- case APR_CRYPTO_DIGEST_MD5:
- key->hmac = EVP_md5();
- break;
- case APR_CRYPTO_DIGEST_SHA1:
- key->hmac = EVP_sha1();
- break;
- case APR_CRYPTO_DIGEST_SHA224:
- key->hmac = EVP_sha224();
- break;
- case APR_CRYPTO_DIGEST_SHA256:
- key->hmac = EVP_sha256();
- break;
- case APR_CRYPTO_DIGEST_SHA384:
- key->hmac = EVP_sha384();
- break;
- case APR_CRYPTO_DIGEST_SHA512:
- key->hmac = EVP_sha512();
- break;
- default:
- return APR_ENODIGEST;
- }
-
#else
- return APR_ENOTIMPL;
+ if (rec->ktype == APR_CRYPTO_KTYPE_HMAC) {
+ key->mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ }
+ else {
+ key->mac = EVP_MAC_fetch(NULL, "CMAC", NULL);
+ }
+ if (!key->mac) {
+ return APR_ENOMEM;
+ }
#endif
break;
@@ -900,29 +957,34 @@ static apr_status_t crypto_block_encrypt
unsigned char *usedIv;
apr_crypto_config_t *config = key->f->config;
apr_crypto_block_t *block = *ctx;
+
if (!block) {
*ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
+ if (!block) {
+ return APR_ENOMEM;
+ }
+ apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
+ apr_pool_cleanup_null);
}
- if (!block) {
- return APR_ENOMEM;
+ else {
+ crypto_block_cleanup(block);
}
block->f = key->f;
block->pool = p;
block->provider = key->provider;
block->key = key;
- apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
- apr_pool_cleanup_null);
-
switch (key->rec->ktype) {
case APR_CRYPTO_KTYPE_PASSPHRASE:
case APR_CRYPTO_KTYPE_SECRET: {
/* create a new context for encryption */
- if (!block->initialised) {
+ if (!block->cipherCtx) {
block->cipherCtx = EVP_CIPHER_CTX_new();
- block->initialised = 1;
+ if (!block->cipherCtx) {
+ return APR_ENOMEM;
+ }
}
/* generate an IV, if necessary */
@@ -936,7 +998,6 @@ static apr_status_t crypto_block_encrypt
if (!usedIv) {
return APR_ENOMEM;
}
- apr_crypto_clear(p, usedIv, key->ivSize);
if (!((RAND_status() == 1)
&& (RAND_bytes(usedIv, key->ivSize) == 1))) {
return APR_ENOIV;
@@ -953,7 +1014,8 @@ static apr_status_t crypto_block_encrypt
if (!EVP_EncryptInit_ex(block->cipherCtx, key->cipher, config->engine,
key->key, usedIv)) {
#else
- if (!EVP_EncryptInit_ex(block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) usedIv)) {
+ if (!EVP_EncryptInit_ex(block->cipherCtx, key->cipher, config->engine,
+ (unsigned char *) key->key, (unsigned char *) usedIv)) {
#endif
return APR_EINIT;
}
@@ -1017,11 +1079,10 @@ static apr_status_t crypto_block_encrypt
/* must we allocate the output buffer from a pool? */
if (!*out) {
- buffer = apr_palloc(block->pool, inlen + EVP_MAX_BLOCK_LENGTH);
+ buffer = apr_pcalloc(block->pool, inlen + EVP_MAX_BLOCK_LENGTH);
if (!buffer) {
return APR_ENOMEM;
}
- apr_crypto_clear(block->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH);
*out = buffer;
}
@@ -1031,7 +1092,6 @@ static apr_status_t crypto_block_encrypt
if (!EVP_EncryptUpdate(block->cipherCtx, (*out), &outl,
(unsigned char *) in, inlen)) {
#endif
- crypto_block_cleanup(block);
return APR_ECRYPT;
}
*outlen = outl;
@@ -1083,7 +1143,6 @@ static apr_status_t crypto_block_encrypt
else {
*outlen = len;
}
- crypto_block_cleanup(block);
return rc;
@@ -1118,29 +1177,34 @@ static apr_status_t crypto_block_decrypt
{
apr_crypto_config_t *config = key->f->config;
apr_crypto_block_t *block = *ctx;
+
if (!block) {
*ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t));
+ if (!block) {
+ return APR_ENOMEM;
+ }
+ apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
+ apr_pool_cleanup_null);
}
- if (!block) {
- return APR_ENOMEM;
+ else {
+ crypto_block_cleanup(block);
}
block->f = key->f;
block->pool = p;
block->provider = key->provider;
block->key = key;
- apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper,
- apr_pool_cleanup_null);
-
switch (key->rec->ktype) {
case APR_CRYPTO_KTYPE_PASSPHRASE:
case APR_CRYPTO_KTYPE_SECRET: {
/* create a new context for encryption */
- if (!block->initialised) {
+ if (!block->cipherCtx) {
block->cipherCtx = EVP_CIPHER_CTX_new();
- block->initialised = 1;
+ if (!block->cipherCtx) {
+ return APR_ENOMEM;
+ }
}
/* generate an IV, if necessary */
@@ -1155,7 +1219,8 @@ static apr_status_t crypto_block_decrypt
if (!EVP_DecryptInit_ex(block->cipherCtx, key->cipher, config->engine,
key->key, iv)) {
#else
- if (!EVP_DecryptInit_ex(block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) iv)) {
+ if (!EVP_DecryptInit_ex(block->cipherCtx, key->cipher, config->engine,
+ (unsigned char *) key->key, (unsigned char *) iv)) {
#endif
return APR_EINIT;
}
@@ -1219,11 +1284,10 @@ static apr_status_t crypto_block_decrypt
/* must we allocate the output buffer from a pool? */
if (!(*out)) {
- buffer = apr_palloc(block->pool, inlen + EVP_MAX_BLOCK_LENGTH);
+ buffer = apr_pcalloc(block->pool, inlen + EVP_MAX_BLOCK_LENGTH);
if (!buffer) {
return APR_ENOMEM;
}
- apr_crypto_clear(block->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH);
*out = buffer;
}
@@ -1233,8 +1297,6 @@ static apr_status_t crypto_block_decrypt
if (!EVP_DecryptUpdate(block->cipherCtx, *out, &outl, (unsigned char *) in,
inlen)) {
#endif
- crypto_block_cleanup(block);
-
return APR_ECRYPT;
}
*outlen = outl;
@@ -1286,7 +1348,6 @@ static apr_status_t crypto_block_decrypt
else {
*outlen = len;
}
- crypto_block_cleanup(block);
return rc;
@@ -1305,11 +1366,17 @@ static apr_status_t crypto_digest_init(a
{
apr_crypto_config_t *config = key->f->config;
apr_crypto_digest_t *digest = *d;
+
if (!digest) {
*d = digest = apr_pcalloc(p, sizeof(apr_crypto_digest_t));
+ if (!digest) {
+ return APR_ENOMEM;
+ }
+ apr_pool_cleanup_register(p, digest, crypto_digest_cleanup_helper,
+ apr_pool_cleanup_null);
}
- if (!digest) {
- return APR_ENOMEM;
+ else {
+ crypto_digest_cleanup(digest);
}
digest->f = key->f;
digest->pool = p;
@@ -1317,22 +1384,16 @@ static apr_status_t crypto_digest_init(a
digest->key = key;
digest->rec = rec;
- /* create a new context for digest */
- if (!digest->initialised) {
- digest->mdCtx = EVP_MD_CTX_new();
- digest->initialised = 1;
- }
-
- apr_pool_cleanup_register(p, digest, crypto_digest_cleanup_helper,
- apr_pool_cleanup_null);
-
switch (key->rec->ktype) {
case APR_CRYPTO_KTYPE_HASH: {
-
- if (1
- != EVP_DigestInit_ex(digest->mdCtx, key->hmac,
- config->engine)) {
+ if (!digest->mdCtx) {
+ digest->mdCtx = EVP_MD_CTX_new();
+ if (!digest->mdCtx) {
+ return APR_ENOMEM;
+ }
+ }
+ if (!EVP_DigestInit_ex(digest->mdCtx, key->md, config->engine)) {
return APR_EINIT;
}
@@ -1340,11 +1401,45 @@ static apr_status_t crypto_digest_init(a
}
case APR_CRYPTO_KTYPE_HMAC:
case APR_CRYPTO_KTYPE_CMAC: {
- if (1
- != EVP_DigestSignInit(digest->mdCtx, NULL, key->hmac,
- config->engine, key->pkey)) {
+#if APR_USE_OPENSSL_PRE_3_0_API
+ if (!digest->mdCtx) {
+ digest->mdCtx = EVP_MD_CTX_new();
+ if (!digest->mdCtx) {
+ return APR_ENOMEM;
+ }
+ }
+ if (!EVP_DigestSignInit(digest->mdCtx, NULL, key->md,
+ config->engine, key->pkey)) {
return APR_EINIT;
}
+#else
+ OSSL_PARAM params[2];
+ if (!digest->macCtx) {
+ digest->macCtx = EVP_MAC_CTX_new(key->mac);
+ if (!digest->macCtx) {
+ return APR_ENOMEM;
+ }
+ }
+ if (key->rec->ktype == APR_CRYPTO_KTYPE_HMAC) {
+ params[0] =
+ OSSL_PARAM_construct_utf8_string("digest",
+ (char *)EVP_MD_name(key->md),
+ 0);
+ }
+ else {
+ params[0] =
+ OSSL_PARAM_construct_utf8_string("cipher",
+ (char *)EVP_CIPHER_name(key->cipher),
+ 0);
+ }
+ params[1] = OSSL_PARAM_construct_end();
+ if (!EVP_MAC_init(digest->macCtx,
+ key->rec->k.hmac.secret,
+ key->rec->k.hmac.secretLen,
+ params)) {
+ return APR_EINIT;
+ }
+#endif
break;
}
default: {
@@ -1362,23 +1457,24 @@ static apr_status_t crypto_digest_update
switch (digest->key->rec->ktype) {
case APR_CRYPTO_KTYPE_HASH: {
-
- if (1 != EVP_DigestUpdate(digest->mdCtx, in, inlen)) {
- crypto_digest_cleanup(digest);
+ if (!EVP_DigestUpdate(digest->mdCtx, in, inlen)) {
return APR_ECRYPT;
}
return APR_SUCCESS;
}
-
case APR_CRYPTO_KTYPE_HMAC:
case APR_CRYPTO_KTYPE_CMAC: {
-
- if (1 != EVP_DigestSignUpdate(digest->mdCtx, in, inlen)) {
- crypto_digest_cleanup(digest);
+#if APR_USE_OPENSSL_PRE_3_0_API
+ if (!EVP_DigestSignUpdate(digest->mdCtx, in, inlen)) {
return APR_ECRYPT;
}
+#else
+ if (!EVP_MAC_update(digest->macCtx, in, inlen)) {
+ return APR_ECRYPT;
+ }
+#endif
return APR_SUCCESS;
@@ -1392,31 +1488,29 @@ static apr_status_t crypto_digest_update
static apr_status_t crypto_digest_final(apr_crypto_digest_t *digest)
{
+ apr_status_t status = APR_SUCCESS;
switch (digest->key->rec->ktype) {
case APR_CRYPTO_KTYPE_HASH: {
-
- apr_status_t status = APR_SUCCESS;
-
- unsigned int len = EVP_MD_CTX_size(digest->mdCtx);
-
switch (digest->rec->dtype) {
case APR_CRYPTO_DTYPE_HASH: {
+ unsigned int len = EVP_MD_CTX_size(digest->mdCtx);
/* must we allocate the output buffer from a pool? */
if (!digest->rec->d.hash.s || digest->rec->d.hash.slen != len) {
digest->rec->d.hash.slen = len;
- digest->rec->d.hash.s = apr_palloc(digest->pool, len);
+ digest->rec->d.hash.s = apr_pcalloc(digest->pool, len);
if (!digest->rec->d.hash.s) {
return APR_ENOMEM;
}
- apr_crypto_clear(digest->pool, digest->rec->d.hash.s, len);
}
/* then, determine the signature */
if (EVP_DigestFinal_ex(digest->mdCtx, digest->rec->d.hash.s, &len)
== 0) {
+ OPENSSL_cleanse(digest->rec->d.hash.s,
+ digest->rec->d.hash.slen);
status = APR_ECRYPT;
}
@@ -1426,92 +1520,101 @@ static apr_status_t crypto_digest_final(
status = APR_ENODIGEST;
}
- crypto_digest_cleanup(digest);
-
- return status;
-
+ break;
}
-
case APR_CRYPTO_KTYPE_HMAC:
case APR_CRYPTO_KTYPE_CMAC: {
-
- apr_status_t status = APR_SUCCESS;
-
size_t len;
/* first, determine the signature length */
- if (1 != EVP_DigestSignFinal(digest->mdCtx, NULL, &len)) {
+#if APR_USE_OPENSSL_PRE_3_0_API
+ if (!EVP_DigestSignFinal(digest->mdCtx, NULL, &len)) {
status = APR_ECRYPT;
- } else {
-
+ }
+#else
+ if (!EVP_MAC_final(digest->macCtx, NULL, &len, 0)) {
+ status = APR_ECRYPT;
+ }
+#endif
+ if (status == APR_SUCCESS) {
switch (digest->rec->dtype) {
case APR_CRYPTO_DTYPE_SIGN: {
-
/* must we allocate the output buffer from a pool? */
if (!digest->rec->d.sign.s || digest->rec->d.sign.slen != len) {
digest->rec->d.sign.slen = len;
- digest->rec->d.sign.s = apr_palloc(digest->pool, len);
+ digest->rec->d.sign.s = apr_pcalloc(digest->pool, len);
if (!digest->rec->d.sign.s) {
return APR_ENOMEM;
}
- apr_crypto_clear(digest->pool, digest->rec->d.sign.s, len);
}
/* then, determine the signature */
- if (EVP_DigestSignFinal(digest->mdCtx, digest->rec->d.sign.s,
- &len) == 0) {
+#if APR_USE_OPENSSL_PRE_3_0_API
+ if (!EVP_DigestSignFinal(digest->mdCtx,
+ digest->rec->d.sign.s, &len)) {
+ status = APR_ECRYPT;
+ }
+#else
+ if (!EVP_MAC_final(digest->macCtx,
+ digest->rec->d.sign.s, &len, len)) {
status = APR_ECRYPT;
}
+#endif
+ if (status != APR_SUCCESS) {
+ OPENSSL_cleanse(digest->rec->d.sign.s,
+ digest->rec->d.sign.slen);
+ }
break;
}
case APR_CRYPTO_DTYPE_VERIFY: {
-
/* must we allocate the output buffer from a pool? */
if (!digest->rec->d.verify.s
|| digest->rec->d.verify.slen != len) {
digest->rec->d.verify.slen = len;
- digest->rec->d.verify.s = apr_palloc(digest->pool, len);
+ digest->rec->d.verify.s = apr_pcalloc(digest->pool, len);
if (!digest->rec->d.verify.s) {
return APR_ENOMEM;
}
- apr_crypto_clear(digest->pool, digest->rec->d.verify.s,
- len);
}
/* then, determine the signature */
- if (EVP_DigestSignFinal(digest->mdCtx, digest->rec->d.verify.s,
- &len) == 0) {
+#if APR_USE_OPENSSL_PRE_3_0_API
+ if (!EVP_DigestSignFinal(digest->mdCtx,
+ digest->rec->d.verify.s, &len)) {
status = APR_ECRYPT;
- } else if (digest->rec->d.verify.slen
- == digest->rec->d.verify.vlen) {
- status =
- CRYPTO_memcmp(digest->rec->d.verify.s,
- digest->rec->d.verify.v,
- digest->rec->d.verify.slen) ?
- APR_ENOVERIFY : APR_SUCCESS;
- } else {
+ }
+#else
+ if (!EVP_MAC_final(digest->macCtx,
+ digest->rec->d.verify.s, &len, len)) {
+ status = APR_ECRYPT;
+ }
+#endif
+ if (status == APR_SUCCESS
+ && (len != digest->rec->d.verify.vlen
+ || CRYPTO_memcmp(digest->rec->d.verify.v,
+ digest->rec->d.verify.s, len))) {
status = APR_ENOVERIFY;
}
+ if (status != APR_SUCCESS) {
+ OPENSSL_cleanse(digest->rec->d.verify.s,
+ digest->rec->d.verify.slen);
+ }
break;
}
default:
status = APR_ENODIGEST;
}
-
}
- crypto_digest_cleanup(digest);
-
- return status;
-
- }
- default: {
- return APR_EINVAL;
+ break;
}
+ default:
+ status = APR_EINVAL;
}
+ return status;
}
static apr_status_t crypto_digest(
Modified: apr/apr-util/branches/1.7.x/test/testcrypto.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/test/testcrypto.c?rev=1908581&r1=1908580&r2=1908581&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/test/testcrypto.c (original)
+++ apr/apr-util/branches/1.7.x/test/testcrypto.c Mon Mar 20 17:12:44 2023
@@ -878,6 +878,10 @@ static void crypto_block_cross(abts_case
f1 = make(tc, pool, driver1);
f2 = make(tc, pool, driver2);
+ if (!f1 || !f2) {
+ return;
+ }
+
key1 = passphrase(tc, pool, driver1, f1, type, mode, doPad, description);
key2 = passphrase(tc, pool, driver2, f2, type, mode, doPad, description);
@@ -973,6 +977,9 @@ static void crypto_cross_hash(abts_case
f1 = make(tc, pool, driver1);
f2 = make(tc, pool, driver2);
+ if (!f1 || !f2) {
+ return;
+ }
key7 = keyhash(tc, pool, driver1, f1, digest, description);
key8 = keyhash(tc, pool, driver2, f2, digest, description);
@@ -1038,6 +1045,9 @@ static void crypto_cross_sign(abts_case
f1 = make(tc, pool, driver1);
f2 = make(tc, pool, driver2);
+ if (!f1 || !f2) {
+ return;
+ }
key7 = keyhmac(tc, pool, driver1, f1, digest, type, mode, doPad, secretLen,
description);
@@ -1096,6 +1106,10 @@ static void test_crypto_key_openssl(abts
driver = get_openssl_driver(tc, pool);
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32,
"KEY_AES_256/MODE_CBC");
apr_pool_destroy(pool);
@@ -1115,6 +1129,10 @@ static void test_crypto_key_nss(abts_cas
driver = get_nss_driver(tc, pool);
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32,
"KEY_AES_256/MODE_CBC");
apr_pool_destroy(pool);
@@ -1134,6 +1152,10 @@ static void test_crypto_key_commoncrypto
driver = get_commoncrypto_driver(tc, pool);
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
keysecret(tc, pool, driver, f, APR_KEY_AES_256, APR_MODE_CBC, 1, 32,
"KEY_AES_256/MODE_CBC");
apr_pool_destroy(pool);
@@ -2080,6 +2102,10 @@ static void test_crypto_get_block_key_ty
if (driver) {
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
apr_crypto_get_block_key_types(&types, f);
key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING);
@@ -2123,6 +2149,10 @@ static void test_crypto_get_block_key_ty
if (driver) {
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
apr_crypto_get_block_key_types(&types, f);
key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING);
@@ -2166,6 +2196,10 @@ static void test_crypto_get_block_key_ty
if (driver) {
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
apr_crypto_get_block_key_types(&types, f);
key_3des_192 = apr_hash_get(types, "3des192", APR_HASH_KEY_STRING);
@@ -2207,6 +2241,10 @@ static void test_crypto_get_block_key_mo
if (driver) {
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
apr_crypto_get_block_key_modes(&modes, f);
mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING);
@@ -2240,6 +2278,10 @@ static void test_crypto_get_block_key_mo
if (driver) {
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
apr_crypto_get_block_key_modes(&modes, f);
mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING);
@@ -2273,6 +2315,10 @@ static void test_crypto_get_block_key_mo
if (driver) {
f = make(tc, pool, driver);
+ if (!f) {
+ return;
+ }
+
apr_crypto_get_block_key_modes(&modes, f);
mode_ecb = apr_hash_get(modes, "ecb", APR_HASH_KEY_STRING);