axtls.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
  9. * Copyright (C) 2010 - 2014, 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 http://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. * Source file for all axTLS-specific code for the TLS/SSL layer. No code
  25. * but vtls.c should ever call or use these functions.
  26. */
  27. #include "curl_setup.h"
  28. #ifdef USE_AXTLS
  29. #include <axTLS/ssl.h>
  30. #include "axtls.h"
  31. #include "sendf.h"
  32. #include "inet_pton.h"
  33. #include "vtls.h"
  34. #include "parsedate.h"
  35. #include "connect.h" /* for the connect timeout */
  36. #include "select.h"
  37. #define _MPRINTF_REPLACE /* use our functions only */
  38. #include <curl/mprintf.h>
  39. #include "curl_memory.h"
  40. #include <unistd.h>
  41. /* The last #include file should be: */
  42. #include "memdebug.h"
  43. #include "hostcheck.h"
  44. /* Global axTLS init, called from Curl_ssl_init() */
  45. int Curl_axtls_init(void)
  46. {
  47. /* axTLS has no global init. Everything is done through SSL and SSL_CTX
  48. * structs stored in connectdata structure. Perhaps can move to axtls.h.
  49. */
  50. return 1;
  51. }
  52. int Curl_axtls_cleanup(void)
  53. {
  54. /* axTLS has no global cleanup. Perhaps can move this to axtls.h. */
  55. return 1;
  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. static Curl_recv axtls_recv;
  109. static Curl_send axtls_send;
  110. static void free_ssl_structs(struct ssl_connect_data *connssl)
  111. {
  112. if(connssl->ssl) {
  113. ssl_free (connssl->ssl);
  114. connssl->ssl = NULL;
  115. }
  116. if(connssl->ssl_ctx) {
  117. ssl_ctx_free(connssl->ssl_ctx);
  118. connssl->ssl_ctx = NULL;
  119. }
  120. }
  121. /*
  122. * For both blocking and non-blocking connects, this function sets up the
  123. * ssl context and state. This function is called after the TCP connect
  124. * has completed.
  125. */
  126. static CURLcode connect_prep(struct connectdata *conn, int sockindex)
  127. {
  128. struct SessionHandle *data = conn->data;
  129. SSL_CTX *ssl_ctx;
  130. SSL *ssl = NULL;
  131. int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
  132. int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
  133. int i, ssl_fcn_return;
  134. const uint8_t *ssl_sessionid;
  135. size_t ssl_idsize;
  136. /* Assuming users will not compile in custom key/cert to axTLS.
  137. * Also, even for blocking connects, use axTLS non-blocking feature.
  138. */
  139. uint32_t client_option = SSL_NO_DEFAULT_KEY |
  140. SSL_SERVER_VERIFY_LATER |
  141. SSL_CONNECT_IN_PARTS;
  142. if(conn->ssl[sockindex].state == ssl_connection_complete)
  143. /* to make us tolerant against being called more than once for the
  144. same connection */
  145. return CURLE_OK;
  146. /* axTLS only supports TLSv1 */
  147. /* check to see if we've been told to use an explicit SSL/TLS version */
  148. switch(data->set.ssl.version) {
  149. case CURL_SSLVERSION_DEFAULT:
  150. case CURL_SSLVERSION_TLSv1:
  151. break;
  152. default:
  153. failf(data, "axTLS only supports TLS 1.0 and 1.1, "
  154. "and it cannot be specified which one to use");
  155. return CURLE_SSL_CONNECT_ERROR;
  156. }
  157. #ifdef AXTLSDEBUG
  158. client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
  159. #endif /* AXTLSDEBUG */
  160. /* Allocate an SSL_CTX struct */
  161. ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
  162. if(ssl_ctx == NULL) {
  163. failf(data, "unable to create client SSL context");
  164. return CURLE_SSL_CONNECT_ERROR;
  165. }
  166. conn->ssl[sockindex].ssl_ctx = ssl_ctx;
  167. conn->ssl[sockindex].ssl = NULL;
  168. /* Load the trusted CA cert bundle file */
  169. if(data->set.ssl.CAfile) {
  170. if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
  171. != SSL_OK) {
  172. infof(data, "error reading ca cert file %s \n",
  173. data->set.ssl.CAfile);
  174. if(data->set.ssl.verifypeer) {
  175. return CURLE_SSL_CACERT_BADFILE;
  176. }
  177. }
  178. else
  179. infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
  180. }
  181. /* gtls.c tasks we're skipping for now:
  182. * 1) certificate revocation list checking
  183. * 2) dns name assignment to host
  184. * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
  185. * 4) set certificate priority. axTLS ignores type and sends certs in
  186. * order added. can probably ignore this.
  187. */
  188. /* Load client certificate */
  189. if(data->set.str[STRING_CERT]) {
  190. i=0;
  191. /* Instead of trying to analyze cert type here, let axTLS try them all. */
  192. while(cert_types[i] != 0) {
  193. ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
  194. data->set.str[STRING_CERT], NULL);
  195. if(ssl_fcn_return == SSL_OK) {
  196. infof(data, "successfully read cert file %s \n",
  197. data->set.str[STRING_CERT]);
  198. break;
  199. }
  200. i++;
  201. }
  202. /* Tried all cert types, none worked. */
  203. if(cert_types[i] == 0) {
  204. failf(data, "%s is not x509 or pkcs12 format",
  205. data->set.str[STRING_CERT]);
  206. return CURLE_SSL_CERTPROBLEM;
  207. }
  208. }
  209. /* Load client key.
  210. If a pkcs12 file successfully loaded a cert, then there's nothing to do
  211. because the key has already been loaded. */
  212. if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) {
  213. i=0;
  214. /* Instead of trying to analyze key type here, let axTLS try them all. */
  215. while(key_types[i] != 0) {
  216. ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
  217. data->set.str[STRING_KEY], NULL);
  218. if(ssl_fcn_return == SSL_OK) {
  219. infof(data, "successfully read key file %s \n",
  220. data->set.str[STRING_KEY]);
  221. break;
  222. }
  223. i++;
  224. }
  225. /* Tried all key types, none worked. */
  226. if(key_types[i] == 0) {
  227. failf(data, "Failure: %s is not a supported key file",
  228. data->set.str[STRING_KEY]);
  229. return CURLE_SSL_CONNECT_ERROR;
  230. }
  231. }
  232. /* gtls.c does more here that is being left out for now
  233. * 1) set session credentials. can probably ignore since axtls puts this
  234. * info in the ssl_ctx struct
  235. * 2) setting up callbacks. these seem gnutls specific
  236. */
  237. /* In axTLS, handshaking happens inside ssl_client_new. */
  238. if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) {
  239. /* we got a session id, use it! */
  240. infof (data, "SSL re-using session ID\n");
  241. ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
  242. ssl_sessionid, (uint8_t)ssl_idsize);
  243. }
  244. else
  245. ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
  246. conn->ssl[sockindex].ssl = ssl;
  247. return CURLE_OK;
  248. }
  249. /*
  250. * For both blocking and non-blocking connects, this function finalizes the
  251. * SSL connection.
  252. */
  253. static CURLcode connect_finish(struct connectdata *conn, int sockindex)
  254. {
  255. struct SessionHandle *data = conn->data;
  256. SSL *ssl = conn->ssl[sockindex].ssl;
  257. const uint8_t *ssl_sessionid;
  258. size_t ssl_idsize;
  259. const char *peer_CN;
  260. uint32_t dns_altname_index;
  261. const char *dns_altname;
  262. int8_t found_subject_alt_names = 0;
  263. int8_t found_subject_alt_name_matching_conn = 0;
  264. /* Here, gtls.c gets the peer certificates and fails out depending on
  265. * settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
  266. */
  267. /* Verify server's certificate */
  268. if(data->set.ssl.verifypeer) {
  269. if(ssl_verify_cert(ssl) != SSL_OK) {
  270. Curl_axtls_close(conn, sockindex);
  271. failf(data, "server cert verify failed");
  272. return CURLE_PEER_FAILED_VERIFICATION;
  273. }
  274. }
  275. else
  276. infof(data, "\t server certificate verification SKIPPED\n");
  277. /* Here, gtls.c does issuer verification. axTLS has no straightforward
  278. * equivalent, so omitting for now.*/
  279. /* Here, gtls.c does the following
  280. * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
  281. * it seems useful. This is now implemented, by Oscar Koeroo
  282. * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
  283. * 3) displays a bunch of cert information. axTLS doesn't support most of
  284. * this, but a couple fields are available.
  285. */
  286. /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
  287. risk of an inifite loop */
  288. for(dns_altname_index = 0; ; dns_altname_index++) {
  289. dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
  290. if(dns_altname == NULL) {
  291. break;
  292. }
  293. found_subject_alt_names = 1;
  294. infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
  295. dns_altname, conn->host.name);
  296. if(Curl_cert_hostcheck(dns_altname, conn->host.name)) {
  297. found_subject_alt_name_matching_conn = 1;
  298. break;
  299. }
  300. }
  301. /* RFC2818 checks */
  302. if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
  303. if(data->set.ssl.verifyhost) {
  304. /* Break connection ! */
  305. Curl_axtls_close(conn, sockindex);
  306. failf(data, "\tsubjectAltName(s) do not match %s\n",
  307. conn->host.dispname);
  308. return CURLE_PEER_FAILED_VERIFICATION;
  309. }
  310. else
  311. infof(data, "\tsubjectAltName(s) do not match %s\n",
  312. conn->host.dispname);
  313. }
  314. else if(found_subject_alt_names == 0) {
  315. /* Per RFC2818, when no Subject Alt Names were available, examine the peer
  316. CN as a legacy fallback */
  317. peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
  318. if(peer_CN == NULL) {
  319. if(data->set.ssl.verifyhost) {
  320. Curl_axtls_close(conn, sockindex);
  321. failf(data, "unable to obtain common name from peer certificate");
  322. return CURLE_PEER_FAILED_VERIFICATION;
  323. }
  324. else
  325. infof(data, "unable to obtain common name from peer certificate");
  326. }
  327. else {
  328. if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
  329. if(data->set.ssl.verifyhost) {
  330. /* Break connection ! */
  331. Curl_axtls_close(conn, sockindex);
  332. failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
  333. peer_CN, conn->host.dispname);
  334. return CURLE_PEER_FAILED_VERIFICATION;
  335. }
  336. else
  337. infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
  338. peer_CN, conn->host.dispname);
  339. }
  340. }
  341. }
  342. /* General housekeeping */
  343. conn->ssl[sockindex].state = ssl_connection_complete;
  344. conn->recv[sockindex] = axtls_recv;
  345. conn->send[sockindex] = axtls_send;
  346. /* Put our freshly minted SSL session in cache */
  347. ssl_idsize = ssl_get_session_id_size(ssl);
  348. ssl_sessionid = ssl_get_session_id(ssl);
  349. if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
  350. != CURLE_OK)
  351. infof (data, "failed to add session to cache\n");
  352. return CURLE_OK;
  353. }
  354. /*
  355. * Use axTLS's non-blocking connection feature to open an SSL connection.
  356. * This is called after a TCP connection is already established.
  357. */
  358. CURLcode Curl_axtls_connect_nonblocking(
  359. struct connectdata *conn,
  360. int sockindex,
  361. bool *done)
  362. {
  363. CURLcode conn_step;
  364. int ssl_fcn_return;
  365. int i;
  366. *done = FALSE;
  367. /* connectdata is calloc'd and connecting_state is only changed in this
  368. function, so this is safe, as the state is effectively initialized. */
  369. if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
  370. conn_step = connect_prep(conn, sockindex);
  371. if(conn_step != CURLE_OK) {
  372. Curl_axtls_close(conn, sockindex);
  373. return conn_step;
  374. }
  375. conn->ssl[sockindex].connecting_state = ssl_connect_2;
  376. }
  377. if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
  378. /* Check to make sure handshake was ok. */
  379. if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
  380. /* Loop to perform more work in between sleeps. This is work around the
  381. fact that axtls does not expose any knowledge about when work needs
  382. to be performed. This can save ~25% of time on SSL handshakes. */
  383. for(i=0; i<5; i++) {
  384. ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
  385. if(ssl_fcn_return < 0) {
  386. Curl_axtls_close(conn, sockindex);
  387. ssl_display_error(ssl_fcn_return); /* goes to stdout. */
  388. return map_error_to_curl(ssl_fcn_return);
  389. }
  390. return CURLE_OK;
  391. }
  392. }
  393. infof (conn->data, "handshake completed successfully\n");
  394. conn->ssl[sockindex].connecting_state = ssl_connect_3;
  395. }
  396. if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
  397. conn_step = connect_finish(conn, sockindex);
  398. if(conn_step != CURLE_OK) {
  399. Curl_axtls_close(conn, sockindex);
  400. return conn_step;
  401. }
  402. /* Reset connect state */
  403. conn->ssl[sockindex].connecting_state = ssl_connect_1;
  404. *done = TRUE;
  405. return CURLE_OK;
  406. }
  407. /* Unrecognized state. Things are very bad. */
  408. conn->ssl[sockindex].state = ssl_connection_none;
  409. conn->ssl[sockindex].connecting_state = ssl_connect_1;
  410. /* Return value perhaps not strictly correct, but distinguishes the issue.*/
  411. return CURLE_BAD_FUNCTION_ARGUMENT;
  412. }
  413. /*
  414. * This function is called after the TCP connect has completed. Setup the TLS
  415. * layer and do all necessary magic for a blocking connect.
  416. */
  417. CURLcode
  418. Curl_axtls_connect(struct connectdata *conn,
  419. int sockindex)
  420. {
  421. CURLcode conn_step = connect_prep(conn, sockindex);
  422. int ssl_fcn_return;
  423. SSL *ssl = conn->ssl[sockindex].ssl;
  424. if(conn_step != CURLE_OK) {
  425. Curl_axtls_close(conn, sockindex);
  426. return conn_step;
  427. }
  428. /* Check to make sure handshake was ok. */
  429. while(ssl_handshake_status(ssl) != SSL_OK) {
  430. ssl_fcn_return = ssl_read(ssl, NULL);
  431. if(ssl_fcn_return < 0) {
  432. Curl_axtls_close(conn, sockindex);
  433. ssl_display_error(ssl_fcn_return); /* goes to stdout. */
  434. return map_error_to_curl(ssl_fcn_return);
  435. }
  436. usleep(10000);
  437. /* TODO: check for timeout as this could hang indefinitely otherwise */
  438. }
  439. infof (conn->data, "handshake completed successfully\n");
  440. conn_step = connect_finish(conn, sockindex);
  441. if(conn_step != CURLE_OK) {
  442. Curl_axtls_close(conn, sockindex);
  443. return conn_step;
  444. }
  445. return CURLE_OK;
  446. }
  447. /* return number of sent (non-SSL) bytes */
  448. static ssize_t axtls_send(struct connectdata *conn,
  449. int sockindex,
  450. const void *mem,
  451. size_t len,
  452. CURLcode *err)
  453. {
  454. /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
  455. int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
  456. infof(conn->data, " axtls_send\n");
  457. if(rc < 0 ) {
  458. *err = map_error_to_curl(rc);
  459. rc = -1; /* generic error code for send failure */
  460. }
  461. *err = CURLE_OK;
  462. return rc;
  463. }
  464. void Curl_axtls_close_all(struct SessionHandle *data)
  465. {
  466. (void)data;
  467. infof(data, " Curl_axtls_close_all\n");
  468. }
  469. void Curl_axtls_close(struct connectdata *conn, int sockindex)
  470. {
  471. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  472. infof(conn->data, " Curl_axtls_close\n");
  473. /* line from openssl.c: (void)SSL_shutdown(connssl->ssl);
  474. axTLS compat layer does nothing for SSL_shutdown */
  475. /* The following line is from openssl.c. There seems to be no axTLS
  476. equivalent. ssl_free and ssl_ctx_free close things.
  477. SSL_set_connect_state(connssl->handle); */
  478. free_ssl_structs(connssl);
  479. }
  480. /*
  481. * This function is called to shut down the SSL layer but keep the
  482. * socket open (CCC - Clear Command Channel)
  483. */
  484. int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
  485. {
  486. /* Outline taken from openssl.c since functions are in axTLS compat layer.
  487. axTLS's error set is much smaller, so a lot of error-handling was removed.
  488. */
  489. int retval = 0;
  490. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  491. struct SessionHandle *data = conn->data;
  492. uint8_t *buf;
  493. ssize_t nread;
  494. infof(conn->data, " Curl_axtls_shutdown\n");
  495. /* This has only been tested on the proftpd server, and the mod_tls code
  496. sends a close notify alert without waiting for a close notify alert in
  497. response. Thus we wait for a close notify alert from the server, but
  498. we do not send one. Let's hope other servers do the same... */
  499. /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
  500. if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
  501. (void)SSL_shutdown(connssl->ssl);
  502. */
  503. if(connssl->ssl) {
  504. int what = Curl_socket_ready(conn->sock[sockindex],
  505. CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
  506. if(what > 0) {
  507. /* Something to read, let's do it and hope that it is the close
  508. notify alert from the server. buf is managed internally by
  509. axTLS and will be released upon calling ssl_free via
  510. free_ssl_structs. */
  511. nread = (ssize_t)ssl_read(connssl->ssl, &buf);
  512. if(nread < SSL_OK) {
  513. failf(data, "close notify alert not received during shutdown");
  514. retval = -1;
  515. }
  516. }
  517. else if(0 == what) {
  518. /* timeout */
  519. failf(data, "SSL shutdown timeout");
  520. }
  521. else {
  522. /* anything that gets here is fatally bad */
  523. failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
  524. retval = -1;
  525. }
  526. free_ssl_structs(connssl);
  527. }
  528. return retval;
  529. }
  530. static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
  531. int num, /* socketindex */
  532. char *buf, /* store read data here */
  533. size_t buffersize, /* max amount to read */
  534. CURLcode *err)
  535. {
  536. struct ssl_connect_data *connssl = &conn->ssl[num];
  537. ssize_t ret = 0;
  538. uint8_t *read_buf;
  539. infof(conn->data, " axtls_recv\n");
  540. *err = CURLE_OK;
  541. if(connssl) {
  542. ret = ssl_read(connssl->ssl, &read_buf);
  543. if(ret > SSL_OK) {
  544. /* ssl_read returns SSL_OK if there is more data to read, so if it is
  545. larger, then all data has been read already. */
  546. memcpy(buf, read_buf,
  547. (size_t)ret > buffersize ? buffersize : (size_t)ret);
  548. }
  549. else if(ret == SSL_OK) {
  550. /* more data to be read, signal caller to call again */
  551. *err = CURLE_AGAIN;
  552. ret = -1;
  553. }
  554. else if(ret == -3) {
  555. /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
  556. team approves proposed fix. */
  557. Curl_axtls_close(conn, num);
  558. }
  559. else {
  560. failf(conn->data, "axTLS recv error (%d)", ret);
  561. *err = map_error_to_curl((int) ret);
  562. ret = -1;
  563. }
  564. }
  565. return ret;
  566. }
  567. /*
  568. * Return codes:
  569. * 1 means the connection is still in place
  570. * 0 means the connection has been closed
  571. * -1 means the connection status is unknown
  572. */
  573. int Curl_axtls_check_cxn(struct connectdata *conn)
  574. {
  575. /* openssl.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
  576. axTLS compat layer always returns the last argument, so connection is
  577. always alive? */
  578. infof(conn->data, " Curl_axtls_check_cxn\n");
  579. return 1; /* connection still in place */
  580. }
  581. void Curl_axtls_session_free(void *ptr)
  582. {
  583. (void)ptr;
  584. /* free the ID */
  585. /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
  586. compatibility layer does nothing, so we do nothing too. */
  587. }
  588. size_t Curl_axtls_version(char *buffer, size_t size)
  589. {
  590. return snprintf(buffer, size, "axTLS/%s", ssl_version());
  591. }
  592. int Curl_axtls_random(struct SessionHandle *data,
  593. unsigned char *entropy,
  594. size_t length)
  595. {
  596. static bool ssl_seeded = FALSE;
  597. (void)data;
  598. if(!ssl_seeded) {
  599. ssl_seeded = TRUE;
  600. /* Initialize the seed if not already done. This call is not exactly thread
  601. * safe (and neither is the ssl_seeded check), but the worst effect of a
  602. * race condition is that some global resources will leak. */
  603. RNG_initialize();
  604. }
  605. get_random(length, entropy);
  606. return 0;
  607. }
  608. #endif /* USE_AXTLS */