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() */
Curl_axtls_init(void)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
Curl_axtls_cleanup(void)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
map_error_to_curl(int axtls_err)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
free_ssl_structs(struct ssl_connect_data * connssl)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 */
connect_prep(struct connectdata * conn,int sockindex)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(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 */
connect_finish(struct connectdata * conn,int sockindex)286 static 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 */
Curl_axtls_connect_nonblocking(struct connectdata * conn,int sockindex,bool * done)406 CURLcode 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 */
473 CURLcode
Curl_axtls_connect(struct connectdata * conn,int sockindex)474 Curl_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 */
axtls_send(struct connectdata * conn,int sockindex,const void * mem,size_t len,CURLcode * err)521 static 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
Curl_axtls_close(struct connectdata * conn,int sockindex)541 void 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 */
Curl_axtls_shutdown(struct connectdata * conn,int sockindex)561 int 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
axtls_recv(struct connectdata * conn,int num,char * buf,size_t buffersize,CURLcode * err)613 static 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 */
Curl_axtls_check_cxn(struct connectdata * conn)660 int 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
Curl_axtls_session_free(void * ptr)670 void 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
Curl_axtls_version(char * buffer,size_t size)678 size_t Curl_axtls_version(char *buffer, size_t size)
679 {
680 return snprintf(buffer, size, "axTLS/%s", ssl_version());
681 }
682
Curl_axtls_random(struct Curl_easy * data,unsigned char * entropy,size_t length)683 int 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