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 <log...@free.fr> --- configure.ac | 9 ++ src/openvpn/openssl_compat.h | 190 +++++++++++++++++++++++++++++++++++++++++++ src/openvpn/ssl_openssl.c | 22 ++--- 3 files changed, 210 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 0c55d78327597a0690fa9625e06adb8b055852b1..2406ad8d6bf10f202d3fc1e9b971bc8ec135bd4f 100644 --- a/configure.ac +++ b/configure.ac @@ -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 \ ] ) diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h index 458a6adbe2b3fcd5ea63dcea6596cc24315d463c..e98e8dffc5773d73684398ae28215d4fdccac3c4 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -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_ */ diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index bf0f643f25439f71cbfe71bf5a7e8eb834b0f012..f011e06702529ff34e91f6d0169d1adf8cc9d767 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c @@ -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(); -- 2.7.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel