b6c69ad51a468093c46cc7c7045a159cb6c53f79
[platform/upstream/curl.git] / lib / vtls / axtls.c
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() */
52 int 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
60 int Curl_axtls_cleanup(void)
61 {
62   /* axTLS has no global cleanup.  Perhaps can move this to axtls.h. */
63   return 1;
64 }
65
66 static 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
118 static Curl_recv axtls_recv;
119 static Curl_send axtls_send;
120
121 static 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  */
138 static 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(data->set.ssl.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(data->set.ssl.CAfile) {
187     if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
188        != SSL_OK) {
189       infof(data, "error reading ca cert file %s \n",
190             data->set.ssl.CAfile);
191       if(data->set.ssl.verifypeer) {
192         return CURLE_SSL_CACERT_BADFILE;
193       }
194     }
195     else
196       infof(data, "found certificates in %s\n", data->set.ssl.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(data->set.str[STRING_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                                     data->set.str[STRING_CERT], NULL);
214       if(ssl_fcn_return == SSL_OK) {
215         infof(data, "successfully read cert file %s \n",
216               data->set.str[STRING_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             data->set.str[STRING_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(data->set.str[STRING_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                                     data->set.str[STRING_KEY], NULL);
238       if(ssl_fcn_return == SSL_OK) {
239         infof(data, "successfully read key file %s \n",
240               data->set.str[STRING_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             data->set.str[STRING_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(conn->ssl_config.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       /* we got a session id, use it! */
267       infof (data, "SSL re-using session ID\n");
268       ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
269                            ssl_sessionid, (uint8_t)ssl_idsize);
270     }
271     Curl_ssl_sessionid_unlock(conn);
272   }
273
274   if(!ssl)
275     ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
276
277   conn->ssl[sockindex].ssl = ssl;
278   return CURLE_OK;
279 }
280
281 /*
282  * For both blocking and non-blocking connects, this function finalizes the
283  * SSL connection.
284  */
285 static CURLcode connect_finish(struct connectdata *conn, int sockindex)
286 {
287   struct Curl_easy *data = conn->data;
288   SSL *ssl = conn->ssl[sockindex].ssl;
289   const char *peer_CN;
290   uint32_t dns_altname_index;
291   const char *dns_altname;
292   int8_t found_subject_alt_names = 0;
293   int8_t found_subject_alt_name_matching_conn = 0;
294
295   /* Here, gtls.c gets the peer certificates and fails out depending on
296    * settings in "data."  axTLS api doesn't have get cert chain fcn, so omit?
297    */
298
299   /* Verify server's certificate */
300   if(data->set.ssl.verifypeer) {
301     if(ssl_verify_cert(ssl) != SSL_OK) {
302       Curl_axtls_close(conn, sockindex);
303       failf(data, "server cert verify failed");
304       return CURLE_PEER_FAILED_VERIFICATION;
305     }
306   }
307   else
308     infof(data, "\t server certificate verification SKIPPED\n");
309
310   /* Here, gtls.c does issuer verification. axTLS has no straightforward
311    * equivalent, so omitting for now.*/
312
313   /* Here, gtls.c does the following
314    * 1) x509 hostname checking per RFC2818.  axTLS doesn't support this, but
315    *    it seems useful. This is now implemented, by Oscar Koeroo
316    * 2) checks cert validity based on time.  axTLS does this in ssl_verify_cert
317    * 3) displays a bunch of cert information.  axTLS doesn't support most of
318    *    this, but a couple fields are available.
319    */
320
321   /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
322      risk of an inifite loop */
323   for(dns_altname_index = 0; ; dns_altname_index++) {
324     dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
325     if(dns_altname == NULL) {
326       break;
327     }
328     found_subject_alt_names = 1;
329
330     infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
331           dns_altname, conn->host.name);
332     if(Curl_cert_hostcheck(dns_altname, conn->host.name)) {
333       found_subject_alt_name_matching_conn = 1;
334       break;
335     }
336   }
337
338   /* RFC2818 checks */
339   if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
340     if(data->set.ssl.verifyhost) {
341       /* Break connection ! */
342       Curl_axtls_close(conn, sockindex);
343       failf(data, "\tsubjectAltName(s) do not match %s\n",
344             conn->host.dispname);
345       return CURLE_PEER_FAILED_VERIFICATION;
346     }
347     else
348       infof(data, "\tsubjectAltName(s) do not match %s\n",
349             conn->host.dispname);
350   }
351   else if(found_subject_alt_names == 0) {
352     /* Per RFC2818, when no Subject Alt Names were available, examine the peer
353        CN as a legacy fallback */
354     peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
355     if(peer_CN == NULL) {
356       if(data->set.ssl.verifyhost) {
357         Curl_axtls_close(conn, sockindex);
358         failf(data, "unable to obtain common name from peer certificate");
359         return CURLE_PEER_FAILED_VERIFICATION;
360       }
361       else
362         infof(data, "unable to obtain common name from peer certificate");
363     }
364     else {
365       if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
366         if(data->set.ssl.verifyhost) {
367           /* Break connection ! */
368           Curl_axtls_close(conn, sockindex);
369           failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
370                 peer_CN, conn->host.dispname);
371           return CURLE_PEER_FAILED_VERIFICATION;
372         }
373         else
374           infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
375                 peer_CN, conn->host.dispname);
376       }
377     }
378   }
379
380   /* General housekeeping */
381   conn->ssl[sockindex].state = ssl_connection_complete;
382   conn->recv[sockindex] = axtls_recv;
383   conn->send[sockindex] = axtls_send;
384
385   /* Put our freshly minted SSL session in cache */
386   if(conn->ssl_config.sessionid) {
387     const uint8_t *ssl_sessionid = ssl_get_session_id_size(ssl);
388     size_t ssl_idsize = ssl_get_session_id(ssl);
389     Curl_ssl_sessionid_lock(conn);
390     if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
391        != CURLE_OK)
392       infof (data, "failed to add session to cache\n");
393     Curl_ssl_sessionid_unlock(conn);
394   }
395
396   return CURLE_OK;
397 }
398
399 /*
400  * Use axTLS's non-blocking connection feature to open an SSL connection.
401  * This is called after a TCP connection is already established.
402  */
403 CURLcode Curl_axtls_connect_nonblocking(
404     struct connectdata *conn,
405     int sockindex,
406     bool *done)
407 {
408   CURLcode conn_step;
409   int ssl_fcn_return;
410   int i;
411
412  *done = FALSE;
413   /* connectdata is calloc'd and connecting_state is only changed in this
414      function, so this is safe, as the state is effectively initialized. */
415   if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
416     conn_step = connect_prep(conn, sockindex);
417     if(conn_step != CURLE_OK) {
418       Curl_axtls_close(conn, sockindex);
419       return conn_step;
420     }
421     conn->ssl[sockindex].connecting_state = ssl_connect_2;
422   }
423
424   if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
425     /* Check to make sure handshake was ok. */
426     if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
427       /* Loop to perform more work in between sleeps. This is work around the
428          fact that axtls does not expose any knowledge about when work needs
429          to be performed. This can save ~25% of time on SSL handshakes. */
430       for(i=0; i<5; i++) {
431         ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
432         if(ssl_fcn_return < 0) {
433           Curl_axtls_close(conn, sockindex);
434           ssl_display_error(ssl_fcn_return); /* goes to stdout. */
435           return map_error_to_curl(ssl_fcn_return);
436         }
437         return CURLE_OK;
438       }
439     }
440     infof (conn->data, "handshake completed successfully\n");
441     conn->ssl[sockindex].connecting_state = ssl_connect_3;
442   }
443
444   if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
445     conn_step = connect_finish(conn, sockindex);
446     if(conn_step != CURLE_OK) {
447       Curl_axtls_close(conn, sockindex);
448       return conn_step;
449     }
450
451     /* Reset connect state */
452     conn->ssl[sockindex].connecting_state = ssl_connect_1;
453
454     *done = TRUE;
455     return CURLE_OK;
456   }
457
458   /* Unrecognized state.  Things are very bad. */
459   conn->ssl[sockindex].state  = ssl_connection_none;
460   conn->ssl[sockindex].connecting_state = ssl_connect_1;
461   /* Return value perhaps not strictly correct, but distinguishes the issue.*/
462   return CURLE_BAD_FUNCTION_ARGUMENT;
463 }
464
465
466 /*
467  * This function is called after the TCP connect has completed. Setup the TLS
468  * layer and do all necessary magic for a blocking connect.
469  */
470 CURLcode
471 Curl_axtls_connect(struct connectdata *conn,
472                   int sockindex)
473
474 {
475   struct Curl_easy *data = conn->data;
476   CURLcode conn_step = connect_prep(conn, sockindex);
477   int ssl_fcn_return;
478   SSL *ssl = conn->ssl[sockindex].ssl;
479   long timeout_ms;
480
481   if(conn_step != CURLE_OK) {
482     Curl_axtls_close(conn, sockindex);
483     return conn_step;
484   }
485
486   /* Check to make sure handshake was ok. */
487   while(ssl_handshake_status(ssl) != SSL_OK) {
488     /* check allowed time left */
489     timeout_ms = Curl_timeleft(data, NULL, TRUE);
490
491     if(timeout_ms < 0) {
492       /* no need to continue if time already is up */
493       failf(data, "SSL connection timeout");
494       return CURLE_OPERATION_TIMEDOUT;
495     }
496
497     ssl_fcn_return = ssl_read(ssl, NULL);
498     if(ssl_fcn_return < 0) {
499       Curl_axtls_close(conn, sockindex);
500       ssl_display_error(ssl_fcn_return); /* goes to stdout. */
501       return map_error_to_curl(ssl_fcn_return);
502     }
503     /* TODO: avoid polling */
504     Curl_wait_ms(10);
505   }
506   infof (conn->data, "handshake completed successfully\n");
507
508   conn_step = connect_finish(conn, sockindex);
509   if(conn_step != CURLE_OK) {
510     Curl_axtls_close(conn, sockindex);
511     return conn_step;
512   }
513
514   return CURLE_OK;
515 }
516
517 /* return number of sent (non-SSL) bytes */
518 static ssize_t axtls_send(struct connectdata *conn,
519                           int sockindex,
520                           const void *mem,
521                           size_t len,
522                           CURLcode *err)
523 {
524   /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
525   int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
526
527   infof(conn->data, "  axtls_send\n");
528
529   if(rc < 0) {
530     *err = map_error_to_curl(rc);
531     rc = -1; /* generic error code for send failure */
532   }
533
534   *err = CURLE_OK;
535   return rc;
536 }
537
538 void Curl_axtls_close(struct connectdata *conn, int sockindex)
539 {
540   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
541
542   infof(conn->data, "  Curl_axtls_close\n");
543
544     /* line from openssl.c: (void)SSL_shutdown(connssl->ssl);
545        axTLS compat layer does nothing for SSL_shutdown */
546
547     /* The following line is from openssl.c.  There seems to be no axTLS
548        equivalent.  ssl_free and ssl_ctx_free close things.
549        SSL_set_connect_state(connssl->handle); */
550
551   free_ssl_structs(connssl);
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 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(connssl->ssl);
579   */
580
581   if(connssl->ssl) {
582     int what = Curl_socket_ready(conn->sock[sockindex],
583                                  CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
584     if(what > 0) {
585       /* Something to read, let's do it and hope that it is the close
586          notify alert from the server.  buf is managed internally by
587          axTLS and will be released upon calling ssl_free via
588          free_ssl_structs. */
589       nread = (ssize_t)ssl_read(connssl->ssl, &buf);
590
591       if(nread < SSL_OK) {
592         failf(data, "close notify alert not received during shutdown");
593         retval = -1;
594       }
595     }
596     else if(0 == what) {
597       /* timeout */
598       failf(data, "SSL shutdown timeout");
599     }
600     else {
601       /* anything that gets here is fatally bad */
602       failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
603       retval = -1;
604     }
605
606     free_ssl_structs(connssl);
607   }
608   return retval;
609 }
610
611 static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
612                           int num,                  /* socketindex */
613                           char *buf,                /* store read data here */
614                           size_t buffersize,        /* max amount to read */
615                           CURLcode *err)
616 {
617   struct ssl_connect_data *connssl = &conn->ssl[num];
618   ssize_t ret = 0;
619   uint8_t *read_buf;
620
621   infof(conn->data, "  axtls_recv\n");
622
623   *err = CURLE_OK;
624   if(connssl) {
625     ret = ssl_read(connssl->ssl, &read_buf);
626     if(ret > SSL_OK) {
627       /* ssl_read returns SSL_OK if there is more data to read, so if it is
628          larger, then all data has been read already.  */
629       memcpy(buf, read_buf,
630              (size_t)ret > buffersize ? buffersize : (size_t)ret);
631     }
632     else if(ret == SSL_OK) {
633       /* more data to be read, signal caller to call again */
634       *err = CURLE_AGAIN;
635       ret = -1;
636     }
637     else if(ret == -3) {
638       /* With patched axTLS, SSL_CLOSE_NOTIFY=-3.  Hard-coding until axTLS
639          team approves proposed fix. */
640       Curl_axtls_close(conn, num);
641     }
642     else {
643       failf(conn->data, "axTLS recv error (%d)", ret);
644       *err = map_error_to_curl((int) ret);
645       ret = -1;
646     }
647   }
648
649   return ret;
650 }
651
652 /*
653  * Return codes:
654  *     1 means the connection is still in place
655  *     0 means the connection has been closed
656  *    -1 means the connection status is unknown
657  */
658 int Curl_axtls_check_cxn(struct connectdata *conn)
659 {
660   /* openssl.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].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 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 size_t Curl_axtls_version(char *buffer, size_t size)
677 {
678   return snprintf(buffer, size, "axTLS/%s", ssl_version());
679 }
680
681 int Curl_axtls_random(struct Curl_easy *data,
682                       unsigned char *entropy,
683                       size_t length)
684 {
685   static bool ssl_seeded = FALSE;
686   (void)data;
687   if(!ssl_seeded) {
688     ssl_seeded = TRUE;
689     /* Initialize the seed if not already done. This call is not exactly thread
690      * safe (and neither is the ssl_seeded check), but the worst effect of a
691      * race condition is that some global resources will leak. */
692     RNG_initialize();
693   }
694   get_random((int)length, entropy);
695   return 0;
696 }
697
698 #endif /* USE_AXTLS */