1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu (at) directv.com>. 9 * Copyright (C) 2010 - 2016, Daniel Stenberg, <daniel (at) 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 */ 699