Browse code

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

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 <logout@free.fr>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <20170612134330.20971-4-logout@free.fr>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14790.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Emmanuel Deloget authored on 2017/06/12 22:43:25
Showing 3 changed files
... ...
@@ -928,6 +928,10 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
928 928
 			EVP_PKEY_id \
929 929
 			EVP_PKEY_get0_RSA \
930 930
 			EVP_PKEY_get0_DSA \
931
+			RSA_set_flags \
932
+			RSA_bits \
933
+			RSA_get0_key \
934
+			RSA_set0_key \
931 935
 			RSA_meth_new \
932 936
 			RSA_meth_free \
933 937
 			RSA_meth_set_pub_enc \
... ...
@@ -175,6 +175,106 @@ EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
175 175
 }
176 176
 #endif
177 177
 
178
+#if !defined(HAVE_RSA_SET_FLAGS)
179
+/**
180
+ * Set the RSA flags
181
+ *
182
+ * @param rsa                 The RSA object
183
+ * @param flags               New flags value
184
+ */
185
+static inline void
186
+RSA_set_flags(RSA *rsa, int flags)
187
+{
188
+    if (rsa)
189
+    {
190
+        rsa->flags = flags;
191
+    }
192
+}
193
+#endif
194
+
195
+#if !defined(HAVE_RSA_GET0_KEY)
196
+/**
197
+ * Get the RSA parameters
198
+ *
199
+ * @param rsa                 The RSA object
200
+ * @param n                   The @c n parameter
201
+ * @param e                   The @c e parameter
202
+ * @param d                   The @c d parameter
203
+ */
204
+static inline void
205
+RSA_get0_key(const RSA *rsa, const BIGNUM **n,
206
+             const BIGNUM **e, const BIGNUM **d)
207
+{
208
+    if (n != NULL)
209
+    {
210
+        *n = rsa ? rsa->n : NULL;
211
+    }
212
+    if (e != NULL)
213
+    {
214
+        *e = rsa ? rsa->e : NULL;
215
+    }
216
+    if (d != NULL)
217
+    {
218
+        *d = rsa ? rsa->d : NULL;
219
+    }
220
+}
221
+#endif
222
+
223
+#if !defined(HAVE_RSA_SET0_KEY)
224
+/**
225
+ * Set the RSA parameters
226
+ *
227
+ * @param rsa                 The RSA object
228
+ * @param n                   The @c n parameter
229
+ * @param e                   The @c e parameter
230
+ * @param d                   The @c d parameter
231
+ * @return                    1 on success, 0 on error
232
+ */
233
+static inline int
234
+RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d)
235
+{
236
+    if ((rsa->n == NULL && n == NULL)
237
+        || (rsa->e == NULL && e == NULL))
238
+    {
239
+        return 0;
240
+    }
241
+
242
+    if (n != NULL)
243
+    {
244
+        BN_free(rsa->n);
245
+        rsa->n = n;
246
+    }
247
+    if (e != NULL)
248
+    {
249
+        BN_free(rsa->e);
250
+        rsa->e = e;
251
+    }
252
+    if (d != NULL)
253
+    {
254
+        BN_free(rsa->d);
255
+        rsa->d = d;
256
+    }
257
+
258
+    return 1;
259
+}
260
+#endif
261
+
262
+#if !defined(HAVE_RSA_BITS)
263
+/**
264
+ * Number of significant RSA bits
265
+ *
266
+ * @param rsa                The RSA object ; shall not be NULL
267
+ * @return                   The number of RSA bits or 0 on error
268
+ */
269
+static inline int
270
+RSA_bits(const RSA *rsa)
271
+{
272
+    const BIGNUM *n = NULL;
273
+    RSA_get0_key(rsa, &n, NULL, NULL);
274
+    return n ? BN_num_bits(n) : 0;
275
+}
276
+#endif
277
+
178 278
 #if !defined(HAVE_RSA_METH_NEW)
179 279
 /**
180 280
  * Allocate a new RSA method object
... ...
@@ -973,10 +973,13 @@ rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, i
973 973
 
974 974
 /* called at RSA_free */
975 975
 static int
976
-rsa_finish(RSA *rsa)
976
+openvpn_extkey_rsa_finish(RSA *rsa)
977 977
 {
978
-    RSA_meth_free(rsa->meth);
979
-    rsa->meth = NULL;
978
+    /* meth was allocated in tls_ctx_use_external_private_key() ; since
979
+     * this function is called when the parent RSA object is destroyed,
980
+     * it is no longer used after this point so kill it. */
981
+    const RSA_METHOD *meth = RSA_get_method(rsa);
982
+    RSA_meth_free((RSA_METHOD *)meth);
980 983
     return 1;
981 984
 }
982 985
 
... ...
@@ -1058,7 +1061,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
1058 1058
     RSA_meth_set_priv_enc(rsa_meth, rsa_priv_enc);
1059 1059
     RSA_meth_set_priv_dec(rsa_meth, rsa_priv_dec);
1060 1060
     RSA_meth_set_init(rsa_meth, NULL);
1061
-    RSA_meth_set_finish(rsa_meth, rsa_finish);
1061
+    RSA_meth_set_finish(rsa_meth, openvpn_extkey_rsa_finish);
1062 1062
     RSA_meth_set0_app_data(rsa_meth, NULL);
1063 1063
 
1064 1064
     /* allocate RSA object */
... ...
@@ -1075,8 +1078,11 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
1075 1075
     pub_rsa = EVP_PKEY_get0_RSA(pkey);
1076 1076
 
1077 1077
     /* initialize RSA object */
1078
-    rsa->n = BN_dup(pub_rsa->n);
1079
-    rsa->flags |= RSA_FLAG_EXT_PKEY;
1078
+    const BIGNUM *n = NULL;
1079
+    const BIGNUM *e = NULL;
1080
+    RSA_get0_key(pub_rsa, &n, &e, NULL);
1081
+    RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL);
1082
+    RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY);
1080 1083
     if (!RSA_set_method(rsa, rsa_meth))
1081 1084
     {
1082 1085
         goto err;
... ...
@@ -1677,11 +1683,11 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix)
1677 1677
         EVP_PKEY *pkey = X509_get_pubkey(cert);
1678 1678
         if (pkey != NULL)
1679 1679
         {
1680
-            if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL
1681
-                && pkey->pkey.rsa->n != NULL)
1680
+            if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL)
1682 1681
             {
1682
+                RSA *rsa = EVP_PKEY_get0_RSA(pkey);
1683 1683
                 openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA",
1684
-                                 BN_num_bits(pkey->pkey.rsa->n));
1684
+                                 RSA_bits(rsa));
1685 1685
             }
1686 1686
             else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL
1687 1687
                      && pkey->pkey.dsa->p != NULL)