PageRenderTime 77ms CodeModel.GetById 49ms RepoModel.GetById 1ms app.codeStats 0ms

/curl-7.28.0/lib/axtls.c

https://bitbucket.org/vlaznev/curl
C | 497 lines | 310 code | 62 blank | 125 comment | 50 complexity | 7886bca3b8021898f64930f44d2effa6 MD5 | raw file
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 2010, DirecTV
  9. * contact: Eric Hu <ehu@directv.com>
  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 sslgen.c should ever call or use these functions.
  26. */
  27. #include "setup.h"
  28. #ifdef USE_AXTLS
  29. #include <axTLS/ssl.h>
  30. #include "axtls.h"
  31. #ifdef HAVE_SYS_SOCKET_H
  32. #include <sys/socket.h>
  33. #endif
  34. #include "sendf.h"
  35. #include "inet_pton.h"
  36. #include "sslgen.h"
  37. #include "parsedate.h"
  38. #include "connect.h" /* for the connect timeout */
  39. #include "select.h"
  40. #define _MPRINTF_REPLACE /* use our functions only */
  41. #include <curl/mprintf.h>
  42. #include "curl_memory.h"
  43. /* The last #include file should be: */
  44. #include "memdebug.h"
  45. /* SSL_read is opied from axTLS compat layer */
  46. static int SSL_read(SSL *ssl, void *buf, int num)
  47. {
  48. uint8_t *read_buf;
  49. int ret;
  50. while((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
  51. if(ret > SSL_OK) {
  52. memcpy(buf, read_buf, ret > num ? num : ret);
  53. }
  54. return ret;
  55. }
  56. /* Global axTLS init, called from Curl_ssl_init() */
  57. int Curl_axtls_init(void)
  58. {
  59. /* axTLS has no global init. Everything is done through SSL and SSL_CTX
  60. * structs stored in connectdata structure. Perhaps can move to axtls.h.
  61. */
  62. return 1;
  63. }
  64. int Curl_axtls_cleanup(void)
  65. {
  66. /* axTLS has no global cleanup. Perhaps can move this to axtls.h. */
  67. return 1;
  68. }
  69. static CURLcode map_error_to_curl(int axtls_err)
  70. {
  71. switch (axtls_err) {
  72. case SSL_ERROR_NOT_SUPPORTED:
  73. case SSL_ERROR_INVALID_VERSION:
  74. case -70: /* protocol version alert from server */
  75. return CURLE_UNSUPPORTED_PROTOCOL;
  76. break;
  77. case SSL_ERROR_NO_CIPHER:
  78. return CURLE_SSL_CIPHER;
  79. break;
  80. case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
  81. case SSL_ERROR_NO_CERT_DEFINED:
  82. case -42: /* bad certificate alert from server */
  83. case -43: /* unsupported cert alert from server */
  84. case -44: /* cert revoked alert from server */
  85. case -45: /* cert expired alert from server */
  86. case -46: /* cert unknown alert from server */
  87. return CURLE_SSL_CERTPROBLEM;
  88. break;
  89. case SSL_X509_ERROR(X509_NOT_OK):
  90. case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
  91. case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
  92. case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
  93. case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
  94. case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
  95. case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
  96. case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
  97. case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
  98. return CURLE_PEER_FAILED_VERIFICATION;
  99. break;
  100. case -48: /* unknown ca alert from server */
  101. return CURLE_SSL_CACERT;
  102. break;
  103. case -49: /* access denied alert from server */
  104. return CURLE_REMOTE_ACCESS_DENIED;
  105. break;
  106. case SSL_ERROR_CONN_LOST:
  107. case SSL_ERROR_SOCK_SETUP_FAILURE:
  108. case SSL_ERROR_INVALID_HANDSHAKE:
  109. case SSL_ERROR_INVALID_PROT_MSG:
  110. case SSL_ERROR_INVALID_HMAC:
  111. case SSL_ERROR_INVALID_SESSION:
  112. case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */
  113. case SSL_ERROR_FINISHED_INVALID:
  114. case SSL_ERROR_NO_CLIENT_RENOG:
  115. default:
  116. return CURLE_SSL_CONNECT_ERROR;
  117. break;
  118. }
  119. }
  120. static Curl_recv axtls_recv;
  121. static Curl_send axtls_send;
  122. /*
  123. * This function is called after the TCP connect has completed. Setup the TLS
  124. * layer and do all necessary magic.
  125. */
  126. CURLcode
  127. Curl_axtls_connect(struct connectdata *conn,
  128. int sockindex)
  129. {
  130. struct SessionHandle *data = conn->data;
  131. SSL_CTX *ssl_ctx;
  132. SSL *ssl;
  133. int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
  134. int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
  135. int i, ssl_fcn_return;
  136. const uint8_t *ssl_sessionid;
  137. size_t ssl_idsize;
  138. const char *x509;
  139. /* Assuming users will not compile in custom key/cert to axTLS */
  140. uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER;
  141. if(conn->ssl[sockindex].state == ssl_connection_complete)
  142. /* to make us tolerant against being called more than once for the
  143. same connection */
  144. return CURLE_OK;
  145. /* axTLS only supports TLSv1 */
  146. /* check to see if we've been told to use an explicit SSL/TLS version */
  147. switch(data->set.ssl.version) {
  148. case CURL_SSLVERSION_DEFAULT:
  149. case CURL_SSLVERSION_TLSv1:
  150. break;
  151. default:
  152. failf(data, "axTLS only supports TLSv1");
  153. return CURLE_SSL_CONNECT_ERROR;
  154. }
  155. #ifdef AXTLSDEBUG
  156. client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
  157. #endif /* AXTLSDEBUG */
  158. /* Allocate an SSL_CTX struct */
  159. ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
  160. if(ssl_ctx == NULL) {
  161. failf(data, "unable to create client SSL context");
  162. return CURLE_SSL_CONNECT_ERROR;
  163. }
  164. /* Load the trusted CA cert bundle file */
  165. if(data->set.ssl.CAfile) {
  166. if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
  167. != SSL_OK) {
  168. infof(data, "error reading ca cert file %s \n",
  169. data->set.ssl.CAfile);
  170. if(data->set.ssl.verifypeer) {
  171. Curl_axtls_close(conn, sockindex);
  172. return CURLE_SSL_CACERT_BADFILE;
  173. }
  174. }
  175. else
  176. infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
  177. }
  178. /* gtls.c tasks we're skipping for now:
  179. * 1) certificate revocation list checking
  180. * 2) dns name assignment to host
  181. * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
  182. * 4) set certificate priority. axTLS ignores type and sends certs in
  183. * order added. can probably ignore this.
  184. */
  185. /* Load client certificate */
  186. if(data->set.str[STRING_CERT]) {
  187. i=0;
  188. /* Instead of trying to analyze cert type here, let axTLS try them all. */
  189. while(cert_types[i] != 0) {
  190. ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
  191. data->set.str[STRING_CERT], NULL);
  192. if(ssl_fcn_return == SSL_OK) {
  193. infof(data, "successfully read cert file %s \n",
  194. data->set.str[STRING_CERT]);
  195. break;
  196. }
  197. i++;
  198. }
  199. /* Tried all cert types, none worked. */
  200. if(cert_types[i] == 0) {
  201. failf(data, "%s is not x509 or pkcs12 format",
  202. data->set.str[STRING_CERT]);
  203. Curl_axtls_close(conn, sockindex);
  204. return CURLE_SSL_CERTPROBLEM;
  205. }
  206. }
  207. /* Load client key.
  208. If a pkcs12 file successfully loaded a cert, then there's nothing to do
  209. because the key has already been loaded. */
  210. if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) {
  211. i=0;
  212. /* Instead of trying to analyze key type here, let axTLS try them all. */
  213. while(key_types[i] != 0) {
  214. ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
  215. data->set.str[STRING_KEY], NULL);
  216. if(ssl_fcn_return == SSL_OK) {
  217. infof(data, "successfully read key file %s \n",
  218. data->set.str[STRING_KEY]);
  219. break;
  220. }
  221. i++;
  222. }
  223. /* Tried all key types, none worked. */
  224. if(key_types[i] == 0) {
  225. failf(data, "Failure: %s is not a supported key file",
  226. data->set.str[STRING_KEY]);
  227. Curl_axtls_close(conn, sockindex);
  228. return CURLE_SSL_CONNECT_ERROR;
  229. }
  230. }
  231. /* gtls.c does more here that is being left out for now
  232. * 1) set session credentials. can probably ignore since axtls puts this
  233. * info in the ssl_ctx struct
  234. * 2) setting up callbacks. these seem gnutls specific
  235. */
  236. /* In axTLS, handshaking happens inside ssl_client_new. */
  237. if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) {
  238. /* we got a session id, use it! */
  239. infof (data, "SSL re-using session ID\n");
  240. ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
  241. ssl_sessionid, (uint8_t)ssl_idsize);
  242. }
  243. else
  244. ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
  245. /* Check to make sure handshake was ok. */
  246. ssl_fcn_return = ssl_handshake_status(ssl);
  247. if(ssl_fcn_return != SSL_OK) {
  248. Curl_axtls_close(conn, sockindex);
  249. ssl_display_error(ssl_fcn_return); /* goes to stdout. */
  250. return map_error_to_curl(ssl_fcn_return);
  251. }
  252. infof (data, "handshake completed successfully\n");
  253. /* Here, gtls.c gets the peer certificates and fails out depending on
  254. * settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
  255. */
  256. /* Verify server's certificate */
  257. if(data->set.ssl.verifypeer) {
  258. if(ssl_verify_cert(ssl) != SSL_OK) {
  259. Curl_axtls_close(conn, sockindex);
  260. failf(data, "server cert verify failed");
  261. return CURLE_SSL_CONNECT_ERROR;
  262. }
  263. }
  264. else
  265. infof(data, "\t server certificate verification SKIPPED\n");
  266. /* Here, gtls.c does issuer verification. axTLS has no straightforward
  267. * equivalent, so omitting for now.*/
  268. /* See if common name was set in server certificate */
  269. x509 = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
  270. if(x509 == NULL)
  271. infof(data, "error fetching CN from cert\n");
  272. /* Here, gtls.c does the following
  273. * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
  274. * it seems useful. Omitting for now.
  275. * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
  276. * 3) displays a bunch of cert information. axTLS doesn't support most of
  277. * this, but a couple fields are available.
  278. */
  279. /* General housekeeping */
  280. conn->ssl[sockindex].state = ssl_connection_complete;
  281. conn->ssl[sockindex].ssl = ssl;
  282. conn->ssl[sockindex].ssl_ctx = ssl_ctx;
  283. conn->recv[sockindex] = axtls_recv;
  284. conn->send[sockindex] = axtls_send;
  285. /* Put our freshly minted SSL session in cache */
  286. ssl_idsize = ssl_get_session_id_size(ssl);
  287. ssl_sessionid = ssl_get_session_id(ssl);
  288. if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
  289. != CURLE_OK)
  290. infof (data, "failed to add session to cache\n");
  291. return CURLE_OK;
  292. }
  293. /* return number of sent (non-SSL) bytes */
  294. static ssize_t axtls_send(struct connectdata *conn,
  295. int sockindex,
  296. const void *mem,
  297. size_t len,
  298. CURLcode *err)
  299. {
  300. /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
  301. int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
  302. infof(conn->data, " axtls_send\n");
  303. if(rc < 0 ) {
  304. *err = map_error_to_curl(rc);
  305. rc = -1; /* generic error code for send failure */
  306. }
  307. *err = CURLE_OK;
  308. return rc;
  309. }
  310. void Curl_axtls_close_all(struct SessionHandle *data)
  311. {
  312. (void)data;
  313. infof(data, " Curl_axtls_close_all\n");
  314. }
  315. void Curl_axtls_close(struct connectdata *conn, int sockindex)
  316. {
  317. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  318. infof(conn->data, " Curl_axtls_close\n");
  319. if(connssl->ssl) {
  320. /* line from ssluse.c: (void)SSL_shutdown(connssl->ssl);
  321. axTLS compat layer does nothing for SSL_shutdown */
  322. /* The following line is from ssluse.c. There seems to be no axTLS
  323. equivalent. ssl_free and ssl_ctx_free close things.
  324. SSL_set_connect_state(connssl->handle); */
  325. ssl_free (connssl->ssl);
  326. connssl->ssl = NULL;
  327. }
  328. if(connssl->ssl_ctx) {
  329. ssl_ctx_free (connssl->ssl_ctx);
  330. connssl->ssl_ctx = NULL;
  331. }
  332. }
  333. /*
  334. * This function is called to shut down the SSL layer but keep the
  335. * socket open (CCC - Clear Command Channel)
  336. */
  337. int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
  338. {
  339. /* Outline taken from ssluse.c since functions are in axTLS compat layer.
  340. axTLS's error set is much smaller, so a lot of error-handling was removed.
  341. */
  342. int retval = 0;
  343. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  344. struct SessionHandle *data = conn->data;
  345. char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
  346. to be at least 120 bytes long. */
  347. ssize_t nread;
  348. infof(conn->data, " Curl_axtls_shutdown\n");
  349. /* This has only been tested on the proftpd server, and the mod_tls code
  350. sends a close notify alert without waiting for a close notify alert in
  351. response. Thus we wait for a close notify alert from the server, but
  352. we do not send one. Let's hope other servers do the same... */
  353. /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
  354. if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
  355. (void)SSL_shutdown(connssl->ssl);
  356. */
  357. if(connssl->ssl) {
  358. int what = Curl_socket_ready(conn->sock[sockindex],
  359. CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
  360. if(what > 0) {
  361. /* Something to read, let's do it and hope that it is the close
  362. notify alert from the server */
  363. nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
  364. sizeof(buf));
  365. if(nread < SSL_OK) {
  366. failf(data, "close notify alert not received during shutdown");
  367. retval = -1;
  368. }
  369. }
  370. else if(0 == what) {
  371. /* timeout */
  372. failf(data, "SSL shutdown timeout");
  373. }
  374. else {
  375. /* anything that gets here is fatally bad */
  376. failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
  377. retval = -1;
  378. }
  379. ssl_free (connssl->ssl);
  380. connssl->ssl = NULL;
  381. }
  382. return retval;
  383. }
  384. static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
  385. int num, /* socketindex */
  386. char *buf, /* store read data here */
  387. size_t buffersize, /* max amount to read */
  388. CURLcode *err)
  389. {
  390. struct ssl_connect_data *connssl = &conn->ssl[num];
  391. ssize_t ret = 0;
  392. infof(conn->data, " axtls_recv\n");
  393. if(connssl) {
  394. ret = (ssize_t)SSL_read(conn->ssl[num].ssl, buf, (int)buffersize);
  395. /* axTLS isn't terribly generous about error reporting */
  396. /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
  397. team approves proposed fix. */
  398. if(ret == -3 ) {
  399. Curl_axtls_close(conn, num);
  400. }
  401. else if(ret < 0) {
  402. failf(conn->data, "axTLS recv error (%d)", (int)ret);
  403. *err = map_error_to_curl(ret);
  404. return -1;
  405. }
  406. }
  407. *err = CURLE_OK;
  408. return ret;
  409. }
  410. /*
  411. * Return codes:
  412. * 1 means the connection is still in place
  413. * 0 means the connection has been closed
  414. * -1 means the connection status is unknown
  415. */
  416. int Curl_axtls_check_cxn(struct connectdata *conn)
  417. {
  418. /* ssluse.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
  419. axTLS compat layer always returns the last argument, so connection is
  420. always alive? */
  421. infof(conn->data, " Curl_axtls_check_cxn\n");
  422. return 1; /* connection still in place */
  423. }
  424. void Curl_axtls_session_free(void *ptr)
  425. {
  426. (void)ptr;
  427. /* free the ID */
  428. /* both ssluse.c and gtls.c do something here, but axTLS's OpenSSL
  429. compatibility layer does nothing, so we do nothing too. */
  430. }
  431. size_t Curl_axtls_version(char *buffer, size_t size)
  432. {
  433. return snprintf(buffer, size, "axTLS/%s", ssl_version());
  434. }
  435. #endif /* USE_AXTLS */