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