Lines Matching +full:persist +full:- +full:credentials
9 * Copyright (C) Marc Hoersken, <info@marc-hoersken.de>
23 * SPDX-License-Identifier: curl
28 * Source file for all Schannel-specific code for the TLS/SSL layer. No code
65 https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx
154 buffer->cbBuffer = BufByteSize; in InitSecBuffer()
155 buffer->BufferType = BufType; in InitSecBuffer()
156 buffer->pvBuffer = BufDataPtr; in InitSecBuffer()
162 desc->ulVersion = SECBUFFER_VERSION; in InitSecBufferDesc()
163 desc->pBuffers = BufArr; in InitSecBufferDesc()
164 desc->cBuffers = NumArrElem; in InitSecBufferDesc()
173 long ssl_version = conn_config->version; in schannel_set_ssl_version_min_max()
174 long ssl_version_max = conn_config->version_max; in schannel_set_ssl_version_min_max()
182 built-in. Previous builds of Windows 10 had broken TLS 1.3 in schannel_set_ssl_version_min_max()
344 size_t n = nameEnd ? (size_t)(nameEnd - name) : strlen(name); in get_alg_id_by_name()
369 sizeof("USE_STRONG_CRYPTO") - 1) || in set_ssl_ciphers()
371 sizeof("SCH_USE_STRONG_CRYPTO") - 1)) in set_ssl_ciphers()
372 schannel_cred->dwFlags |= SCH_USE_STRONG_CRYPTO; in set_ssl_ciphers()
379 schannel_cred->palgSupportedAlgs = algIds; in set_ssl_ciphers()
380 schannel_cred->cSupportedAlgs = algCount; in set_ssl_ciphers()
399 store_name_len = sep - path; in get_cert_location()
452 struct ssl_connect_data *connssl = cf->ctx; in schannel_acquire_credential_handle()
468 (struct schannel_ssl_backend_data *)(connssl->backend); in schannel_acquire_credential_handle()
472 if(conn_config->verifypeer) { in schannel_acquire_credential_handle()
474 if(backend->use_manual_cred_validation) in schannel_acquire_credential_handle()
480 if(ssl_config->no_revoke) { in schannel_acquire_credential_handle()
487 else if(ssl_config->revoke_best_effort) { in schannel_acquire_credential_handle()
508 if(!conn_config->verifyhost) { in schannel_acquire_credential_handle()
515 if(!ssl_config->auto_client_cert) { in schannel_acquire_credential_handle()
523 switch(conn_config->version) { in schannel_acquire_credential_handle()
547 if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { in schannel_acquire_credential_handle()
557 bool blob = data->set.ssl.primary.cert_blob != NULL; in schannel_acquire_credential_handle()
560 certdata = data->set.ssl.primary.cert_blob->data; in schannel_acquire_credential_handle()
561 certsize = data->set.ssl.primary.cert_blob->len; in schannel_acquire_credential_handle()
565 data->set.ssl.primary.clientcert); in schannel_acquire_credential_handle()
572 if(result && (data->set.ssl.primary.clientcert[0]!='\0')) in schannel_acquire_credential_handle()
573 fInCert = fopen(data->set.ssl.primary.clientcert, "rb"); in schannel_acquire_credential_handle()
578 data->set.ssl.primary.clientcert); in schannel_acquire_credential_handle()
584 if((fInCert || blob) && (data->set.ssl.cert_type) && in schannel_acquire_credential_handle()
585 (!strcasecompare(data->set.ssl.cert_type, "P12"))) { in schannel_acquire_credential_handle()
588 blob ? "(memory blob)" : data->set.ssl.primary.clientcert); in schannel_acquire_credential_handle()
596 en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5 in schannel_acquire_credential_handle()
603 "(memory blob)" : data->set.ssl.primary.clientcert; in schannel_acquire_credential_handle()
624 data->set.ssl.primary.clientcert); in schannel_acquire_credential_handle()
630 /* Convert key-pair data to the in-memory certificate store */ in schannel_acquire_credential_handle()
634 if(data->set.ssl.key_passwd) in schannel_acquire_credential_handle()
635 pwd_len = strlen(data->set.ssl.key_passwd); in schannel_acquire_credential_handle()
641 data->set.ssl.key_passwd, in schannel_acquire_credential_handle()
736 if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { in schannel_acquire_credential_handle()
743 backend->cred = (struct Curl_schannel_cred *) in schannel_acquire_credential_handle()
745 if(!backend->cred) { in schannel_acquire_credential_handle()
757 backend->cred->refcount = 1; in schannel_acquire_credential_handle()
760 /* Since we did not persist the key, we need to extend the store's in schannel_acquire_credential_handle()
763 backend->cred->client_cert_store = client_cert_store; in schannel_acquire_credential_handle()
769 if(!conn_config->cipher_list && in schannel_acquire_credential_handle()
781 SCH_CREDENTIALS credentials = { 0 }; in schannel_acquire_credential_handle() local
791 * disable all the ciphers and re-enable which in schannel_acquire_credential_handle()
794 ciphers13 = conn_config->cipher_list13; in schannel_acquire_credential_handle()
816 n = nameEnd ? (size_t)(nameEnd - startCur) : strlen(startCur); in schannel_acquire_credential_handle()
936 Disable ChaCha20-Poly1305. in schannel_acquire_credential_handle()
954 credentials.pTlsParameters = &tls_parameters; in schannel_acquire_credential_handle()
955 credentials.cTlsParameters = 1; in schannel_acquire_credential_handle()
957 credentials.dwVersion = SCH_CREDENTIALS_VERSION; in schannel_acquire_credential_handle()
958 credentials.dwFlags = flags | SCH_USE_STRONG_CRYPTO; in schannel_acquire_credential_handle()
960 credentials.pTlsParameters->grbitDisabledProtocols = in schannel_acquire_credential_handle()
965 credentials.cCreds = 1; in schannel_acquire_credential_handle()
966 credentials.paCred = client_certs; in schannel_acquire_credential_handle()
971 s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, in schannel_acquire_credential_handle()
973 &credentials, NULL, NULL, in schannel_acquire_credential_handle()
974 &backend->cred->cred_handle, in schannel_acquire_credential_handle()
975 &backend->cred->time_stamp); in schannel_acquire_credential_handle()
978 /* Pre-Windows 10 1809 or the user set a legacy algorithm list. Although MS in schannel_acquire_credential_handle()
982 char *ciphers = conn_config->cipher_list; in schannel_acquire_credential_handle()
991 "negotiate a less-secure TLS version than TLS 1.3 because the " in schannel_acquire_credential_handle()
994 if(conn_config->cipher_list13) { in schannel_acquire_credential_handle()
1018 s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, in schannel_acquire_credential_handle()
1021 &backend->cred->cred_handle, in schannel_acquire_credential_handle()
1022 &backend->cred->time_stamp); in schannel_acquire_credential_handle()
1034 Curl_safefree(backend->cred); in schannel_acquire_credential_handle()
1054 ssize_t written = -1; in schannel_connect_step1()
1055 struct ssl_connect_data *connssl = cf->ctx; in schannel_connect_step1()
1057 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_connect_step1()
1074 connssl->peer.hostname, connssl->peer.port)); in schannel_connect_step1()
1087 backend->use_alpn = connssl->alpn && in schannel_connect_step1()
1093 backend->use_alpn = false; in schannel_connect_step1()
1100 backend->use_manual_cred_validation = true; in schannel_connect_step1()
1106 if(conn_config->CAfile || conn_config->ca_info_blob) { in schannel_connect_step1()
1109 backend->use_manual_cred_validation = true; in schannel_connect_step1()
1118 backend->use_manual_cred_validation = false; in schannel_connect_step1()
1120 if(conn_config->CAfile || conn_config->ca_info_blob) { in schannel_connect_step1()
1127 backend->cred = NULL; in schannel_connect_step1()
1130 if(ssl_config->primary.sessionid) { in schannel_connect_step1()
1132 if(!Curl_ssl_getsessionid(cf, data, &connssl->peer, in schannel_connect_step1()
1134 backend->cred = old_cred; in schannel_connect_step1()
1138 backend->cred->refcount++; in schannel_connect_step1()
1141 backend->cred->refcount)); in schannel_connect_step1()
1146 if(!backend->cred) { in schannel_connect_step1()
1151 /* schannel_acquire_credential_handle() sets backend->cred accordingly or in schannel_connect_step1()
1156 snihost = connssl->peer.sni? connssl->peer.sni : connssl->peer.hostname; in schannel_connect_step1()
1157 backend->cred->sni_hostname = curlx_convert_UTF8_to_tchar(snihost); in schannel_connect_step1()
1158 if(!backend->cred->sni_hostname) in schannel_connect_step1()
1163 if(connssl->peer.type != CURL_SSL_PEER_DNS) { in schannel_connect_step1()
1168 if(backend->use_alpn) { in schannel_connect_step1()
1193 result = Curl_alpn_to_proto_buf(&proto, connssl->alpn); in schannel_connect_step1()
1201 *list_len = curlx_uitous(cur - list_start_index); in schannel_connect_step1()
1208 Curl_alpn_to_proto_str(&proto, connssl->alpn); in schannel_connect_step1()
1225 backend->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | in schannel_connect_step1()
1229 if(!ssl_config->auto_client_cert) { in schannel_connect_step1()
1230 backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; in schannel_connect_step1()
1234 backend->ctxt = (struct Curl_schannel_ctxt *) in schannel_connect_step1()
1236 if(!backend->ctxt) { in schannel_connect_step1()
1242 https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx in schannel_connect_step1()
1248 sspi_status = s_pSecFn->InitializeSecurityContext( in schannel_connect_step1()
1249 &backend->cred->cred_handle, NULL, backend->cred->sni_hostname, in schannel_connect_step1()
1250 backend->req_flags, 0, 0, in schannel_connect_step1()
1251 (backend->use_alpn ? &inbuf_desc : NULL), in schannel_connect_step1()
1252 0, &backend->ctxt->ctxt_handle, in schannel_connect_step1()
1253 &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp); in schannel_connect_step1()
1257 Curl_safefree(backend->ctxt); in schannel_connect_step1()
1289 written = Curl_conn_cf_send(cf->next, data, in schannel_connect_step1()
1292 s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); in schannel_connect_step1()
1302 backend->recv_unrecoverable_err = CURLE_OK; in schannel_connect_step1()
1303 backend->recv_sspi_close_notify = false; in schannel_connect_step1()
1304 backend->recv_connection_closed = false; in schannel_connect_step1()
1305 backend->recv_renegotiating = false; in schannel_connect_step1()
1306 backend->encdata_is_incomplete = false; in schannel_connect_step1()
1309 connssl->connecting_state = ssl_connect_2; in schannel_connect_step1()
1317 struct ssl_connect_data *connssl = cf->ctx; in schannel_connect_step2()
1319 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_connect_step2()
1322 ssize_t nread = -1, written = -1; in schannel_connect_step2()
1335 doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; in schannel_connect_step2()
1339 connssl->peer.hostname, connssl->peer.port)); in schannel_connect_step2()
1341 if(!backend->cred || !backend->ctxt) in schannel_connect_step2()
1345 if(!backend->decdata_buffer) { in schannel_connect_step2()
1346 backend->decdata_offset = 0; in schannel_connect_step2()
1347 backend->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; in schannel_connect_step2()
1348 backend->decdata_buffer = malloc(backend->decdata_length); in schannel_connect_step2()
1349 if(!backend->decdata_buffer) { in schannel_connect_step2()
1356 if(!backend->encdata_buffer) { in schannel_connect_step2()
1357 backend->encdata_is_incomplete = false; in schannel_connect_step2()
1358 backend->encdata_offset = 0; in schannel_connect_step2()
1359 backend->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; in schannel_connect_step2()
1360 backend->encdata_buffer = malloc(backend->encdata_length); in schannel_connect_step2()
1361 if(!backend->encdata_buffer) { in schannel_connect_step2()
1368 if(backend->encdata_length - backend->encdata_offset < in schannel_connect_step2()
1371 size_t reallocated_length = backend->encdata_offset + in schannel_connect_step2()
1373 reallocated_buffer = realloc(backend->encdata_buffer, in schannel_connect_step2()
1377 failf(data, "schannel: unable to re-allocate memory"); in schannel_connect_step2()
1381 backend->encdata_buffer = reallocated_buffer; in schannel_connect_step2()
1382 backend->encdata_length = reallocated_length; in schannel_connect_step2()
1389 nread = Curl_conn_cf_recv(cf->next, data, in schannel_connect_step2()
1390 (char *) (backend->encdata_buffer + in schannel_connect_step2()
1391 backend->encdata_offset), in schannel_connect_step2()
1392 backend->encdata_length - in schannel_connect_step2()
1393 backend->encdata_offset, in schannel_connect_step2()
1396 if(connssl->connecting_state != ssl_connect_2_writing) in schannel_connect_step2()
1397 connssl->connecting_state = ssl_connect_2_reading; in schannel_connect_step2()
1409 backend->encdata_offset += nread; in schannel_connect_step2()
1410 backend->encdata_is_incomplete = false; in schannel_connect_step2()
1416 backend->encdata_offset, backend->encdata_length)); in schannel_connect_step2()
1419 InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(backend->encdata_offset), in schannel_connect_step2()
1420 curlx_uztoul(backend->encdata_offset)); in schannel_connect_step2()
1436 memcpy(inbuf[0].pvBuffer, backend->encdata_buffer, in schannel_connect_step2()
1437 backend->encdata_offset); in schannel_connect_step2()
1439 sspi_status = s_pSecFn->InitializeSecurityContext( in schannel_connect_step2()
1440 &backend->cred->cred_handle, &backend->ctxt->ctxt_handle, in schannel_connect_step2()
1441 backend->cred->sni_hostname, backend->req_flags, in schannel_connect_step2()
1443 &outbuf_desc, &backend->ret_flags, &backend->ctxt->time_stamp); in schannel_connect_step2()
1450 backend->encdata_is_incomplete = true; in schannel_connect_step2()
1451 connssl->connecting_state = ssl_connect_2_reading; in schannel_connect_step2()
1461 !(backend->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { in schannel_connect_step2()
1462 backend->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; in schannel_connect_step2()
1463 connssl->connecting_state = ssl_connect_2_writing; in schannel_connect_step2()
1478 written = Curl_conn_cf_send(cf->next, data, in schannel_connect_step2()
1491 s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer); in schannel_connect_step2()
1544 if(backend->encdata_offset > inbuf[1].cbBuffer) { in schannel_connect_step2()
1545 memmove(backend->encdata_buffer, in schannel_connect_step2()
1546 (backend->encdata_buffer + backend->encdata_offset) - in schannel_connect_step2()
1548 backend->encdata_offset = inbuf[1].cbBuffer; in schannel_connect_step2()
1556 backend->encdata_offset = 0; in schannel_connect_step2()
1563 connssl->connecting_state = ssl_connect_2_reading; in schannel_connect_step2()
1569 connssl->connecting_state = ssl_connect_3; in schannel_connect_step2()
1575 data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]: in schannel_connect_step2()
1576 data->set.str[STRING_SSL_PINNEDPUBLICKEY]; in schannel_connect_step2()
1578 pubkey_ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; in schannel_connect_step2()
1589 if(conn_config->verifypeer && backend->use_manual_cred_validation) { in schannel_connect_step2()
1597 if(!conn_config->verifypeer && conn_config->verifyhost) in schannel_connect_step2()
1607 ((cert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) && in valid_cert_encoding()
1608 (cert_context->pbCertEncoded != NULL) && in valid_cert_encoding()
1609 (cert_context->cbCertEncoded > 0); in valid_cert_encoding()
1625 context->hCertStore, in traverse_cert_store()
1628 leaf-to-root order while all previous versions of Windows enumerate in traverse_cert_store()
1629 certificates in root-to-leaf order. Determine the order of enumeration in traverse_cert_store()
1632 if(first && context->pbCertEncoded != current_context->pbCertEncoded) in traverse_cert_store()
1665 args->result = CURLE_OK; in add_cert_to_certinfo()
1667 const char *beg = (const char *) ccert_context->pbCertEncoded; in add_cert_to_certinfo()
1668 const char *end = beg + ccert_context->cbCertEncoded; in add_cert_to_certinfo()
1669 int insert_index = reverse_order ? (args->certs_count - 1) - args->idx : in add_cert_to_certinfo()
1670 args->idx; in add_cert_to_certinfo()
1671 args->result = Curl_extract_certinfo(args->data, insert_index, in add_cert_to_certinfo()
1673 args->idx++; in add_cert_to_certinfo()
1675 return args->result == CURLE_OK; in add_cert_to_certinfo()
1685 cred->refcount--; in schannel_session_free()
1686 if(cred->refcount == 0) { in schannel_session_free()
1687 s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); in schannel_session_free()
1688 curlx_unicodefree(cred->sni_hostname); in schannel_session_free()
1690 if(cred->client_cert_store) { in schannel_session_free()
1691 CertCloseStore(cred->client_cert_store, 0); in schannel_session_free()
1692 cred->client_cert_store = NULL; in schannel_session_free()
1703 struct ssl_connect_data *connssl = cf->ctx; in schannel_connect_step3()
1705 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_connect_step3()
1714 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); in schannel_connect_step3()
1719 connssl->peer.hostname, connssl->peer.port)); in schannel_connect_step3()
1721 if(!backend->cred) in schannel_connect_step3()
1725 if(backend->ret_flags != backend->req_flags) { in schannel_connect_step3()
1726 if(!(backend->ret_flags & ISC_RET_SEQUENCE_DETECT)) in schannel_connect_step3()
1728 if(!(backend->ret_flags & ISC_RET_REPLAY_DETECT)) in schannel_connect_step3()
1730 if(!(backend->ret_flags & ISC_RET_CONFIDENTIALITY)) in schannel_connect_step3()
1732 if(!(backend->ret_flags & ISC_RET_ALLOCATED_MEMORY)) in schannel_connect_step3()
1734 if(!(backend->ret_flags & ISC_RET_STREAM)) in schannel_connect_step3()
1740 if(backend->use_alpn) { in schannel_connect_step3()
1742 s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, in schannel_connect_step3()
1753 unsigned char prev_alpn = cf->conn->alpn; in schannel_connect_step3()
1757 if(backend->recv_renegotiating) { in schannel_connect_step3()
1758 if(prev_alpn != cf->conn->alpn && in schannel_connect_step3()
1768 if(!backend->recv_renegotiating) in schannel_connect_step3()
1775 if(ssl_config->primary.sessionid) { in schannel_connect_step3()
1780 incache = !(Curl_ssl_getsessionid(cf, data, &connssl->peer, in schannel_connect_step3()
1783 if(old_cred != backend->cred) { in schannel_connect_step3()
1793 backend->cred->refcount++; in schannel_connect_step3()
1794 result = Curl_ssl_addsessionid(cf, data, &connssl->peer, backend->cred, in schannel_connect_step3()
1805 if(data->set.ssl.certinfo) { in schannel_connect_step3()
1808 s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, in schannel_connect_step3()
1833 connssl->connecting_state = ssl_connect_done; in schannel_connect_step3()
1844 struct ssl_connect_data *connssl = cf->ctx; in schannel_connect_common()
1850 if(ssl_connection_complete == connssl->state) { in schannel_connect_common()
1855 if(ssl_connect_1 == connssl->connecting_state) { in schannel_connect_common()
1870 while(ssl_connect_2 == connssl->connecting_state || in schannel_connect_common()
1871 ssl_connect_2_reading == connssl->connecting_state || in schannel_connect_common()
1872 ssl_connect_2_writing == connssl->connecting_state) { in schannel_connect_common()
1884 if(connssl->connecting_state == ssl_connect_2_reading in schannel_connect_common()
1885 || connssl->connecting_state == ssl_connect_2_writing) { in schannel_connect_common()
1888 connssl->connecting_state ? sockfd : CURL_SOCKET_BAD; in schannel_connect_common()
1890 connssl->connecting_state ? sockfd : CURL_SOCKET_BAD; in schannel_connect_common()
1922 (ssl_connect_2 == connssl->connecting_state || in schannel_connect_common()
1923 ssl_connect_2_reading == connssl->connecting_state || in schannel_connect_common()
1924 ssl_connect_2_writing == connssl->connecting_state))) in schannel_connect_common()
1929 if(ssl_connect_3 == connssl->connecting_state) { in schannel_connect_common()
1935 if(ssl_connect_done == connssl->connecting_state) { in schannel_connect_common()
1936 connssl->state = ssl_connection_complete; in schannel_connect_common()
1946 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_connect_common()
1948 cf->conn->sslContext = &backend->ctxt->ctxt_handle; in schannel_connect_common()
1958 connssl->connecting_state = ssl_connect_1; in schannel_connect_common()
1967 ssize_t written = -1; in schannel_send()
1970 struct ssl_connect_data *connssl = cf->ctx; in schannel_send()
1976 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_send()
1981 if(backend->stream_sizes.cbMaximumMessage == 0) { in schannel_send()
1982 sspi_status = s_pSecFn->QueryContextAttributes( in schannel_send()
1983 &backend->ctxt->ctxt_handle, in schannel_send()
1985 &backend->stream_sizes); in schannel_send()
1988 return -1; in schannel_send()
1993 if(len > backend->stream_sizes.cbMaximumMessage) { in schannel_send()
1994 len = backend->stream_sizes.cbMaximumMessage; in schannel_send()
1998 data_len = backend->stream_sizes.cbHeader + len + in schannel_send()
1999 backend->stream_sizes.cbTrailer; in schannel_send()
2003 return -1; in schannel_send()
2008 ptr, backend->stream_sizes.cbHeader); in schannel_send()
2010 ptr + backend->stream_sizes.cbHeader, curlx_uztoul(len)); in schannel_send()
2012 ptr + backend->stream_sizes.cbHeader + len, in schannel_send()
2013 backend->stream_sizes.cbTrailer); in schannel_send()
2020 /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */ in schannel_send()
2021 sspi_status = s_pSecFn->EncryptMessage(&backend->ctxt->ctxt_handle, 0, in schannel_send()
2041 Here's the catch with this - if we tell the client that all the in schannel_send()
2057 written = -1; in schannel_send()
2067 written = -1; in schannel_send()
2074 written = -1; in schannel_send()
2079 this_write = Curl_conn_cf_send(cf->next, data, in schannel_send()
2080 ptr + written, len - written, in schannel_send()
2086 written = -1; in schannel_send()
2115 ssize_t nread = -1; in schannel_recv()
2116 struct ssl_connect_data *connssl = cf->ctx; in schannel_recv()
2127 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_recv()
2132 * Don't return or set backend->recv_unrecoverable_err unless in the cleanup. in schannel_recv()
2144 if(len && len <= backend->decdata_offset) { in schannel_recv()
2148 else if(backend->recv_unrecoverable_err) { in schannel_recv()
2149 *err = backend->recv_unrecoverable_err; in schannel_recv()
2153 else if(backend->recv_sspi_close_notify) { in schannel_recv()
2162 else if(len && !backend->recv_connection_closed) { in schannel_recv()
2164 size = backend->encdata_length - backend->encdata_offset; in schannel_recv()
2166 backend->encdata_length < min_encdata_length) { in schannel_recv()
2167 reallocated_length = backend->encdata_offset + in schannel_recv()
2172 reallocated_buffer = realloc(backend->encdata_buffer, in schannel_recv()
2176 failf(data, "schannel: unable to re-allocate memory"); in schannel_recv()
2180 backend->encdata_buffer = reallocated_buffer; in schannel_recv()
2181 backend->encdata_length = reallocated_length; in schannel_recv()
2182 size = backend->encdata_length - backend->encdata_offset; in schannel_recv()
2184 backend->encdata_length)); in schannel_recv()
2189 backend->encdata_offset, backend->encdata_length)); in schannel_recv()
2192 nread = Curl_conn_cf_recv(cf->next, data, in schannel_recv()
2193 (char *)(backend->encdata_buffer + in schannel_recv()
2194 backend->encdata_offset), in schannel_recv()
2197 nread = -1; in schannel_recv()
2207 backend->recv_connection_closed = true; in schannel_recv()
2211 backend->encdata_offset += (size_t)nread; in schannel_recv()
2212 backend->encdata_is_incomplete = false; in schannel_recv()
2219 backend->encdata_offset, backend->encdata_length)); in schannel_recv()
2222 while(backend->encdata_offset > 0 && sspi_status == SEC_E_OK && in schannel_recv()
2223 (!len || backend->decdata_offset < len || in schannel_recv()
2224 backend->recv_connection_closed)) { in schannel_recv()
2226 InitSecBuffer(&inbuf[0], SECBUFFER_DATA, backend->encdata_buffer, in schannel_recv()
2227 curlx_uztoul(backend->encdata_offset)); in schannel_recv()
2235 /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx in schannel_recv()
2237 sspi_status = s_pSecFn->DecryptMessage(&backend->ctxt->ctxt_handle, in schannel_recv()
2253 if(backend->decdata_length - backend->decdata_offset < size || in schannel_recv()
2254 backend->decdata_length < len) { in schannel_recv()
2256 reallocated_length = backend->decdata_offset + size; in schannel_recv()
2261 reallocated_buffer = realloc(backend->decdata_buffer, in schannel_recv()
2265 failf(data, "schannel: unable to re-allocate memory"); in schannel_recv()
2268 backend->decdata_buffer = reallocated_buffer; in schannel_recv()
2269 backend->decdata_length = reallocated_length; in schannel_recv()
2275 memcpy(backend->decdata_buffer + backend->decdata_offset, in schannel_recv()
2277 backend->decdata_offset += size; in schannel_recv()
2283 backend->decdata_offset, backend->decdata_length)); in schannel_recv()
2294 if(backend->encdata_offset > inbuf[3].cbBuffer) { in schannel_recv()
2297 memmove(backend->encdata_buffer, in schannel_recv()
2298 (backend->encdata_buffer + backend->encdata_offset) - in schannel_recv()
2300 backend->encdata_offset = inbuf[3].cbBuffer; in schannel_recv()
2305 backend->encdata_offset, backend->encdata_length)); in schannel_recv()
2309 backend->encdata_offset = 0; in schannel_recv()
2322 connssl->state = ssl_connection_negotiating; in schannel_recv()
2323 connssl->connecting_state = ssl_connect_2_writing; in schannel_recv()
2324 backend->recv_renegotiating = true; in schannel_recv()
2326 backend->recv_renegotiating = false; in schannel_recv()
2340 backend->recv_sspi_close_notify = true; in schannel_recv()
2341 if(!backend->recv_connection_closed) in schannel_recv()
2342 backend->recv_connection_closed = true; in schannel_recv()
2349 backend->encdata_is_incomplete = true; in schannel_recv()
2368 backend->encdata_offset, backend->encdata_length)); in schannel_recv()
2372 backend->decdata_offset, backend->decdata_length)); in schannel_recv()
2375 /* Warning- there is no guarantee the encdata state is valid at this point */ in schannel_recv()
2389 if(len && !backend->decdata_offset && backend->recv_connection_closed && in schannel_recv()
2390 !backend->recv_sspi_close_notify) { in schannel_recv()
2395 backend->recv_sspi_close_notify = true; in schannel_recv()
2404 backend->recv_unrecoverable_err = *err; in schannel_recv()
2406 size = len < backend->decdata_offset ? len : backend->decdata_offset; in schannel_recv()
2408 memcpy(buf, backend->decdata_buffer, size); in schannel_recv()
2409 memmove(backend->decdata_buffer, backend->decdata_buffer + size, in schannel_recv()
2410 backend->decdata_offset - size); in schannel_recv()
2411 backend->decdata_offset -= size; in schannel_recv()
2415 backend->decdata_offset, backend->decdata_length)); in schannel_recv()
2420 if(!*err && !backend->recv_connection_closed) in schannel_recv()
2430 return *err ? -1 : 0; in schannel_recv()
2458 const struct ssl_connect_data *connssl = cf->ctx; in schannel_data_pending()
2460 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_data_pending()
2465 if(backend->ctxt) /* SSL/TLS is in use */ in schannel_data_pending()
2466 return (backend->decdata_offset > 0 || in schannel_data_pending()
2467 (backend->encdata_offset > 0 && !backend->encdata_is_incomplete) || in schannel_data_pending()
2468 backend->recv_connection_closed || in schannel_data_pending()
2469 backend->recv_sspi_close_notify || in schannel_data_pending()
2470 backend->recv_unrecoverable_err); in schannel_data_pending()
2481 /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx in schannel_shutdown()
2484 struct ssl_connect_data *connssl = cf->ctx; in schannel_shutdown()
2486 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_shutdown()
2491 if(backend->ctxt) { in schannel_shutdown()
2493 connssl->peer.hostname, connssl->peer.port); in schannel_shutdown()
2496 if(backend->cred && backend->ctxt) { in schannel_shutdown()
2508 sspi_status = s_pSecFn->ApplyControlToken(&backend->ctxt->ctxt_handle, in schannel_shutdown()
2521 sspi_status = s_pSecFn->InitializeSecurityContext( in schannel_shutdown()
2522 &backend->cred->cred_handle, in schannel_shutdown()
2523 &backend->ctxt->ctxt_handle, in schannel_shutdown()
2524 backend->cred->sni_hostname, in schannel_shutdown()
2525 backend->req_flags, in schannel_shutdown()
2530 &backend->ctxt->ctxt_handle, in schannel_shutdown()
2532 &backend->ret_flags, in schannel_shutdown()
2533 &backend->ctxt->time_stamp); in schannel_shutdown()
2537 ssize_t written = Curl_conn_cf_send(cf->next, data, in schannel_shutdown()
2540 s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); in schannel_shutdown()
2549 if(backend->ctxt) { in schannel_shutdown()
2551 s_pSecFn->DeleteSecurityContext(&backend->ctxt->ctxt_handle); in schannel_shutdown()
2552 Curl_safefree(backend->ctxt); in schannel_shutdown()
2556 if(backend->cred) { in schannel_shutdown()
2558 schannel_session_free(backend->cred, 0); in schannel_shutdown()
2560 backend->cred = NULL; in schannel_shutdown()
2564 if(backend->encdata_buffer) { in schannel_shutdown()
2565 Curl_safefree(backend->encdata_buffer); in schannel_shutdown()
2566 backend->encdata_length = 0; in schannel_shutdown()
2567 backend->encdata_offset = 0; in schannel_shutdown()
2568 backend->encdata_is_incomplete = false; in schannel_shutdown()
2572 if(backend->decdata_buffer) { in schannel_shutdown()
2573 Curl_safefree(backend->decdata_buffer); in schannel_shutdown()
2574 backend->decdata_length = 0; in schannel_shutdown()
2575 backend->decdata_offset = 0; in schannel_shutdown()
2615 struct ssl_connect_data *connssl = cf->ctx; in schannel_pkp_pin_peer_pubkey()
2617 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_pkp_pin_peer_pubkey()
2637 s_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, in schannel_pkp_pin_peer_pubkey()
2649 if(!(((pCertContextServer->dwCertEncodingType & X509_ASN_ENCODING) != 0) && in schannel_pkp_pin_peer_pubkey()
2650 (pCertContextServer->cbCertEncoded > 0))) in schannel_pkp_pin_peer_pubkey()
2653 x509_der = (const char *)pCertContextServer->pbCertEncoded; in schannel_pkp_pin_peer_pubkey()
2654 x509_der_len = pCertContextServer->cbCertEncoded; in schannel_pkp_pin_peer_pubkey()
2660 if(!pubkey->header || pubkey->end <= pubkey->header) { in schannel_pkp_pin_peer_pubkey()
2667 (const unsigned char *)pubkey->header, in schannel_pkp_pin_peer_pubkey()
2668 (size_t)(pubkey->end - pubkey->header)); in schannel_pkp_pin_peer_pubkey()
2743 (struct schannel_ssl_backend_data *)connssl->backend; in schannel_get_internals()
2746 return &backend->ctxt->ctxt_handle; in schannel_get_internals()
2753 struct Curl_multi *multi = data->multi; in Curl_schannel_get_cached_cert_store()
2754 const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; in Curl_schannel_get_cached_cert_store()
2756 const struct ssl_general_config *cfg = &data->set.general_ssl; in Curl_schannel_get_cached_cert_store()
2764 if(!multi || !multi->ssl_backend_data) { in Curl_schannel_get_cached_cert_store()
2768 mbackend = (struct schannel_multi_ssl_backend_data *)multi->ssl_backend_data; in Curl_schannel_get_cached_cert_store()
2769 if(!mbackend->cert_store) { in Curl_schannel_get_cached_cert_store()
2774 if(!cfg->ca_cache_timeout) { in Curl_schannel_get_cached_cert_store()
2781 timeout_ms = cfg->ca_cache_timeout * (timediff_t)1000; in Curl_schannel_get_cached_cert_store()
2784 elapsed_ms = Curl_timediff(now, mbackend->time); in Curl_schannel_get_cached_cert_store()
2791 if(!mbackend->CAinfo_blob_digest) { in Curl_schannel_get_cached_cert_store()
2794 if(mbackend->CAinfo_blob_size != ca_info_blob->len) { in Curl_schannel_get_cached_cert_store()
2797 schannel_sha256sum((const unsigned char *)ca_info_blob->data, in Curl_schannel_get_cached_cert_store()
2798 ca_info_blob->len, in Curl_schannel_get_cached_cert_store()
2801 if(memcmp(mbackend->CAinfo_blob_digest, in Curl_schannel_get_cached_cert_store()
2808 if(!conn_config->CAfile || !mbackend->CAfile || in Curl_schannel_get_cached_cert_store()
2809 strcmp(mbackend->CAfile, conn_config->CAfile)) { in Curl_schannel_get_cached_cert_store()
2814 return mbackend->cert_store; in Curl_schannel_get_cached_cert_store()
2822 struct Curl_multi *multi = data->multi; in Curl_schannel_set_cached_cert_store()
2823 const struct curl_blob *ca_info_blob = conn_config->ca_info_blob; in Curl_schannel_set_cached_cert_store()
2835 if(!multi->ssl_backend_data) { in Curl_schannel_set_cached_cert_store()
2836 multi->ssl_backend_data = in Curl_schannel_set_cached_cert_store()
2838 if(!multi->ssl_backend_data) { in Curl_schannel_set_cached_cert_store()
2843 mbackend = (struct schannel_multi_ssl_backend_data *)multi->ssl_backend_data; in Curl_schannel_set_cached_cert_store()
2851 schannel_sha256sum((const unsigned char *)ca_info_blob->data, in Curl_schannel_set_cached_cert_store()
2852 ca_info_blob->len, in Curl_schannel_set_cached_cert_store()
2855 CAinfo_blob_size = ca_info_blob->len; in Curl_schannel_set_cached_cert_store()
2858 if(conn_config->CAfile) { in Curl_schannel_set_cached_cert_store()
2859 CAfile = strdup(conn_config->CAfile); in Curl_schannel_set_cached_cert_store()
2867 if(mbackend->cert_store) { in Curl_schannel_set_cached_cert_store()
2868 CertCloseStore(mbackend->cert_store, 0); in Curl_schannel_set_cached_cert_store()
2870 free(mbackend->CAinfo_blob_digest); in Curl_schannel_set_cached_cert_store()
2871 free(mbackend->CAfile); in Curl_schannel_set_cached_cert_store()
2873 mbackend->time = Curl_now(); in Curl_schannel_set_cached_cert_store()
2874 mbackend->cert_store = cert_store; in Curl_schannel_set_cached_cert_store()
2875 mbackend->CAinfo_blob_digest = CAinfo_blob_digest; in Curl_schannel_set_cached_cert_store()
2876 mbackend->CAinfo_blob_size = CAinfo_blob_size; in Curl_schannel_set_cached_cert_store()
2877 mbackend->CAfile = CAfile; in Curl_schannel_set_cached_cert_store()
2886 if(mbackend->cert_store) { in schannel_free_multi_ssl_backend_data()
2887 CertCloseStore(mbackend->cert_store, 0); in schannel_free_multi_ssl_backend_data()
2889 free(mbackend->CAinfo_blob_digest); in schannel_free_multi_ssl_backend_data()
2890 free(mbackend->CAfile); in schannel_free_multi_ssl_backend_data()