axtls.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
9  * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
10  *
11  * This software is licensed as described in the file COPYING, which
12  * you should have received as part of this distribution. The terms
13  * are also available at https://curl.haxx.se/docs/copyright.html.
14  *
15  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16  * copies of the Software, and permit persons to whom the Software is
17  * furnished to do so, under the terms of the COPYING file.
18  *
19  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20  * KIND, either express or implied.
21  *
22  ***************************************************************************/
23 
24 /*
25  * Source file for all axTLS-specific code for the TLS/SSL layer. No code
26  * but vtls.c should ever call or use these functions.
27  */
28 
29 #include "curl_setup.h"
30 
31 #ifdef USE_AXTLS
32 #include <axTLS/config.h>
33 #include <axTLS/ssl.h>
34 #include "axtls.h"
35 
36 #include "sendf.h"
37 #include "inet_pton.h"
38 #include "vtls.h"
39 #include "parsedate.h"
40 #include "connect.h" /* for the connect timeout */
41 #include "select.h"
42 #include "curl_printf.h"
43 #include "hostcheck.h"
44 #include <unistd.h>
45 
46 /* The last #include files should be: */
47 #include "curl_memory.h"
48 #include "memdebug.h"
49 
50 struct ssl_backend_data {
51  SSL_CTX* ssl_ctx;
52  SSL* ssl;
53 };
54 
55 #define BACKEND connssl->backend
56 
57 static CURLcode map_error_to_curl(int axtls_err)
58 {
59  switch(axtls_err) {
60  case SSL_ERROR_NOT_SUPPORTED:
61  case SSL_ERROR_INVALID_VERSION:
62  case -70: /* protocol version alert from server */
64  break;
65  case SSL_ERROR_NO_CIPHER:
66  return CURLE_SSL_CIPHER;
67  break;
68  case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
69  case SSL_ERROR_NO_CERT_DEFINED:
70  case -42: /* bad certificate alert from server */
71  case -43: /* unsupported cert alert from server */
72  case -44: /* cert revoked alert from server */
73  case -45: /* cert expired alert from server */
74  case -46: /* cert unknown alert from server */
75  return CURLE_SSL_CERTPROBLEM;
76  break;
77  case SSL_X509_ERROR(X509_NOT_OK):
78  case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
79  case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
80  case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
81  case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
82  case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
83  case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
84  case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
85  case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
87  break;
88  case -48: /* unknown ca alert from server */
89  return CURLE_SSL_CACERT;
90  break;
91  case -49: /* access denied alert from server */
93  break;
94  case SSL_ERROR_CONN_LOST:
95  case SSL_ERROR_SOCK_SETUP_FAILURE:
96  case SSL_ERROR_INVALID_HANDSHAKE:
97  case SSL_ERROR_INVALID_PROT_MSG:
98  case SSL_ERROR_INVALID_HMAC:
99  case SSL_ERROR_INVALID_SESSION:
100  case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */
101  case SSL_ERROR_FINISHED_INVALID:
102  case SSL_ERROR_NO_CLIENT_RENOG:
103  default:
105  break;
106  }
107 }
108 
109 static Curl_recv axtls_recv;
110 static Curl_send axtls_send;
111 
112 static void free_ssl_structs(struct ssl_connect_data *connssl)
113 {
114  if(BACKEND->ssl) {
115  ssl_free(BACKEND->ssl);
116  BACKEND->ssl = NULL;
117  }
118  if(BACKEND->ssl_ctx) {
119  ssl_ctx_free(BACKEND->ssl_ctx);
120  BACKEND->ssl_ctx = NULL;
121  }
122 }
123 
124 /*
125  * For both blocking and non-blocking connects, this function sets up the
126  * ssl context and state. This function is called after the TCP connect
127  * has completed.
128  */
129 static CURLcode connect_prep(struct connectdata *conn, int sockindex)
130 {
131  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
132  struct Curl_easy *data = conn->data;
133  SSL_CTX *ssl_ctx;
134  SSL *ssl = NULL;
135  int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
136  int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
137  int i, ssl_fcn_return;
138 
139  /* Assuming users will not compile in custom key/cert to axTLS.
140  * Also, even for blocking connects, use axTLS non-blocking feature.
141  */
142  uint32_t client_option = SSL_NO_DEFAULT_KEY |
143  SSL_SERVER_VERIFY_LATER |
144  SSL_CONNECT_IN_PARTS;
145 
146  if(connssl->state == ssl_connection_complete)
147  /* to make us tolerant against being called more than once for the
148  same connection */
149  return CURLE_OK;
150 
151  if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
152  failf(data, "axtls does not support CURL_SSLVERSION_MAX");
154  }
155 
156 
157  /* axTLS only supports TLSv1 */
158  /* check to see if we've been told to use an explicit SSL/TLS version */
159  switch(SSL_CONN_CONFIG(version)) {
162  break;
163  default:
164  failf(data, "axTLS only supports TLS 1.0 and 1.1, "
165  "and it cannot be specified which one to use");
167  }
168 
169 #ifdef AXTLSDEBUG
170  client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
171 #endif /* AXTLSDEBUG */
172 
173  /* Allocate an SSL_CTX struct */
174  ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
175  if(ssl_ctx == NULL) {
176  failf(data, "unable to create client SSL context");
178  }
179 
180  BACKEND->ssl_ctx = ssl_ctx;
181  BACKEND->ssl = NULL;
182 
183  /* Load the trusted CA cert bundle file */
184  if(SSL_CONN_CONFIG(CAfile)) {
185  if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
186  SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
187  infof(data, "error reading ca cert file %s \n",
188  SSL_CONN_CONFIG(CAfile));
189  if(SSL_CONN_CONFIG(verifypeer)) {
191  }
192  }
193  else
194  infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
195  }
196 
197  /* gtls.c tasks we're skipping for now:
198  * 1) certificate revocation list checking
199  * 2) dns name assignment to host
200  * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
201  * 4) set certificate priority. axTLS ignores type and sends certs in
202  * order added. can probably ignore this.
203  */
204 
205  /* Load client certificate */
206  if(SSL_SET_OPTION(cert)) {
207  i = 0;
208  /* Instead of trying to analyze cert type here, let axTLS try them all. */
209  while(cert_types[i] != 0) {
210  ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
211  SSL_SET_OPTION(cert), NULL);
212  if(ssl_fcn_return == SSL_OK) {
213  infof(data, "successfully read cert file %s \n",
214  SSL_SET_OPTION(cert));
215  break;
216  }
217  i++;
218  }
219  /* Tried all cert types, none worked. */
220  if(cert_types[i] == 0) {
221  failf(data, "%s is not x509 or pkcs12 format",
222  SSL_SET_OPTION(cert));
223  return CURLE_SSL_CERTPROBLEM;
224  }
225  }
226 
227  /* Load client key.
228  If a pkcs12 file successfully loaded a cert, then there's nothing to do
229  because the key has already been loaded. */
230  if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
231  i = 0;
232  /* Instead of trying to analyze key type here, let axTLS try them all. */
233  while(key_types[i] != 0) {
234  ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
235  SSL_SET_OPTION(key), NULL);
236  if(ssl_fcn_return == SSL_OK) {
237  infof(data, "successfully read key file %s \n",
239  break;
240  }
241  i++;
242  }
243  /* Tried all key types, none worked. */
244  if(key_types[i] == 0) {
245  failf(data, "Failure: %s is not a supported key file",
248  }
249  }
250 
251  /* gtls.c does more here that is being left out for now
252  * 1) set session credentials. can probably ignore since axtls puts this
253  * info in the ssl_ctx struct
254  * 2) setting up callbacks. these seem gnutls specific
255  */
256 
257  if(SSL_SET_OPTION(primary.sessionid)) {
258  const uint8_t *ssl_sessionid;
259  size_t ssl_idsize;
260 
261  /* In axTLS, handshaking happens inside ssl_client_new. */
262  Curl_ssl_sessionid_lock(conn);
263  if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
264  sockindex)) {
265  /* we got a session id, use it! */
266  infof(data, "SSL re-using session ID\n");
267  ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
268  ssl_sessionid, (uint8_t)ssl_idsize, NULL);
269  }
270  Curl_ssl_sessionid_unlock(conn);
271  }
272 
273  if(!ssl)
274  ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
275 
276  BACKEND->ssl = ssl;
277  return CURLE_OK;
278 }
279 
280 static void Curl_axtls_close(struct connectdata *conn, int sockindex)
281 {
282  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
283 
284  infof(conn->data, " Curl_axtls_close\n");
285 
286  /* line from openssl.c: (void)SSL_shutdown(BACKEND->ssl);
287  axTLS compat layer does nothing for SSL_shutdown */
288 
289  /* The following line is from openssl.c. There seems to be no axTLS
290  equivalent. ssl_free and ssl_ctx_free close things.
291  SSL_set_connect_state(connssl->handle); */
292 
293  free_ssl_structs(connssl);
294 }
295 
296 /*
297  * For both blocking and non-blocking connects, this function finalizes the
298  * SSL connection.
299  */
300 static CURLcode connect_finish(struct connectdata *conn, int sockindex)
301 {
302  struct Curl_easy *data = conn->data;
303  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
304  SSL *ssl = BACKEND->ssl;
305  const char *peer_CN;
306  uint32_t dns_altname_index;
307  const char *dns_altname;
308  int8_t found_subject_alt_names = 0;
309  int8_t found_subject_alt_name_matching_conn = 0;
310  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
311  conn->host.name;
312  const char * const dispname = SSL_IS_PROXY() ?
313  conn->http_proxy.host.dispname : conn->host.dispname;
314 
315  /* Here, gtls.c gets the peer certificates and fails out depending on
316  * settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
317  */
318 
319  /* Verify server's certificate */
320  if(SSL_CONN_CONFIG(verifypeer)) {
321  if(ssl_verify_cert(ssl) != SSL_OK) {
322  Curl_axtls_close(conn, sockindex);
323  failf(data, "server cert verify failed");
325  }
326  }
327  else
328  infof(data, "\t server certificate verification SKIPPED\n");
329 
330  /* Here, gtls.c does issuer verification. axTLS has no straightforward
331  * equivalent, so omitting for now.*/
332 
333  /* Here, gtls.c does the following
334  * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
335  * it seems useful. This is now implemented, by Oscar Koeroo
336  * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
337  * 3) displays a bunch of cert information. axTLS doesn't support most of
338  * this, but a couple fields are available.
339  */
340 
341  /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
342  risk of an inifite loop */
343  for(dns_altname_index = 0; ; dns_altname_index++) {
344  dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
345  if(dns_altname == NULL) {
346  break;
347  }
348  found_subject_alt_names = 1;
349 
350  infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
351  dns_altname, hostname);
352  if(Curl_cert_hostcheck(dns_altname, hostname)) {
353  found_subject_alt_name_matching_conn = 1;
354  break;
355  }
356  }
357 
358  /* RFC2818 checks */
359  if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
360  if(SSL_CONN_CONFIG(verifyhost)) {
361  /* Break connection ! */
362  Curl_axtls_close(conn, sockindex);
363  failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
365  }
366  else
367  infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
368  }
369  else if(found_subject_alt_names == 0) {
370  /* Per RFC2818, when no Subject Alt Names were available, examine the peer
371  CN as a legacy fallback */
372  peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
373  if(peer_CN == NULL) {
374  if(SSL_CONN_CONFIG(verifyhost)) {
375  Curl_axtls_close(conn, sockindex);
376  failf(data, "unable to obtain common name from peer certificate");
378  }
379  else
380  infof(data, "unable to obtain common name from peer certificate");
381  }
382  else {
383  if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
384  if(SSL_CONN_CONFIG(verifyhost)) {
385  /* Break connection ! */
386  Curl_axtls_close(conn, sockindex);
387  failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
388  peer_CN, dispname);
390  }
391  else
392  infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
393  peer_CN, dispname);
394  }
395  }
396  }
397 
398  /* General housekeeping */
399  connssl->state = ssl_connection_complete;
400  conn->recv[sockindex] = axtls_recv;
401  conn->send[sockindex] = axtls_send;
402 
403  /* Put our freshly minted SSL session in cache */
404  if(SSL_SET_OPTION(primary.sessionid)) {
405  const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
406  size_t ssl_idsize = ssl_get_session_id_size(ssl);
407  Curl_ssl_sessionid_lock(conn);
408  if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
409  sockindex) != CURLE_OK)
410  infof(data, "failed to add session to cache\n");
411  Curl_ssl_sessionid_unlock(conn);
412  }
413 
414  return CURLE_OK;
415 }
416 
417 /*
418  * Use axTLS's non-blocking connection feature to open an SSL connection.
419  * This is called after a TCP connection is already established.
420  */
421 static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
422  int sockindex, bool *done)
423 {
424  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
425  CURLcode conn_step;
426  int ssl_fcn_return;
427  int i;
428 
429  *done = FALSE;
430  /* connectdata is calloc'd and connecting_state is only changed in this
431  function, so this is safe, as the state is effectively initialized. */
432  if(connssl->connecting_state == ssl_connect_1) {
433  conn_step = connect_prep(conn, sockindex);
434  if(conn_step != CURLE_OK) {
435  Curl_axtls_close(conn, sockindex);
436  return conn_step;
437  }
438  connssl->connecting_state = ssl_connect_2;
439  }
440 
441  if(connssl->connecting_state == ssl_connect_2) {
442  /* Check to make sure handshake was ok. */
443  if(ssl_handshake_status(BACKEND->ssl) != SSL_OK) {
444  /* Loop to perform more work in between sleeps. This is work around the
445  fact that axtls does not expose any knowledge about when work needs
446  to be performed. This can save ~25% of time on SSL handshakes. */
447  for(i = 0; i<5; i++) {
448  ssl_fcn_return = ssl_read(BACKEND->ssl, NULL);
449  if(ssl_fcn_return < 0) {
450  Curl_axtls_close(conn, sockindex);
451  ssl_display_error(ssl_fcn_return); /* goes to stdout. */
452  return map_error_to_curl(ssl_fcn_return);
453  }
454  return CURLE_OK;
455  }
456  }
457  infof(conn->data, "handshake completed successfully\n");
458  connssl->connecting_state = ssl_connect_3;
459  }
460 
461  if(connssl->connecting_state == ssl_connect_3) {
462  conn_step = connect_finish(conn, sockindex);
463  if(conn_step != CURLE_OK) {
464  Curl_axtls_close(conn, sockindex);
465  return conn_step;
466  }
467 
468  /* Reset connect state */
469  connssl->connecting_state = ssl_connect_1;
470 
471  *done = TRUE;
472  return CURLE_OK;
473  }
474 
475  /* Unrecognized state. Things are very bad. */
476  connssl->state = ssl_connection_none;
477  connssl->connecting_state = ssl_connect_1;
478  /* Return value perhaps not strictly correct, but distinguishes the issue.*/
480 }
481 
482 
483 /*
484  * This function is called after the TCP connect has completed. Setup the TLS
485  * layer and do all necessary magic for a blocking connect.
486  */
487 static CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex)
488 {
489  struct Curl_easy *data = conn->data;
490  CURLcode conn_step = connect_prep(conn, sockindex);
491  int ssl_fcn_return;
492  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
493  SSL *ssl = BACKEND->ssl;
494  long timeout_ms;
495 
496  if(conn_step != CURLE_OK) {
497  Curl_axtls_close(conn, sockindex);
498  return conn_step;
499  }
500 
501  /* Check to make sure handshake was ok. */
502  while(ssl_handshake_status(ssl) != SSL_OK) {
503  /* check allowed time left */
504  timeout_ms = Curl_timeleft(data, NULL, TRUE);
505 
506  if(timeout_ms < 0) {
507  /* no need to continue if time already is up */
508  failf(data, "SSL connection timeout");
510  }
511 
512  ssl_fcn_return = ssl_read(ssl, NULL);
513  if(ssl_fcn_return < 0) {
514  Curl_axtls_close(conn, sockindex);
515  ssl_display_error(ssl_fcn_return); /* goes to stdout. */
516  return map_error_to_curl(ssl_fcn_return);
517  }
518  /* TODO: avoid polling */
519  Curl_wait_ms(10);
520  }
521  infof(conn->data, "handshake completed successfully\n");
522 
523  conn_step = connect_finish(conn, sockindex);
524  if(conn_step != CURLE_OK) {
525  Curl_axtls_close(conn, sockindex);
526  return conn_step;
527  }
528 
529  return CURLE_OK;
530 }
531 
532 /* return number of sent (non-SSL) bytes */
533 static ssize_t axtls_send(struct connectdata *conn,
534  int sockindex,
535  const void *mem,
536  size_t len,
537  CURLcode *err)
538 {
539  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
540  /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
541  int rc = ssl_write(BACKEND->ssl, mem, (int)len);
542 
543  infof(conn->data, " axtls_send\n");
544 
545  if(rc < 0) {
546  *err = map_error_to_curl(rc);
547  rc = -1; /* generic error code for send failure */
548  }
549 
550  *err = CURLE_OK;
551  return rc;
552 }
553 
554 /*
555  * This function is called to shut down the SSL layer but keep the
556  * socket open (CCC - Clear Command Channel)
557  */
558 static int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
559 {
560  /* Outline taken from openssl.c since functions are in axTLS compat layer.
561  axTLS's error set is much smaller, so a lot of error-handling was removed.
562  */
563  int retval = 0;
564  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
565  struct Curl_easy *data = conn->data;
566  uint8_t *buf;
567  ssize_t nread;
568 
569  infof(conn->data, " Curl_axtls_shutdown\n");
570 
571  /* This has only been tested on the proftpd server, and the mod_tls code
572  sends a close notify alert without waiting for a close notify alert in
573  response. Thus we wait for a close notify alert from the server, but
574  we do not send one. Let's hope other servers do the same... */
575 
576  /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
577  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
578  (void)SSL_shutdown(BACKEND->ssl);
579  */
580 
581  if(BACKEND->ssl) {
582  int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
583  if(what > 0) {
584  /* Something to read, let's do it and hope that it is the close
585  notify alert from the server. buf is managed internally by
586  axTLS and will be released upon calling ssl_free via
587  free_ssl_structs. */
588  nread = (ssize_t)ssl_read(BACKEND->ssl, &buf);
589 
590  if(nread < SSL_OK) {
591  failf(data, "close notify alert not received during shutdown");
592  retval = -1;
593  }
594  }
595  else if(0 == what) {
596  /* timeout */
597  failf(data, "SSL shutdown timeout");
598  }
599  else {
600  /* anything that gets here is fatally bad */
601  failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
602  retval = -1;
603  }
604 
605  free_ssl_structs(connssl);
606  }
607  return retval;
608 }
609 
610 static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
611  int num, /* socketindex */
612  char *buf, /* store read data here */
613  size_t buffersize, /* max amount to read */
614  CURLcode *err)
615 {
616  struct ssl_connect_data *connssl = &conn->ssl[num];
617  ssize_t ret = 0;
618  uint8_t *read_buf;
619 
620  infof(conn->data, " axtls_recv\n");
621 
622  *err = CURLE_OK;
623  if(connssl) {
624  ret = ssl_read(BACKEND->ssl, &read_buf);
625  if(ret > SSL_OK) {
626  /* ssl_read returns SSL_OK if there is more data to read, so if it is
627  larger, then all data has been read already. */
628  memcpy(buf, read_buf,
629  (size_t)ret > buffersize ? buffersize : (size_t)ret);
630  }
631  else if(ret == SSL_OK) {
632  /* more data to be read, signal caller to call again */
633  *err = CURLE_AGAIN;
634  ret = -1;
635  }
636  else if(ret == -3) {
637  /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
638  team approves proposed fix. */
639  Curl_axtls_close(conn, num);
640  }
641  else {
642  failf(conn->data, "axTLS recv error (%d)", ret);
643  *err = map_error_to_curl((int) ret);
644  ret = -1;
645  }
646  }
647 
648  return ret;
649 }
650 
651 /*
652  * Return codes:
653  * 1 means the connection is still in place
654  * 0 means the connection has been closed
655  * -1 means the connection status is unknown
656  */
657 static int Curl_axtls_check_cxn(struct connectdata *conn)
658 {
659  /* openssl.c line:
660  rc = SSL_peek(conn->ssl[FIRSTSOCKET].backend->ssl, (void*)&buf, 1);
661  axTLS compat layer always returns the last argument, so connection is
662  always alive? */
663 
664  infof(conn->data, " Curl_axtls_check_cxn\n");
665  return 1; /* connection still in place */
666 }
667 
668 static void Curl_axtls_session_free(void *ptr)
669 {
670  (void)ptr;
671  /* free the ID */
672  /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
673  compatibility layer does nothing, so we do nothing too. */
674 }
675 
676 static size_t Curl_axtls_version(char *buffer, size_t size)
677 {
678  return snprintf(buffer, size, "axTLS/%s", ssl_version());
679 }
680 
681 static CURLcode Curl_axtls_random(struct Curl_easy *data,
682  unsigned char *entropy, size_t length)
683 {
684  static bool ssl_seeded = FALSE;
685  (void)data;
686  if(!ssl_seeded) {
687  ssl_seeded = TRUE;
688  /* Initialize the seed if not already done. This call is not exactly thread
689  * safe (and neither is the ssl_seeded check), but the worst effect of a
690  * race condition is that some global resources will leak. */
691  RNG_initialize();
692  }
693  get_random((int)length, entropy);
694  return CURLE_OK;
695 }
696 
697 static void *Curl_axtls_get_internals(struct ssl_connect_data *connssl,
698  CURLINFO info UNUSED_PARAM)
699 {
700  (void)info;
701  return BACKEND->ssl;
702 }
703 
704 const struct Curl_ssl Curl_ssl_axtls = {
705  { CURLSSLBACKEND_AXTLS, "axtls" }, /* info */
706 
707  0, /* have_ca_path */
708  0, /* have_certinfo */
709  0, /* have_pinnedpubkey */
710  0, /* have_ssl_ctx */
711  0, /* support_https_proxy */
712 
713  sizeof(struct ssl_backend_data),
714 
715  /*
716  * axTLS has no global init. Everything is done through SSL and SSL_CTX
717  * structs stored in connectdata structure.
718  */
719  Curl_none_init, /* init */
720  /* axTLS has no global cleanup. */
721  Curl_none_cleanup, /* cleanup */
722  Curl_axtls_version, /* version */
723  Curl_axtls_check_cxn, /* check_cxn */
724  Curl_axtls_shutdown, /* shutdown */
725  Curl_none_data_pending, /* data_pending */
726  Curl_axtls_random, /* random */
727  Curl_none_cert_status_request, /* cert_status_request */
728  Curl_axtls_connect, /* connect */
729  Curl_axtls_connect_nonblocking, /* connect_nonblocking */
730  Curl_axtls_get_internals, /* get_internals */
731  Curl_axtls_close, /* close */
732  Curl_none_close_all, /* close_all */
733  Curl_axtls_session_free, /* session_free */
734  Curl_none_set_engine, /* set_engine */
735  Curl_none_set_engine_default, /* set_engine_default */
736  Curl_none_engines_list, /* engines_list */
737  Curl_none_false_start, /* false_start */
738  Curl_none_md5sum, /* md5sum */
739  NULL /* sha256sum */
740 };
741 
742 #endif /* USE_AXTLS */
struct ssl_connect_data ssl[2]
Definition: urldata.h:887
#define UNUSED_PARAM
Definition: curl_setup.h:660
ssize_t( Curl_recv)(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err)
Definition: urldata.h:737
Curl_recv * recv[2]
Definition: urldata.h:881
#define SSL_CONN_CONFIG(var)
Definition: vtls.h:135
struct hostname host
Definition: urldata.h:758
Definition: vtls.h:29
int Curl_none_init(void)
#define failf
Definition: sendf.h:48
#define SSL_SET_OPTION(var)
Definition: vtls.h:133
ssl_connect_state connecting_state
Definition: urldata.h:201
#define SOCKERRNO
UNITTEST_START char * ptr
Definition: unit1330.c:38
CURLcode
Definition: curl.h:454
CURLINFO
Definition: curl.h:2439
bool Curl_none_data_pending(const struct connectdata *conn, int connindex)
struct hostname host
Definition: urldata.h:833
char * name
Definition: urldata.h:444
char buffer[]
Definition: unit1308.c:48
unsigned int i
Definition: unit1303.c:79
size_t len
Definition: curl_sasl.c:55
struct proxy_info http_proxy
Definition: urldata.h:839
ssl_connection_state state
Definition: urldata.h:200
memcpy(filename, filename1, strlen(filename1))
int Curl_wait_ms(int timeout_ms)
Definition: select.c:75
#define FALSE
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
Definition: connect.c:182
UNITTEST_START int rc
Definition: unit1301.c:31
bool Curl_none_false_start(void)
#define SOCKET_READABLE(x, z)
Definition: select.h:79
bool Curl_none_cert_status_request(void)
void Curl_none_cleanup(void)
Curl_send * send[2]
Definition: urldata.h:882
Definition: curl.h:455
ssize_t( Curl_send)(struct connectdata *conn, int sockindex, const void *buf, size_t len, CURLcode *err)
Definition: urldata.h:730
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5len)
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine)
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
#define ssize_t
Definition: config-win32.h:382
curl_socket_t sock[2]
Definition: urldata.h:876
struct curl_slist * Curl_none_engines_list(struct Curl_easy *data)
char buf[3]
Definition: unit1398.c:32
#define infof
Definition: sendf.h:44
size_t size
Definition: unit1302.c:52
#define snprintf
Definition: curl_printf.h:42
#define TRUE
void * SSL
Definition: net_skeleton.h:128
const char * dispname
Definition: urldata.h:445
int key
Definition: unit1602.c:56
CURLcode Curl_none_set_engine_default(struct Curl_easy *data)
Definition: debug.c:29
void Curl_none_close_all(struct Curl_easy *data)
#define SSL_IS_PROXY()
Definition: vtls.h:130
void * SSL_CTX
Definition: net_skeleton.h:129
struct Curl_easy * data
Definition: urldata.h:791


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:08