OpenVPN
openssl_compat.h
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9  * Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2
13  * as published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
35 #ifndef OPENSSL_COMPAT_H_
36 #define OPENSSL_COMPAT_H_
37 
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41 
42 #include "buffer.h"
43 
44 #include <openssl/rsa.h>
45 #include <openssl/ssl.h>
46 #include <openssl/x509.h>
47 #include <openssl/err.h>
48 
49 /* Functionality missing in 1.1.0 */
50 #if OPENSSL_VERSION_NUMBER < 0x10101000L && !defined(ENABLE_CRYPTO_WOLFSSL)
51 #define SSL_CTX_set1_groups SSL_CTX_set1_curves
52 #endif
53 
54 /* Functionality missing in LibreSSL before 3.5 */
55 #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050000fL
56 
61 static inline void
62 X509_OBJECT_free(X509_OBJECT *obj)
63 {
64  if (obj)
65  {
66  X509_OBJECT_free_contents(obj);
67  OPENSSL_free(obj);
68  }
69 }
70 
71 #define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG
72 #define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG
73 #endif
74 
75 #if defined(LIBRESSL_VERSION_NUMBER)
76 #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT
77 #endif
78 
79 #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050400fL || defined(OPENSSL_IS_AWSLC)
80 #define SSL_get_peer_tmp_key SSL_get_server_tmp_key
81 #endif
82 
83 /* Functionality missing in 1.1.1 */
84 #if OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(OPENSSL_NO_EC)
85 
86 /* Note that this is not a perfect emulation of the new function but
87  * is good enough for our case of printing certificate details during
88  * handshake */
89 static inline
90 int
91 EVP_PKEY_get_group_name(EVP_PKEY *pkey, char *gname, size_t gname_sz,
92  size_t *gname_len)
93 {
94  const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
95  if (ec == NULL)
96  {
97  return 0;
98  }
99  const EC_GROUP *group = EC_KEY_get0_group(ec);
100  int nid = EC_GROUP_get_curve_name(group);
101 
102  if (nid == 0)
103  {
104  return 0;
105  }
106  const char *curve = OBJ_nid2sn(nid);
107  if (!curve)
108  {
109  curve = "(error fetching curve name)";
110  }
111 
112  strncpynt(gname, curve, gname_sz);
113 
114  /* strncpynt ensures null termination so just strlen is fine here */
115  *gname_len = strlen(curve);
116  return 1;
117 }
118 #endif /* if OPENSSL_VERSION_NUMBER < 0x30000000L && !defined(OPENSSL_NO_EC) */
119 
120 #if OPENSSL_VERSION_NUMBER < 0x30000000L
121 #define EVP_MD_get0_name EVP_MD_name
122 #define EVP_CIPHER_get0_name EVP_CIPHER_name
123 #define EVP_CIPHER_CTX_get_mode EVP_CIPHER_CTX_mode
124 
126 #define SSL_CTX_new_ex(libctx, propq, method) \
127  SSL_CTX_new((method))
128 
129 /* Some safe typedefs to avoid too many ifdefs */
130 typedef void OSSL_LIB_CTX;
131 typedef void OSSL_PROVIDER;
132 
133 /* Mimics the functions but only when the default context without
134  * options is chosen */
135 static inline const EVP_CIPHER *
136 EVP_CIPHER_fetch(void *ctx, const char *algorithm, const char *properties)
137 {
138  ASSERT(!ctx);
139  ASSERT(!properties);
140  return EVP_get_cipherbyname(algorithm);
141 }
142 
143 static inline const EVP_MD *
144 EVP_MD_fetch(void *ctx, const char *algorithm, const char *properties)
145 {
146  ASSERT(!ctx);
147  ASSERT(!properties);
148  return EVP_get_digestbyname(algorithm);
149 }
150 
151 static inline void
152 EVP_CIPHER_free(const EVP_CIPHER *cipher)
153 {
154  /* OpenSSL 1.1.1 and lower use only const EVP_CIPHER, nothing to free */
155 }
156 
157 static inline void
158 EVP_MD_free(const EVP_MD *md)
159 {
160  /* OpenSSL 1.1.1 and lower use only const EVP_MD, nothing to free */
161 }
162 
163 static inline unsigned long
164 ERR_get_error_all(const char **file, int *line,
165  const char **func,
166  const char **data, int *flags)
167 {
168  static const char *empty = "";
169  *func = empty;
170  unsigned long err = ERR_get_error_line_data(file, line, data, flags);
171  return err;
172 }
173 
174 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
175 
176 #endif /* OPENSSL_COMPAT_H_ */
EVP_CIPHER_free
static void EVP_CIPHER_free(const EVP_CIPHER *cipher)
Definition: openssl_compat.h:152
EVP_MD_fetch
static const EVP_MD * EVP_MD_fetch(void *ctx, const char *algorithm, const char *properties)
Definition: openssl_compat.h:144
EVP_MD_free
static void EVP_MD_free(const EVP_MD *md)
Definition: openssl_compat.h:158
EVP_CIPHER_fetch
static const EVP_CIPHER * EVP_CIPHER_fetch(void *ctx, const char *algorithm, const char *properties)
Definition: openssl_compat.h:136
ASSERT
#define ASSERT(x)
Definition: error.h:195
ERR_get_error_all
static unsigned long ERR_get_error_all(const char **file, int *line, const char **func, const char **data, int *flags)
Definition: openssl_compat.h:164
buffer.h
EVP_PKEY_get_group_name
static int EVP_PKEY_get_group_name(EVP_PKEY *pkey, char *gname, size_t gname_sz, size_t *gname_len)
Definition: openssl_compat.h:91
strncpynt
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition: buffer.h:361
OSSL_PROVIDER
void OSSL_PROVIDER
Definition: openssl_compat.h:131
config.h
OSSL_LIB_CTX
void OSSL_LIB_CTX
Definition: openssl_compat.h:130