Browse code

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

OpenSSL 1.1 does not allow us to directly access the internal of
any data type, including EVP_PKEY. 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-3-logout@free.fr>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14795.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit b8ca5bc3593e539d0735a74b55ed41a792e55033)

Emmanuel Deloget authored on 2017/06/12 22:43:24
Showing 3 changed files
... ...
@@ -905,6 +905,9 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
905 905
 			X509_STORE_get0_objects \
906 906
 			X509_OBJECT_free \
907 907
 			X509_OBJECT_get_type \
908
+			EVP_PKEY_id \
909
+			EVP_PKEY_get0_RSA \
910
+			EVP_PKEY_get0_DSA \
908 911
 			RSA_meth_new \
909 912
 			RSA_meth_free \
910 913
 			RSA_meth_set_pub_enc \
... ...
@@ -133,6 +133,48 @@ X509_OBJECT_get_type(const X509_OBJECT *obj)
133 133
 }
134 134
 #endif
135 135
 
136
+#if !defined(HAVE_EVP_PKEY_GET0_RSA)
137
+/**
138
+ * Get the RSA object of a public key
139
+ *
140
+ * @param pkey                Public key object
141
+ * @return                    The underlying RSA object
142
+ */
143
+static inline RSA *
144
+EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
145
+{
146
+    return pkey ? pkey->pkey.rsa : NULL;
147
+}
148
+#endif
149
+
150
+#if !defined(HAVE_EVP_PKEY_ID)
151
+/**
152
+ * Get the PKEY type
153
+ *
154
+ * @param pkey                Public key object
155
+ * @return                    The key type
156
+ */
157
+static inline int
158
+EVP_PKEY_id(const EVP_PKEY *pkey)
159
+{
160
+    return pkey ? pkey->type : EVP_PKEY_NONE;
161
+}
162
+#endif
163
+
164
+#if !defined(HAVE_EVP_PKEY_GET0_DSA)
165
+/**
166
+ * Get the DSA object of a public key
167
+ *
168
+ * @param pkey                Public key object
169
+ * @return                    The underlying DSA object
170
+ */
171
+static inline DSA *
172
+EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
173
+{
174
+    return pkey ? pkey->pkey.dsa : NULL;
175
+}
176
+#endif
177
+
136 178
 #if !defined(HAVE_RSA_METH_NEW)
137 179
 /**
138 180
  * Allocate a new RSA method object
... ...
@@ -1075,7 +1075,7 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
1075 1075
     /* get the public key */
1076 1076
     EVP_PKEY *pkey = X509_get0_pubkey(cert);
1077 1077
     ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
1078
-    pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
1078
+    pub_rsa = EVP_PKEY_get0_RSA(pkey);
1079 1079
 
1080 1080
     /* initialize RSA object */
1081 1081
     rsa->n = BN_dup(pub_rsa->n);
... ...
@@ -1680,13 +1680,13 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix)
1680 1680
         EVP_PKEY *pkey = X509_get_pubkey(cert);
1681 1681
         if (pkey != NULL)
1682 1682
         {
1683
-            if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
1683
+            if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL
1684 1684
                 && pkey->pkey.rsa->n != NULL)
1685 1685
             {
1686 1686
                 openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA",
1687 1687
                                  BN_num_bits(pkey->pkey.rsa->n));
1688 1688
             }
1689
-            else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
1689
+            else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL
1690 1690
                      && pkey->pkey.dsa->p != NULL)
1691 1691
             {
1692 1692
                 openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA",