2
0

gskit.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. ***************************************************************************/
  22. #include "curl_setup.h"
  23. #ifdef USE_GSKIT
  24. #include <gskssl.h>
  25. #include <qsoasync.h>
  26. #undef HAVE_SOCKETPAIR /* because the native one isn't good enough */
  27. #include "socketpair.h"
  28. #include "strerror.h"
  29. /* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
  30. #ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
  31. #define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
  32. #endif
  33. #ifndef GSK_TLSV10_CIPHER_SPECS
  34. #define GSK_TLSV10_CIPHER_SPECS 236
  35. #endif
  36. #ifndef GSK_TLSV11_CIPHER_SPECS
  37. #define GSK_TLSV11_CIPHER_SPECS 237
  38. #endif
  39. #ifndef GSK_TLSV12_CIPHER_SPECS
  40. #define GSK_TLSV12_CIPHER_SPECS 238
  41. #endif
  42. #ifndef GSK_PROTOCOL_TLSV11
  43. #define GSK_PROTOCOL_TLSV11 437
  44. #endif
  45. #ifndef GSK_PROTOCOL_TLSV12
  46. #define GSK_PROTOCOL_TLSV12 438
  47. #endif
  48. #ifndef GSK_FALSE
  49. #define GSK_FALSE 0
  50. #endif
  51. #ifndef GSK_TRUE
  52. #define GSK_TRUE 1
  53. #endif
  54. #include <limits.h>
  55. #include <curl/curl.h>
  56. #include "urldata.h"
  57. #include "sendf.h"
  58. #include "gskit.h"
  59. #include "vtls.h"
  60. #include "connect.h" /* for the connect timeout */
  61. #include "select.h"
  62. #include "strcase.h"
  63. #include "timediff.h"
  64. #include "x509asn1.h"
  65. #include "curl_printf.h"
  66. #include "curl_memory.h"
  67. /* The last #include file should be: */
  68. #include "memdebug.h"
  69. /* Directions. */
  70. #define SOS_READ 0x01
  71. #define SOS_WRITE 0x02
  72. /* SSL version flags. */
  73. #define CURL_GSKPROTO_SSLV2 0
  74. #define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2)
  75. #define CURL_GSKPROTO_SSLV3 1
  76. #define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3)
  77. #define CURL_GSKPROTO_TLSV10 2
  78. #define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10)
  79. #define CURL_GSKPROTO_TLSV11 3
  80. #define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11)
  81. #define CURL_GSKPROTO_TLSV12 4
  82. #define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
  83. #define CURL_GSKPROTO_LAST 5
  84. struct ssl_backend_data {
  85. gsk_handle handle;
  86. int iocport;
  87. #ifndef CURL_DISABLE_PROXY
  88. int localfd;
  89. int remotefd;
  90. #endif
  91. };
  92. #define BACKEND connssl->backend
  93. /* Supported ciphers. */
  94. struct gskit_cipher {
  95. const char *name; /* Cipher name. */
  96. const char *gsktoken; /* Corresponding token for GSKit String. */
  97. unsigned int versions; /* SSL version flags. */
  98. };
  99. static const struct gskit_cipher ciphertable[] = {
  100. { "null-md5", "01",
  101. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
  102. CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
  103. { "null-sha", "02",
  104. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
  105. CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
  106. { "exp-rc4-md5", "03",
  107. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
  108. { "rc4-md5", "04",
  109. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
  110. CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
  111. { "rc4-sha", "05",
  112. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
  113. CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
  114. { "exp-rc2-cbc-md5", "06",
  115. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
  116. { "exp-des-cbc-sha", "09",
  117. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
  118. CURL_GSKPROTO_TLSV11_MASK },
  119. { "des-cbc3-sha", "0A",
  120. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
  121. CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
  122. { "aes128-sha", "2F",
  123. CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
  124. CURL_GSKPROTO_TLSV12_MASK },
  125. { "aes256-sha", "35",
  126. CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
  127. CURL_GSKPROTO_TLSV12_MASK },
  128. { "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK },
  129. { "aes128-sha256", "3C", CURL_GSKPROTO_TLSV12_MASK },
  130. { "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
  131. { "aes128-gcm-sha256",
  132. "9C", CURL_GSKPROTO_TLSV12_MASK },
  133. { "aes256-gcm-sha384",
  134. "9D", CURL_GSKPROTO_TLSV12_MASK },
  135. { "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK },
  136. { "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK },
  137. { "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK },
  138. { "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK },
  139. { "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK },
  140. { "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK },
  141. { (const char *) NULL, (const char *) NULL, 0 }
  142. };
  143. static bool is_separator(char c)
  144. {
  145. /* Return whether character is a cipher list separator. */
  146. switch(c) {
  147. case ' ':
  148. case '\t':
  149. case ':':
  150. case ',':
  151. case ';':
  152. return true;
  153. }
  154. return false;
  155. }
  156. static CURLcode gskit_status(struct Curl_easy *data, int rc,
  157. const char *procname, CURLcode defcode)
  158. {
  159. char buffer[STRERROR_LEN];
  160. /* Process GSKit status and map it to a CURLcode. */
  161. switch(rc) {
  162. case GSK_OK:
  163. case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
  164. return CURLE_OK;
  165. case GSK_KEYRING_OPEN_ERROR:
  166. case GSK_OS400_ERROR_NO_ACCESS:
  167. return CURLE_SSL_CACERT_BADFILE;
  168. case GSK_INSUFFICIENT_STORAGE:
  169. return CURLE_OUT_OF_MEMORY;
  170. case GSK_ERROR_BAD_V2_CIPHER:
  171. case GSK_ERROR_BAD_V3_CIPHER:
  172. case GSK_ERROR_NO_CIPHERS:
  173. return CURLE_SSL_CIPHER;
  174. case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
  175. case GSK_ERROR_CERT_VALIDATION:
  176. return CURLE_PEER_FAILED_VERIFICATION;
  177. case GSK_OS400_ERROR_TIMED_OUT:
  178. return CURLE_OPERATION_TIMEDOUT;
  179. case GSK_WOULD_BLOCK:
  180. return CURLE_AGAIN;
  181. case GSK_OS400_ERROR_NOT_REGISTERED:
  182. break;
  183. case GSK_ERROR_IO:
  184. switch(errno) {
  185. case ENOMEM:
  186. return CURLE_OUT_OF_MEMORY;
  187. default:
  188. failf(data, "%s I/O error: %s", procname,
  189. Curl_strerror(errno, buffer, sizeof(buffer)));
  190. break;
  191. }
  192. break;
  193. default:
  194. failf(data, "%s: %s", procname, gsk_strerror(rc));
  195. break;
  196. }
  197. return defcode;
  198. }
  199. static CURLcode set_enum(struct Curl_easy *data, gsk_handle h,
  200. GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
  201. {
  202. char buffer[STRERROR_LEN];
  203. int rc = gsk_attribute_set_enum(h, id, value);
  204. switch(rc) {
  205. case GSK_OK:
  206. return CURLE_OK;
  207. case GSK_ERROR_IO:
  208. failf(data, "gsk_attribute_set_enum() I/O error: %s",
  209. Curl_strerror(errno, buffer, sizeof(buffer)));
  210. break;
  211. case GSK_ATTRIBUTE_INVALID_ID:
  212. if(unsupported_ok)
  213. return CURLE_UNSUPPORTED_PROTOCOL;
  214. default:
  215. failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
  216. break;
  217. }
  218. return CURLE_SSL_CONNECT_ERROR;
  219. }
  220. static CURLcode set_buffer(struct Curl_easy *data, gsk_handle h,
  221. GSK_BUF_ID id, const char *buf, bool unsupported_ok)
  222. {
  223. char buffer[STRERROR_LEN];
  224. int rc = gsk_attribute_set_buffer(h, id, buf, 0);
  225. switch(rc) {
  226. case GSK_OK:
  227. return CURLE_OK;
  228. case GSK_ERROR_IO:
  229. failf(data, "gsk_attribute_set_buffer() I/O error: %s",
  230. Curl_strerror(errno, buffer, sizeof(buffer)));
  231. break;
  232. case GSK_ATTRIBUTE_INVALID_ID:
  233. if(unsupported_ok)
  234. return CURLE_UNSUPPORTED_PROTOCOL;
  235. default:
  236. failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
  237. break;
  238. }
  239. return CURLE_SSL_CONNECT_ERROR;
  240. }
  241. static CURLcode set_numeric(struct Curl_easy *data,
  242. gsk_handle h, GSK_NUM_ID id, int value)
  243. {
  244. char buffer[STRERROR_LEN];
  245. int rc = gsk_attribute_set_numeric_value(h, id, value);
  246. switch(rc) {
  247. case GSK_OK:
  248. return CURLE_OK;
  249. case GSK_ERROR_IO:
  250. failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
  251. Curl_strerror(errno, buffer, sizeof(buffer)));
  252. break;
  253. default:
  254. failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
  255. break;
  256. }
  257. return CURLE_SSL_CONNECT_ERROR;
  258. }
  259. static CURLcode set_callback(struct Curl_easy *data,
  260. gsk_handle h, GSK_CALLBACK_ID id, void *info)
  261. {
  262. char buffer[STRERROR_LEN];
  263. int rc = gsk_attribute_set_callback(h, id, info);
  264. switch(rc) {
  265. case GSK_OK:
  266. return CURLE_OK;
  267. case GSK_ERROR_IO:
  268. failf(data, "gsk_attribute_set_callback() I/O error: %s",
  269. Curl_strerror(errno, buffer, sizeof(buffer)));
  270. break;
  271. default:
  272. failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
  273. break;
  274. }
  275. return CURLE_SSL_CONNECT_ERROR;
  276. }
  277. static CURLcode set_ciphers(struct Curl_easy *data,
  278. gsk_handle h, unsigned int *protoflags)
  279. {
  280. struct connectdata *conn = data->conn;
  281. const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
  282. const char *clp;
  283. const struct gskit_cipher *ctp;
  284. int i;
  285. int l;
  286. bool unsupported;
  287. CURLcode result;
  288. struct {
  289. char *buf;
  290. char *ptr;
  291. } ciphers[CURL_GSKPROTO_LAST];
  292. /* Compile cipher list into GSKit-compatible cipher lists. */
  293. if(!cipherlist)
  294. return CURLE_OK;
  295. while(is_separator(*cipherlist)) /* Skip initial separators. */
  296. cipherlist++;
  297. if(!*cipherlist)
  298. return CURLE_OK;
  299. /* We allocate GSKit buffers of the same size as the input string: since
  300. GSKit tokens are always shorter than their cipher names, allocated buffers
  301. will always be large enough to accommodate the result. */
  302. l = strlen(cipherlist) + 1;
  303. memset((char *) ciphers, 0, sizeof(ciphers));
  304. for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
  305. ciphers[i].buf = malloc(l);
  306. if(!ciphers[i].buf) {
  307. while(i--)
  308. free(ciphers[i].buf);
  309. return CURLE_OUT_OF_MEMORY;
  310. }
  311. ciphers[i].ptr = ciphers[i].buf;
  312. *ciphers[i].ptr = '\0';
  313. }
  314. /* Process each cipher in input string. */
  315. unsupported = FALSE;
  316. result = CURLE_OK;
  317. for(;;) {
  318. for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
  319. cipherlist++;
  320. l = cipherlist - clp;
  321. if(!l)
  322. break;
  323. /* Search the cipher in our table. */
  324. for(ctp = ciphertable; ctp->name; ctp++)
  325. if(strncasecompare(ctp->name, clp, l) && !ctp->name[l])
  326. break;
  327. if(!ctp->name) {
  328. failf(data, "Unknown cipher %.*s", l, clp);
  329. result = CURLE_SSL_CIPHER;
  330. }
  331. else {
  332. unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
  333. CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
  334. for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
  335. if(ctp->versions & (1 << i)) {
  336. strcpy(ciphers[i].ptr, ctp->gsktoken);
  337. ciphers[i].ptr += strlen(ctp->gsktoken);
  338. }
  339. }
  340. }
  341. /* Advance to next cipher name or end of string. */
  342. while(is_separator(*cipherlist))
  343. cipherlist++;
  344. }
  345. /* Disable protocols with empty cipher lists. */
  346. for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
  347. if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
  348. *protoflags &= ~(1 << i);
  349. ciphers[i].buf[0] = '\0';
  350. }
  351. }
  352. /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
  353. if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
  354. result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
  355. ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
  356. if(result == CURLE_UNSUPPORTED_PROTOCOL) {
  357. result = CURLE_OK;
  358. if(unsupported) {
  359. failf(data, "TLSv1.1-only ciphers are not yet supported");
  360. result = CURLE_SSL_CIPHER;
  361. }
  362. }
  363. }
  364. if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
  365. result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
  366. ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
  367. if(result == CURLE_UNSUPPORTED_PROTOCOL) {
  368. result = CURLE_OK;
  369. if(unsupported) {
  370. failf(data, "TLSv1.2-only ciphers are not yet supported");
  371. result = CURLE_SSL_CIPHER;
  372. }
  373. }
  374. }
  375. /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
  376. the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
  377. if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
  378. result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
  379. ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
  380. if(result == CURLE_UNSUPPORTED_PROTOCOL) {
  381. result = CURLE_OK;
  382. strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
  383. ciphers[CURL_GSKPROTO_TLSV10].ptr);
  384. }
  385. }
  386. /* Set-up other ciphers. */
  387. if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
  388. result = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
  389. ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
  390. if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
  391. result = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
  392. ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
  393. /* Clean-up. */
  394. for(i = 0; i < CURL_GSKPROTO_LAST; i++)
  395. free(ciphers[i].buf);
  396. return result;
  397. }
  398. static int gskit_init(void)
  399. {
  400. /* No initialization needed. */
  401. return 1;
  402. }
  403. static void gskit_cleanup(void)
  404. {
  405. /* Nothing to do. */
  406. }
  407. static CURLcode init_environment(struct Curl_easy *data,
  408. gsk_handle *envir, const char *appid,
  409. const char *file, const char *label,
  410. const char *password)
  411. {
  412. int rc;
  413. CURLcode result;
  414. gsk_handle h;
  415. /* Creates the GSKit environment. */
  416. rc = gsk_environment_open(&h);
  417. switch(rc) {
  418. case GSK_OK:
  419. break;
  420. case GSK_INSUFFICIENT_STORAGE:
  421. return CURLE_OUT_OF_MEMORY;
  422. default:
  423. failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
  424. return CURLE_SSL_CONNECT_ERROR;
  425. }
  426. result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
  427. if(!result && appid)
  428. result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
  429. if(!result && file)
  430. result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
  431. if(!result && label)
  432. result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
  433. if(!result && password)
  434. result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
  435. if(!result) {
  436. /* Locate CAs, Client certificate and key according to our settings.
  437. Note: this call may be blocking for some tenths of seconds. */
  438. result = gskit_status(data, gsk_environment_init(h),
  439. "gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
  440. if(!result) {
  441. *envir = h;
  442. return result;
  443. }
  444. }
  445. /* Error: rollback. */
  446. gsk_environment_close(&h);
  447. return result;
  448. }
  449. static void cancel_async_handshake(struct connectdata *conn, int sockindex)
  450. {
  451. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  452. Qso_OverlappedIO_t cstat;
  453. DEBUGASSERT(BACKEND);
  454. if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
  455. QsoWaitForIOCompletion(BACKEND->iocport, &cstat, (struct timeval *) NULL);
  456. }
  457. static void close_async_handshake(struct ssl_connect_data *connssl)
  458. {
  459. DEBUGASSERT(BACKEND);
  460. QsoDestroyIOCompletionPort(BACKEND->iocport);
  461. BACKEND->iocport = -1;
  462. }
  463. static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
  464. int directions)
  465. {
  466. #ifndef CURL_DISABLE_PROXY
  467. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  468. struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex];
  469. struct pollfd fds[2];
  470. int n;
  471. int m;
  472. int i;
  473. int ret = 0;
  474. char buf[CURL_MAX_WRITE_SIZE];
  475. DEBUGASSERT(BACKEND);
  476. DEBUGASSERT(connproxyssl->backend);
  477. if(!connssl->use || !connproxyssl->use)
  478. return 0; /* No SSL over SSL: OK. */
  479. n = 1;
  480. fds[0].fd = BACKEND->remotefd;
  481. fds[1].fd = conn->sock[sockindex];
  482. if(directions & SOS_READ) {
  483. fds[0].events |= POLLOUT;
  484. }
  485. if(directions & SOS_WRITE) {
  486. n = 2;
  487. fds[0].events |= POLLIN;
  488. fds[1].events |= POLLOUT;
  489. }
  490. i = Curl_poll(fds, n, 0);
  491. if(i < 0)
  492. return -1; /* Select error. */
  493. if(fds[0].revents & POLLOUT) {
  494. /* Try getting data from HTTPS proxy and pipe it upstream. */
  495. n = 0;
  496. i = gsk_secure_soc_read(connproxyssl->backend->handle,
  497. buf, sizeof(buf), &n);
  498. switch(i) {
  499. case GSK_OK:
  500. if(n) {
  501. i = write(BACKEND->remotefd, buf, n);
  502. if(i < 0)
  503. return -1;
  504. ret = 1;
  505. }
  506. break;
  507. case GSK_OS400_ERROR_TIMED_OUT:
  508. case GSK_WOULD_BLOCK:
  509. break;
  510. default:
  511. return -1;
  512. }
  513. }
  514. if((fds[0].revents & POLLIN) && (fds[1].revents & POLLOUT)) {
  515. /* Pipe data to HTTPS proxy. */
  516. n = read(BACKEND->remotefd, buf, sizeof(buf));
  517. if(n < 0)
  518. return -1;
  519. if(n) {
  520. i = gsk_secure_soc_write(connproxyssl->backend->handle, buf, n, &m);
  521. if(i != GSK_OK || n != m)
  522. return -1;
  523. ret = 1;
  524. }
  525. }
  526. return ret; /* OK */
  527. #else
  528. return 0;
  529. #endif
  530. }
  531. static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data,
  532. struct connectdata *conn, int sockindex)
  533. {
  534. DEBUGASSERT(BACKEND);
  535. if(BACKEND->handle) {
  536. gskit_status(data, gsk_secure_soc_close(&BACKEND->handle),
  537. "gsk_secure_soc_close()", 0);
  538. /* Last chance to drain output. */
  539. while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
  540. ;
  541. BACKEND->handle = (gsk_handle) NULL;
  542. #ifndef CURL_DISABLE_PROXY
  543. if(BACKEND->localfd >= 0) {
  544. close(BACKEND->localfd);
  545. BACKEND->localfd = -1;
  546. }
  547. if(BACKEND->remotefd >= 0) {
  548. close(BACKEND->remotefd);
  549. BACKEND->remotefd = -1;
  550. }
  551. #endif
  552. }
  553. if(BACKEND->iocport >= 0)
  554. close_async_handshake(connssl);
  555. }
  556. static ssize_t gskit_send(struct Curl_easy *data, int sockindex,
  557. const void *mem, size_t len, CURLcode *curlcode)
  558. {
  559. struct connectdata *conn = data->conn;
  560. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  561. CURLcode cc = CURLE_SEND_ERROR;
  562. int written;
  563. DEBUGASSERT(BACKEND);
  564. if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
  565. cc = gskit_status(data,
  566. gsk_secure_soc_write(BACKEND->handle,
  567. (char *) mem, (int) len, &written),
  568. "gsk_secure_soc_write()", CURLE_SEND_ERROR);
  569. if(cc == CURLE_OK)
  570. if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) < 0)
  571. cc = CURLE_SEND_ERROR;
  572. }
  573. if(cc != CURLE_OK) {
  574. *curlcode = cc;
  575. written = -1;
  576. }
  577. return (ssize_t) written; /* number of bytes */
  578. }
  579. static ssize_t gskit_recv(struct Curl_easy *data, int num, char *buf,
  580. size_t buffersize, CURLcode *curlcode)
  581. {
  582. struct connectdata *conn = data->conn;
  583. struct ssl_connect_data *connssl = &conn->ssl[num];
  584. int nread;
  585. CURLcode cc = CURLE_RECV_ERROR;
  586. DEBUGASSERT(BACKEND);
  587. if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
  588. int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
  589. cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle,
  590. buf, buffsize, &nread),
  591. "gsk_secure_soc_read()", CURLE_RECV_ERROR);
  592. }
  593. switch(cc) {
  594. case CURLE_OK:
  595. break;
  596. case CURLE_OPERATION_TIMEDOUT:
  597. cc = CURLE_AGAIN;
  598. default:
  599. *curlcode = cc;
  600. nread = -1;
  601. break;
  602. }
  603. return (ssize_t) nread;
  604. }
  605. static CURLcode
  606. set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data)
  607. {
  608. struct connectdata *conn = data->conn;
  609. long ssl_version = SSL_CONN_CONFIG(version);
  610. long ssl_version_max = SSL_CONN_CONFIG(version_max);
  611. long i = ssl_version;
  612. switch(ssl_version_max) {
  613. case CURL_SSLVERSION_MAX_NONE:
  614. case CURL_SSLVERSION_MAX_DEFAULT:
  615. ssl_version_max = CURL_SSLVERSION_TLSv1_2;
  616. break;
  617. }
  618. for(; i <= (ssl_version_max >> 16); ++i) {
  619. switch(i) {
  620. case CURL_SSLVERSION_TLSv1_0:
  621. *protoflags |= CURL_GSKPROTO_TLSV10_MASK;
  622. break;
  623. case CURL_SSLVERSION_TLSv1_1:
  624. *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
  625. break;
  626. case CURL_SSLVERSION_TLSv1_2:
  627. *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
  628. break;
  629. case CURL_SSLVERSION_TLSv1_3:
  630. failf(data, "GSKit: TLS 1.3 is not yet supported");
  631. return CURLE_SSL_CONNECT_ERROR;
  632. }
  633. }
  634. return CURLE_OK;
  635. }
  636. static CURLcode gskit_connect_step1(struct Curl_easy *data,
  637. struct connectdata *conn, int sockindex)
  638. {
  639. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  640. gsk_handle envir;
  641. CURLcode result;
  642. const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
  643. const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
  644. const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert);
  645. const long int ssl_version = SSL_CONN_CONFIG(version);
  646. const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
  647. const char * const hostname = SSL_HOST_NAME();
  648. const char *sni;
  649. unsigned int protoflags = 0;
  650. Qso_OverlappedIO_t commarea;
  651. #ifndef CURL_DISABLE_PROXY
  652. int sockpair[2];
  653. static const int sobufsize = CURL_MAX_WRITE_SIZE;
  654. #endif
  655. /* Create SSL environment, start (preferably asynchronous) handshake. */
  656. DEBUGASSERT(BACKEND);
  657. BACKEND->handle = (gsk_handle) NULL;
  658. BACKEND->iocport = -1;
  659. #ifndef CURL_DISABLE_PROXY
  660. BACKEND->localfd = -1;
  661. BACKEND->remotefd = -1;
  662. #endif
  663. /* GSKit supports two ways of specifying an SSL context: either by
  664. * application identifier (that should have been defined at the system
  665. * level) or by keyring file, password and certificate label.
  666. * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
  667. * application identifier of the certificate label.
  668. * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
  669. * It is not possible to have different keyrings for the CAs and the
  670. * local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
  671. * the keyring file.
  672. * If no key password is given and the keyring is the system keyring,
  673. * application identifier mode is tried first, as recommended in IBM doc.
  674. */
  675. envir = (gsk_handle) NULL;
  676. if(keyringlabel && *keyringlabel && !keyringpwd &&
  677. !strcmp(keyringfile, CURL_CA_BUNDLE)) {
  678. /* Try application identifier mode. */
  679. init_environment(data, &envir, keyringlabel, (const char *) NULL,
  680. (const char *) NULL, (const char *) NULL);
  681. }
  682. if(!envir) {
  683. /* Use keyring mode. */
  684. result = init_environment(data, &envir, (const char *) NULL,
  685. keyringfile, keyringlabel, keyringpwd);
  686. if(result)
  687. return result;
  688. }
  689. /* Create secure session. */
  690. result = gskit_status(data, gsk_secure_soc_open(envir, &BACKEND->handle),
  691. "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
  692. gsk_environment_close(&envir);
  693. if(result)
  694. return result;
  695. #ifndef CURL_DISABLE_PROXY
  696. /* Establish a pipelining socket pair for SSL over SSL. */
  697. if(conn->proxy_ssl[sockindex].use) {
  698. if(Curl_socketpair(0, 0, 0, sockpair))
  699. return CURLE_SSL_CONNECT_ERROR;
  700. BACKEND->localfd = sockpair[0];
  701. BACKEND->remotefd = sockpair[1];
  702. setsockopt(BACKEND->localfd, SOL_SOCKET, SO_RCVBUF,
  703. (void *) sobufsize, sizeof(sobufsize));
  704. setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_RCVBUF,
  705. (void *) sobufsize, sizeof(sobufsize));
  706. setsockopt(BACKEND->localfd, SOL_SOCKET, SO_SNDBUF,
  707. (void *) sobufsize, sizeof(sobufsize));
  708. setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_SNDBUF,
  709. (void *) sobufsize, sizeof(sobufsize));
  710. curlx_nonblock(BACKEND->localfd, TRUE);
  711. curlx_nonblock(BACKEND->remotefd, TRUE);
  712. }
  713. #endif
  714. /* Determine which SSL/TLS version should be enabled. */
  715. sni = hostname;
  716. switch(ssl_version) {
  717. case CURL_SSLVERSION_SSLv2:
  718. protoflags = CURL_GSKPROTO_SSLV2_MASK;
  719. sni = NULL;
  720. break;
  721. case CURL_SSLVERSION_SSLv3:
  722. protoflags = CURL_GSKPROTO_SSLV3_MASK;
  723. sni = NULL;
  724. break;
  725. case CURL_SSLVERSION_DEFAULT:
  726. case CURL_SSLVERSION_TLSv1:
  727. protoflags = CURL_GSKPROTO_TLSV10_MASK |
  728. CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
  729. break;
  730. case CURL_SSLVERSION_TLSv1_0:
  731. case CURL_SSLVERSION_TLSv1_1:
  732. case CURL_SSLVERSION_TLSv1_2:
  733. case CURL_SSLVERSION_TLSv1_3:
  734. result = set_ssl_version_min_max(&protoflags, data);
  735. if(result != CURLE_OK)
  736. return result;
  737. break;
  738. default:
  739. failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
  740. return CURLE_SSL_CONNECT_ERROR;
  741. }
  742. /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
  743. if(sni) {
  744. char *snihost = Curl_ssl_snihost(data, sni, NULL);
  745. if(!snihost) {
  746. failf(data, "Failed to set SNI");
  747. return CURLE_SSL_CONNECT_ERROR;
  748. }
  749. result = set_buffer(data, BACKEND->handle,
  750. GSK_SSL_EXTN_SERVERNAME_REQUEST, snihost, TRUE);
  751. if(result == CURLE_UNSUPPORTED_PROTOCOL)
  752. result = CURLE_OK;
  753. }
  754. /* Set session parameters. */
  755. if(!result) {
  756. /* Compute the handshake timeout. Since GSKit granularity is 1 second,
  757. we round up the required value. */
  758. timediff_t timeout = Curl_timeleft(data, NULL, TRUE);
  759. if(timeout < 0)
  760. result = CURLE_OPERATION_TIMEDOUT;
  761. else
  762. result = set_numeric(data, BACKEND->handle, GSK_HANDSHAKE_TIMEOUT,
  763. (timeout + 999) / 1000);
  764. }
  765. if(!result)
  766. result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1);
  767. if(!result)
  768. #ifndef CURL_DISABLE_PROXY
  769. result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
  770. BACKEND->localfd: conn->sock[sockindex]);
  771. #else
  772. result = set_numeric(data, BACKEND->handle, GSK_FD,
  773. conn->sock[sockindex]);
  774. #endif
  775. if(!result)
  776. result = set_ciphers(data, BACKEND->handle, &protoflags);
  777. if(!protoflags) {
  778. failf(data, "No SSL protocol/cipher combination enabled");
  779. result = CURLE_SSL_CIPHER;
  780. }
  781. if(!result)
  782. result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV2,
  783. (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
  784. GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
  785. if(!result)
  786. result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV3,
  787. (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
  788. GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
  789. if(!result)
  790. result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV1,
  791. (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
  792. GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
  793. if(!result) {
  794. result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV11,
  795. (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
  796. GSK_TRUE: GSK_FALSE, TRUE);
  797. if(result == CURLE_UNSUPPORTED_PROTOCOL) {
  798. result = CURLE_OK;
  799. if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
  800. failf(data, "TLS 1.1 not yet supported");
  801. result = CURLE_SSL_CIPHER;
  802. }
  803. }
  804. }
  805. if(!result) {
  806. result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV12,
  807. (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
  808. GSK_TRUE: GSK_FALSE, TRUE);
  809. if(result == CURLE_UNSUPPORTED_PROTOCOL) {
  810. result = CURLE_OK;
  811. if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
  812. failf(data, "TLS 1.2 not yet supported");
  813. result = CURLE_SSL_CIPHER;
  814. }
  815. }
  816. }
  817. if(!result)
  818. result = set_enum(data, BACKEND->handle, GSK_SERVER_AUTH_TYPE,
  819. verifypeer? GSK_SERVER_AUTH_FULL:
  820. GSK_SERVER_AUTH_PASSTHRU, FALSE);
  821. if(!result) {
  822. /* Start handshake. Try asynchronous first. */
  823. memset(&commarea, 0, sizeof(commarea));
  824. BACKEND->iocport = QsoCreateIOCompletionPort();
  825. if(BACKEND->iocport != -1) {
  826. result = gskit_status(data,
  827. gsk_secure_soc_startInit(BACKEND->handle,
  828. BACKEND->iocport,
  829. &commarea),
  830. "gsk_secure_soc_startInit()",
  831. CURLE_SSL_CONNECT_ERROR);
  832. if(!result) {
  833. connssl->connecting_state = ssl_connect_2;
  834. return CURLE_OK;
  835. }
  836. else
  837. close_async_handshake(connssl);
  838. }
  839. else if(errno != ENOBUFS)
  840. result = gskit_status(data, GSK_ERROR_IO,
  841. "QsoCreateIOCompletionPort()", 0);
  842. #ifndef CURL_DISABLE_PROXY
  843. else if(conn->proxy_ssl[sockindex].use) {
  844. /* Cannot pipeline while handshaking synchronously. */
  845. result = CURLE_SSL_CONNECT_ERROR;
  846. }
  847. #endif
  848. else {
  849. /* No more completion port available. Use synchronous IO. */
  850. result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle),
  851. "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
  852. if(!result) {
  853. connssl->connecting_state = ssl_connect_3;
  854. return CURLE_OK;
  855. }
  856. }
  857. }
  858. /* Error: rollback. */
  859. close_one(connssl, data, conn, sockindex);
  860. return result;
  861. }
  862. static CURLcode gskit_connect_step2(struct Curl_easy *data,
  863. struct connectdata *conn, int sockindex,
  864. bool nonblocking)
  865. {
  866. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  867. Qso_OverlappedIO_t cstat;
  868. struct timeval stmv;
  869. CURLcode result;
  870. /* Poll or wait for end of SSL asynchronous handshake. */
  871. DEBUGASSERT(BACKEND);
  872. for(;;) {
  873. timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
  874. stmv.tv_sec = 0;
  875. stmv.tv_usec = 0;
  876. if(timeout_ms < 0)
  877. timeout_ms = 0;
  878. switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat,
  879. curlx_mstotv(&stmv, timeout_ms))) {
  880. case 1: /* Operation complete. */
  881. break;
  882. case -1: /* An error occurred: handshake still in progress. */
  883. if(errno == EINTR) {
  884. if(nonblocking)
  885. return CURLE_OK;
  886. continue; /* Retry. */
  887. }
  888. if(errno != ETIME) {
  889. char buffer[STRERROR_LEN];
  890. failf(data, "QsoWaitForIOCompletion() I/O error: %s",
  891. Curl_strerror(errno, buffer, sizeof(buffer)));
  892. cancel_async_handshake(conn, sockindex);
  893. close_async_handshake(connssl);
  894. return CURLE_SSL_CONNECT_ERROR;
  895. }
  896. /* FALL INTO... */
  897. case 0: /* Handshake in progress, timeout occurred. */
  898. if(nonblocking)
  899. return CURLE_OK;
  900. cancel_async_handshake(conn, sockindex);
  901. close_async_handshake(connssl);
  902. return CURLE_OPERATION_TIMEDOUT;
  903. }
  904. break;
  905. }
  906. result = gskit_status(data, cstat.returnValue, "SSL handshake",
  907. CURLE_SSL_CONNECT_ERROR);
  908. if(!result)
  909. connssl->connecting_state = ssl_connect_3;
  910. close_async_handshake(connssl);
  911. return result;
  912. }
  913. static CURLcode gskit_connect_step3(struct Curl_easy *data,
  914. struct connectdata *conn, int sockindex)
  915. {
  916. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  917. const gsk_cert_data_elem *cdev;
  918. int cdec;
  919. const gsk_cert_data_elem *p;
  920. const char *cert = (const char *) NULL;
  921. const char *certend;
  922. const char *ptr;
  923. CURLcode result;
  924. /* SSL handshake done: gather certificate info and verify host. */
  925. DEBUGASSERT(BACKEND);
  926. if(gskit_status(data, gsk_attribute_get_cert_info(BACKEND->handle,
  927. GSK_PARTNER_CERT_INFO,
  928. &cdev, &cdec),
  929. "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
  930. CURLE_OK) {
  931. int i;
  932. infof(data, "Server certificate:");
  933. p = cdev;
  934. for(i = 0; i++ < cdec; p++)
  935. switch(p->cert_data_id) {
  936. case CERT_BODY_DER:
  937. cert = p->cert_data_p;
  938. certend = cert + cdev->cert_data_l;
  939. break;
  940. case CERT_DN_PRINTABLE:
  941. infof(data, "\t subject: %.*s", p->cert_data_l, p->cert_data_p);
  942. break;
  943. case CERT_ISSUER_DN_PRINTABLE:
  944. infof(data, "\t issuer: %.*s", p->cert_data_l, p->cert_data_p);
  945. break;
  946. case CERT_VALID_FROM:
  947. infof(data, "\t start date: %.*s", p->cert_data_l, p->cert_data_p);
  948. break;
  949. case CERT_VALID_TO:
  950. infof(data, "\t expire date: %.*s", p->cert_data_l, p->cert_data_p);
  951. break;
  952. }
  953. }
  954. /* Verify host. */
  955. result = Curl_verifyhost(data, conn, cert, certend);
  956. if(result)
  957. return result;
  958. /* The only place GSKit can get the whole CA chain is a validation
  959. callback where no user data pointer is available. Therefore it's not
  960. possible to copy this chain into our structures for CAINFO.
  961. However the server certificate may be available, thus we can return
  962. info about it. */
  963. if(data->set.ssl.certinfo) {
  964. result = Curl_ssl_init_certinfo(data, 1);
  965. if(result)
  966. return result;
  967. if(cert) {
  968. result = Curl_extract_certinfo(data, 0, cert, certend);
  969. if(result)
  970. return result;
  971. }
  972. }
  973. /* Check pinned public key. */
  974. ptr = SSL_PINNED_PUB_KEY();
  975. if(!result && ptr) {
  976. struct Curl_X509certificate x509;
  977. struct Curl_asn1Element *p;
  978. memset(&x509, 0, sizeof(x509));
  979. if(Curl_parseX509(&x509, cert, certend))
  980. return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
  981. p = &x509.subjectPublicKeyInfo;
  982. result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header);
  983. if(result) {
  984. failf(data, "SSL: public key does not match pinned public key");
  985. return result;
  986. }
  987. }
  988. connssl->connecting_state = ssl_connect_done;
  989. return CURLE_OK;
  990. }
  991. static CURLcode gskit_connect_common(struct Curl_easy *data,
  992. struct connectdata *conn, int sockindex,
  993. bool nonblocking, bool *done)
  994. {
  995. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  996. timediff_t timeout_ms;
  997. CURLcode result = CURLE_OK;
  998. *done = connssl->state == ssl_connection_complete;
  999. if(*done)
  1000. return CURLE_OK;
  1001. /* Step 1: create session, start handshake. */
  1002. if(connssl->connecting_state == ssl_connect_1) {
  1003. /* check allowed time left */
  1004. timeout_ms = Curl_timeleft(data, NULL, TRUE);
  1005. if(timeout_ms < 0) {
  1006. /* no need to continue if time already is up */
  1007. failf(data, "SSL connection timeout");
  1008. result = CURLE_OPERATION_TIMEDOUT;
  1009. }
  1010. else
  1011. result = gskit_connect_step1(data, conn, sockindex);
  1012. }
  1013. /* Handle handshake pipelining. */
  1014. if(!result)
  1015. if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
  1016. result = CURLE_SSL_CONNECT_ERROR;
  1017. /* Step 2: check if handshake is over. */
  1018. if(!result && connssl->connecting_state == ssl_connect_2) {
  1019. /* check allowed time left */
  1020. timeout_ms = Curl_timeleft(data, NULL, TRUE);
  1021. if(timeout_ms < 0) {
  1022. /* no need to continue if time already is up */
  1023. failf(data, "SSL connection timeout");
  1024. result = CURLE_OPERATION_TIMEDOUT;
  1025. }
  1026. else
  1027. result = gskit_connect_step2(data, conn, sockindex, nonblocking);
  1028. }
  1029. /* Handle handshake pipelining. */
  1030. if(!result)
  1031. if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
  1032. result = CURLE_SSL_CONNECT_ERROR;
  1033. /* Step 3: gather certificate info, verify host. */
  1034. if(!result && connssl->connecting_state == ssl_connect_3)
  1035. result = gskit_connect_step3(data, conn, sockindex);
  1036. if(result)
  1037. close_one(connssl, data, conn, sockindex);
  1038. else if(connssl->connecting_state == ssl_connect_done) {
  1039. connssl->state = ssl_connection_complete;
  1040. connssl->connecting_state = ssl_connect_1;
  1041. conn->recv[sockindex] = gskit_recv;
  1042. conn->send[sockindex] = gskit_send;
  1043. *done = TRUE;
  1044. }
  1045. return result;
  1046. }
  1047. static CURLcode gskit_connect_nonblocking(struct Curl_easy *data,
  1048. struct connectdata *conn,
  1049. int sockindex, bool *done)
  1050. {
  1051. CURLcode result;
  1052. result = gskit_connect_common(data, conn, sockindex, TRUE, done);
  1053. if(*done || result)
  1054. conn->ssl[sockindex].connecting_state = ssl_connect_1;
  1055. return result;
  1056. }
  1057. static CURLcode gskit_connect(struct Curl_easy *data,
  1058. struct connectdata *conn, int sockindex)
  1059. {
  1060. CURLcode result;
  1061. bool done;
  1062. conn->ssl[sockindex].connecting_state = ssl_connect_1;
  1063. result = gskit_connect_common(data, conn, sockindex, FALSE, &done);
  1064. if(result)
  1065. return result;
  1066. DEBUGASSERT(done);
  1067. return CURLE_OK;
  1068. }
  1069. static void gskit_close(struct Curl_easy *data, struct connectdata *conn,
  1070. int sockindex)
  1071. {
  1072. close_one(&conn->ssl[sockindex], data, conn, sockindex);
  1073. #ifndef CURL_DISABLE_PROXY
  1074. close_one(&conn->proxy_ssl[sockindex], data, conn, sockindex);
  1075. #endif
  1076. }
  1077. static int gskit_shutdown(struct Curl_easy *data,
  1078. struct connectdata *conn, int sockindex)
  1079. {
  1080. struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  1081. int what;
  1082. int rc;
  1083. char buf[120];
  1084. int loop = 10; /* don't get stuck */
  1085. DEBUGASSERT(BACKEND);
  1086. if(!BACKEND->handle)
  1087. return 0;
  1088. #ifndef CURL_DISABLE_FTP
  1089. if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
  1090. return 0;
  1091. #endif
  1092. close_one(connssl, data, conn, sockindex);
  1093. rc = 0;
  1094. what = SOCKET_READABLE(conn->sock[sockindex],
  1095. SSL_SHUTDOWN_TIMEOUT);
  1096. while(loop--) {
  1097. ssize_t nread;
  1098. if(what < 0) {
  1099. /* anything that gets here is fatally bad */
  1100. failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
  1101. rc = -1;
  1102. break;
  1103. }
  1104. if(!what) { /* timeout */
  1105. failf(data, "SSL shutdown timeout");
  1106. break;
  1107. }
  1108. /* Something to read, let's do it and hope that it is the close
  1109. notify alert from the server. No way to gsk_secure_soc_read() now, so
  1110. use read(). */
  1111. nread = read(conn->sock[sockindex], buf, sizeof(buf));
  1112. if(nread < 0) {
  1113. char buffer[STRERROR_LEN];
  1114. failf(data, "read: %s", Curl_strerror(errno, buffer, sizeof(buffer)));
  1115. rc = -1;
  1116. }
  1117. if(nread <= 0)
  1118. break;
  1119. what = SOCKET_READABLE(conn->sock[sockindex], 0);
  1120. }
  1121. return rc;
  1122. }
  1123. static size_t gskit_version(char *buffer, size_t size)
  1124. {
  1125. return msnprintf(buffer, size, "GSKit");
  1126. }
  1127. static int gskit_check_cxn(struct connectdata *cxn)
  1128. {
  1129. struct ssl_connect_data *connssl = &cxn->ssl[FIRSTSOCKET];
  1130. int err;
  1131. int errlen;
  1132. /* The only thing that can be tested here is at the socket level. */
  1133. DEBUGASSERT(BACKEND);
  1134. if(!BACKEND->handle)
  1135. return 0; /* connection has been closed */
  1136. err = 0;
  1137. errlen = sizeof(err);
  1138. if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
  1139. (unsigned char *) &err, &errlen) ||
  1140. errlen != sizeof(err) || err)
  1141. return 0; /* connection has been closed */
  1142. return -1; /* connection status unknown */
  1143. }
  1144. static void *gskit_get_internals(struct ssl_connect_data *connssl,
  1145. CURLINFO info UNUSED_PARAM)
  1146. {
  1147. (void)info;
  1148. DEBUGASSERT(BACKEND);
  1149. return BACKEND->handle;
  1150. }
  1151. const struct Curl_ssl Curl_ssl_gskit = {
  1152. { CURLSSLBACKEND_GSKIT, "gskit" }, /* info */
  1153. SSLSUPP_CERTINFO |
  1154. SSLSUPP_PINNEDPUBKEY,
  1155. sizeof(struct ssl_backend_data),
  1156. gskit_init, /* init */
  1157. gskit_cleanup, /* cleanup */
  1158. gskit_version, /* version */
  1159. gskit_check_cxn, /* check_cxn */
  1160. gskit_shutdown, /* shutdown */
  1161. Curl_none_data_pending, /* data_pending */
  1162. Curl_none_random, /* random */
  1163. Curl_none_cert_status_request, /* cert_status_request */
  1164. gskit_connect, /* connect */
  1165. gskit_connect_nonblocking, /* connect_nonblocking */
  1166. Curl_ssl_getsock, /* getsock */
  1167. gskit_get_internals, /* get_internals */
  1168. gskit_close, /* close_one */
  1169. Curl_none_close_all, /* close_all */
  1170. /* No session handling for GSKit */
  1171. Curl_none_session_free, /* session_free */
  1172. Curl_none_set_engine, /* set_engine */
  1173. Curl_none_set_engine_default, /* set_engine_default */
  1174. Curl_none_engines_list, /* engines_list */
  1175. Curl_none_false_start, /* false_start */
  1176. NULL, /* sha256sum */
  1177. NULL, /* associate_connection */
  1178. NULL /* disassociate_connection */
  1179. };
  1180. #endif /* USE_GSKIT */