00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "curl_setup.h"
00030
00031 #ifdef USE_AXTLS
00032 #include <axTLS/config.h>
00033 #include <axTLS/ssl.h>
00034 #include "axtls.h"
00035
00036 #include "sendf.h"
00037 #include "inet_pton.h"
00038 #include "vtls.h"
00039 #include "parsedate.h"
00040 #include "connect.h"
00041 #include "select.h"
00042 #include "curl_printf.h"
00043 #include "hostcheck.h"
00044 #include <unistd.h>
00045
00046
00047 #include "curl_memory.h"
00048 #include "memdebug.h"
00049
00050
00051
00052 int Curl_axtls_init(void)
00053 {
00054
00055
00056
00057 return 1;
00058 }
00059
00060 int Curl_axtls_cleanup(void)
00061 {
00062
00063 return 1;
00064 }
00065
00066 static CURLcode map_error_to_curl(int axtls_err)
00067 {
00068 switch(axtls_err) {
00069 case SSL_ERROR_NOT_SUPPORTED:
00070 case SSL_ERROR_INVALID_VERSION:
00071 case -70:
00072 return CURLE_UNSUPPORTED_PROTOCOL;
00073 break;
00074 case SSL_ERROR_NO_CIPHER:
00075 return CURLE_SSL_CIPHER;
00076 break;
00077 case SSL_ERROR_BAD_CERTIFICATE:
00078 case SSL_ERROR_NO_CERT_DEFINED:
00079 case -42:
00080 case -43:
00081 case -44:
00082 case -45:
00083 case -46:
00084 return CURLE_SSL_CERTPROBLEM;
00085 break;
00086 case SSL_X509_ERROR(X509_NOT_OK):
00087 case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
00088 case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
00089 case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
00090 case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
00091 case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
00092 case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
00093 case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
00094 case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
00095 return CURLE_PEER_FAILED_VERIFICATION;
00096 break;
00097 case -48:
00098 return CURLE_SSL_CACERT;
00099 break;
00100 case -49:
00101 return CURLE_REMOTE_ACCESS_DENIED;
00102 break;
00103 case SSL_ERROR_CONN_LOST:
00104 case SSL_ERROR_SOCK_SETUP_FAILURE:
00105 case SSL_ERROR_INVALID_HANDSHAKE:
00106 case SSL_ERROR_INVALID_PROT_MSG:
00107 case SSL_ERROR_INVALID_HMAC:
00108 case SSL_ERROR_INVALID_SESSION:
00109 case SSL_ERROR_INVALID_KEY:
00110 case SSL_ERROR_FINISHED_INVALID:
00111 case SSL_ERROR_NO_CLIENT_RENOG:
00112 default:
00113 return CURLE_SSL_CONNECT_ERROR;
00114 break;
00115 }
00116 }
00117
00118 static Curl_recv axtls_recv;
00119 static Curl_send axtls_send;
00120
00121 static void free_ssl_structs(struct ssl_connect_data *connssl)
00122 {
00123 if(connssl->ssl) {
00124 ssl_free(connssl->ssl);
00125 connssl->ssl = NULL;
00126 }
00127 if(connssl->ssl_ctx) {
00128 ssl_ctx_free(connssl->ssl_ctx);
00129 connssl->ssl_ctx = NULL;
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138 static CURLcode connect_prep(struct connectdata *conn, int sockindex)
00139 {
00140 struct Curl_easy *data = conn->data;
00141 SSL_CTX *ssl_ctx;
00142 SSL *ssl = NULL;
00143 int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
00144 int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
00145 int i, ssl_fcn_return;
00146
00147
00148
00149
00150 uint32_t client_option = SSL_NO_DEFAULT_KEY |
00151 SSL_SERVER_VERIFY_LATER |
00152 SSL_CONNECT_IN_PARTS;
00153
00154 if(conn->ssl[sockindex].state == ssl_connection_complete)
00155
00156
00157 return CURLE_OK;
00158
00159
00160
00161 switch(SSL_CONN_CONFIG(version)) {
00162 case CURL_SSLVERSION_DEFAULT:
00163 case CURL_SSLVERSION_TLSv1:
00164 break;
00165 default:
00166 failf(data, "axTLS only supports TLS 1.0 and 1.1, "
00167 "and it cannot be specified which one to use");
00168 return CURLE_SSL_CONNECT_ERROR;
00169 }
00170
00171 #ifdef AXTLSDEBUG
00172 client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
00173 #endif
00174
00175
00176 ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
00177 if(ssl_ctx == NULL) {
00178 failf(data, "unable to create client SSL context");
00179 return CURLE_SSL_CONNECT_ERROR;
00180 }
00181
00182 conn->ssl[sockindex].ssl_ctx = ssl_ctx;
00183 conn->ssl[sockindex].ssl = NULL;
00184
00185
00186 if(SSL_CONN_CONFIG(CAfile)) {
00187 if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
00188 SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
00189 infof(data, "error reading ca cert file %s \n",
00190 SSL_CONN_CONFIG(CAfile));
00191 if(SSL_CONN_CONFIG(verifypeer)) {
00192 return CURLE_SSL_CACERT_BADFILE;
00193 }
00194 }
00195 else
00196 infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 if(SSL_SET_OPTION(cert)) {
00209 i=0;
00210
00211 while(cert_types[i] != 0) {
00212 ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
00213 SSL_SET_OPTION(cert), NULL);
00214 if(ssl_fcn_return == SSL_OK) {
00215 infof(data, "successfully read cert file %s \n",
00216 SSL_SET_OPTION(cert));
00217 break;
00218 }
00219 i++;
00220 }
00221
00222 if(cert_types[i] == 0) {
00223 failf(data, "%s is not x509 or pkcs12 format",
00224 SSL_SET_OPTION(cert));
00225 return CURLE_SSL_CERTPROBLEM;
00226 }
00227 }
00228
00229
00230
00231
00232 if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
00233 i=0;
00234
00235 while(key_types[i] != 0) {
00236 ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
00237 SSL_SET_OPTION(key), NULL);
00238 if(ssl_fcn_return == SSL_OK) {
00239 infof(data, "successfully read key file %s \n",
00240 SSL_SET_OPTION(key));
00241 break;
00242 }
00243 i++;
00244 }
00245
00246 if(key_types[i] == 0) {
00247 failf(data, "Failure: %s is not a supported key file",
00248 SSL_SET_OPTION(key));
00249 return CURLE_SSL_CONNECT_ERROR;
00250 }
00251 }
00252
00253
00254
00255
00256
00257
00258
00259 if(data->set.general_ssl.sessionid) {
00260 const uint8_t *ssl_sessionid;
00261 size_t ssl_idsize;
00262
00263
00264 Curl_ssl_sessionid_lock(conn);
00265 if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
00266 sockindex)) {
00267
00268 infof(data, "SSL re-using session ID\n");
00269 ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
00270 ssl_sessionid, (uint8_t)ssl_idsize);
00271 }
00272 Curl_ssl_sessionid_unlock(conn);
00273 }
00274
00275 if(!ssl)
00276 ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
00277
00278 conn->ssl[sockindex].ssl = ssl;
00279 return CURLE_OK;
00280 }
00281
00282
00283
00284
00285
00286 static CURLcode connect_finish(struct connectdata *conn, int sockindex)
00287 {
00288 struct Curl_easy *data = conn->data;
00289 SSL *ssl = conn->ssl[sockindex].ssl;
00290 const char *peer_CN;
00291 uint32_t dns_altname_index;
00292 const char *dns_altname;
00293 int8_t found_subject_alt_names = 0;
00294 int8_t found_subject_alt_name_matching_conn = 0;
00295 const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
00296 conn->host.name;
00297 const char * const dispname = SSL_IS_PROXY() ?
00298 conn->http_proxy.host.dispname : conn->host.dispname;
00299
00300
00301
00302
00303
00304
00305 if(SSL_CONN_CONFIG(verifypeer)) {
00306 if(ssl_verify_cert(ssl) != SSL_OK) {
00307 Curl_axtls_close(conn, sockindex);
00308 failf(data, "server cert verify failed");
00309 return CURLE_PEER_FAILED_VERIFICATION;
00310 }
00311 }
00312 else
00313 infof(data, "\t server certificate verification SKIPPED\n");
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 for(dns_altname_index = 0; ; dns_altname_index++) {
00329 dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
00330 if(dns_altname == NULL) {
00331 break;
00332 }
00333 found_subject_alt_names = 1;
00334
00335 infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
00336 dns_altname, hostname);
00337 if(Curl_cert_hostcheck(dns_altname, hostname)) {
00338 found_subject_alt_name_matching_conn = 1;
00339 break;
00340 }
00341 }
00342
00343
00344 if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
00345 if(SSL_CONN_CONFIG(verifyhost)) {
00346
00347 Curl_axtls_close(conn, sockindex);
00348 failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
00349 return CURLE_PEER_FAILED_VERIFICATION;
00350 }
00351 else
00352 infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
00353 }
00354 else if(found_subject_alt_names == 0) {
00355
00356
00357 peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
00358 if(peer_CN == NULL) {
00359 if(SSL_CONN_CONFIG(verifyhost)) {
00360 Curl_axtls_close(conn, sockindex);
00361 failf(data, "unable to obtain common name from peer certificate");
00362 return CURLE_PEER_FAILED_VERIFICATION;
00363 }
00364 else
00365 infof(data, "unable to obtain common name from peer certificate");
00366 }
00367 else {
00368 if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
00369 if(SSL_CONN_CONFIG(verifyhost)) {
00370
00371 Curl_axtls_close(conn, sockindex);
00372 failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
00373 peer_CN, dispname);
00374 return CURLE_PEER_FAILED_VERIFICATION;
00375 }
00376 else
00377 infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
00378 peer_CN, dispname);
00379 }
00380 }
00381 }
00382
00383
00384 conn->ssl[sockindex].state = ssl_connection_complete;
00385 conn->recv[sockindex] = axtls_recv;
00386 conn->send[sockindex] = axtls_send;
00387
00388
00389 if(data->set.general_ssl.sessionid) {
00390 const uint8_t *ssl_sessionid = ssl_get_session_id_size(ssl);
00391 size_t ssl_idsize = ssl_get_session_id(ssl);
00392 Curl_ssl_sessionid_lock(conn);
00393 if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
00394 sockindex) != CURLE_OK)
00395 infof(data, "failed to add session to cache\n");
00396 Curl_ssl_sessionid_unlock(conn);
00397 }
00398
00399 return CURLE_OK;
00400 }
00401
00402
00403
00404
00405
00406 CURLcode Curl_axtls_connect_nonblocking(
00407 struct connectdata *conn,
00408 int sockindex,
00409 bool *done)
00410 {
00411 CURLcode conn_step;
00412 int ssl_fcn_return;
00413 int i;
00414
00415 *done = FALSE;
00416
00417
00418 if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
00419 conn_step = connect_prep(conn, sockindex);
00420 if(conn_step != CURLE_OK) {
00421 Curl_axtls_close(conn, sockindex);
00422 return conn_step;
00423 }
00424 conn->ssl[sockindex].connecting_state = ssl_connect_2;
00425 }
00426
00427 if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
00428
00429 if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
00430
00431
00432
00433 for(i=0; i<5; i++) {
00434 ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
00435 if(ssl_fcn_return < 0) {
00436 Curl_axtls_close(conn, sockindex);
00437 ssl_display_error(ssl_fcn_return);
00438 return map_error_to_curl(ssl_fcn_return);
00439 }
00440 return CURLE_OK;
00441 }
00442 }
00443 infof(conn->data, "handshake completed successfully\n");
00444 conn->ssl[sockindex].connecting_state = ssl_connect_3;
00445 }
00446
00447 if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
00448 conn_step = connect_finish(conn, sockindex);
00449 if(conn_step != CURLE_OK) {
00450 Curl_axtls_close(conn, sockindex);
00451 return conn_step;
00452 }
00453
00454
00455 conn->ssl[sockindex].connecting_state = ssl_connect_1;
00456
00457 *done = TRUE;
00458 return CURLE_OK;
00459 }
00460
00461
00462 conn->ssl[sockindex].state = ssl_connection_none;
00463 conn->ssl[sockindex].connecting_state = ssl_connect_1;
00464
00465 return CURLE_BAD_FUNCTION_ARGUMENT;
00466 }
00467
00468
00469
00470
00471
00472
00473 CURLcode
00474 Curl_axtls_connect(struct connectdata *conn,
00475 int sockindex)
00476
00477 {
00478 struct Curl_easy *data = conn->data;
00479 CURLcode conn_step = connect_prep(conn, sockindex);
00480 int ssl_fcn_return;
00481 SSL *ssl = conn->ssl[sockindex].ssl;
00482 long timeout_ms;
00483
00484 if(conn_step != CURLE_OK) {
00485 Curl_axtls_close(conn, sockindex);
00486 return conn_step;
00487 }
00488
00489
00490 while(ssl_handshake_status(ssl) != SSL_OK) {
00491
00492 timeout_ms = Curl_timeleft(data, NULL, TRUE);
00493
00494 if(timeout_ms < 0) {
00495
00496 failf(data, "SSL connection timeout");
00497 return CURLE_OPERATION_TIMEDOUT;
00498 }
00499
00500 ssl_fcn_return = ssl_read(ssl, NULL);
00501 if(ssl_fcn_return < 0) {
00502 Curl_axtls_close(conn, sockindex);
00503 ssl_display_error(ssl_fcn_return);
00504 return map_error_to_curl(ssl_fcn_return);
00505 }
00506
00507 Curl_wait_ms(10);
00508 }
00509 infof(conn->data, "handshake completed successfully\n");
00510
00511 conn_step = connect_finish(conn, sockindex);
00512 if(conn_step != CURLE_OK) {
00513 Curl_axtls_close(conn, sockindex);
00514 return conn_step;
00515 }
00516
00517 return CURLE_OK;
00518 }
00519
00520
00521 static ssize_t axtls_send(struct connectdata *conn,
00522 int sockindex,
00523 const void *mem,
00524 size_t len,
00525 CURLcode *err)
00526 {
00527
00528 int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
00529
00530 infof(conn->data, " axtls_send\n");
00531
00532 if(rc < 0) {
00533 *err = map_error_to_curl(rc);
00534 rc = -1;
00535 }
00536
00537 *err = CURLE_OK;
00538 return rc;
00539 }
00540
00541 void Curl_axtls_close(struct connectdata *conn, int sockindex)
00542 {
00543 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
00544
00545 infof(conn->data, " Curl_axtls_close\n");
00546
00547
00548
00549
00550
00551
00552
00553
00554 free_ssl_structs(connssl);
00555 }
00556
00557
00558
00559
00560
00561 int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
00562 {
00563
00564
00565
00566 int retval = 0;
00567 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
00568 struct Curl_easy *data = conn->data;
00569 uint8_t *buf;
00570 ssize_t nread;
00571
00572 infof(conn->data, " Curl_axtls_shutdown\n");
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 if(connssl->ssl) {
00585 int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
00586 if(what > 0) {
00587
00588
00589
00590
00591 nread = (ssize_t)ssl_read(connssl->ssl, &buf);
00592
00593 if(nread < SSL_OK) {
00594 failf(data, "close notify alert not received during shutdown");
00595 retval = -1;
00596 }
00597 }
00598 else if(0 == what) {
00599
00600 failf(data, "SSL shutdown timeout");
00601 }
00602 else {
00603
00604 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
00605 retval = -1;
00606 }
00607
00608 free_ssl_structs(connssl);
00609 }
00610 return retval;
00611 }
00612
00613 static ssize_t axtls_recv(struct connectdata *conn,
00614 int num,
00615 char *buf,
00616 size_t buffersize,
00617 CURLcode *err)
00618 {
00619 struct ssl_connect_data *connssl = &conn->ssl[num];
00620 ssize_t ret = 0;
00621 uint8_t *read_buf;
00622
00623 infof(conn->data, " axtls_recv\n");
00624
00625 *err = CURLE_OK;
00626 if(connssl) {
00627 ret = ssl_read(connssl->ssl, &read_buf);
00628 if(ret > SSL_OK) {
00629
00630
00631 memcpy(buf, read_buf,
00632 (size_t)ret > buffersize ? buffersize : (size_t)ret);
00633 }
00634 else if(ret == SSL_OK) {
00635
00636 *err = CURLE_AGAIN;
00637 ret = -1;
00638 }
00639 else if(ret == -3) {
00640
00641
00642 Curl_axtls_close(conn, num);
00643 }
00644 else {
00645 failf(conn->data, "axTLS recv error (%d)", ret);
00646 *err = map_error_to_curl((int) ret);
00647 ret = -1;
00648 }
00649 }
00650
00651 return ret;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660 int Curl_axtls_check_cxn(struct connectdata *conn)
00661 {
00662
00663
00664
00665
00666 infof(conn->data, " Curl_axtls_check_cxn\n");
00667 return 1;
00668 }
00669
00670 void Curl_axtls_session_free(void *ptr)
00671 {
00672 (void)ptr;
00673
00674
00675
00676 }
00677
00678 size_t Curl_axtls_version(char *buffer, size_t size)
00679 {
00680 return snprintf(buffer, size, "axTLS/%s", ssl_version());
00681 }
00682
00683 int Curl_axtls_random(struct Curl_easy *data,
00684 unsigned char *entropy,
00685 size_t length)
00686 {
00687 static bool ssl_seeded = FALSE;
00688 (void)data;
00689 if(!ssl_seeded) {
00690 ssl_seeded = TRUE;
00691
00692
00693
00694 RNG_initialize();
00695 }
00696 get_random((int)length, entropy);
00697 return 0;
00698 }
00699
00700 #endif