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
61static inline void
62X509_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 */
89static inline
90int
91EVP_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 */
130typedef void OSSL_LIB_CTX;
131typedef void OSSL_PROVIDER;
132
133/* Mimics the functions but only when the default context without
134 * options is chosen */
135static inline const EVP_CIPHER *
136EVP_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
143static inline const EVP_MD *
144EVP_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
151static inline void
152EVP_CIPHER_free(const EVP_CIPHER *cipher)
153{
154 /* OpenSSL 1.1.1 and lower use only const EVP_CIPHER, nothing to free */
155}
156
157static inline void
158EVP_MD_free(const EVP_MD *md)
159{
160 /* OpenSSL 1.1.1 and lower use only const EVP_MD, nothing to free */
161}
162
163static inline unsigned long
164ERR_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_ */
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void EVP_CIPHER_free(const EVP_CIPHER *cipher)
void OSSL_PROVIDER
static const EVP_CIPHER * EVP_CIPHER_fetch(void *ctx, const char *algorithm, const char *properties)
static unsigned long ERR_get_error_all(const char **file, int *line, const char **func, const char **data, int *flags)
void OSSL_LIB_CTX
static void EVP_MD_free(const EVP_MD *md)
static const EVP_MD * EVP_MD_fetch(void *ctx, const char *algorithm, const char *properties)
static int EVP_PKEY_get_group_name(EVP_PKEY *pkey, char *gname, size_t gname_sz, size_t *gname_len)
#define ASSERT(x)
Definition error.h:195