ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/tls_openssl.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/tls_openssl.c (file contents):
Revision 7708 by michael, Fri Sep 23 16:46:01 2016 UTC vs.
Revision 9149 by michael, Sun Jan 12 10:59:03 2020 UTC

# Line 3 | Line 3
3   *
4   *  Copyright (c) 2015 Attila Molnar <attilamolnar@hush.com>
5   *  Copyright (c) 2015 Adam <Adam@anope.org>
6 < *  Copyright (c) 2005-2016 ircd-hybrid development team
6 > *  Copyright (c) 2005-2020 ircd-hybrid development team
7   *
8   *  This program is free software; you can redistribute it and/or modify
9   *  it under the terms of the GNU General Public License as published by
# Line 34 | Line 34
34   #include "memory.h"
35  
36   #ifdef HAVE_TLS_OPENSSL
37 + #if OPENSSL_VERSION_NUMBER < 0x1010100fL
38 + #error "OpenSSL 1.1.1 and above is required to build this module"
39 + #endif
40  
41 < static int TLS_initialized;
41 > static bool TLS_initialized;
42  
43   /*
44   * report_crypto_errors - Dump crypto error list to log
# Line 43 | Line 46 | static int TLS_initialized;
46   static void
47   report_crypto_errors(void)
48   {
49 <  unsigned long e = 0;
49 >  unsigned long e;
50  
51    while ((e = ERR_get_error()))
52      ilog(LOG_TYPE_IRCD, "SSL error: %s", ERR_error_string(e, 0));
# Line 55 | Line 58 | always_accept_verify_cb(int preverify_ok
58    return 1;
59   }
60  
61 < int
61 > bool
62   tls_is_initialized(void)
63   {
64    return TLS_initialized;
# Line 70 | Line 73 | tls_is_initialized(void)
73   void
74   tls_init(void)
75   {
76 <  SSL_load_error_strings();
74 <  SSLeay_add_ssl_algorithms();
75 <
76 <  if (!(ConfigServerInfo.tls_ctx.server_ctx = SSL_CTX_new(SSLv23_server_method())))
76 >  if ((ConfigServerInfo.tls_ctx.server_ctx = SSL_CTX_new(TLS_server_method())) == NULL)
77    {
78      const char *s = ERR_lib_error_string(ERR_get_error());
79  
80 <    ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the TLS Server context -- %s", s);
80 >    ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the TLS server context -- %s", s);
81      exit(EXIT_FAILURE);
82      return;  /* Not reached */
83    }
84  
85 <  SSL_CTX_set_options(ConfigServerInfo.tls_ctx.server_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET);
86 <  SSL_CTX_set_options(ConfigServerInfo.tls_ctx.server_ctx, SSL_OP_SINGLE_DH_USE|SSL_OP_CIPHER_SERVER_PREFERENCE);
87 <  SSL_CTX_set_verify(ConfigServerInfo.tls_ctx.server_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
88 <                     always_accept_verify_cb);
85 >  SSL_CTX_set_min_proto_version(ConfigServerInfo.tls_ctx.server_ctx, TLS1_2_VERSION);
86 >  SSL_CTX_set_options(ConfigServerInfo.tls_ctx.server_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE|SSL_OP_NO_TICKET);
87 >  SSL_CTX_set_verify(ConfigServerInfo.tls_ctx.server_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, always_accept_verify_cb);
88    SSL_CTX_set_session_cache_mode(ConfigServerInfo.tls_ctx.server_ctx, SSL_SESS_CACHE_OFF);
89    SSL_CTX_set_cipher_list(ConfigServerInfo.tls_ctx.server_ctx, "EECDH+HIGH:EDH+HIGH:HIGH:!aNULL");
90  
91 < #ifndef OPENSSL_NO_ECDH
93 <  EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
94 <
95 <  if (key)
96 <  {
97 <    SSL_CTX_set_tmp_ecdh(ConfigServerInfo.tls_ctx.server_ctx, key);
98 <    EC_KEY_free(key);
99 <  }
100 <
101 <  SSL_CTX_set_options(ConfigServerInfo.tls_ctx.server_ctx, SSL_OP_SINGLE_ECDH_USE);
102 < #endif
103 <
104 <  if (!(ConfigServerInfo.tls_ctx.client_ctx = SSL_CTX_new(SSLv23_client_method())))
91 >  if ((ConfigServerInfo.tls_ctx.client_ctx = SSL_CTX_new(TLS_client_method())) == NULL)
92    {
93      const char *s = ERR_lib_error_string(ERR_get_error());
94  
95 <    ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the TLS Client context -- %s", s);
95 >    ilog(LOG_TYPE_IRCD, "ERROR: Could not initialize the TLS client context -- %s", s);
96      exit(EXIT_FAILURE);
97      return;  /* Not reached */
98    }
99  
100 <  SSL_CTX_set_options(ConfigServerInfo.tls_ctx.client_ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET);
101 <  SSL_CTX_set_options(ConfigServerInfo.tls_ctx.client_ctx, SSL_OP_SINGLE_DH_USE);
102 <  SSL_CTX_set_verify(ConfigServerInfo.tls_ctx.client_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
116 <                     always_accept_verify_cb);
100 >  SSL_CTX_set_min_proto_version(ConfigServerInfo.tls_ctx.client_ctx, TLS1_2_VERSION);
101 >  SSL_CTX_set_options(ConfigServerInfo.tls_ctx.client_ctx, SSL_OP_NO_TICKET);
102 >  SSL_CTX_set_verify(ConfigServerInfo.tls_ctx.client_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, always_accept_verify_cb);
103    SSL_CTX_set_session_cache_mode(ConfigServerInfo.tls_ctx.client_ctx, SSL_SESS_CACHE_OFF);
104   }
105  
106 < int
106 > bool
107   tls_new_cred(void)
108   {
109 <  TLS_initialized = 0;
109 >  TLS_initialized = false;
110  
111 <  if (!ConfigServerInfo.ssl_certificate_file || !ConfigServerInfo.rsa_private_key_file)
112 <    return 1;
111 >  if (!ConfigServerInfo.tls_certificate_file || !ConfigServerInfo.rsa_private_key_file)
112 >    return true;
113  
114 <  if (SSL_CTX_use_certificate_chain_file(ConfigServerInfo.tls_ctx.server_ctx, ConfigServerInfo.ssl_certificate_file) <= 0 ||
115 <      SSL_CTX_use_certificate_chain_file(ConfigServerInfo.tls_ctx.client_ctx, ConfigServerInfo.ssl_certificate_file) <= 0)
114 >  if (SSL_CTX_use_certificate_chain_file(ConfigServerInfo.tls_ctx.server_ctx, ConfigServerInfo.tls_certificate_file) <= 0 ||
115 >      SSL_CTX_use_certificate_chain_file(ConfigServerInfo.tls_ctx.client_ctx, ConfigServerInfo.tls_certificate_file) <= 0)
116    {
117      report_crypto_errors();
118 <    return 0;
118 >    return false;
119    }
120  
121    if (SSL_CTX_use_PrivateKey_file(ConfigServerInfo.tls_ctx.server_ctx, ConfigServerInfo.rsa_private_key_file, SSL_FILETYPE_PEM) <= 0 ||
122        SSL_CTX_use_PrivateKey_file(ConfigServerInfo.tls_ctx.client_ctx, ConfigServerInfo.rsa_private_key_file, SSL_FILETYPE_PEM) <= 0)
123    {
124      report_crypto_errors();
125 <    return 0;
125 >    return false;
126    }
127  
128    if (!SSL_CTX_check_private_key(ConfigServerInfo.tls_ctx.server_ctx) ||
129        !SSL_CTX_check_private_key(ConfigServerInfo.tls_ctx.client_ctx))
130    {
131      report_crypto_errors();
132 <    return 0;
132 >    return false;
133    }
134  
135 <  if (ConfigServerInfo.ssl_dh_param_file)
135 >  if (ConfigServerInfo.tls_dh_param_file)
136    {
137 <    BIO *file = BIO_new_file(ConfigServerInfo.ssl_dh_param_file, "r");
137 >    BIO *file = BIO_new_file(ConfigServerInfo.tls_dh_param_file, "r");
138  
139      if (file)
140      {
# Line 163 | Line 149 | tls_new_cred(void)
149        }
150      }
151      else
152 <      ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_dh_param_file -- could not open/read Diffie-Hellman parameter file");
152 >      ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::tls_dh_param_file -- could not open/read Diffie-Hellman parameter file");
153    }
154  
155 < #ifndef OPENSSL_NO_ECDH
156 <  if (ConfigServerInfo.ssl_dh_elliptic_curve)
155 >  if (ConfigServerInfo.tls_supported_groups == NULL)
156 >    SSL_CTX_set1_groups_list(ConfigServerInfo.tls_ctx.server_ctx, "X25519:P-256");
157 >  else if (SSL_CTX_set1_groups_list(ConfigServerInfo.tls_ctx.server_ctx, ConfigServerInfo.tls_supported_groups) == 0)
158    {
159 <    int nid = 0;
160 <    EC_KEY *key = NULL;
174 <
175 <    if ((nid = OBJ_sn2nid(ConfigServerInfo.ssl_dh_elliptic_curve)) == 0)
176 <      goto set_default_curve;
177 <
178 <    if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
179 <      goto set_default_curve;
180 <
181 <    SSL_CTX_set_tmp_ecdh(ConfigServerInfo.tls_ctx.server_ctx, key);
182 <    EC_KEY_free(key);
183 <  }
184 <  else
185 <  {
186 <    EC_KEY *key;
187 <
188 < set_default_curve:
189 <
190 <    key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
191 <
192 <    if (key)
193 <    {
194 <      SSL_CTX_set_tmp_ecdh(ConfigServerInfo.tls_ctx.server_ctx, key);
195 <      EC_KEY_free(key);
196 <    }
159 >    ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::tls_supported_groups -- could not set supported group(s)");
160 >    SSL_CTX_set1_groups_list(ConfigServerInfo.tls_ctx.server_ctx, "X25519:P-256");
161    }
198 #endif
162  
163 <  if (ConfigServerInfo.ssl_message_digest_algorithm == NULL)
163 >  if (ConfigServerInfo.tls_message_digest_algorithm == NULL)
164      ConfigServerInfo.message_digest_algorithm = EVP_sha256();
165    else
166    {
167 <    ConfigServerInfo.message_digest_algorithm = EVP_get_digestbyname(ConfigServerInfo.ssl_message_digest_algorithm);
167 >    ConfigServerInfo.message_digest_algorithm = EVP_get_digestbyname(ConfigServerInfo.tls_message_digest_algorithm);
168  
169      if (ConfigServerInfo.message_digest_algorithm == NULL)
170      {
171        ConfigServerInfo.message_digest_algorithm = EVP_sha256();
172 <      ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::ssl_message_digest_algorithm -- unknown message digest algorithm");
172 >      ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::tls_message_digest_algorithm -- unknown message digest algorithm");
173      }
174    }
175  
176 <  if (ConfigServerInfo.ssl_cipher_list)
177 <    SSL_CTX_set_cipher_list(ConfigServerInfo.tls_ctx.server_ctx, ConfigServerInfo.ssl_cipher_list);
176 >  if (ConfigServerInfo.tls_cipher_list)
177 >    if (SSL_CTX_set_cipher_list(ConfigServerInfo.tls_ctx.server_ctx, ConfigServerInfo.tls_cipher_list) == 0)
178 >      ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::tls_cipher_list -- could not set supported cipher(s)");
179 >
180 > #ifndef LIBRESSL_VERSION_NUMBER
181 >  if (ConfigServerInfo.tls_cipher_suites == NULL)
182 >    /* Default to TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 */
183 >    SSL_CTX_set_ciphersuites(ConfigServerInfo.tls_ctx.server_ctx, "");
184 >  else if (SSL_CTX_set_ciphersuites(ConfigServerInfo.tls_ctx.server_ctx, ConfigServerInfo.tls_cipher_suites) == 0)
185 >  {
186 >    ilog(LOG_TYPE_IRCD, "Ignoring serverinfo::tls_cipher_suites -- could not set supported cipher suite(s)");
187 >    SSL_CTX_set_ciphersuites(ConfigServerInfo.tls_ctx.server_ctx, "");
188 >  }
189 > #endif
190  
191 <  TLS_initialized = 1;
192 <  return 1;
191 >  TLS_initialized = true;
192 >  return true;
193   }
194  
195   const char *
196   tls_get_cipher(const tls_data_t *tls_data)
197   {
198    static char buffer[IRCD_BUFSIZE];
224  int bits = 0;
199    SSL *ssl = *tls_data;
200  
201 <  SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), &bits);
228 <
229 <  snprintf(buffer, sizeof(buffer), "%s-%s-%d", SSL_get_version(ssl),
230 <           SSL_get_cipher(ssl), bits);
201 >  snprintf(buffer, sizeof(buffer), "%s-%s", SSL_get_version(ssl), SSL_get_cipher(ssl));
202    return buffer;
203   }
204  
# Line 237 | Line 208 | tls_get_version(void)
208    static char buf[IRCD_BUFSIZE];
209  
210    snprintf(buf, sizeof(buf), "OpenSSL version: library: %s, header: %s",
211 <           SSLeay_version(SSLEAY_VERSION), OPENSSL_VERSION_TEXT);
211 >           OpenSSL_version(OPENSSL_VERSION), OPENSSL_VERSION_TEXT);
212    return buf;
213   }
214  
215 < int
215 > bool
216   tls_isusing(tls_data_t *tls_data)
217   {
218    SSL *ssl = *tls_data;
# Line 255 | Line 226 | tls_free(tls_data_t *tls_data)
226    *tls_data = NULL;
227   }
228  
229 < int
230 < tls_read(tls_data_t *tls_data, char *buf, size_t bufsize, int *want_write)
229 > ssize_t
230 > tls_read(tls_data_t *tls_data, char *buf, size_t bufsize, bool *want_write)
231   {
232    SSL *ssl = *tls_data;
233 <  int length = SSL_read(ssl, buf, bufsize);
233 >  ssize_t length = SSL_read(ssl, buf, bufsize);
234  
235    /* Translate openssl error codes, sigh */
236    if (length < 0)
# Line 269 | Line 240 | tls_read(tls_data_t *tls_data, char *buf
240        case SSL_ERROR_WANT_WRITE:
241        {
242          /* OpenSSL wants to write, we signal this to the caller and do nothing about that here */
243 <        *want_write = 1;
243 >        *want_write = true;
244          break;
245        }
246        case SSL_ERROR_WANT_READ:
# Line 288 | Line 259 | tls_read(tls_data_t *tls_data, char *buf
259    return length;
260   }
261  
262 < int
263 < tls_write(tls_data_t *tls_data, const char *buf, size_t bufsize, int *want_read)
262 > ssize_t
263 > tls_write(tls_data_t *tls_data, const char *buf, size_t bufsize, bool *want_read)
264   {
265    SSL *ssl = *tls_data;
266 <  int retlen = SSL_write(ssl, buf, bufsize);
266 >  ssize_t retlen = SSL_write(ssl, buf, bufsize);
267  
268    /* Translate openssl error codes, sigh */
269    if (retlen < 0)
# Line 300 | Line 271 | tls_write(tls_data_t *tls_data, const ch
271      switch (SSL_get_error(ssl, retlen))
272      {
273        case SSL_ERROR_WANT_READ:
274 <        *want_read = 1;
274 >        *want_read = true;
275          break;  /* Retry later, don't register for write events */
276        case SSL_ERROR_WANT_WRITE:
277          errno = EWOULDBLOCK;
# Line 326 | Line 297 | tls_shutdown(tls_data_t *tls_data)
297  
298    SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
299  
300 <  if (!SSL_shutdown(ssl))
300 >  if (SSL_shutdown(ssl) == 0)
301      SSL_shutdown(ssl);
302   }
303  
304 < int
304 > bool
305   tls_new(tls_data_t *tls_data, int fd, tls_role_t role)
306   {
307    SSL *ssl;
308  
309 <  if (!TLS_initialized)
310 <    return 0;
309 >  if (TLS_initialized == false)
310 >    return false;
311  
312    if (role == TLS_ROLE_SERVER)
313      ssl = SSL_new(ConfigServerInfo.tls_ctx.server_ctx);
314    else
315      ssl = SSL_new(ConfigServerInfo.tls_ctx.client_ctx);
316  
317 <  if (!ssl)
317 >  if (ssl == NULL)
318    {
319      ilog(LOG_TYPE_IRCD, "SSL_new() ERROR! -- %s",
320           ERR_error_string(ERR_get_error(), NULL));
321 <    return 0;
321 >    return false;
322    }
323  
324    *tls_data = ssl;
325    SSL_set_fd(ssl, fd);
326 <  return 1;
326 >  return true;
327   }
328  
329 < int
329 > bool
330   tls_set_ciphers(tls_data_t *tls_data, const char *cipher_list)
331   {
332    SSL_set_cipher_list(*tls_data, cipher_list);
333 <  return 1;
333 >  return true;
334   }
335  
336   tls_handshake_status_t
# Line 394 | Line 365 | tls_handshake(tls_data_t *tls_data, tls_
365    }
366   }
367  
368 < int
368 > bool
369   tls_verify_cert(tls_data_t *tls_data, tls_md_t digest, char **fingerprint)
370   {
371    SSL *ssl = *tls_data;
401  X509 *cert = SSL_get_peer_certificate(ssl);
372    unsigned int n;
373    char buf[EVP_MAX_MD_SIZE * 2 + 1];
374    unsigned char md[EVP_MAX_MD_SIZE];
375 <  int ret = 0;
375 >  bool ret = false;
376  
377    /* Accept NULL return from SSL_get_peer_certificate */
378 <  if (!cert)
379 <    return 1;
378 >  X509 *cert = SSL_get_peer_certificate(ssl);
379 >  if (cert == NULL)
380 >    return true;
381  
382 <  int res = SSL_get_verify_result(ssl);
412 <  if (res == X509_V_OK || res == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
413 <      res == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE ||
414 <      res == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
382 >  switch (SSL_get_verify_result(ssl))
383    {
384 <    ret = 1;
384 >    case X509_V_OK:
385 >    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
386 >    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
387 >    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
388 >      ret = true;
389  
390 <    if (X509_digest(cert, digest, md, &n))
391 <    {
392 <      binary_to_hex(md, buf, n);
393 <      *fingerprint = xstrdup(buf);
394 <    }
390 >      if (X509_digest(cert, digest, md, &n))
391 >      {
392 >        binary_to_hex(md, buf, n);
393 >        *fingerprint = xstrdup(buf);
394 >      }
395 >    default:
396 >      break;
397    }
398  
399    X509_free(cert);

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)