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