schannel.c 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
  9. * Copyright (C) Marc Hoersken, <info@marc-hoersken.de>
  10. * Copyright (C) Mark Salisbury, <mark.salisbury@hp.com>
  11. *
  12. * This software is licensed as described in the file COPYING, which
  13. * you should have received as part of this distribution. The terms
  14. * are also available at https://curl.se/docs/copyright.html.
  15. *
  16. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  17. * copies of the Software, and permit persons to whom the Software is
  18. * furnished to do so, under the terms of the COPYING file.
  19. *
  20. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  21. * KIND, either express or implied.
  22. *
  23. * SPDX-License-Identifier: curl
  24. *
  25. ***************************************************************************/
  26. /*
  27. * Source file for all Schannel-specific code for the TLS/SSL layer. No code
  28. * but vtls.c should ever call or use these functions.
  29. */
  30. #include "curl_setup.h"
  31. #ifdef USE_SCHANNEL
  32. #ifndef USE_WINDOWS_SSPI
  33. # error "cannot compile SCHANNEL support without SSPI."
  34. #endif
  35. #include "schannel.h"
  36. #include "schannel_int.h"
  37. #include "vtls.h"
  38. #include "vtls_int.h"
  39. #include "strcase.h"
  40. #include "sendf.h"
  41. #include "connect.h" /* for the connect timeout */
  42. #include "strerror.h"
  43. #include "select.h" /* for the socket readiness */
  44. #include "inet_pton.h" /* for IP addr SNI check */
  45. #include "curl_multibyte.h"
  46. #include "warnless.h"
  47. #include "x509asn1.h"
  48. #include "curl_printf.h"
  49. #include "multiif.h"
  50. #include "version_win32.h"
  51. #include "rand.h"
  52. /* The last #include file should be: */
  53. #include "curl_memory.h"
  54. #include "memdebug.h"
  55. /* Some verbose debug messages are wrapped by SCH_DEV() instead of DEBUGF()
  56. * and only shown if CURL_SCHANNEL_DEV_DEBUG was defined at build time. These
  57. * messages are extra verbose and intended for curl developers debugging
  58. * Schannel recv decryption.
  59. */
  60. #ifdef CURL_SCHANNEL_DEV_DEBUG
  61. #define SCH_DEV(x) x
  62. #else
  63. #define SCH_DEV(x) do { } while(0)
  64. #endif
  65. /* ALPN requires version 8.1 of the Windows SDK, which was
  66. shipped with Visual Studio 2013, aka _MSC_VER 1800:
  67. https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx
  68. */
  69. #if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(_USING_V110_SDK71_)
  70. # define HAS_ALPN 1
  71. #endif
  72. #ifndef BCRYPT_CHACHA20_POLY1305_ALGORITHM
  73. #define BCRYPT_CHACHA20_POLY1305_ALGORITHM L"CHACHA20_POLY1305"
  74. #endif
  75. #ifndef BCRYPT_CHAIN_MODE_CCM
  76. #define BCRYPT_CHAIN_MODE_CCM L"ChainingModeCCM"
  77. #endif
  78. #ifndef BCRYPT_CHAIN_MODE_GCM
  79. #define BCRYPT_CHAIN_MODE_GCM L"ChainingModeGCM"
  80. #endif
  81. #ifndef BCRYPT_AES_ALGORITHM
  82. #define BCRYPT_AES_ALGORITHM L"AES"
  83. #endif
  84. #ifndef BCRYPT_SHA256_ALGORITHM
  85. #define BCRYPT_SHA256_ALGORITHM L"SHA256"
  86. #endif
  87. #ifndef BCRYPT_SHA384_ALGORITHM
  88. #define BCRYPT_SHA384_ALGORITHM L"SHA384"
  89. #endif
  90. #ifdef HAS_CLIENT_CERT_PATH
  91. #ifdef UNICODE
  92. #define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_W
  93. #else
  94. #define CURL_CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_A
  95. #endif
  96. #endif
  97. #ifndef SP_PROT_TLS1_0_CLIENT
  98. #define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT
  99. #endif
  100. #ifndef SP_PROT_TLS1_1_CLIENT
  101. #define SP_PROT_TLS1_1_CLIENT 0x00000200
  102. #endif
  103. #ifndef SP_PROT_TLS1_2_CLIENT
  104. #define SP_PROT_TLS1_2_CLIENT 0x00000800
  105. #endif
  106. #ifndef SP_PROT_TLS1_3_CLIENT
  107. #define SP_PROT_TLS1_3_CLIENT 0x00002000
  108. #endif
  109. #ifndef SCH_USE_STRONG_CRYPTO
  110. #define SCH_USE_STRONG_CRYPTO 0x00400000
  111. #endif
  112. #ifndef SECBUFFER_ALERT
  113. #define SECBUFFER_ALERT 17
  114. #endif
  115. /* Both schannel buffer sizes must be > 0 */
  116. #define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096
  117. #define CURL_SCHANNEL_BUFFER_FREE_SIZE 1024
  118. #define CERT_THUMBPRINT_STR_LEN 40
  119. #define CERT_THUMBPRINT_DATA_LEN 20
  120. /* Uncomment to force verbose output
  121. * #define infof(x, y, ...) printf(y, __VA_ARGS__)
  122. * #define failf(x, y, ...) printf(y, __VA_ARGS__)
  123. */
  124. #ifndef CALG_SHA_256
  125. # define CALG_SHA_256 0x0000800c
  126. #endif
  127. #ifndef PKCS12_NO_PERSIST_KEY
  128. #define PKCS12_NO_PERSIST_KEY 0x00008000
  129. #endif
  130. static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
  131. struct Curl_easy *data,
  132. const char *pinnedpubkey);
  133. static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
  134. void *BufDataPtr, unsigned long BufByteSize)
  135. {
  136. buffer->cbBuffer = BufByteSize;
  137. buffer->BufferType = BufType;
  138. buffer->pvBuffer = BufDataPtr;
  139. }
  140. static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
  141. unsigned long NumArrElem)
  142. {
  143. desc->ulVersion = SECBUFFER_VERSION;
  144. desc->pBuffers = BufArr;
  145. desc->cBuffers = NumArrElem;
  146. }
  147. static CURLcode
  148. schannel_set_ssl_version_min_max(DWORD *enabled_protocols,
  149. struct Curl_cfilter *cf,
  150. struct Curl_easy *data)
  151. {
  152. struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
  153. long ssl_version = conn_config->version;
  154. long ssl_version_max = (long)conn_config->version_max;
  155. long i = ssl_version;
  156. switch(ssl_version_max) {
  157. case CURL_SSLVERSION_MAX_NONE:
  158. case CURL_SSLVERSION_MAX_DEFAULT:
  159. /* Windows Server 2022 and newer (including Windows 11) support TLS 1.3
  160. built-in. Previous builds of Windows 10 had broken TLS 1.3
  161. implementations that could be enabled via registry.
  162. */
  163. if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT,
  164. VERSION_GREATER_THAN_EQUAL)) {
  165. ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3;
  166. }
  167. else /* Windows 10 and older */
  168. ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
  169. break;
  170. }
  171. for(; i <= (ssl_version_max >> 16); ++i) {
  172. switch(i) {
  173. case CURL_SSLVERSION_TLSv1_0:
  174. (*enabled_protocols) |= SP_PROT_TLS1_0_CLIENT;
  175. break;
  176. case CURL_SSLVERSION_TLSv1_1:
  177. (*enabled_protocols) |= SP_PROT_TLS1_1_CLIENT;
  178. break;
  179. case CURL_SSLVERSION_TLSv1_2:
  180. (*enabled_protocols) |= SP_PROT_TLS1_2_CLIENT;
  181. break;
  182. case CURL_SSLVERSION_TLSv1_3:
  183. /* Windows Server 2022 and newer */
  184. if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT,
  185. VERSION_GREATER_THAN_EQUAL)) {
  186. (*enabled_protocols) |= SP_PROT_TLS1_3_CLIENT;
  187. break;
  188. }
  189. else { /* Windows 10 and older */
  190. failf(data, "schannel: TLS 1.3 not supported on Windows prior to 11");
  191. return CURLE_SSL_CONNECT_ERROR;
  192. }
  193. }
  194. }
  195. return CURLE_OK;
  196. }
  197. /* longest is 26, buffer is slightly bigger */
  198. #define LONGEST_ALG_ID 32
  199. #define CIPHEROPTION(x) {#x, x}
  200. struct algo {
  201. const char *name;
  202. int id;
  203. };
  204. static const struct algo algs[]= {
  205. CIPHEROPTION(CALG_MD2),
  206. CIPHEROPTION(CALG_MD4),
  207. CIPHEROPTION(CALG_MD5),
  208. CIPHEROPTION(CALG_SHA),
  209. CIPHEROPTION(CALG_SHA1),
  210. CIPHEROPTION(CALG_MAC),
  211. CIPHEROPTION(CALG_RSA_SIGN),
  212. CIPHEROPTION(CALG_DSS_SIGN),
  213. /* ifdefs for the options that are defined conditionally in wincrypt.h */
  214. #ifdef CALG_NO_SIGN
  215. CIPHEROPTION(CALG_NO_SIGN),
  216. #endif
  217. CIPHEROPTION(CALG_RSA_KEYX),
  218. CIPHEROPTION(CALG_DES),
  219. #ifdef CALG_3DES_112
  220. CIPHEROPTION(CALG_3DES_112),
  221. #endif
  222. CIPHEROPTION(CALG_3DES),
  223. CIPHEROPTION(CALG_DESX),
  224. CIPHEROPTION(CALG_RC2),
  225. CIPHEROPTION(CALG_RC4),
  226. CIPHEROPTION(CALG_SEAL),
  227. #ifdef CALG_DH_SF
  228. CIPHEROPTION(CALG_DH_SF),
  229. #endif
  230. CIPHEROPTION(CALG_DH_EPHEM),
  231. #ifdef CALG_AGREEDKEY_ANY
  232. CIPHEROPTION(CALG_AGREEDKEY_ANY),
  233. #endif
  234. #ifdef CALG_HUGHES_MD5
  235. CIPHEROPTION(CALG_HUGHES_MD5),
  236. #endif
  237. CIPHEROPTION(CALG_SKIPJACK),
  238. #ifdef CALG_TEK
  239. CIPHEROPTION(CALG_TEK),
  240. #endif
  241. CIPHEROPTION(CALG_CYLINK_MEK),
  242. CIPHEROPTION(CALG_SSL3_SHAMD5),
  243. #ifdef CALG_SSL3_MASTER
  244. CIPHEROPTION(CALG_SSL3_MASTER),
  245. #endif
  246. #ifdef CALG_SCHANNEL_MASTER_HASH
  247. CIPHEROPTION(CALG_SCHANNEL_MASTER_HASH),
  248. #endif
  249. #ifdef CALG_SCHANNEL_MAC_KEY
  250. CIPHEROPTION(CALG_SCHANNEL_MAC_KEY),
  251. #endif
  252. #ifdef CALG_SCHANNEL_ENC_KEY
  253. CIPHEROPTION(CALG_SCHANNEL_ENC_KEY),
  254. #endif
  255. #ifdef CALG_PCT1_MASTER
  256. CIPHEROPTION(CALG_PCT1_MASTER),
  257. #endif
  258. #ifdef CALG_SSL2_MASTER
  259. CIPHEROPTION(CALG_SSL2_MASTER),
  260. #endif
  261. #ifdef CALG_TLS1_MASTER
  262. CIPHEROPTION(CALG_TLS1_MASTER),
  263. #endif
  264. #ifdef CALG_RC5
  265. CIPHEROPTION(CALG_RC5),
  266. #endif
  267. #ifdef CALG_HMAC
  268. CIPHEROPTION(CALG_HMAC),
  269. #endif
  270. #ifdef CALG_TLS1PRF
  271. CIPHEROPTION(CALG_TLS1PRF),
  272. #endif
  273. #ifdef CALG_HASH_REPLACE_OWF
  274. CIPHEROPTION(CALG_HASH_REPLACE_OWF),
  275. #endif
  276. #ifdef CALG_AES_128
  277. CIPHEROPTION(CALG_AES_128),
  278. #endif
  279. #ifdef CALG_AES_192
  280. CIPHEROPTION(CALG_AES_192),
  281. #endif
  282. #ifdef CALG_AES_256
  283. CIPHEROPTION(CALG_AES_256),
  284. #endif
  285. #ifdef CALG_AES
  286. CIPHEROPTION(CALG_AES),
  287. #endif
  288. #ifdef CALG_SHA_256
  289. CIPHEROPTION(CALG_SHA_256),
  290. #endif
  291. #ifdef CALG_SHA_384
  292. CIPHEROPTION(CALG_SHA_384),
  293. #endif
  294. #ifdef CALG_SHA_512
  295. CIPHEROPTION(CALG_SHA_512),
  296. #endif
  297. #ifdef CALG_ECDH
  298. CIPHEROPTION(CALG_ECDH),
  299. #endif
  300. #ifdef CALG_ECMQV
  301. CIPHEROPTION(CALG_ECMQV),
  302. #endif
  303. #ifdef CALG_ECDSA
  304. CIPHEROPTION(CALG_ECDSA),
  305. #endif
  306. #ifdef CALG_ECDH_EPHEM
  307. CIPHEROPTION(CALG_ECDH_EPHEM),
  308. #endif
  309. {NULL, 0},
  310. };
  311. static int
  312. get_alg_id_by_name(char *name)
  313. {
  314. char *nameEnd = strchr(name, ':');
  315. size_t n = nameEnd ? (size_t)(nameEnd - name) : strlen(name);
  316. int i;
  317. for(i = 0; algs[i].name; i++) {
  318. if((n == strlen(algs[i].name) && !strncmp(algs[i].name, name, n)))
  319. return algs[i].id;
  320. }
  321. return 0; /* not found */
  322. }
  323. #define NUM_CIPHERS 47 /* There are 47 options listed above */
  324. static CURLcode
  325. set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers,
  326. ALG_ID *algIds)
  327. {
  328. char *startCur = ciphers;
  329. int algCount = 0;
  330. while(startCur && (0 != *startCur) && (algCount < NUM_CIPHERS)) {
  331. long alg = strtol(startCur, 0, 0);
  332. if(!alg)
  333. alg = get_alg_id_by_name(startCur);
  334. if(alg)
  335. algIds[algCount++] = (ALG_ID)alg;
  336. else if(!strncmp(startCur, "USE_STRONG_CRYPTO",
  337. sizeof("USE_STRONG_CRYPTO") - 1) ||
  338. !strncmp(startCur, "SCH_USE_STRONG_CRYPTO",
  339. sizeof("SCH_USE_STRONG_CRYPTO") - 1))
  340. schannel_cred->dwFlags |= SCH_USE_STRONG_CRYPTO;
  341. else
  342. return CURLE_SSL_CIPHER;
  343. startCur = strchr(startCur, ':');
  344. if(startCur)
  345. startCur++;
  346. }
  347. schannel_cred->palgSupportedAlgs = algIds;
  348. schannel_cred->cSupportedAlgs = (DWORD)algCount;
  349. return CURLE_OK;
  350. }
  351. #ifdef HAS_CLIENT_CERT_PATH
  352. /* Function allocates memory for store_path only if CURLE_OK is returned */
  353. static CURLcode
  354. get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
  355. TCHAR **thumbprint)
  356. {
  357. TCHAR *sep;
  358. TCHAR *store_path_start;
  359. size_t store_name_len;
  360. sep = _tcschr(path, TEXT('\\'));
  361. if(!sep)
  362. return CURLE_SSL_CERTPROBLEM;
  363. store_name_len = sep - path;
  364. if(_tcsncmp(path, TEXT("CurrentUser"), store_name_len) == 0)
  365. *store_name = CERT_SYSTEM_STORE_CURRENT_USER;
  366. else if(_tcsncmp(path, TEXT("LocalMachine"), store_name_len) == 0)
  367. *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE;
  368. else if(_tcsncmp(path, TEXT("CurrentService"), store_name_len) == 0)
  369. *store_name = CERT_SYSTEM_STORE_CURRENT_SERVICE;
  370. else if(_tcsncmp(path, TEXT("Services"), store_name_len) == 0)
  371. *store_name = CERT_SYSTEM_STORE_SERVICES;
  372. else if(_tcsncmp(path, TEXT("Users"), store_name_len) == 0)
  373. *store_name = CERT_SYSTEM_STORE_USERS;
  374. else if(_tcsncmp(path, TEXT("CurrentUserGroupPolicy"),
  375. store_name_len) == 0)
  376. *store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
  377. else if(_tcsncmp(path, TEXT("LocalMachineGroupPolicy"),
  378. store_name_len) == 0)
  379. *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
  380. else if(_tcsncmp(path, TEXT("LocalMachineEnterprise"),
  381. store_name_len) == 0)
  382. *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE;
  383. else
  384. return CURLE_SSL_CERTPROBLEM;
  385. store_path_start = sep + 1;
  386. sep = _tcschr(store_path_start, TEXT('\\'));
  387. if(!sep)
  388. return CURLE_SSL_CERTPROBLEM;
  389. *thumbprint = sep + 1;
  390. if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN)
  391. return CURLE_SSL_CERTPROBLEM;
  392. *sep = TEXT('\0');
  393. *store_path = _tcsdup(store_path_start);
  394. *sep = TEXT('\\');
  395. if(!*store_path)
  396. return CURLE_OUT_OF_MEMORY;
  397. return CURLE_OK;
  398. }
  399. #endif
  400. static CURLcode
  401. schannel_acquire_credential_handle(struct Curl_cfilter *cf,
  402. struct Curl_easy *data)
  403. {
  404. struct ssl_connect_data *connssl = cf->ctx;
  405. struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
  406. struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
  407. #ifdef HAS_CLIENT_CERT_PATH
  408. PCCERT_CONTEXT client_certs[1] = { NULL };
  409. HCERTSTORE client_cert_store = NULL;
  410. #endif
  411. SECURITY_STATUS sspi_status = SEC_E_OK;
  412. CURLcode result;
  413. /* setup Schannel API options */
  414. DWORD flags = 0;
  415. DWORD enabled_protocols = 0;
  416. struct schannel_ssl_backend_data *backend =
  417. (struct schannel_ssl_backend_data *)(connssl->backend);
  418. DEBUGASSERT(backend);
  419. if(conn_config->verifypeer) {
  420. #ifdef HAS_MANUAL_VERIFY_API
  421. if(backend->use_manual_cred_validation)
  422. flags = SCH_CRED_MANUAL_CRED_VALIDATION;
  423. else
  424. #endif
  425. flags = SCH_CRED_AUTO_CRED_VALIDATION;
  426. if(ssl_config->no_revoke) {
  427. flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
  428. SCH_CRED_IGNORE_REVOCATION_OFFLINE;
  429. DEBUGF(infof(data, "schannel: disabled server certificate revocation "
  430. "checks"));
  431. }
  432. else if(ssl_config->revoke_best_effort) {
  433. flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
  434. SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN;
  435. DEBUGF(infof(data, "schannel: ignore revocation offline errors"));
  436. }
  437. else {
  438. flags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
  439. DEBUGF(infof(data,
  440. "schannel: checking server certificate revocation"));
  441. }
  442. }
  443. else {
  444. flags = SCH_CRED_MANUAL_CRED_VALIDATION |
  445. SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
  446. SCH_CRED_IGNORE_REVOCATION_OFFLINE;
  447. DEBUGF(infof(data,
  448. "schannel: disabled server cert revocation checks"));
  449. }
  450. if(!conn_config->verifyhost) {
  451. flags |= SCH_CRED_NO_SERVERNAME_CHECK;
  452. DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from "
  453. "comparing the supplied target name with the subject "
  454. "names in server certificates."));
  455. }
  456. if(!ssl_config->auto_client_cert) {
  457. flags &= ~(DWORD)SCH_CRED_USE_DEFAULT_CREDS;
  458. flags |= SCH_CRED_NO_DEFAULT_CREDS;
  459. infof(data, "schannel: disabled automatic use of client certificate");
  460. }
  461. else
  462. infof(data, "schannel: enabled automatic use of client certificate");
  463. switch(conn_config->version) {
  464. case CURL_SSLVERSION_DEFAULT:
  465. case CURL_SSLVERSION_TLSv1:
  466. case CURL_SSLVERSION_TLSv1_0:
  467. case CURL_SSLVERSION_TLSv1_1:
  468. case CURL_SSLVERSION_TLSv1_2:
  469. case CURL_SSLVERSION_TLSv1_3:
  470. {
  471. result = schannel_set_ssl_version_min_max(&enabled_protocols, cf, data);
  472. if(result != CURLE_OK)
  473. return result;
  474. break;
  475. }
  476. case CURL_SSLVERSION_SSLv3:
  477. case CURL_SSLVERSION_SSLv2:
  478. failf(data, "SSL versions not supported");
  479. return CURLE_NOT_BUILT_IN;
  480. default:
  481. failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
  482. return CURLE_SSL_CONNECT_ERROR;
  483. }
  484. #ifdef HAS_CLIENT_CERT_PATH
  485. /* client certificate */
  486. if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
  487. DWORD cert_store_name = 0;
  488. TCHAR *cert_store_path = NULL;
  489. TCHAR *cert_thumbprint_str = NULL;
  490. CRYPT_HASH_BLOB cert_thumbprint;
  491. BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN];
  492. HCERTSTORE cert_store = NULL;
  493. FILE *fInCert = NULL;
  494. void *certdata = NULL;
  495. size_t certsize = 0;
  496. bool blob = data->set.ssl.primary.cert_blob != NULL;
  497. TCHAR *cert_path = NULL;
  498. if(blob) {
  499. certdata = data->set.ssl.primary.cert_blob->data;
  500. certsize = data->set.ssl.primary.cert_blob->len;
  501. }
  502. else {
  503. cert_path = curlx_convert_UTF8_to_tchar(
  504. data->set.ssl.primary.clientcert);
  505. if(!cert_path)
  506. return CURLE_OUT_OF_MEMORY;
  507. result = get_cert_location(cert_path, &cert_store_name,
  508. &cert_store_path, &cert_thumbprint_str);
  509. if(result && (data->set.ssl.primary.clientcert[0]!='\0'))
  510. fInCert = fopen(data->set.ssl.primary.clientcert, "rb");
  511. if(result && !fInCert) {
  512. failf(data, "schannel: Failed to get certificate location"
  513. " or file for %s",
  514. data->set.ssl.primary.clientcert);
  515. curlx_unicodefree(cert_path);
  516. return result;
  517. }
  518. }
  519. if((fInCert || blob) && (data->set.ssl.cert_type) &&
  520. (!strcasecompare(data->set.ssl.cert_type, "P12"))) {
  521. failf(data, "schannel: certificate format compatibility error "
  522. " for %s",
  523. blob ? "(memory blob)" : data->set.ssl.primary.clientcert);
  524. curlx_unicodefree(cert_path);
  525. return CURLE_SSL_CERTPROBLEM;
  526. }
  527. if(fInCert || blob) {
  528. /* Reading a .P12 or .pfx file, like the example at bottom of
  529. https://social.msdn.microsoft.com/Forums/windowsdesktop/
  530. en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5
  531. */
  532. CRYPT_DATA_BLOB datablob;
  533. WCHAR* pszPassword;
  534. size_t pwd_len = 0;
  535. int str_w_len = 0;
  536. const char *cert_showfilename_error = blob ?
  537. "(memory blob)" : data->set.ssl.primary.clientcert;
  538. curlx_unicodefree(cert_path);
  539. if(fInCert) {
  540. long cert_tell = 0;
  541. bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0;
  542. if(continue_reading)
  543. cert_tell = ftell(fInCert);
  544. if(cert_tell < 0)
  545. continue_reading = FALSE;
  546. else
  547. certsize = (size_t)cert_tell;
  548. if(continue_reading)
  549. continue_reading = fseek(fInCert, 0, SEEK_SET) == 0;
  550. if(continue_reading)
  551. certdata = malloc(certsize + 1);
  552. if((!certdata) ||
  553. ((int) fread(certdata, certsize, 1, fInCert) != 1))
  554. continue_reading = FALSE;
  555. fclose(fInCert);
  556. if(!continue_reading) {
  557. failf(data, "schannel: Failed to read cert file %s",
  558. data->set.ssl.primary.clientcert);
  559. free(certdata);
  560. return CURLE_SSL_CERTPROBLEM;
  561. }
  562. }
  563. /* Convert key-pair data to the in-memory certificate store */
  564. datablob.pbData = (BYTE*)certdata;
  565. datablob.cbData = (DWORD)certsize;
  566. if(data->set.ssl.key_passwd)
  567. pwd_len = strlen(data->set.ssl.key_passwd);
  568. pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1));
  569. if(pszPassword) {
  570. if(pwd_len > 0)
  571. str_w_len = MultiByteToWideChar(CP_UTF8,
  572. MB_ERR_INVALID_CHARS,
  573. data->set.ssl.key_passwd,
  574. (int)pwd_len,
  575. pszPassword, (int)(pwd_len + 1));
  576. if((str_w_len >= 0) && (str_w_len <= (int)pwd_len))
  577. pszPassword[str_w_len] = 0;
  578. else
  579. pszPassword[0] = 0;
  580. if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
  581. VERSION_GREATER_THAN_EQUAL))
  582. cert_store = PFXImportCertStore(&datablob, pszPassword,
  583. PKCS12_NO_PERSIST_KEY);
  584. else
  585. cert_store = PFXImportCertStore(&datablob, pszPassword, 0);
  586. free(pszPassword);
  587. }
  588. if(!blob)
  589. free(certdata);
  590. if(!cert_store) {
  591. DWORD errorcode = GetLastError();
  592. if(errorcode == ERROR_INVALID_PASSWORD)
  593. failf(data, "schannel: Failed to import cert file %s, "
  594. "password is bad",
  595. cert_showfilename_error);
  596. else
  597. failf(data, "schannel: Failed to import cert file %s, "
  598. "last error is 0x%lx",
  599. cert_showfilename_error, errorcode);
  600. return CURLE_SSL_CERTPROBLEM;
  601. }
  602. client_certs[0] = CertFindCertificateInStore(
  603. cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
  604. CERT_FIND_ANY, NULL, NULL);
  605. if(!client_certs[0]) {
  606. failf(data, "schannel: Failed to get certificate from file %s"
  607. ", last error is 0x%lx",
  608. cert_showfilename_error, GetLastError());
  609. CertCloseStore(cert_store, 0);
  610. return CURLE_SSL_CERTPROBLEM;
  611. }
  612. }
  613. else {
  614. cert_store =
  615. CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0,
  616. (HCRYPTPROV)NULL,
  617. CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name,
  618. cert_store_path);
  619. if(!cert_store) {
  620. char *path_utf8 =
  621. curlx_convert_tchar_to_UTF8(cert_store_path);
  622. failf(data, "schannel: Failed to open cert store %lx %s, "
  623. "last error is 0x%lx",
  624. cert_store_name,
  625. (path_utf8 ? path_utf8 : "(unknown)"),
  626. GetLastError());
  627. free(cert_store_path);
  628. curlx_unicodefree(path_utf8);
  629. curlx_unicodefree(cert_path);
  630. return CURLE_SSL_CERTPROBLEM;
  631. }
  632. free(cert_store_path);
  633. cert_thumbprint.pbData = cert_thumbprint_data;
  634. cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN;
  635. if(!CryptStringToBinary(cert_thumbprint_str,
  636. CERT_THUMBPRINT_STR_LEN,
  637. CRYPT_STRING_HEX,
  638. cert_thumbprint_data,
  639. &cert_thumbprint.cbData,
  640. NULL, NULL)) {
  641. curlx_unicodefree(cert_path);
  642. CertCloseStore(cert_store, 0);
  643. return CURLE_SSL_CERTPROBLEM;
  644. }
  645. client_certs[0] = CertFindCertificateInStore(
  646. cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
  647. CERT_FIND_HASH, &cert_thumbprint, NULL);
  648. curlx_unicodefree(cert_path);
  649. if(!client_certs[0]) {
  650. /* CRYPT_E_NOT_FOUND / E_INVALIDARG */
  651. CertCloseStore(cert_store, 0);
  652. return CURLE_SSL_CERTPROBLEM;
  653. }
  654. }
  655. client_cert_store = cert_store;
  656. }
  657. #else
  658. if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) {
  659. failf(data, "schannel: client cert support not built in");
  660. return CURLE_NOT_BUILT_IN;
  661. }
  662. #endif
  663. /* allocate memory for the reusable credential handle */
  664. backend->cred = (struct Curl_schannel_cred *)
  665. calloc(1, sizeof(struct Curl_schannel_cred));
  666. if(!backend->cred) {
  667. failf(data, "schannel: unable to allocate memory");
  668. #ifdef HAS_CLIENT_CERT_PATH
  669. if(client_certs[0])
  670. CertFreeCertificateContext(client_certs[0]);
  671. if(client_cert_store)
  672. CertCloseStore(client_cert_store, 0);
  673. #endif
  674. return CURLE_OUT_OF_MEMORY;
  675. }
  676. backend->cred->refcount = 1;
  677. #ifdef HAS_CLIENT_CERT_PATH
  678. /* Since we did not persist the key, we need to extend the store's
  679. * lifetime until the end of the connection
  680. */
  681. backend->cred->client_cert_store = client_cert_store;
  682. #endif
  683. /* We support TLS 1.3 starting in Windows 10 version 1809 (OS build 17763) as
  684. long as the user did not set a legacy algorithm list
  685. (CURLOPT_SSL_CIPHER_LIST). */
  686. if(!conn_config->cipher_list &&
  687. curlx_verify_windows_version(10, 0, 17763, PLATFORM_WINNT,
  688. VERSION_GREATER_THAN_EQUAL)) {
  689. SCH_CREDENTIALS credentials = { 0 };
  690. TLS_PARAMETERS tls_parameters = { 0 };
  691. CRYPTO_SETTINGS crypto_settings[1] = { { 0 } };
  692. tls_parameters.pDisabledCrypto = crypto_settings;
  693. /* The number of blocked suites */
  694. tls_parameters.cDisabledCrypto = (DWORD)0;
  695. credentials.pTlsParameters = &tls_parameters;
  696. credentials.cTlsParameters = 1;
  697. credentials.dwVersion = SCH_CREDENTIALS_VERSION;
  698. credentials.dwFlags = flags | SCH_USE_STRONG_CRYPTO;
  699. credentials.pTlsParameters->grbitDisabledProtocols =
  700. (DWORD)~enabled_protocols;
  701. #ifdef HAS_CLIENT_CERT_PATH
  702. if(client_certs[0]) {
  703. credentials.cCreds = 1;
  704. credentials.paCred = client_certs;
  705. }
  706. #endif
  707. sspi_status =
  708. Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME,
  709. SECPKG_CRED_OUTBOUND, NULL,
  710. &credentials, NULL, NULL,
  711. &backend->cred->cred_handle,
  712. &backend->cred->time_stamp);
  713. }
  714. else {
  715. /* Pre-Windows 10 1809 or the user set a legacy algorithm list.
  716. Schannel will not negotiate TLS 1.3 when SCHANNEL_CRED is used. */
  717. ALG_ID algIds[NUM_CIPHERS];
  718. char *ciphers = conn_config->cipher_list;
  719. SCHANNEL_CRED schannel_cred = { 0 };
  720. schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
  721. schannel_cred.dwFlags = flags;
  722. schannel_cred.grbitEnabledProtocols = enabled_protocols;
  723. if(ciphers) {
  724. if((enabled_protocols & SP_PROT_TLS1_3_CLIENT)) {
  725. infof(data, "schannel: WARNING: This version of Schannel "
  726. "negotiates a less-secure TLS version than TLS 1.3 because the "
  727. "user set an algorithm cipher list.");
  728. }
  729. result = set_ssl_ciphers(&schannel_cred, ciphers, algIds);
  730. if(CURLE_OK != result) {
  731. failf(data, "schannel: Failed setting algorithm cipher list");
  732. return result;
  733. }
  734. }
  735. else {
  736. schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO;
  737. }
  738. #ifdef HAS_CLIENT_CERT_PATH
  739. if(client_certs[0]) {
  740. schannel_cred.cCreds = 1;
  741. schannel_cred.paCred = client_certs;
  742. }
  743. #endif
  744. sspi_status =
  745. Curl_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME,
  746. SECPKG_CRED_OUTBOUND, NULL,
  747. &schannel_cred, NULL, NULL,
  748. &backend->cred->cred_handle,
  749. &backend->cred->time_stamp);
  750. }
  751. #ifdef HAS_CLIENT_CERT_PATH
  752. if(client_certs[0])
  753. CertFreeCertificateContext(client_certs[0]);
  754. #endif
  755. if(sspi_status != SEC_E_OK) {
  756. char buffer[STRERROR_LEN];
  757. failf(data, "schannel: AcquireCredentialsHandle failed: %s",
  758. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  759. Curl_safefree(backend->cred);
  760. switch(sspi_status) {
  761. case SEC_E_INSUFFICIENT_MEMORY:
  762. return CURLE_OUT_OF_MEMORY;
  763. case SEC_E_NO_CREDENTIALS:
  764. case SEC_E_SECPKG_NOT_FOUND:
  765. case SEC_E_NOT_OWNER:
  766. case SEC_E_UNKNOWN_CREDENTIALS:
  767. case SEC_E_INTERNAL_ERROR:
  768. default:
  769. return CURLE_SSL_CONNECT_ERROR;
  770. }
  771. }
  772. return CURLE_OK;
  773. }
  774. static CURLcode
  775. schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
  776. {
  777. ssize_t written = -1;
  778. struct ssl_connect_data *connssl = cf->ctx;
  779. struct schannel_ssl_backend_data *backend =
  780. (struct schannel_ssl_backend_data *)connssl->backend;
  781. struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
  782. struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
  783. SecBuffer outbuf;
  784. SecBufferDesc outbuf_desc;
  785. SecBuffer inbuf;
  786. SecBufferDesc inbuf_desc;
  787. #ifdef HAS_ALPN
  788. unsigned char alpn_buffer[128];
  789. #endif
  790. SECURITY_STATUS sspi_status = SEC_E_OK;
  791. struct Curl_schannel_cred *old_cred = NULL;
  792. CURLcode result;
  793. DEBUGASSERT(backend);
  794. DEBUGF(infof(data,
  795. "schannel: SSL/TLS connection with %s port %d (step 1/3)",
  796. connssl->peer.hostname, connssl->peer.port));
  797. if(curlx_verify_windows_version(5, 1, 0, PLATFORM_WINNT,
  798. VERSION_LESS_THAN_EQUAL)) {
  799. /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and
  800. algorithms that may not be supported by all servers. */
  801. infof(data, "schannel: Windows version is old and may not be able to "
  802. "connect to some servers due to lack of SNI, algorithms, etc.");
  803. }
  804. #ifdef HAS_ALPN
  805. /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
  806. Also it does not seem to be supported for WINE, see curl bug #983. */
  807. backend->use_alpn = connssl->alpn &&
  808. !GetProcAddress(GetModuleHandle(TEXT("ntdll")),
  809. "wine_get_version") &&
  810. curlx_verify_windows_version(6, 3, 0, PLATFORM_WINNT,
  811. VERSION_GREATER_THAN_EQUAL);
  812. #else
  813. backend->use_alpn = FALSE;
  814. #endif
  815. #ifdef _WIN32_WCE
  816. #ifdef HAS_MANUAL_VERIFY_API
  817. /* certificate validation on CE does not seem to work right; we will
  818. * do it following a more manual process. */
  819. backend->use_manual_cred_validation = TRUE;
  820. #else
  821. #error "compiler too old to support Windows CE requisite manual cert verify"
  822. #endif
  823. #else
  824. #ifdef HAS_MANUAL_VERIFY_API
  825. if(conn_config->CAfile || conn_config->ca_info_blob) {
  826. if(curlx_verify_windows_version(6, 1, 0, PLATFORM_WINNT,
  827. VERSION_GREATER_THAN_EQUAL)) {
  828. backend->use_manual_cred_validation = TRUE;
  829. }
  830. else {
  831. failf(data, "schannel: this version of Windows is too old to support "
  832. "certificate verification via CA bundle file.");
  833. return CURLE_SSL_CACERT_BADFILE;
  834. }
  835. }
  836. else
  837. backend->use_manual_cred_validation = FALSE;
  838. #else
  839. if(conn_config->CAfile || conn_config->ca_info_blob) {
  840. failf(data, "schannel: CA cert support not built in");
  841. return CURLE_NOT_BUILT_IN;
  842. }
  843. #endif
  844. #endif
  845. backend->cred = NULL;
  846. /* check for an existing reusable credential handle */
  847. if(ssl_config->primary.cache_session) {
  848. Curl_ssl_sessionid_lock(data);
  849. if(!Curl_ssl_getsessionid(cf, data, &connssl->peer,
  850. (void **)&old_cred, NULL, NULL)) {
  851. backend->cred = old_cred;
  852. DEBUGF(infof(data, "schannel: reusing existing credential handle"));
  853. /* increment the reference counter of the credential/session handle */
  854. backend->cred->refcount++;
  855. DEBUGF(infof(data,
  856. "schannel: incremented credential handle refcount = %d",
  857. backend->cred->refcount));
  858. }
  859. Curl_ssl_sessionid_unlock(data);
  860. }
  861. if(!backend->cred) {
  862. char *snihost;
  863. result = schannel_acquire_credential_handle(cf, data);
  864. if(result)
  865. return result;
  866. /* schannel_acquire_credential_handle() sets backend->cred accordingly or
  867. it returns error otherwise. */
  868. /* A hostname associated with the credential is needed by
  869. InitializeSecurityContext for SNI and other reasons. */
  870. snihost = connssl->peer.sni ? connssl->peer.sni : connssl->peer.hostname;
  871. backend->cred->sni_hostname = curlx_convert_UTF8_to_tchar(snihost);
  872. if(!backend->cred->sni_hostname)
  873. return CURLE_OUT_OF_MEMORY;
  874. }
  875. /* Warn if SNI is disabled due to use of an IP address */
  876. if(connssl->peer.type != CURL_SSL_PEER_DNS) {
  877. infof(data, "schannel: using IP address, SNI is not supported by OS.");
  878. }
  879. #ifdef HAS_ALPN
  880. if(backend->use_alpn) {
  881. int cur = 0;
  882. int list_start_index = 0;
  883. unsigned int *extension_len = NULL;
  884. unsigned short* list_len = NULL;
  885. struct alpn_proto_buf proto;
  886. /* The first four bytes will be an unsigned int indicating number
  887. of bytes of data in the rest of the buffer. */
  888. extension_len = (unsigned int *)(void *)(&alpn_buffer[cur]);
  889. cur += (int)sizeof(unsigned int);
  890. /* The next four bytes are an indicator that this buffer will contain
  891. ALPN data, as opposed to NPN, for example. */
  892. *(unsigned int *)(void *)&alpn_buffer[cur] =
  893. SecApplicationProtocolNegotiationExt_ALPN;
  894. cur += (int)sizeof(unsigned int);
  895. /* The next two bytes will be an unsigned short indicating the number
  896. of bytes used to list the preferred protocols. */
  897. list_len = (unsigned short*)(void *)(&alpn_buffer[cur]);
  898. cur += (int)sizeof(unsigned short);
  899. list_start_index = cur;
  900. result = Curl_alpn_to_proto_buf(&proto, connssl->alpn);
  901. if(result) {
  902. failf(data, "Error setting ALPN");
  903. return CURLE_SSL_CONNECT_ERROR;
  904. }
  905. memcpy(&alpn_buffer[cur], proto.data, proto.len);
  906. cur += proto.len;
  907. *list_len = curlx_uitous(cur - list_start_index);
  908. *extension_len = (unsigned int)(*list_len +
  909. sizeof(unsigned int) + sizeof(unsigned short));
  910. InitSecBuffer(&inbuf, SECBUFFER_APPLICATION_PROTOCOLS, alpn_buffer, cur);
  911. InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
  912. Curl_alpn_to_proto_str(&proto, connssl->alpn);
  913. infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
  914. }
  915. else {
  916. InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0);
  917. InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
  918. }
  919. #else /* HAS_ALPN */
  920. InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0);
  921. InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
  922. #endif
  923. /* setup output buffer */
  924. InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
  925. InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
  926. /* security request flags */
  927. backend->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
  928. ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
  929. ISC_REQ_STREAM;
  930. if(!ssl_config->auto_client_cert) {
  931. backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
  932. }
  933. /* allocate memory for the security context handle */
  934. backend->ctxt = (struct Curl_schannel_ctxt *)
  935. calloc(1, sizeof(struct Curl_schannel_ctxt));
  936. if(!backend->ctxt) {
  937. failf(data, "schannel: unable to allocate memory");
  938. return CURLE_OUT_OF_MEMORY;
  939. }
  940. /* Schannel InitializeSecurityContext:
  941. https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
  942. At the moment we do not pass inbuf unless we are using ALPN since we only
  943. use it for that, and WINE (for which we currently disable ALPN) is giving
  944. us problems with inbuf regardless. https://github.com/curl/curl/issues/983
  945. */
  946. sspi_status = Curl_pSecFn->InitializeSecurityContext(
  947. &backend->cred->cred_handle, NULL, backend->cred->sni_hostname,
  948. backend->req_flags, 0, 0,
  949. (backend->use_alpn ? &inbuf_desc : NULL),
  950. 0, &backend->ctxt->ctxt_handle,
  951. &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
  952. if(sspi_status != SEC_I_CONTINUE_NEEDED) {
  953. char buffer[STRERROR_LEN];
  954. Curl_safefree(backend->ctxt);
  955. switch(sspi_status) {
  956. case SEC_E_INSUFFICIENT_MEMORY:
  957. failf(data, "schannel: initial InitializeSecurityContext failed: %s",
  958. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  959. return CURLE_OUT_OF_MEMORY;
  960. case SEC_E_WRONG_PRINCIPAL:
  961. failf(data, "schannel: SNI or certificate check failed: %s",
  962. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  963. return CURLE_PEER_FAILED_VERIFICATION;
  964. /*
  965. case SEC_E_INVALID_HANDLE:
  966. case SEC_E_INVALID_TOKEN:
  967. case SEC_E_LOGON_DENIED:
  968. case SEC_E_TARGET_UNKNOWN:
  969. case SEC_E_NO_AUTHENTICATING_AUTHORITY:
  970. case SEC_E_INTERNAL_ERROR:
  971. case SEC_E_NO_CREDENTIALS:
  972. case SEC_E_UNSUPPORTED_FUNCTION:
  973. case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
  974. */
  975. default:
  976. failf(data, "schannel: initial InitializeSecurityContext failed: %s",
  977. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  978. return CURLE_SSL_CONNECT_ERROR;
  979. }
  980. }
  981. DEBUGF(infof(data, "schannel: sending initial handshake data: "
  982. "sending %lu bytes.", outbuf.cbBuffer));
  983. /* send initial handshake data which is now stored in output buffer */
  984. written = Curl_conn_cf_send(cf->next, data,
  985. outbuf.pvBuffer, outbuf.cbBuffer, FALSE,
  986. &result);
  987. Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
  988. if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
  989. failf(data, "schannel: failed to send initial handshake data: "
  990. "sent %zd of %lu bytes", written, outbuf.cbBuffer);
  991. return CURLE_SSL_CONNECT_ERROR;
  992. }
  993. DEBUGF(infof(data, "schannel: sent initial handshake data: "
  994. "sent %zd bytes", written));
  995. backend->recv_unrecoverable_err = CURLE_OK;
  996. backend->recv_sspi_close_notify = FALSE;
  997. backend->recv_connection_closed = FALSE;
  998. backend->recv_renegotiating = FALSE;
  999. backend->encdata_is_incomplete = FALSE;
  1000. /* continue to second handshake step */
  1001. connssl->connecting_state = ssl_connect_2;
  1002. return CURLE_OK;
  1003. }
  1004. static CURLcode
  1005. schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
  1006. {
  1007. struct ssl_connect_data *connssl = cf->ctx;
  1008. struct schannel_ssl_backend_data *backend =
  1009. (struct schannel_ssl_backend_data *)connssl->backend;
  1010. struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
  1011. int i;
  1012. ssize_t nread = -1, written = -1;
  1013. unsigned char *reallocated_buffer;
  1014. SecBuffer outbuf[3];
  1015. SecBufferDesc outbuf_desc;
  1016. SecBuffer inbuf[2];
  1017. SecBufferDesc inbuf_desc;
  1018. SECURITY_STATUS sspi_status = SEC_E_OK;
  1019. CURLcode result;
  1020. bool doread;
  1021. const char *pubkey_ptr;
  1022. DEBUGASSERT(backend);
  1023. doread = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ? FALSE : TRUE;
  1024. connssl->io_need = CURL_SSL_IO_NEED_NONE;
  1025. DEBUGF(infof(data,
  1026. "schannel: SSL/TLS connection with %s port %d (step 2/3)",
  1027. connssl->peer.hostname, connssl->peer.port));
  1028. if(!backend->cred || !backend->ctxt)
  1029. return CURLE_SSL_CONNECT_ERROR;
  1030. /* buffer to store previously received and decrypted data */
  1031. if(!backend->decdata_buffer) {
  1032. backend->decdata_offset = 0;
  1033. backend->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
  1034. backend->decdata_buffer = malloc(backend->decdata_length);
  1035. if(!backend->decdata_buffer) {
  1036. failf(data, "schannel: unable to allocate memory");
  1037. return CURLE_OUT_OF_MEMORY;
  1038. }
  1039. }
  1040. /* buffer to store previously received and encrypted data */
  1041. if(!backend->encdata_buffer) {
  1042. backend->encdata_is_incomplete = FALSE;
  1043. backend->encdata_offset = 0;
  1044. backend->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
  1045. backend->encdata_buffer = malloc(backend->encdata_length);
  1046. if(!backend->encdata_buffer) {
  1047. failf(data, "schannel: unable to allocate memory");
  1048. return CURLE_OUT_OF_MEMORY;
  1049. }
  1050. }
  1051. /* if we need a bigger buffer to read a full message, increase buffer now */
  1052. if(backend->encdata_length - backend->encdata_offset <
  1053. CURL_SCHANNEL_BUFFER_FREE_SIZE) {
  1054. /* increase internal encrypted data buffer */
  1055. size_t reallocated_length = backend->encdata_offset +
  1056. CURL_SCHANNEL_BUFFER_FREE_SIZE;
  1057. reallocated_buffer = realloc(backend->encdata_buffer,
  1058. reallocated_length);
  1059. if(!reallocated_buffer) {
  1060. failf(data, "schannel: unable to re-allocate memory");
  1061. return CURLE_OUT_OF_MEMORY;
  1062. }
  1063. else {
  1064. backend->encdata_buffer = reallocated_buffer;
  1065. backend->encdata_length = reallocated_length;
  1066. }
  1067. }
  1068. for(;;) {
  1069. if(doread) {
  1070. /* read encrypted handshake data from socket */
  1071. nread = Curl_conn_cf_recv(cf->next, data,
  1072. (char *) (backend->encdata_buffer +
  1073. backend->encdata_offset),
  1074. backend->encdata_length -
  1075. backend->encdata_offset,
  1076. &result);
  1077. if(result == CURLE_AGAIN) {
  1078. connssl->io_need = CURL_SSL_IO_NEED_RECV;
  1079. DEBUGF(infof(data, "schannel: failed to receive handshake, "
  1080. "need more data"));
  1081. return CURLE_OK;
  1082. }
  1083. else if((result != CURLE_OK) || (nread == 0)) {
  1084. failf(data, "schannel: failed to receive handshake, "
  1085. "SSL/TLS connection failed");
  1086. return CURLE_SSL_CONNECT_ERROR;
  1087. }
  1088. /* increase encrypted data buffer offset */
  1089. backend->encdata_offset += nread;
  1090. backend->encdata_is_incomplete = FALSE;
  1091. SCH_DEV(infof(data, "schannel: encrypted data got %zd", nread));
  1092. }
  1093. SCH_DEV(infof(data,
  1094. "schannel: encrypted data buffer: offset %zu length %zu",
  1095. backend->encdata_offset, backend->encdata_length));
  1096. /* setup input buffers */
  1097. InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(backend->encdata_offset),
  1098. curlx_uztoul(backend->encdata_offset));
  1099. InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
  1100. InitSecBufferDesc(&inbuf_desc, inbuf, 2);
  1101. /* setup output buffers */
  1102. InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
  1103. InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0);
  1104. InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
  1105. InitSecBufferDesc(&outbuf_desc, outbuf, 3);
  1106. if(!inbuf[0].pvBuffer) {
  1107. failf(data, "schannel: unable to allocate memory");
  1108. return CURLE_OUT_OF_MEMORY;
  1109. }
  1110. /* copy received handshake data into input buffer */
  1111. memcpy(inbuf[0].pvBuffer, backend->encdata_buffer,
  1112. backend->encdata_offset);
  1113. sspi_status = Curl_pSecFn->InitializeSecurityContext(
  1114. &backend->cred->cred_handle, &backend->ctxt->ctxt_handle,
  1115. backend->cred->sni_hostname, backend->req_flags,
  1116. 0, 0, &inbuf_desc, 0, NULL,
  1117. &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp);
  1118. /* free buffer for received handshake data */
  1119. Curl_safefree(inbuf[0].pvBuffer);
  1120. /* check if the handshake was incomplete */
  1121. if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
  1122. backend->encdata_is_incomplete = TRUE;
  1123. connssl->io_need = CURL_SSL_IO_NEED_RECV;
  1124. DEBUGF(infof(data,
  1125. "schannel: received incomplete message, need more data"));
  1126. return CURLE_OK;
  1127. }
  1128. /* If the server has requested a client certificate, attempt to continue
  1129. the handshake without one. This will allow connections to servers which
  1130. request a client certificate but do not require it. */
  1131. if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
  1132. !(backend->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
  1133. backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
  1134. connssl->io_need = CURL_SSL_IO_NEED_SEND;
  1135. DEBUGF(infof(data,
  1136. "schannel: a client certificate has been requested"));
  1137. return CURLE_OK;
  1138. }
  1139. /* check if the handshake needs to be continued */
  1140. if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) {
  1141. for(i = 0; i < 3; i++) {
  1142. /* search for handshake tokens that need to be send */
  1143. if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
  1144. DEBUGF(infof(data, "schannel: sending next handshake data: "
  1145. "sending %lu bytes.", outbuf[i].cbBuffer));
  1146. /* send handshake token to server */
  1147. written = Curl_conn_cf_send(cf->next, data,
  1148. outbuf[i].pvBuffer, outbuf[i].cbBuffer,
  1149. FALSE, &result);
  1150. if((result != CURLE_OK) ||
  1151. (outbuf[i].cbBuffer != (size_t) written)) {
  1152. failf(data, "schannel: failed to send next handshake data: "
  1153. "sent %zd of %lu bytes", written, outbuf[i].cbBuffer);
  1154. return CURLE_SSL_CONNECT_ERROR;
  1155. }
  1156. }
  1157. /* free obsolete buffer */
  1158. if(outbuf[i].pvBuffer) {
  1159. Curl_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
  1160. }
  1161. }
  1162. }
  1163. else {
  1164. char buffer[STRERROR_LEN];
  1165. switch(sspi_status) {
  1166. case SEC_E_INSUFFICIENT_MEMORY:
  1167. failf(data, "schannel: next InitializeSecurityContext failed: %s",
  1168. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  1169. return CURLE_OUT_OF_MEMORY;
  1170. case SEC_E_WRONG_PRINCIPAL:
  1171. failf(data, "schannel: SNI or certificate check failed: %s",
  1172. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  1173. return CURLE_PEER_FAILED_VERIFICATION;
  1174. case SEC_E_UNTRUSTED_ROOT:
  1175. failf(data, "schannel: %s",
  1176. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  1177. return CURLE_PEER_FAILED_VERIFICATION;
  1178. /*
  1179. case SEC_E_INVALID_HANDLE:
  1180. case SEC_E_INVALID_TOKEN:
  1181. case SEC_E_LOGON_DENIED:
  1182. case SEC_E_TARGET_UNKNOWN:
  1183. case SEC_E_NO_AUTHENTICATING_AUTHORITY:
  1184. case SEC_E_INTERNAL_ERROR:
  1185. case SEC_E_NO_CREDENTIALS:
  1186. case SEC_E_UNSUPPORTED_FUNCTION:
  1187. case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
  1188. */
  1189. default:
  1190. failf(data, "schannel: next InitializeSecurityContext failed: %s",
  1191. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  1192. return CURLE_SSL_CONNECT_ERROR;
  1193. }
  1194. }
  1195. /* check if there was additional remaining encrypted data */
  1196. if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
  1197. SCH_DEV(infof(data, "schannel: encrypted data length: %lu",
  1198. inbuf[1].cbBuffer));
  1199. /*
  1200. There are two cases where we could be getting extra data here:
  1201. 1) If we are renegotiating a connection and the handshake is already
  1202. complete (from the server perspective), it can encrypted app data
  1203. (not handshake data) in an extra buffer at this point.
  1204. 2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a
  1205. connection and this extra data is part of the handshake.
  1206. We should process the data immediately; waiting for the socket to
  1207. be ready may fail since the server is done sending handshake data.
  1208. */
  1209. /* check if the remaining data is less than the total amount
  1210. and therefore begins after the already processed data */
  1211. if(backend->encdata_offset > inbuf[1].cbBuffer) {
  1212. memmove(backend->encdata_buffer,
  1213. (backend->encdata_buffer + backend->encdata_offset) -
  1214. inbuf[1].cbBuffer, inbuf[1].cbBuffer);
  1215. backend->encdata_offset = inbuf[1].cbBuffer;
  1216. if(sspi_status == SEC_I_CONTINUE_NEEDED) {
  1217. doread = FALSE;
  1218. continue;
  1219. }
  1220. }
  1221. }
  1222. else {
  1223. backend->encdata_offset = 0;
  1224. }
  1225. break;
  1226. }
  1227. /* check if the handshake needs to be continued */
  1228. if(sspi_status == SEC_I_CONTINUE_NEEDED) {
  1229. connssl->io_need = CURL_SSL_IO_NEED_RECV;
  1230. return CURLE_OK;
  1231. }
  1232. /* check if the handshake is complete */
  1233. if(sspi_status == SEC_E_OK) {
  1234. connssl->connecting_state = ssl_connect_3;
  1235. DEBUGF(infof(data, "schannel: SSL/TLS handshake complete"));
  1236. }
  1237. #ifndef CURL_DISABLE_PROXY
  1238. pubkey_ptr = Curl_ssl_cf_is_proxy(cf) ?
  1239. data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
  1240. data->set.str[STRING_SSL_PINNEDPUBLICKEY];
  1241. #else
  1242. pubkey_ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY];
  1243. #endif
  1244. if(pubkey_ptr) {
  1245. result = schannel_pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
  1246. if(result) {
  1247. failf(data, "SSL: public key does not match pinned public key");
  1248. return result;
  1249. }
  1250. }
  1251. #ifdef HAS_MANUAL_VERIFY_API
  1252. if(conn_config->verifypeer && backend->use_manual_cred_validation) {
  1253. /* Certificate verification also verifies the hostname if verifyhost */
  1254. return Curl_verify_certificate(cf, data);
  1255. }
  1256. #endif
  1257. /* Verify the hostname manually when certificate verification is disabled,
  1258. because in that case Schannel will not verify it. */
  1259. if(!conn_config->verifypeer && conn_config->verifyhost)
  1260. return Curl_verify_host(cf, data);
  1261. return CURLE_OK;
  1262. }
  1263. static bool
  1264. valid_cert_encoding(const CERT_CONTEXT *cert_context)
  1265. {
  1266. return (cert_context != NULL) &&
  1267. ((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
  1268. (cert_context->pbCertEncoded != NULL) &&
  1269. (cert_context->cbCertEncoded > 0);
  1270. }
  1271. typedef bool(*Read_crt_func)(const CERT_CONTEXT *ccert_context,
  1272. bool reverse_order, void *arg);
  1273. static void
  1274. traverse_cert_store(const CERT_CONTEXT *context, Read_crt_func func,
  1275. void *arg)
  1276. {
  1277. const CERT_CONTEXT *current_context = NULL;
  1278. bool should_continue = TRUE;
  1279. bool first = TRUE;
  1280. bool reverse_order = FALSE;
  1281. while(should_continue &&
  1282. (current_context = CertEnumCertificatesInStore(
  1283. context->hCertStore,
  1284. current_context)) != NULL) {
  1285. /* Windows 11 22H2 OS Build 22621.674 or higher enumerates certificates in
  1286. leaf-to-root order while all previous versions of Windows enumerate
  1287. certificates in root-to-leaf order. Determine the order of enumeration
  1288. by comparing SECPKG_ATTR_REMOTE_CERT_CONTEXT's pbCertContext with the
  1289. first certificate's pbCertContext. */
  1290. if(first && context->pbCertEncoded != current_context->pbCertEncoded)
  1291. reverse_order = TRUE;
  1292. should_continue = func(current_context, reverse_order, arg);
  1293. first = FALSE;
  1294. }
  1295. if(current_context)
  1296. CertFreeCertificateContext(current_context);
  1297. }
  1298. static bool
  1299. cert_counter_callback(const CERT_CONTEXT *ccert_context, bool reverse_order,
  1300. void *certs_count)
  1301. {
  1302. (void)reverse_order; /* unused */
  1303. if(valid_cert_encoding(ccert_context))
  1304. (*(int *)certs_count)++;
  1305. return TRUE;
  1306. }
  1307. struct Adder_args
  1308. {
  1309. struct Curl_easy *data;
  1310. CURLcode result;
  1311. int idx;
  1312. int certs_count;
  1313. };
  1314. static bool
  1315. add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, bool reverse_order,
  1316. void *raw_arg)
  1317. {
  1318. struct Adder_args *args = (struct Adder_args*)raw_arg;
  1319. args->result = CURLE_OK;
  1320. if(valid_cert_encoding(ccert_context)) {
  1321. const char *beg = (const char *) ccert_context->pbCertEncoded;
  1322. const char *end = beg + ccert_context->cbCertEncoded;
  1323. int insert_index = reverse_order ? (args->certs_count - 1) - args->idx :
  1324. args->idx;
  1325. args->result = Curl_extract_certinfo(args->data, insert_index,
  1326. beg, end);
  1327. args->idx++;
  1328. }
  1329. return args->result == CURLE_OK;
  1330. }
  1331. static void schannel_session_free(void *sessionid, size_t idsize)
  1332. {
  1333. /* this is expected to be called under sessionid lock */
  1334. struct Curl_schannel_cred *cred = sessionid;
  1335. (void)idsize;
  1336. if(cred) {
  1337. cred->refcount--;
  1338. if(cred->refcount == 0) {
  1339. Curl_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
  1340. curlx_unicodefree(cred->sni_hostname);
  1341. #ifdef HAS_CLIENT_CERT_PATH
  1342. if(cred->client_cert_store) {
  1343. CertCloseStore(cred->client_cert_store, 0);
  1344. cred->client_cert_store = NULL;
  1345. }
  1346. #endif
  1347. Curl_safefree(cred);
  1348. }
  1349. }
  1350. }
  1351. static CURLcode
  1352. schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
  1353. {
  1354. struct ssl_connect_data *connssl = cf->ctx;
  1355. struct schannel_ssl_backend_data *backend =
  1356. (struct schannel_ssl_backend_data *)connssl->backend;
  1357. struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
  1358. CURLcode result = CURLE_OK;
  1359. SECURITY_STATUS sspi_status = SEC_E_OK;
  1360. CERT_CONTEXT *ccert_context = NULL;
  1361. #ifdef HAS_ALPN
  1362. SecPkgContext_ApplicationProtocol alpn_result;
  1363. #endif
  1364. DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
  1365. DEBUGASSERT(backend);
  1366. DEBUGF(infof(data,
  1367. "schannel: SSL/TLS connection with %s port %d (step 3/3)",
  1368. connssl->peer.hostname, connssl->peer.port));
  1369. if(!backend->cred)
  1370. return CURLE_SSL_CONNECT_ERROR;
  1371. /* check if the required context attributes are met */
  1372. if(backend->ret_flags != backend->req_flags) {
  1373. if(!(backend->ret_flags & ISC_RET_SEQUENCE_DETECT))
  1374. failf(data, "schannel: failed to setup sequence detection");
  1375. if(!(backend->ret_flags & ISC_RET_REPLAY_DETECT))
  1376. failf(data, "schannel: failed to setup replay detection");
  1377. if(!(backend->ret_flags & ISC_RET_CONFIDENTIALITY))
  1378. failf(data, "schannel: failed to setup confidentiality");
  1379. if(!(backend->ret_flags & ISC_RET_ALLOCATED_MEMORY))
  1380. failf(data, "schannel: failed to setup memory allocation");
  1381. if(!(backend->ret_flags & ISC_RET_STREAM))
  1382. failf(data, "schannel: failed to setup stream orientation");
  1383. return CURLE_SSL_CONNECT_ERROR;
  1384. }
  1385. #ifdef HAS_ALPN
  1386. if(backend->use_alpn) {
  1387. sspi_status =
  1388. Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
  1389. SECPKG_ATTR_APPLICATION_PROTOCOL,
  1390. &alpn_result);
  1391. if(sspi_status != SEC_E_OK) {
  1392. failf(data, "schannel: failed to retrieve ALPN result");
  1393. return CURLE_SSL_CONNECT_ERROR;
  1394. }
  1395. if(alpn_result.ProtoNegoStatus ==
  1396. SecApplicationProtocolNegotiationStatus_Success) {
  1397. unsigned char prev_alpn = cf->conn->alpn;
  1398. Curl_alpn_set_negotiated(cf, data, connssl, alpn_result.ProtocolId,
  1399. alpn_result.ProtocolIdSize);
  1400. if(backend->recv_renegotiating) {
  1401. if(prev_alpn != cf->conn->alpn &&
  1402. prev_alpn != CURL_HTTP_VERSION_NONE) {
  1403. /* Renegotiation selected a different protocol now, we cannot
  1404. * deal with this */
  1405. failf(data, "schannel: server selected an ALPN protocol too late");
  1406. return CURLE_SSL_CONNECT_ERROR;
  1407. }
  1408. }
  1409. }
  1410. else {
  1411. if(!backend->recv_renegotiating)
  1412. Curl_alpn_set_negotiated(cf, data, connssl, NULL, 0);
  1413. }
  1414. }
  1415. #endif
  1416. /* save the current session data for possible reuse */
  1417. if(ssl_config->primary.cache_session) {
  1418. Curl_ssl_sessionid_lock(data);
  1419. /* Up ref count since call takes ownership */
  1420. backend->cred->refcount++;
  1421. result = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
  1422. backend->cred,
  1423. sizeof(struct Curl_schannel_cred),
  1424. schannel_session_free);
  1425. Curl_ssl_sessionid_unlock(data);
  1426. if(result)
  1427. return result;
  1428. }
  1429. if(data->set.ssl.certinfo) {
  1430. int certs_count = 0;
  1431. sspi_status =
  1432. Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
  1433. SECPKG_ATTR_REMOTE_CERT_CONTEXT,
  1434. &ccert_context);
  1435. if((sspi_status != SEC_E_OK) || !ccert_context) {
  1436. failf(data, "schannel: failed to retrieve remote cert context");
  1437. return CURLE_PEER_FAILED_VERIFICATION;
  1438. }
  1439. traverse_cert_store(ccert_context, cert_counter_callback, &certs_count);
  1440. result = Curl_ssl_init_certinfo(data, certs_count);
  1441. if(!result) {
  1442. struct Adder_args args;
  1443. args.data = data;
  1444. args.idx = 0;
  1445. args.certs_count = certs_count;
  1446. traverse_cert_store(ccert_context, add_cert_to_certinfo, &args);
  1447. result = args.result;
  1448. }
  1449. CertFreeCertificateContext(ccert_context);
  1450. if(result)
  1451. return result;
  1452. }
  1453. connssl->connecting_state = ssl_connect_done;
  1454. return CURLE_OK;
  1455. }
  1456. static CURLcode
  1457. schannel_connect_common(struct Curl_cfilter *cf,
  1458. struct Curl_easy *data,
  1459. bool nonblocking, bool *done)
  1460. {
  1461. CURLcode result;
  1462. struct ssl_connect_data *connssl = cf->ctx;
  1463. curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
  1464. timediff_t timeout_ms;
  1465. int what;
  1466. /* check if the connection has already been established */
  1467. if(ssl_connection_complete == connssl->state) {
  1468. *done = TRUE;
  1469. return CURLE_OK;
  1470. }
  1471. if(ssl_connect_1 == connssl->connecting_state) {
  1472. /* check out how much more time we are allowed */
  1473. timeout_ms = Curl_timeleft(data, NULL, TRUE);
  1474. if(timeout_ms < 0) {
  1475. /* no need to continue if time already is up */
  1476. failf(data, "SSL/TLS connection timeout");
  1477. return CURLE_OPERATION_TIMEDOUT;
  1478. }
  1479. result = schannel_connect_step1(cf, data);
  1480. if(result)
  1481. return result;
  1482. }
  1483. while(ssl_connect_2 == connssl->connecting_state) {
  1484. /* check out how much more time we are allowed */
  1485. timeout_ms = Curl_timeleft(data, NULL, TRUE);
  1486. if(timeout_ms < 0) {
  1487. /* no need to continue if time already is up */
  1488. failf(data, "SSL/TLS connection timeout");
  1489. return CURLE_OPERATION_TIMEDOUT;
  1490. }
  1491. /* if ssl is expecting something, check if it is available. */
  1492. if(connssl->io_need) {
  1493. curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ?
  1494. sockfd : CURL_SOCKET_BAD;
  1495. curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV) ?
  1496. sockfd : CURL_SOCKET_BAD;
  1497. what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
  1498. nonblocking ? 0 : timeout_ms);
  1499. if(what < 0) {
  1500. /* fatal error */
  1501. failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
  1502. return CURLE_SSL_CONNECT_ERROR;
  1503. }
  1504. else if(0 == what) {
  1505. if(nonblocking) {
  1506. *done = FALSE;
  1507. return CURLE_OK;
  1508. }
  1509. else {
  1510. /* timeout */
  1511. failf(data, "SSL/TLS connection timeout");
  1512. return CURLE_OPERATION_TIMEDOUT;
  1513. }
  1514. }
  1515. /* socket is readable or writable */
  1516. }
  1517. /* Run transaction, and return to the caller if it failed or if
  1518. * this connection is part of a multi handle and this loop would
  1519. * execute again. This permits the owner of a multi handle to
  1520. * abort a connection attempt before step2 has completed while
  1521. * ensuring that a client using select() or epoll() will always
  1522. * have a valid fdset to wait on.
  1523. */
  1524. result = schannel_connect_step2(cf, data);
  1525. if(result || (nonblocking && (ssl_connect_2 == connssl->connecting_state)))
  1526. return result;
  1527. } /* repeat step2 until all transactions are done. */
  1528. if(ssl_connect_3 == connssl->connecting_state) {
  1529. result = schannel_connect_step3(cf, data);
  1530. if(result)
  1531. return result;
  1532. }
  1533. if(ssl_connect_done == connssl->connecting_state) {
  1534. connssl->state = ssl_connection_complete;
  1535. #ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
  1536. /* When SSPI is used in combination with Schannel
  1537. * we need the Schannel context to create the Schannel
  1538. * binding to pass the IIS extended protection checks.
  1539. * Available on Windows 7 or later.
  1540. */
  1541. {
  1542. struct schannel_ssl_backend_data *backend =
  1543. (struct schannel_ssl_backend_data *)connssl->backend;
  1544. DEBUGASSERT(backend);
  1545. cf->conn->sslContext = &backend->ctxt->ctxt_handle;
  1546. }
  1547. #endif
  1548. *done = TRUE;
  1549. }
  1550. else
  1551. *done = FALSE;
  1552. /* reset our connection state machine */
  1553. connssl->connecting_state = ssl_connect_1;
  1554. return CURLE_OK;
  1555. }
  1556. static ssize_t
  1557. schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
  1558. const void *buf, size_t len, CURLcode *err)
  1559. {
  1560. ssize_t written = -1;
  1561. size_t data_len = 0;
  1562. unsigned char *ptr = NULL;
  1563. struct ssl_connect_data *connssl = cf->ctx;
  1564. SecBuffer outbuf[4];
  1565. SecBufferDesc outbuf_desc;
  1566. SECURITY_STATUS sspi_status = SEC_E_OK;
  1567. CURLcode result;
  1568. struct schannel_ssl_backend_data *backend =
  1569. (struct schannel_ssl_backend_data *)connssl->backend;
  1570. DEBUGASSERT(backend);
  1571. /* check if the maximum stream sizes were queried */
  1572. if(backend->stream_sizes.cbMaximumMessage == 0) {
  1573. sspi_status = Curl_pSecFn->QueryContextAttributes(
  1574. &backend->ctxt->ctxt_handle,
  1575. SECPKG_ATTR_STREAM_SIZES,
  1576. &backend->stream_sizes);
  1577. if(sspi_status != SEC_E_OK) {
  1578. *err = CURLE_SEND_ERROR;
  1579. return -1;
  1580. }
  1581. }
  1582. /* check if the buffer is longer than the maximum message length */
  1583. if(len > backend->stream_sizes.cbMaximumMessage) {
  1584. len = backend->stream_sizes.cbMaximumMessage;
  1585. }
  1586. /* calculate the complete message length and allocate a buffer for it */
  1587. data_len = backend->stream_sizes.cbHeader + len +
  1588. backend->stream_sizes.cbTrailer;
  1589. ptr = (unsigned char *) malloc(data_len);
  1590. if(!ptr) {
  1591. *err = CURLE_OUT_OF_MEMORY;
  1592. return -1;
  1593. }
  1594. /* setup output buffers (header, data, trailer, empty) */
  1595. InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
  1596. ptr, backend->stream_sizes.cbHeader);
  1597. InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
  1598. ptr + backend->stream_sizes.cbHeader, curlx_uztoul(len));
  1599. InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
  1600. ptr + backend->stream_sizes.cbHeader + len,
  1601. backend->stream_sizes.cbTrailer);
  1602. InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
  1603. InitSecBufferDesc(&outbuf_desc, outbuf, 4);
  1604. /* copy data into output buffer */
  1605. memcpy(outbuf[1].pvBuffer, buf, len);
  1606. /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
  1607. sspi_status = Curl_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0,
  1608. &outbuf_desc, 0);
  1609. /* check if the message was encrypted */
  1610. if(sspi_status == SEC_E_OK) {
  1611. written = 0;
  1612. /* send the encrypted message including header, data and trailer */
  1613. len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
  1614. /*
  1615. it is important to send the full message which includes the header,
  1616. encrypted payload, and trailer. Until the client receives all the
  1617. data a coherent message has not been delivered and the client
  1618. cannot read any of it.
  1619. If we wanted to buffer the unwritten encrypted bytes, we would
  1620. tell the client that all data it has requested to be sent has been
  1621. sent. The unwritten encrypted bytes would be the first bytes to
  1622. send on the next invocation.
  1623. Here's the catch with this - if we tell the client that all the
  1624. bytes have been sent, will the client call this method again to
  1625. send the buffered data? Looking at who calls this function, it
  1626. seems the answer is NO.
  1627. */
  1628. /* send entire message or fail */
  1629. while(len > (size_t)written) {
  1630. ssize_t this_write = 0;
  1631. int what;
  1632. timediff_t timeout_ms = Curl_timeleft(data, NULL, FALSE);
  1633. if(timeout_ms < 0) {
  1634. /* we already got the timeout */
  1635. failf(data, "schannel: timed out sending data "
  1636. "(bytes sent: %zd)", written);
  1637. *err = CURLE_OPERATION_TIMEDOUT;
  1638. written = -1;
  1639. break;
  1640. }
  1641. else if(!timeout_ms)
  1642. timeout_ms = TIMEDIFF_T_MAX;
  1643. what = SOCKET_WRITABLE(Curl_conn_cf_get_socket(cf, data), timeout_ms);
  1644. if(what < 0) {
  1645. /* fatal error */
  1646. failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
  1647. *err = CURLE_SEND_ERROR;
  1648. written = -1;
  1649. break;
  1650. }
  1651. else if(0 == what) {
  1652. failf(data, "schannel: timed out sending data "
  1653. "(bytes sent: %zd)", written);
  1654. *err = CURLE_OPERATION_TIMEDOUT;
  1655. written = -1;
  1656. break;
  1657. }
  1658. /* socket is writable */
  1659. this_write = Curl_conn_cf_send(cf->next, data,
  1660. ptr + written, len - written,
  1661. FALSE, &result);
  1662. if(result == CURLE_AGAIN)
  1663. continue;
  1664. else if(result != CURLE_OK) {
  1665. *err = result;
  1666. written = -1;
  1667. break;
  1668. }
  1669. written += this_write;
  1670. }
  1671. }
  1672. else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) {
  1673. *err = CURLE_OUT_OF_MEMORY;
  1674. }
  1675. else{
  1676. *err = CURLE_SEND_ERROR;
  1677. }
  1678. Curl_safefree(ptr);
  1679. if(len == (size_t)written)
  1680. /* Encrypted message including header, data and trailer entirely sent.
  1681. The return value is the number of unencrypted bytes that were sent. */
  1682. written = outbuf[1].cbBuffer;
  1683. return written;
  1684. }
  1685. static ssize_t
  1686. schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
  1687. char *buf, size_t len, CURLcode *err)
  1688. {
  1689. size_t size = 0;
  1690. ssize_t nread = -1;
  1691. struct ssl_connect_data *connssl = cf->ctx;
  1692. unsigned char *reallocated_buffer;
  1693. size_t reallocated_length;
  1694. bool done = FALSE;
  1695. SecBuffer inbuf[4];
  1696. SecBufferDesc inbuf_desc;
  1697. SECURITY_STATUS sspi_status = SEC_E_OK;
  1698. /* we want the length of the encrypted buffer to be at least large enough
  1699. that it can hold all the bytes requested and some TLS record overhead. */
  1700. size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
  1701. struct schannel_ssl_backend_data *backend =
  1702. (struct schannel_ssl_backend_data *)connssl->backend;
  1703. DEBUGASSERT(backend);
  1704. /****************************************************************************
  1705. * Do not return or set backend->recv_unrecoverable_err unless in the
  1706. * cleanup. The pattern for return error is set *err, optional infof, goto
  1707. * cleanup.
  1708. *
  1709. * Some verbose debug messages are wrapped by SCH_DEV() instead of DEBUGF()
  1710. * and only shown if CURL_SCHANNEL_DEV_DEBUG was defined at build time. These
  1711. * messages are extra verbose and intended for curl developers debugging
  1712. * Schannel recv decryption.
  1713. *
  1714. * Our priority is to always return as much decrypted data to the caller as
  1715. * possible, even if an error occurs. The state of the decrypted buffer must
  1716. * always be valid. Transfer of decrypted data to the caller's buffer is
  1717. * handled in the cleanup.
  1718. */
  1719. SCH_DEV(infof(data, "schannel: client wants to read %zu bytes", len));
  1720. *err = CURLE_OK;
  1721. if(len && len <= backend->decdata_offset) {
  1722. SCH_DEV(infof(data,
  1723. "schannel: enough decrypted data is already available"));
  1724. goto cleanup;
  1725. }
  1726. else if(backend->recv_unrecoverable_err) {
  1727. *err = backend->recv_unrecoverable_err;
  1728. infof(data, "schannel: an unrecoverable error occurred in a prior call");
  1729. goto cleanup;
  1730. }
  1731. else if(backend->recv_sspi_close_notify) {
  1732. /* once a server has indicated shutdown there is no more encrypted data */
  1733. infof(data, "schannel: server indicated shutdown in a prior call");
  1734. goto cleanup;
  1735. }
  1736. /* it is debatable what to return when !len. Regardless we cannot return
  1737. immediately because there may be data to decrypt (in the case we want to
  1738. decrypt all encrypted cached data) so handle !len later in cleanup.
  1739. */
  1740. else if(len && !backend->recv_connection_closed) {
  1741. /* increase enc buffer in order to fit the requested amount of data */
  1742. size = backend->encdata_length - backend->encdata_offset;
  1743. if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
  1744. backend->encdata_length < min_encdata_length) {
  1745. reallocated_length = backend->encdata_offset +
  1746. CURL_SCHANNEL_BUFFER_FREE_SIZE;
  1747. if(reallocated_length < min_encdata_length) {
  1748. reallocated_length = min_encdata_length;
  1749. }
  1750. reallocated_buffer = realloc(backend->encdata_buffer,
  1751. reallocated_length);
  1752. if(!reallocated_buffer) {
  1753. *err = CURLE_OUT_OF_MEMORY;
  1754. failf(data, "schannel: unable to re-allocate memory");
  1755. goto cleanup;
  1756. }
  1757. backend->encdata_buffer = reallocated_buffer;
  1758. backend->encdata_length = reallocated_length;
  1759. size = backend->encdata_length - backend->encdata_offset;
  1760. SCH_DEV(infof(data, "schannel: encdata_buffer resized %zu",
  1761. backend->encdata_length));
  1762. }
  1763. SCH_DEV(infof(data,
  1764. "schannel: encrypted data buffer: offset %zu length %zu",
  1765. backend->encdata_offset, backend->encdata_length));
  1766. /* read encrypted data from socket */
  1767. nread = Curl_conn_cf_recv(cf->next, data,
  1768. (char *)(backend->encdata_buffer +
  1769. backend->encdata_offset),
  1770. size, err);
  1771. if(*err) {
  1772. nread = -1;
  1773. if(*err == CURLE_AGAIN)
  1774. SCH_DEV(infof(data, "schannel: recv returned CURLE_AGAIN"));
  1775. else if(*err == CURLE_RECV_ERROR)
  1776. infof(data, "schannel: recv returned CURLE_RECV_ERROR");
  1777. else
  1778. infof(data, "schannel: recv returned error %d", *err);
  1779. }
  1780. else if(nread == 0) {
  1781. backend->recv_connection_closed = TRUE;
  1782. DEBUGF(infof(data, "schannel: server closed the connection"));
  1783. }
  1784. else if(nread > 0) {
  1785. backend->encdata_offset += (size_t)nread;
  1786. backend->encdata_is_incomplete = FALSE;
  1787. SCH_DEV(infof(data, "schannel: encrypted data got %zd", nread));
  1788. }
  1789. }
  1790. SCH_DEV(infof(data, "schannel: encrypted data buffer: offset %zu length %zu",
  1791. backend->encdata_offset, backend->encdata_length));
  1792. /* decrypt loop */
  1793. while(backend->encdata_offset > 0 && sspi_status == SEC_E_OK &&
  1794. (!len || backend->decdata_offset < len ||
  1795. backend->recv_connection_closed)) {
  1796. /* prepare data buffer for DecryptMessage call */
  1797. InitSecBuffer(&inbuf[0], SECBUFFER_DATA, backend->encdata_buffer,
  1798. curlx_uztoul(backend->encdata_offset));
  1799. /* we need 3 more empty input buffers for possible output */
  1800. InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
  1801. InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
  1802. InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
  1803. InitSecBufferDesc(&inbuf_desc, inbuf, 4);
  1804. /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
  1805. */
  1806. sspi_status = Curl_pSecFn->DecryptMessage(&backend->ctxt->ctxt_handle,
  1807. &inbuf_desc, 0, NULL);
  1808. /* check if everything went fine (server may want to renegotiate
  1809. or shutdown the connection context) */
  1810. if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE ||
  1811. sspi_status == SEC_I_CONTEXT_EXPIRED) {
  1812. /* check for successfully decrypted data, even before actual
  1813. renegotiation or shutdown of the connection context */
  1814. if(inbuf[1].BufferType == SECBUFFER_DATA) {
  1815. SCH_DEV(infof(data, "schannel: decrypted data length: %lu",
  1816. inbuf[1].cbBuffer));
  1817. /* increase buffer in order to fit the received amount of data */
  1818. size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
  1819. inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
  1820. if(backend->decdata_length - backend->decdata_offset < size ||
  1821. backend->decdata_length < len) {
  1822. /* increase internal decrypted data buffer */
  1823. reallocated_length = backend->decdata_offset + size;
  1824. /* make sure that the requested amount of data fits */
  1825. if(reallocated_length < len) {
  1826. reallocated_length = len;
  1827. }
  1828. reallocated_buffer = realloc(backend->decdata_buffer,
  1829. reallocated_length);
  1830. if(!reallocated_buffer) {
  1831. *err = CURLE_OUT_OF_MEMORY;
  1832. failf(data, "schannel: unable to re-allocate memory");
  1833. goto cleanup;
  1834. }
  1835. backend->decdata_buffer = reallocated_buffer;
  1836. backend->decdata_length = reallocated_length;
  1837. }
  1838. /* copy decrypted data to internal buffer */
  1839. size = inbuf[1].cbBuffer;
  1840. if(size) {
  1841. memcpy(backend->decdata_buffer + backend->decdata_offset,
  1842. inbuf[1].pvBuffer, size);
  1843. backend->decdata_offset += size;
  1844. }
  1845. SCH_DEV(infof(data, "schannel: decrypted data added: %zu", size));
  1846. SCH_DEV(infof(data,
  1847. "schannel: decrypted cached: offset %zu length %zu",
  1848. backend->decdata_offset, backend->decdata_length));
  1849. }
  1850. /* check for remaining encrypted data */
  1851. if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
  1852. SCH_DEV(infof(data, "schannel: encrypted data length: %lu",
  1853. inbuf[3].cbBuffer));
  1854. /* check if the remaining data is less than the total amount
  1855. * and therefore begins after the already processed data
  1856. */
  1857. if(backend->encdata_offset > inbuf[3].cbBuffer) {
  1858. /* move remaining encrypted data forward to the beginning of
  1859. buffer */
  1860. memmove(backend->encdata_buffer,
  1861. (backend->encdata_buffer + backend->encdata_offset) -
  1862. inbuf[3].cbBuffer, inbuf[3].cbBuffer);
  1863. backend->encdata_offset = inbuf[3].cbBuffer;
  1864. }
  1865. SCH_DEV(infof(data,
  1866. "schannel: encrypted cached: offset %zu length %zu",
  1867. backend->encdata_offset, backend->encdata_length));
  1868. }
  1869. else {
  1870. /* reset encrypted buffer offset, because there is no data remaining */
  1871. backend->encdata_offset = 0;
  1872. }
  1873. /* check if server wants to renegotiate the connection context */
  1874. if(sspi_status == SEC_I_RENEGOTIATE) {
  1875. infof(data, "schannel: remote party requests renegotiation");
  1876. if(*err && *err != CURLE_AGAIN) {
  1877. infof(data, "schannel: cannot renegotiate, an error is pending");
  1878. goto cleanup;
  1879. }
  1880. /* begin renegotiation */
  1881. infof(data, "schannel: renegotiating SSL/TLS connection");
  1882. connssl->state = ssl_connection_negotiating;
  1883. connssl->connecting_state = ssl_connect_2;
  1884. connssl->io_need = CURL_SSL_IO_NEED_SEND;
  1885. backend->recv_renegotiating = TRUE;
  1886. *err = schannel_connect_common(cf, data, FALSE, &done);
  1887. backend->recv_renegotiating = FALSE;
  1888. if(*err) {
  1889. infof(data, "schannel: renegotiation failed");
  1890. goto cleanup;
  1891. }
  1892. /* now retry receiving data */
  1893. sspi_status = SEC_E_OK;
  1894. infof(data, "schannel: SSL/TLS connection renegotiated");
  1895. continue;
  1896. }
  1897. /* check if the server closed the connection */
  1898. else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
  1899. /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
  1900. returned so we have to work around that in cleanup. */
  1901. backend->recv_sspi_close_notify = TRUE;
  1902. if(!backend->recv_connection_closed)
  1903. backend->recv_connection_closed = TRUE;
  1904. /* We received the close notify just fine, any error we got
  1905. * from the lower filters afterwards (e.g. the socket), is not
  1906. * an error on the TLS data stream. That one ended here. */
  1907. if(*err == CURLE_RECV_ERROR)
  1908. *err = CURLE_OK;
  1909. infof(data,
  1910. "schannel: server close notification received (close_notify)");
  1911. goto cleanup;
  1912. }
  1913. }
  1914. else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
  1915. backend->encdata_is_incomplete = TRUE;
  1916. if(!*err)
  1917. *err = CURLE_AGAIN;
  1918. SCH_DEV(infof(data, "schannel: failed to decrypt data, need more data"));
  1919. goto cleanup;
  1920. }
  1921. else {
  1922. #ifndef CURL_DISABLE_VERBOSE_STRINGS
  1923. char buffer[STRERROR_LEN];
  1924. failf(data, "schannel: failed to read data from server: %s",
  1925. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  1926. #endif
  1927. *err = CURLE_RECV_ERROR;
  1928. goto cleanup;
  1929. }
  1930. }
  1931. SCH_DEV(infof(data, "schannel: encrypted data buffer: offset %zu length %zu",
  1932. backend->encdata_offset, backend->encdata_length));
  1933. SCH_DEV(infof(data, "schannel: decrypted data buffer: offset %zu length %zu",
  1934. backend->decdata_offset, backend->decdata_length));
  1935. cleanup:
  1936. /* Warning- there is no guarantee the encdata state is valid at this point */
  1937. SCH_DEV(infof(data, "schannel: schannel_recv cleanup"));
  1938. /* Error if the connection has closed without a close_notify.
  1939. The behavior here is a matter of debate. We do not want to be vulnerable
  1940. to a truncation attack however there is some browser precedent for
  1941. ignoring the close_notify for compatibility reasons.
  1942. Additionally, Windows 2000 (v5.0) is a special case since it seems it
  1943. does not return close_notify. In that case if the connection was closed we
  1944. assume it was graceful (close_notify) since there does not seem to be a
  1945. way to tell.
  1946. */
  1947. if(len && !backend->decdata_offset && backend->recv_connection_closed &&
  1948. !backend->recv_sspi_close_notify) {
  1949. bool isWin2k = curlx_verify_windows_version(5, 0, 0, PLATFORM_WINNT,
  1950. VERSION_EQUAL);
  1951. if(isWin2k && sspi_status == SEC_E_OK)
  1952. backend->recv_sspi_close_notify = TRUE;
  1953. else {
  1954. *err = CURLE_RECV_ERROR;
  1955. failf(data, "schannel: server closed abruptly (missing close_notify)");
  1956. }
  1957. }
  1958. /* Any error other than CURLE_AGAIN is an unrecoverable error. */
  1959. if(*err && *err != CURLE_AGAIN)
  1960. backend->recv_unrecoverable_err = *err;
  1961. size = len < backend->decdata_offset ? len : backend->decdata_offset;
  1962. if(size) {
  1963. memcpy(buf, backend->decdata_buffer, size);
  1964. memmove(backend->decdata_buffer, backend->decdata_buffer + size,
  1965. backend->decdata_offset - size);
  1966. backend->decdata_offset -= size;
  1967. SCH_DEV(infof(data, "schannel: decrypted data returned %zu", size));
  1968. SCH_DEV(infof(data,
  1969. "schannel: decrypted data buffer: offset %zu length %zu",
  1970. backend->decdata_offset, backend->decdata_length));
  1971. *err = CURLE_OK;
  1972. return (ssize_t)size;
  1973. }
  1974. if(!*err && !backend->recv_connection_closed)
  1975. *err = CURLE_AGAIN;
  1976. /* it is debatable what to return when !len. We could return whatever error
  1977. we got from decryption but instead we override here so the return is
  1978. consistent.
  1979. */
  1980. if(!len)
  1981. *err = CURLE_OK;
  1982. return *err ? -1 : 0;
  1983. }
  1984. static CURLcode schannel_connect_nonblocking(struct Curl_cfilter *cf,
  1985. struct Curl_easy *data,
  1986. bool *done)
  1987. {
  1988. return schannel_connect_common(cf, data, TRUE, done);
  1989. }
  1990. static CURLcode schannel_connect(struct Curl_cfilter *cf,
  1991. struct Curl_easy *data)
  1992. {
  1993. CURLcode result;
  1994. bool done = FALSE;
  1995. result = schannel_connect_common(cf, data, FALSE, &done);
  1996. if(result)
  1997. return result;
  1998. DEBUGASSERT(done);
  1999. return CURLE_OK;
  2000. }
  2001. static bool schannel_data_pending(struct Curl_cfilter *cf,
  2002. const struct Curl_easy *data)
  2003. {
  2004. const struct ssl_connect_data *connssl = cf->ctx;
  2005. struct schannel_ssl_backend_data *backend =
  2006. (struct schannel_ssl_backend_data *)connssl->backend;
  2007. (void)data;
  2008. DEBUGASSERT(backend);
  2009. if(backend->ctxt) /* SSL/TLS is in use */
  2010. return (backend->decdata_offset > 0 ||
  2011. (backend->encdata_offset > 0 && !backend->encdata_is_incomplete) ||
  2012. backend->recv_connection_closed ||
  2013. backend->recv_sspi_close_notify ||
  2014. backend->recv_unrecoverable_err);
  2015. else
  2016. return FALSE;
  2017. }
  2018. /* shut down the SSL connection and clean up related memory.
  2019. this function can be called multiple times on the same connection including
  2020. if the SSL connection failed (eg connection made but failed handshake). */
  2021. static CURLcode schannel_shutdown(struct Curl_cfilter *cf,
  2022. struct Curl_easy *data,
  2023. bool send_shutdown, bool *done)
  2024. {
  2025. /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
  2026. * Shutting Down an Schannel Connection
  2027. */
  2028. struct ssl_connect_data *connssl = cf->ctx;
  2029. struct schannel_ssl_backend_data *backend =
  2030. (struct schannel_ssl_backend_data *)connssl->backend;
  2031. CURLcode result = CURLE_OK;
  2032. if(cf->shutdown) {
  2033. *done = TRUE;
  2034. return CURLE_OK;
  2035. }
  2036. DEBUGASSERT(data);
  2037. DEBUGASSERT(backend);
  2038. /* Not supported in schannel */
  2039. (void)send_shutdown;
  2040. *done = FALSE;
  2041. if(backend->ctxt) {
  2042. infof(data, "schannel: shutting down SSL/TLS connection with %s port %d",
  2043. connssl->peer.hostname, connssl->peer.port);
  2044. }
  2045. if(!backend->ctxt || cf->shutdown) {
  2046. *done = TRUE;
  2047. goto out;
  2048. }
  2049. if(backend->cred && backend->ctxt && !backend->sent_shutdown) {
  2050. SecBufferDesc BuffDesc;
  2051. SecBuffer Buffer;
  2052. SECURITY_STATUS sspi_status;
  2053. SecBuffer outbuf;
  2054. SecBufferDesc outbuf_desc;
  2055. DWORD dwshut = SCHANNEL_SHUTDOWN;
  2056. InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
  2057. InitSecBufferDesc(&BuffDesc, &Buffer, 1);
  2058. sspi_status = Curl_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle,
  2059. &BuffDesc);
  2060. if(sspi_status != SEC_E_OK) {
  2061. char buffer[STRERROR_LEN];
  2062. failf(data, "schannel: ApplyControlToken failure: %s",
  2063. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  2064. result = CURLE_SEND_ERROR;
  2065. goto out;
  2066. }
  2067. /* setup output buffer */
  2068. InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
  2069. InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
  2070. sspi_status = Curl_pSecFn->InitializeSecurityContext(
  2071. &backend->cred->cred_handle,
  2072. &backend->ctxt->ctxt_handle,
  2073. backend->cred->sni_hostname,
  2074. backend->req_flags,
  2075. 0,
  2076. 0,
  2077. NULL,
  2078. 0,
  2079. &backend->ctxt->ctxt_handle,
  2080. &outbuf_desc,
  2081. &backend->ret_flags,
  2082. &backend->ctxt->time_stamp);
  2083. if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
  2084. /* send close message which is in output buffer */
  2085. ssize_t written = Curl_conn_cf_send(cf->next, data,
  2086. outbuf.pvBuffer, outbuf.cbBuffer,
  2087. FALSE, &result);
  2088. Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
  2089. if(!result) {
  2090. if(written < (ssize_t)outbuf.cbBuffer) {
  2091. /* TODO: handle partial sends */
  2092. failf(data, "schannel: failed to send close msg: %s"
  2093. " (bytes written: %zd)", curl_easy_strerror(result), written);
  2094. result = CURLE_SEND_ERROR;
  2095. goto out;
  2096. }
  2097. backend->sent_shutdown = TRUE;
  2098. *done = TRUE;
  2099. }
  2100. else if(result == CURLE_AGAIN) {
  2101. connssl->io_need = CURL_SSL_IO_NEED_SEND;
  2102. result = CURLE_OK;
  2103. goto out;
  2104. }
  2105. else {
  2106. if(!backend->recv_connection_closed) {
  2107. failf(data, "schannel: error sending close msg: %d", result);
  2108. result = CURLE_SEND_ERROR;
  2109. goto out;
  2110. }
  2111. /* Looks like server already closed the connection.
  2112. * An error to send our close notify is not a failure. */
  2113. *done = TRUE;
  2114. result = CURLE_OK;
  2115. }
  2116. }
  2117. }
  2118. /* If the connection seems open and we have not seen the close notify
  2119. * from the server yet, try to receive it. */
  2120. if(backend->cred && backend->ctxt &&
  2121. !backend->recv_sspi_close_notify && !backend->recv_connection_closed) {
  2122. char buffer[1024];
  2123. ssize_t nread;
  2124. nread = schannel_recv(cf, data, buffer, sizeof(buffer), &result);
  2125. if(nread > 0) {
  2126. /* still data coming in? */
  2127. }
  2128. else if(nread == 0) {
  2129. /* We got the close notify alert and are done. */
  2130. backend->recv_connection_closed = TRUE;
  2131. *done = TRUE;
  2132. }
  2133. else if(nread < 0 && result == CURLE_AGAIN) {
  2134. connssl->io_need = CURL_SSL_IO_NEED_RECV;
  2135. }
  2136. else {
  2137. CURL_TRC_CF(data, cf, "SSL shutdown, error %d", result);
  2138. result = CURLE_RECV_ERROR;
  2139. }
  2140. }
  2141. out:
  2142. cf->shutdown = (result || *done);
  2143. return result;
  2144. }
  2145. static void schannel_close(struct Curl_cfilter *cf, struct Curl_easy *data)
  2146. {
  2147. struct ssl_connect_data *connssl = cf->ctx;
  2148. struct schannel_ssl_backend_data *backend =
  2149. (struct schannel_ssl_backend_data *)connssl->backend;
  2150. DEBUGASSERT(data);
  2151. DEBUGASSERT(backend);
  2152. /* free SSPI Schannel API security context handle */
  2153. if(backend->ctxt) {
  2154. DEBUGF(infof(data, "schannel: clear security context handle"));
  2155. Curl_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle);
  2156. Curl_safefree(backend->ctxt);
  2157. }
  2158. /* free SSPI Schannel API credential handle */
  2159. if(backend->cred) {
  2160. Curl_ssl_sessionid_lock(data);
  2161. schannel_session_free(backend->cred, 0);
  2162. Curl_ssl_sessionid_unlock(data);
  2163. backend->cred = NULL;
  2164. }
  2165. /* free internal buffer for received encrypted data */
  2166. if(backend->encdata_buffer) {
  2167. Curl_safefree(backend->encdata_buffer);
  2168. backend->encdata_length = 0;
  2169. backend->encdata_offset = 0;
  2170. backend->encdata_is_incomplete = FALSE;
  2171. }
  2172. /* free internal buffer for received decrypted data */
  2173. if(backend->decdata_buffer) {
  2174. Curl_safefree(backend->decdata_buffer);
  2175. backend->decdata_length = 0;
  2176. backend->decdata_offset = 0;
  2177. }
  2178. }
  2179. static int schannel_init(void)
  2180. {
  2181. return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0);
  2182. }
  2183. static void schannel_cleanup(void)
  2184. {
  2185. Curl_sspi_global_cleanup();
  2186. }
  2187. static size_t schannel_version(char *buffer, size_t size)
  2188. {
  2189. return msnprintf(buffer, size, "Schannel");
  2190. }
  2191. static CURLcode schannel_random(struct Curl_easy *data UNUSED_PARAM,
  2192. unsigned char *entropy, size_t length)
  2193. {
  2194. (void)data;
  2195. return Curl_win32_random(entropy, length);
  2196. }
  2197. static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
  2198. struct Curl_easy *data,
  2199. const char *pinnedpubkey)
  2200. {
  2201. struct ssl_connect_data *connssl = cf->ctx;
  2202. struct schannel_ssl_backend_data *backend =
  2203. (struct schannel_ssl_backend_data *)connssl->backend;
  2204. CERT_CONTEXT *pCertContextServer = NULL;
  2205. /* Result is returned to caller */
  2206. CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
  2207. DEBUGASSERT(backend);
  2208. /* if a path was not specified, do not pin */
  2209. if(!pinnedpubkey)
  2210. return CURLE_OK;
  2211. do {
  2212. SECURITY_STATUS sspi_status;
  2213. const char *x509_der;
  2214. DWORD x509_der_len;
  2215. struct Curl_X509certificate x509_parsed;
  2216. struct Curl_asn1Element *pubkey;
  2217. sspi_status =
  2218. Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle,
  2219. SECPKG_ATTR_REMOTE_CERT_CONTEXT,
  2220. &pCertContextServer);
  2221. if((sspi_status != SEC_E_OK) || !pCertContextServer) {
  2222. char buffer[STRERROR_LEN];
  2223. failf(data, "schannel: Failed to read remote certificate context: %s",
  2224. Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer)));
  2225. break; /* failed */
  2226. }
  2227. if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
  2228. (pCertContextServer->cbCertEncoded > 0)))
  2229. break;
  2230. x509_der = (const char *)pCertContextServer->pbCertEncoded;
  2231. x509_der_len = pCertContextServer->cbCertEncoded;
  2232. memset(&x509_parsed, 0, sizeof(x509_parsed));
  2233. if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
  2234. break;
  2235. pubkey = &x509_parsed.subjectPublicKeyInfo;
  2236. if(!pubkey->header || pubkey->end <= pubkey->header) {
  2237. failf(data, "SSL: failed retrieving public key from server certificate");
  2238. break;
  2239. }
  2240. result = Curl_pin_peer_pubkey(data,
  2241. pinnedpubkey,
  2242. (const unsigned char *)pubkey->header,
  2243. (size_t)(pubkey->end - pubkey->header));
  2244. if(result) {
  2245. failf(data, "SSL: public key does not match pinned public key");
  2246. }
  2247. } while(0);
  2248. if(pCertContextServer)
  2249. CertFreeCertificateContext(pCertContextServer);
  2250. return result;
  2251. }
  2252. static void schannel_checksum(const unsigned char *input,
  2253. size_t inputlen,
  2254. unsigned char *checksum,
  2255. size_t checksumlen,
  2256. DWORD provType,
  2257. const unsigned int algId)
  2258. {
  2259. #ifdef CURL_WINDOWS_UWP
  2260. (void)input;
  2261. (void)inputlen;
  2262. (void)provType;
  2263. (void)algId;
  2264. memset(checksum, 0, checksumlen);
  2265. #else
  2266. HCRYPTPROV hProv = 0;
  2267. HCRYPTHASH hHash = 0;
  2268. DWORD cbHashSize = 0;
  2269. DWORD dwHashSizeLen = (DWORD)sizeof(cbHashSize);
  2270. DWORD dwChecksumLen = (DWORD)checksumlen;
  2271. /* since this can fail in multiple ways, zero memory first so we never
  2272. * return old data
  2273. */
  2274. memset(checksum, 0, checksumlen);
  2275. if(!CryptAcquireContext(&hProv, NULL, NULL, provType,
  2276. CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
  2277. return; /* failed */
  2278. do {
  2279. if(!CryptCreateHash(hProv, algId, 0, 0, &hHash))
  2280. break; /* failed */
  2281. if(!CryptHashData(hHash, input, (DWORD)inputlen, 0))
  2282. break; /* failed */
  2283. /* get hash size */
  2284. if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&cbHashSize,
  2285. &dwHashSizeLen, 0))
  2286. break; /* failed */
  2287. /* check hash size */
  2288. if(checksumlen < cbHashSize)
  2289. break; /* failed */
  2290. if(CryptGetHashParam(hHash, HP_HASHVAL, checksum, &dwChecksumLen, 0))
  2291. break; /* failed */
  2292. } while(0);
  2293. if(hHash)
  2294. CryptDestroyHash(hHash);
  2295. if(hProv)
  2296. CryptReleaseContext(hProv, 0);
  2297. #endif
  2298. }
  2299. static CURLcode schannel_sha256sum(const unsigned char *input,
  2300. size_t inputlen,
  2301. unsigned char *sha256sum,
  2302. size_t sha256len)
  2303. {
  2304. schannel_checksum(input, inputlen, sha256sum, sha256len,
  2305. PROV_RSA_AES, CALG_SHA_256);
  2306. return CURLE_OK;
  2307. }
  2308. static void *schannel_get_internals(struct ssl_connect_data *connssl,
  2309. CURLINFO info UNUSED_PARAM)
  2310. {
  2311. struct schannel_ssl_backend_data *backend =
  2312. (struct schannel_ssl_backend_data *)connssl->backend;
  2313. (void)info;
  2314. DEBUGASSERT(backend);
  2315. return &backend->ctxt->ctxt_handle;
  2316. }
  2317. HCERTSTORE Curl_schannel_get_cached_cert_store(struct Curl_cfilter *cf,
  2318. const struct Curl_easy *data)
  2319. {
  2320. struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
  2321. struct Curl_multi *multi = data->multi;
  2322. const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
  2323. struct schannel_cert_share *share;
  2324. const struct ssl_general_config *cfg = &data->set.general_ssl;
  2325. timediff_t timeout_ms;
  2326. timediff_t elapsed_ms;
  2327. struct curltime now;
  2328. unsigned char info_blob_digest[CURL_SHA256_DIGEST_LENGTH];
  2329. DEBUGASSERT(multi);
  2330. if(!multi) {
  2331. return NULL;
  2332. }
  2333. share = Curl_hash_pick(&multi->proto_hash,
  2334. (void *)MPROTO_SCHANNEL_CERT_SHARE_KEY,
  2335. sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY)-1);
  2336. if(!share || !share->cert_store) {
  2337. return NULL;
  2338. }
  2339. /* zero ca_cache_timeout completely disables caching */
  2340. if(!cfg->ca_cache_timeout) {
  2341. return NULL;
  2342. }
  2343. /* check for cache timeout by using the cached_x509_store_expired timediff
  2344. calculation pattern from openssl.c.
  2345. negative timeout means retain forever. */
  2346. timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000;
  2347. if(timeout_ms >= 0) {
  2348. now = Curl_now();
  2349. elapsed_ms = Curl_timediff(now, share->time);
  2350. if(elapsed_ms >= timeout_ms) {
  2351. return NULL;
  2352. }
  2353. }
  2354. if(ca_info_blob) {
  2355. if(share->CAinfo_blob_size != ca_info_blob->len) {
  2356. return NULL;
  2357. }
  2358. schannel_sha256sum((const unsigned char *)ca_info_blob->data,
  2359. ca_info_blob->len,
  2360. info_blob_digest,
  2361. CURL_SHA256_DIGEST_LENGTH);
  2362. if(memcmp(share->CAinfo_blob_digest, info_blob_digest,
  2363. CURL_SHA256_DIGEST_LENGTH)) {
  2364. return NULL;
  2365. }
  2366. }
  2367. else {
  2368. if(!conn_config->CAfile || !share->CAfile ||
  2369. strcmp(share->CAfile, conn_config->CAfile)) {
  2370. return NULL;
  2371. }
  2372. }
  2373. return share->cert_store;
  2374. }
  2375. static void schannel_cert_share_free(void *key, size_t key_len, void *p)
  2376. {
  2377. struct schannel_cert_share *share = p;
  2378. DEBUGASSERT(key_len == (sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY)-1));
  2379. DEBUGASSERT(!memcmp(MPROTO_SCHANNEL_CERT_SHARE_KEY, key, key_len));
  2380. (void)key;
  2381. (void)key_len;
  2382. if(share->cert_store) {
  2383. CertCloseStore(share->cert_store, 0);
  2384. }
  2385. free(share->CAfile);
  2386. free(share);
  2387. }
  2388. bool Curl_schannel_set_cached_cert_store(struct Curl_cfilter *cf,
  2389. const struct Curl_easy *data,
  2390. HCERTSTORE cert_store)
  2391. {
  2392. struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
  2393. struct Curl_multi *multi = data->multi;
  2394. const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
  2395. struct schannel_cert_share *share;
  2396. size_t CAinfo_blob_size = 0;
  2397. char *CAfile = NULL;
  2398. DEBUGASSERT(multi);
  2399. if(!multi) {
  2400. return FALSE;
  2401. }
  2402. share = Curl_hash_pick(&multi->proto_hash,
  2403. (void *)MPROTO_SCHANNEL_CERT_SHARE_KEY,
  2404. sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY)-1);
  2405. if(!share) {
  2406. share = calloc(1, sizeof(*share));
  2407. if(!share) {
  2408. return FALSE;
  2409. }
  2410. if(!Curl_hash_add2(&multi->proto_hash,
  2411. (void *)MPROTO_SCHANNEL_CERT_SHARE_KEY,
  2412. sizeof(MPROTO_SCHANNEL_CERT_SHARE_KEY)-1,
  2413. share, schannel_cert_share_free)) {
  2414. free(share);
  2415. return FALSE;
  2416. }
  2417. }
  2418. if(ca_info_blob) {
  2419. schannel_sha256sum((const unsigned char *)ca_info_blob->data,
  2420. ca_info_blob->len,
  2421. share->CAinfo_blob_digest,
  2422. CURL_SHA256_DIGEST_LENGTH);
  2423. CAinfo_blob_size = ca_info_blob->len;
  2424. }
  2425. else {
  2426. if(conn_config->CAfile) {
  2427. CAfile = strdup(conn_config->CAfile);
  2428. if(!CAfile) {
  2429. return FALSE;
  2430. }
  2431. }
  2432. }
  2433. /* free old cache data */
  2434. if(share->cert_store) {
  2435. CertCloseStore(share->cert_store, 0);
  2436. }
  2437. free(share->CAfile);
  2438. share->time = Curl_now();
  2439. share->cert_store = cert_store;
  2440. share->CAinfo_blob_size = CAinfo_blob_size;
  2441. share->CAfile = CAfile;
  2442. return TRUE;
  2443. }
  2444. const struct Curl_ssl Curl_ssl_schannel = {
  2445. { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */
  2446. SSLSUPP_CERTINFO |
  2447. #ifdef HAS_MANUAL_VERIFY_API
  2448. SSLSUPP_CAINFO_BLOB |
  2449. #endif
  2450. #ifndef CURL_WINDOWS_UWP
  2451. SSLSUPP_PINNEDPUBKEY |
  2452. #endif
  2453. SSLSUPP_CA_CACHE |
  2454. SSLSUPP_HTTPS_PROXY |
  2455. SSLSUPP_CIPHER_LIST,
  2456. sizeof(struct schannel_ssl_backend_data),
  2457. schannel_init, /* init */
  2458. schannel_cleanup, /* cleanup */
  2459. schannel_version, /* version */
  2460. Curl_none_check_cxn, /* check_cxn */
  2461. schannel_shutdown, /* shutdown */
  2462. schannel_data_pending, /* data_pending */
  2463. schannel_random, /* random */
  2464. Curl_none_cert_status_request, /* cert_status_request */
  2465. schannel_connect, /* connect */
  2466. schannel_connect_nonblocking, /* connect_nonblocking */
  2467. Curl_ssl_adjust_pollset, /* adjust_pollset */
  2468. schannel_get_internals, /* get_internals */
  2469. schannel_close, /* close_one */
  2470. Curl_none_close_all, /* close_all */
  2471. Curl_none_set_engine, /* set_engine */
  2472. Curl_none_set_engine_default, /* set_engine_default */
  2473. Curl_none_engines_list, /* engines_list */
  2474. Curl_none_false_start, /* false_start */
  2475. schannel_sha256sum, /* sha256sum */
  2476. NULL, /* associate_connection */
  2477. NULL, /* disassociate_connection */
  2478. schannel_recv, /* recv decrypted data */
  2479. schannel_send, /* send data to encrypt */
  2480. NULL, /* get_channel_binding */
  2481. };
  2482. #endif /* USE_SCHANNEL */