OpenSSL: don't use direct access to the internal of RSA_METHOD

OpenSSL 1.1 does not allow us to directly access the internal of
any data type, including RSA_METHOD. We have to use the defined
functions to do so.

Compatibility with OpenSSL 1.0 is kept by defining the corresponding
functions when they are not found in the library.

Signed-off-by: Emmanuel Deloget <logout@free.fr>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <79d89580db6fd92c059dabc4f5f4d83b72bb9d3d.1487859361.git.logout@free.fr>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14175.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Emmanuel Deloget 2017-02-23 15:35:56 +01:00 committed by Gert Doering
parent 22c5381b71
commit 09776c5b52
3 changed files with 210 additions and 11 deletions

View File

@ -905,6 +905,15 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
X509_STORE_get0_objects \
X509_OBJECT_free \
X509_OBJECT_get_type \
RSA_meth_new \
RSA_meth_free \
RSA_meth_set_pub_enc \
RSA_meth_set_pub_dec \
RSA_meth_set_priv_enc \
RSA_meth_set_priv_dec \
RSA_meth_set_init \
RSA_meth_set_finish \
RSA_meth_set0_app_data \
]
)

View File

@ -41,6 +41,8 @@
#include "config-msvc.h"
#endif
#include "buffer.h"
#include <openssl/ssl.h>
#include <openssl/x509.h>
@ -117,4 +119,192 @@ X509_OBJECT_get_type(const X509_OBJECT *obj)
}
#endif
#if !defined(HAVE_RSA_METH_NEW)
/**
* Allocate a new RSA method object
*
* @param name The object name
* @param flags Configuration flags
* @return A new RSA method object
*/
static inline RSA_METHOD *
RSA_meth_new(const char *name, int flags)
{
RSA_METHOD *rsa_meth = NULL;
ALLOC_OBJ_CLEAR(rsa_meth, RSA_METHOD);
rsa_meth->name = string_alloc(name, NULL);
rsa_meth->flags = flags;
return rsa_meth;
}
#endif
#if !defined(HAVE_RSA_METH_FREE)
/**
* Free an existing RSA_METHOD object
*
* @param meth The RSA_METHOD object
*/
static inline void
RSA_meth_free(RSA_METHOD *meth)
{
if (meth)
{
free(meth->name);
free(meth);
}
}
#endif
#if !defined(HAVE_RSA_METH_SET_PUB_ENC)
/**
* Set the public encoding function of an RSA_METHOD object
*
* @param meth The RSA_METHOD object
* @param pub_enc the public encoding function
* @return 1 on success, 0 on error
*/
static inline int
RSA_meth_set_pub_enc(RSA_METHOD *meth,
int (*pub_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding))
{
if (meth)
{
meth->rsa_pub_enc = pub_enc;
return 1;
}
return 0;
}
#endif
#if !defined(HAVE_RSA_METH_SET_PUB_DEC)
/**
* Set the public decoding function of an RSA_METHOD object
*
* @param meth The RSA_METHOD object
* @param pub_dec the public decoding function
* @return 1 on success, 0 on error
*/
static inline int
RSA_meth_set_pub_dec(RSA_METHOD *meth,
int (*pub_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding))
{
if (meth)
{
meth->rsa_pub_dec = pub_dec;
return 1;
}
return 0;
}
#endif
#if !defined(HAVE_RSA_METH_SET_PRIV_ENC)
/**
* Set the private encoding function of an RSA_METHOD object
*
* @param meth The RSA_METHOD object
* @param priv_enc the private encoding function
* @return 1 on success, 0 on error
*/
static inline int
RSA_meth_set_priv_enc(RSA_METHOD *meth,
int (*priv_enc) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding))
{
if (meth)
{
meth->rsa_priv_enc = priv_enc;
return 1;
}
return 0;
}
#endif
#if !defined(HAVE_RSA_METH_SET_PRIV_DEC)
/**
* Set the private decoding function of an RSA_METHOD object
*
* @param meth The RSA_METHOD object
* @param priv_dec the private decoding function
* @return 1 on success, 0 on error
*/
static inline int
RSA_meth_set_priv_dec(RSA_METHOD *meth,
int (*priv_dec) (int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,
int padding))
{
if (meth)
{
meth->rsa_priv_dec = priv_dec;
return 1;
}
return 0;
}
#endif
#if !defined(HAVE_RSA_METH_SET_INIT)
/**
* Set the init function of an RSA_METHOD object
*
* @param meth The RSA_METHOD object
* @param init the init function
* @return 1 on success, 0 on error
*/
static inline int
RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa))
{
if (meth)
{
meth->init = init;
return 1;
}
return 0;
}
#endif
#if !defined(HAVE_RSA_METH_SET_FINISH)
/**
* Set the finish function of an RSA_METHOD object
*
* @param meth The RSA_METHOD object
* @param finish the finish function
* @return 1 on success, 0 on error
*/
static inline int
RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa))
{
if (meth)
{
meth->finish = finish;
return 1;
}
return 0;
}
#endif
#if !defined(HAVE_RSA_METH_SET0_APP_DATA)
/**
* Set the application data of an RSA_METHOD object
*
* @param meth The RSA_METHOD object
* @param app_data Application data
* @return 1 on success, 0 on error
*/
static inline int
RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data)
{
if (meth)
{
meth->app_data = app_data;
return 1;
}
return 0;
}
#endif
#endif /* OPENSSL_COMPAT_H_ */

View File

@ -978,7 +978,7 @@ rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
static int
rsa_finish(RSA *rsa)
{
free((void *)rsa->meth);
RSA_meth_free(rsa->meth);
rsa->meth = NULL;
return 1;
}
@ -1053,16 +1053,16 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
ASSERT(NULL != cert);
/* allocate custom RSA method object */
ALLOC_OBJ_CLEAR(rsa_meth, RSA_METHOD);
rsa_meth->name = "OpenVPN external private key RSA Method";
rsa_meth->rsa_pub_enc = rsa_pub_enc;
rsa_meth->rsa_pub_dec = rsa_pub_dec;
rsa_meth->rsa_priv_enc = rsa_priv_enc;
rsa_meth->rsa_priv_dec = rsa_priv_dec;
rsa_meth->init = NULL;
rsa_meth->finish = rsa_finish;
rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
rsa_meth->app_data = NULL;
rsa_meth = RSA_meth_new("OpenVPN external private key RSA Method",
RSA_METHOD_FLAG_NO_CHECK);
check_malloc_return(rsa_meth);
RSA_meth_set_pub_enc(rsa_meth, rsa_pub_enc);
RSA_meth_set_pub_dec(rsa_meth, rsa_pub_dec);
RSA_meth_set_priv_enc(rsa_meth, rsa_priv_enc);
RSA_meth_set_priv_dec(rsa_meth, rsa_priv_dec);
RSA_meth_set_init(rsa_meth, NULL);
RSA_meth_set_finish(rsa_meth, rsa_finish);
RSA_meth_set0_app_data(rsa_meth, NULL);
/* allocate RSA object */
rsa = RSA_new();