From e15f70f41d691fc1e6cc82fb398429cdb3444342 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 7 May 2023 18:01:43 +0200 Subject: [PATCH] apc_priv_decrypt: Let the callee allocate the buffer. This complements the previous commit which made the analogous change for public encryption. Passing char ** instead of char * to apc_priv_decrypt() allows us to get rid of the magic 1024 constant in client_common.c. --- client_common.c | 6 ++++-- crypt.h | 4 ++-- gcrypt.c | 12 ++++++++---- openssl.c | 11 ++++++++--- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/client_common.c b/client_common.c index 32a94492..396fd88c 100644 --- a/client_common.c +++ b/client_common.c @@ -324,7 +324,7 @@ static int client_post_monitor(struct sched *s, void *context) */ { /* decrypted challenge/session key buffer */ - unsigned char crypt_buf[1024]; + unsigned char *crypt_buf; struct sb_buffer sbb; ret = recv_sb(ct, &sbb); @@ -337,12 +337,13 @@ static int client_post_monitor(struct sched *s, void *context) } n = sbb.iov.iov_len; PARA_INFO_LOG("<-- [challenge] (%zu bytes)\n", n); - ret = apc_priv_decrypt(ct->key_file, crypt_buf, + ret = apc_priv_decrypt(ct->key_file, &crypt_buf, sbb.iov.iov_base, n); free(sbb.iov.iov_base); if (ret < 0) goto out; if (ret != APC_CHALLENGE_SIZE + 2 * SESSION_KEY_LEN) { + free(crypt_buf); ret = -E_DECRYPT; goto out; } @@ -360,6 +361,7 @@ static int client_post_monitor(struct sched *s, void *context) SESSION_KEY_LEN); ct->scc.recv = sc_new(crypt_buf + APC_CHALLENGE_SIZE + SESSION_KEY_LEN, SESSION_KEY_LEN); + free(crypt_buf); PARA_INFO_LOG("--> %s\n", buf); ct->status = CL_RECEIVED_CHALLENGE; return 0; diff --git a/crypt.h b/crypt.h index 65070995..2e094ced 100644 --- a/crypt.h +++ b/crypt.h @@ -31,7 +31,7 @@ int apc_pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf, * Decrypt a buffer using a private key. * * \param key_file Full path of the key. - * \param outbuf The output buffer. + * \param outbuf The output buffer is allocated by the callee. * \param inbuf The encrypted input buffer. * \param inlen The length of \a inbuf. * @@ -39,7 +39,7 @@ int apc_pub_encrypt(struct asymmetric_key *pub, unsigned char *inbuf, * * \return The size of the recovered plaintext on success, negative on errors. */ -int apc_priv_decrypt(const char *key_file, unsigned char *outbuf, +int apc_priv_decrypt(const char *key_file, unsigned char **outbuf, unsigned char *inbuf, int inlen); /** diff --git a/gcrypt.c b/gcrypt.c index 68f80f27..e5f64688 100644 --- a/gcrypt.c +++ b/gcrypt.c @@ -478,17 +478,20 @@ void apc_free_pubkey(struct asymmetric_key *key) free(key); } -static int decode_rsa(gcry_sexp_t sexp, unsigned char *outbuf, size_t *nbytes) +static int decode_rsa(gcry_sexp_t sexp, unsigned char **outbuf, size_t *nbytes) { const char *p = gcry_sexp_nth_data(sexp, 1, nbytes); - if (!p) + if (!p) { + *outbuf = NULL; return -E_RSA_DECODE; - memcpy(outbuf, p, *nbytes); + } + *outbuf = alloc(*nbytes); + memcpy(*outbuf, p, *nbytes); return 1; } -int apc_priv_decrypt(const char *key_file, unsigned char *outbuf, +int apc_priv_decrypt(const char *key_file, unsigned char **outbuf, unsigned char *inbuf, int inlen) { gcry_error_t gret; @@ -498,6 +501,7 @@ int apc_priv_decrypt(const char *key_file, unsigned char *outbuf, gcry_sexp_t in, out, priv_key; size_t nbytes; + *outbuf = NULL; ret = check_private_key_file(key_file); if (ret < 0) return ret; diff --git a/openssl.c b/openssl.c index acf1120d..5f981437 100644 --- a/openssl.c +++ b/openssl.c @@ -274,12 +274,13 @@ void apc_free_pubkey(struct asymmetric_key *pub) free(pub); } -int apc_priv_decrypt(const char *key_file, unsigned char *outbuf, +int apc_priv_decrypt(const char *key_file, unsigned char **outbuf, unsigned char *inbuf, int inlen) { struct asymmetric_key *priv; int ret; + *outbuf = NULL; ret = check_private_key_file(key_file); if (ret < 0) return ret; @@ -298,11 +299,15 @@ int apc_priv_decrypt(const char *key_file, unsigned char *outbuf, ret = -E_BLINDING; if (RSA_blinding_on(priv->rsa, NULL) == 0) goto out; - ret = RSA_private_decrypt(inlen, inbuf, outbuf, priv->rsa, + *outbuf = alloc(RSA_size(priv->rsa)); + ret = RSA_private_decrypt(inlen, inbuf, *outbuf, priv->rsa, RSA_PKCS1_OAEP_PADDING); RSA_blinding_off(priv->rsa); - if (ret <= 0) + if (ret <= 0) { + free(*outbuf); + *outbuf = NULL; ret = -E_DECRYPT; + } out: RSA_free(priv->rsa); free(priv); -- 2.39.5