Hi, On 12-06-17 15:43, log...@free.fr wrote: > From: Emmanuel Deloget <log...@free.fr> > > OpenSSL 1.1 does not allow us to directly access the internal of > any data type, including RSA. 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 | 4 ++ > src/openvpn/openssl_compat.h | 100 > +++++++++++++++++++++++++++++++++++++++++++ > src/openvpn/ssl_openssl.c | 24 +++++++---- > 3 files changed, 119 insertions(+), 9 deletions(-) > > diff --git a/configure.ac b/configure.ac > index a92e8142..4c5f28ed 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -929,6 +929,10 @@ if test "${enable_crypto}" = "yes" -a > "${with_crypto_library}" = "openssl"; then > EVP_PKEY_id \ > EVP_PKEY_get0_RSA \ > EVP_PKEY_get0_DSA \ > + RSA_set_flags \ > + RSA_bits \ > + RSA_get0_key \ > + RSA_set0_key \ > RSA_meth_new \ > RSA_meth_free \ > RSA_meth_set_pub_enc \ > diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h > index 0d82cf25..44e3e167 100644 > --- a/src/openvpn/openssl_compat.h > +++ b/src/openvpn/openssl_compat.h > @@ -176,6 +176,106 @@ EVP_PKEY_get0_DSA(EVP_PKEY *pkey) > } > #endif > > +#if !defined(HAVE_RSA_SET_FLAGS) > +/** > + * Set the RSA flags > + * > + * @param rsa The RSA object > + * @param flags New flags value > + */ > +static inline void > +RSA_set_flags(RSA *rsa, int flags) > +{ > + if (rsa) > + { > + rsa->flags = flags; > + } > +} > +#endif > + > +#if !defined(HAVE_RSA_GET0_KEY) > +/** > + * Get the RSA parameters > + * > + * @param rsa The RSA object > + * @param n The @c n parameter > + * @param e The @c e parameter > + * @param d The @c d parameter > + */ > +static inline void > +RSA_get0_key(const RSA *rsa, const BIGNUM **n, > + const BIGNUM **e, const BIGNUM **d) > +{ > + if (n != NULL) > + { > + *n = rsa ? rsa->n : NULL; > + } > + if (e != NULL) > + { > + *e = rsa ? rsa->e : NULL; > + } > + if (d != NULL) > + { > + *d = rsa ? rsa->d : NULL; > + } > +} > +#endif > + > +#if !defined(HAVE_RSA_SET0_KEY) > +/** > + * Set the RSA parameters > + * > + * @param rsa The RSA object > + * @param n The @c n parameter > + * @param e The @c e parameter > + * @param d The @c d parameter > + * @return 1 on success, 0 on error > + */ > +static inline int > +RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) > +{ > + if ((rsa->n == NULL && n == NULL) > + || (rsa->e == NULL && e == NULL)) > + { > + return 0; > + } > + > + if (n != NULL) > + { > + BN_free(rsa->n); > + rsa->n = n; > + } > + if (e != NULL) > + { > + BN_free(rsa->e); > + rsa->e = e; > + } > + if (d != NULL) > + { > + BN_free(rsa->d); > + rsa->d = d; > + } > + > + return 1; > +} > +#endif > + > +#if !defined(HAVE_RSA_BITS) > +/** > + * Number of significant RSA bits > + * > + * @param rsa The RSA object ; shall not be NULL > + * @return The number of RSA bits or 0 on error > + */ > +static inline int > +RSA_bits(const RSA *rsa) > +{ > + const BIGNUM *n = NULL; > + RSA_get0_key(rsa, &n, NULL, NULL); > + return n ? BN_num_bits(n) : 0; > +} > +#endif > + > #if !defined(HAVE_RSA_METH_NEW) > /** > * Allocate a new RSA method object > diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c > index 1c73641c..2a42d3c6 100644 > --- a/src/openvpn/ssl_openssl.c > +++ b/src/openvpn/ssl_openssl.c > @@ -973,10 +973,13 @@ rsa_priv_dec(int flen, const unsigned char *from, > unsigned char *to, RSA *rsa, i > > /* called at RSA_free */ > static int > -rsa_finish(RSA *rsa) > +openvpn_extkey_rsa_finish(RSA *rsa) > { > - RSA_meth_free(rsa->meth); > - rsa->meth = NULL; > + /* meth was allocated in tls_ctx_use_external_private_key() ; since > + * this function is called when the parent RSA object is destroyed, > + * it is no longer used after this point so kill it. */ > + const RSA_METHOD *meth = RSA_get_method(rsa); > + RSA_meth_free((RSA_METHOD *)meth); > return 1; > } > > @@ -1058,7 +1061,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx > *ctx, > 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_set_finish(rsa_meth, openvpn_extkey_rsa_finish); > RSA_meth_set0_app_data(rsa_meth, NULL); > > /* allocate RSA object */ > @@ -1075,8 +1078,11 @@ tls_ctx_use_external_private_key(struct tls_root_ctx > *ctx, > pub_rsa = EVP_PKEY_get0_RSA(pkey); > > /* initialize RSA object */ > - rsa->n = BN_dup(pub_rsa->n); > - rsa->flags |= RSA_FLAG_EXT_PKEY; > + const BIGNUM *n = NULL; > + const BIGNUM *e = NULL; > + RSA_get0_key(pub_rsa, &n, &e, NULL); > + RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL); > + RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY); > if (!RSA_set_method(rsa, rsa_meth)) > { > goto err; > @@ -1677,11 +1683,11 @@ print_details(struct key_state_ssl *ks_ssl, const > char *prefix) > EVP_PKEY *pkey = X509_get_pubkey(cert); > if (pkey != NULL) > { > - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) > != NULL > - && pkey->pkey.rsa->n != NULL) > + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) > != NULL) > { > + RSA *rsa = EVP_PKEY_get0_RSA(pkey); > openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", > - BN_num_bits(pkey->pkey.rsa->n)); > + RSA_bits(rsa)); > } > else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && > EVP_PKEY_get0_DSA(pkey) != NULL > && pkey->pkey.dsa->p != NULL) >
Code looks good, and works as advertised. ACK. -Steffan ------------------------------------------------------------------------------ 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