24 #include "config_components.h"
34 #define SECURITY_WIN32
40 #define SCHANNEL_INITIAL_BUFFER_SIZE 4096
41 #define SCHANNEL_FREE_BUFFER_SIZE 1024
44 #ifndef SECBUFFER_ALERT
45 #define SECBUFFER_ALERT 17
61 #define FF_NCRYPT_TEMP_KEY_NAME L"FFMPEG_TEMP_TLS_KEY"
65 const int line_length = 64;
71 if (!CryptBinaryToStringA(
data,
len, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF,
NULL, &base64len)) {
79 if (!CryptBinaryToStringA(
data,
len, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, base64, &base64len)) {
88 for (DWORD
i = 0;
i < base64len;
i += line_length) {
89 av_bprintf(&pem,
"%.*s\n", line_length, base64 +
i);
104 static int pem_to_der(
const char *pem,
char **buf,
int *out_len)
108 if (!CryptStringToBinaryA(pem, 0, CRYPT_STRING_BASE64HEADER,
NULL, &derlen,
NULL,
NULL)) {
117 if (!CryptStringToBinaryA(pem, 0, CRYPT_STRING_BASE64HEADER, *buf, &derlen,
NULL,
NULL)) {
130 unsigned char hash[32];
131 DWORD hashsize =
sizeof(
hash);
133 if (!CryptHashCertificate2(BCRYPT_SHA256_ALGORITHM, 0,
NULL,
data,
len,
hash, &hashsize))
141 for (
int i = 0;
i < hashsize - 1;
i++)
150 NCRYPT_PROV_HANDLE provider = 0;
151 CERT_NAME_BLOB subject = { 0 };
153 DWORD export_props = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
154 DWORD usage_props = NCRYPT_ALLOW_ALL_USAGES;
155 LPCSTR ext_usages[] = { szOID_PKIX_KP_SERVER_AUTH };
156 BYTE key_usage = CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DIGITAL_SIGNATURE_KEY_USAGE;
157 CRYPT_BIT_BLOB key_usage_blob = { 0 };
158 CERT_ENHKEY_USAGE eku = { 0 };
159 CERT_BASIC_CONSTRAINTS2_INFO basic_constraints = { 0 };
160 CERT_ALT_NAME_ENTRY san_entry = { 0 };
161 CERT_ALT_NAME_INFO san_info = { 0 };
162 CERT_EXTENSION ext[4] = { 0 };
163 CERT_EXTENSIONS exts = { 0 };
164 CRYPT_ALGORITHM_IDENTIFIER sig_alg = { (LPSTR)szOID_ECDSA_SHA256 };
165 CRYPT_KEY_PROV_INFO prov_info = { 0 };
166 const char *subj_str =
"CN=lavf";
168 SECURITY_STATUS sspi_ret;
173 sspi_ret = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0);
174 if (sspi_ret != ERROR_SUCCESS) {
180 sspi_ret = NCryptCreatePersistedKey(provider,
key, BCRYPT_ECDSA_P256_ALGORITHM,
FF_NCRYPT_TEMP_KEY_NAME, 0, NCRYPT_OVERWRITE_KEY_FLAG);
181 if (sspi_ret != ERROR_SUCCESS) {
187 sspi_ret = NCryptSetProperty(*
key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)&export_props,
sizeof(export_props), 0);
188 if (sspi_ret != ERROR_SUCCESS) {
194 sspi_ret = NCryptSetProperty(*
key, NCRYPT_KEY_USAGE_PROPERTY, (PBYTE)&usage_props,
sizeof(usage_props), 0);
195 if (sspi_ret != ERROR_SUCCESS) {
201 sspi_ret = NCryptFinalizeKey(*
key, 0);
202 if (sspi_ret != ERROR_SUCCESS) {
208 if (!CertStrToNameA(X509_ASN_ENCODING, subj_str, 0,
NULL,
NULL, &subject.cbData,
NULL))
215 subject.pbData =
av_malloc(subject.cbData);
216 if (!subject.pbData) {
221 if (!CertStrToNameA(X509_ASN_ENCODING, subj_str, 0,
NULL, subject.pbData, &subject.cbData,
NULL))
229 eku.cUsageIdentifier = 1;
230 eku.rgpszUsageIdentifier = (LPSTR*)ext_usages;
232 if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_ENHANCED_KEY_USAGE, &eku,
233 CRYPT_ENCODE_ALLOC_FLAG,
NULL, &ext[0].Value.pbData, &ext[0].Value.cbData)) {
239 ext[0].pszObjId = (LPSTR)szOID_ENHANCED_KEY_USAGE;
240 ext[0].fCritical = TRUE;
243 key_usage_blob.cbData =
sizeof(key_usage);
244 key_usage_blob.pbData = &key_usage;
246 if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_BITS, &key_usage_blob,
247 CRYPT_ENCODE_ALLOC_FLAG,
NULL, &ext[1].Value.pbData, &ext[1].Value.cbData)) {
253 ext[1].pszObjId = (LPSTR)szOID_KEY_USAGE;
254 ext[1].fCritical = TRUE;
257 basic_constraints.fCA = FALSE;
259 if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_BASIC_CONSTRAINTS2, &basic_constraints,
260 CRYPT_ENCODE_ALLOC_FLAG,
NULL, &ext[2].Value.pbData, &ext[2].Value.cbData)) {
266 ext[2].pszObjId = (LPSTR)szOID_BASIC_CONSTRAINTS2;
267 ext[2].fCritical = TRUE;
270 san_entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
271 san_entry.pwszDNSName = (LPWSTR)
L"localhost";
273 san_info.cAltEntry = 1;
274 san_info.rgAltEntry = &san_entry;
276 if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_ALTERNATE_NAME, &san_info,
277 CRYPT_ENCODE_ALLOC_FLAG,
NULL, &ext[3].Value.pbData, &ext[3].Value.cbData)) {
283 ext[3].pszObjId = (LPSTR)szOID_SUBJECT_ALT_NAME2;
284 ext[3].fCritical = TRUE;
287 exts.rgExtension = ext;
289 prov_info.pwszProvName = (LPWSTR)MS_KEY_STORAGE_PROVIDER;
291 prov_info.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
293 *crtctx = CertCreateSelfSignCertificate(*
key, &subject, 0, &prov_info, &sig_alg,
NULL,
NULL, &exts);
300 NCryptFreeObject(provider);
303 LocalFree(ext[
i].Value.pbData);
309 CertFreeCertificateContext(*crtctx);
311 if (NCryptDeleteKey(*
key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
312 NCryptFreeObject(*
key);
314 NCryptFreeObject(provider);
318 if (ext[
i].Value.pbData)
319 LocalFree(ext[
i].Value.pbData);
328 char *key_buf,
size_t key_sz,
char *cert_buf,
size_t cert_sz,
char **fingerprint)
333 SECURITY_STATUS sspi_ret;
336 sspi_ret = NCryptExportKey(
key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB,
NULL,
NULL, 0, &keysize, 0);
337 if (sspi_ret != ERROR_SUCCESS) {
349 sspi_ret = NCryptExportKey(
key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB,
NULL, keybuf, keysize, &keysize, 0);
350 if (sspi_ret != ERROR_SUCCESS) {
356 ret =
der_to_pem(keybuf, keysize,
"PRIVATE KEY", key_buf, key_sz);
360 ret =
der_to_pem(crtctx->pbCertEncoded, crtctx->cbCertEncoded,
"CERTIFICATE", cert_buf, cert_sz);
375 NCRYPT_KEY_HANDLE
key = 0;
376 PCCERT_CONTEXT crtctx =
NULL;
388 if (NCryptDeleteKey(
key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
389 NCryptFreeObject(
key);
391 CertFreeCertificateContext(crtctx);
398 NCRYPT_PROV_HANDLE provider = 0;
400 DWORD export_props = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
401 DWORD usage_props = NCRYPT_ALLOW_ALL_USAGES;
402 NCryptBufferDesc buffer_desc = { 0 };
403 NCryptBuffer
buffer = { 0 };
404 CRYPT_KEY_PROV_INFO prov_info = { 0 };
406 int key_der_len = 0, cert_der_len = 0;
407 char *key_der =
NULL, *cert_der =
NULL;
409 SECURITY_STATUS sspi_ret;
420 sspi_ret = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0);
421 if (sspi_ret != ERROR_SUCCESS) {
427 buffer_desc.ulVersion = NCRYPTBUFFER_VERSION;
428 buffer_desc.cBuffers = 1;
429 buffer_desc.pBuffers = &
buffer;
431 buffer.BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;
435 sspi_ret = NCryptImportKey(provider, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, &buffer_desc,
key, key_der, key_der_len, NCRYPT_DO_NOT_FINALIZE_FLAG | NCRYPT_OVERWRITE_KEY_FLAG);
436 if (sspi_ret != ERROR_SUCCESS) {
442 sspi_ret = NCryptSetProperty(*
key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)&export_props,
sizeof(export_props), 0);
443 if (sspi_ret != ERROR_SUCCESS) {
449 sspi_ret = NCryptSetProperty(*
key, NCRYPT_KEY_USAGE_PROPERTY, (PBYTE)&usage_props,
sizeof(usage_props), 0);
450 if (sspi_ret != ERROR_SUCCESS) {
456 sspi_ret = NCryptFinalizeKey(*
key, 0);
457 if (sspi_ret != ERROR_SUCCESS) {
463 *crtctx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert_der, cert_der_len);
470 if (!CertSetCertificateContextProperty(*crtctx, CERT_NCRYPT_KEY_HANDLE_PROP_ID, 0,
key)) {
471 av_log(
NULL,
AV_LOG_ERROR,
"CertSetCertificateContextProperty(CERT_NCRYPT_KEY_HANDLE_PROP_ID) failed: %lu\n", GetLastError());
476 prov_info.pwszProvName = (LPWSTR)MS_KEY_STORAGE_PROVIDER;
478 prov_info.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
480 if (!CertSetCertificateContextProperty(*crtctx, CERT_KEY_PROV_INFO_PROP_ID, 0, &prov_info)) {
481 av_log(
NULL,
AV_LOG_ERROR,
"CertSetCertificateContextProperty(CERT_KEY_PROV_INFO_PROP_ID) failed: %lu\n", GetLastError());
490 if (NCryptDeleteKey(*
key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
491 NCryptFreeObject(*
key);
493 CertFreeCertificateContext(*crtctx);
504 NCryptFreeObject(provider);
508 static int tls_cert_from_store(
void *logctx,
const char *cert_store_name,
const char *cert_subj, PCCERT_CONTEXT *crtctx)
510 HCERTSTORE cert_store =
NULL;
513 cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, cert_store_name);
520 *crtctx = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, cert_subj,
NULL);
529 CertCloseStore(cert_store, 0);
536 AVBPrint key_bp, cert_bp;
566 int ff_ssl_read_key_cert(
char *key_url,
char *cert_url,
char *key_buf,
size_t key_sz,
char *cert_buf,
size_t cert_sz,
char **fingerprint)
568 NCRYPT_KEY_HANDLE
key = 0;
569 PCCERT_CONTEXT crtctx =
NULL;
581 if (NCryptDeleteKey(
key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
582 NCryptFreeObject(
key);
584 CertFreeCertificateContext(crtctx);
630 c->tls_shared.udp = sock;
632 c->tls_shared.tcp = sock;
639 #if HAVE_SECPKGCONTEXT_KEYINGMATERIALINFO
642 SecPkgContext_KeyingMaterialInfo keying_info = { 0 };
643 SecPkgContext_KeyingMaterial keying_material = { 0 };
645 const char*
dst =
"EXTRACTOR-dtls_srtp";
646 SECURITY_STATUS sspi_ret;
648 if (!
c->have_context)
651 keying_info.cbLabel = strlen(
dst) + 1;
652 keying_info.pszLabel = (LPSTR)
dst;
653 keying_info.cbContextValue = 0;
654 keying_info.pbContextValue =
NULL;
655 keying_info.cbKeyingMaterial = materials_sz;
657 sspi_ret = SetContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL_INFO, &keying_info,
sizeof(keying_info));
658 if (sspi_ret != SEC_E_OK) {
663 sspi_ret = QueryContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL, &keying_material);
664 if (sspi_ret != SEC_E_OK) {
669 memcpy(dtls_srtp_materials, keying_material.pbKeyingMaterial,
FFMIN(materials_sz, keying_material.cbKeyingMaterial));
670 FreeContextBuffer(keying_material.pbKeyingMaterial);
672 if (keying_material.cbKeyingMaterial > materials_sz) {
673 av_log(
h,
AV_LOG_WARNING,
"Keying material size mismatch: %ld > %zu\n", keying_material.cbKeyingMaterial, materials_sz);
692 unsigned long buffer_count)
694 desc->ulVersion = SECBUFFER_VERSION;
695 desc->pBuffers = buffers;
696 desc->cBuffers = buffer_count;
709 ret =
ffurl_write(uc,
c->send_buf +
c->send_buf_offset,
c->send_buf_size -
c->send_buf_offset);
712 }
else if (
ret < 0) {
717 c->send_buf_offset +=
ret;
719 if (
c->send_buf_offset <
c->send_buf_size)
723 c->send_buf_size =
c->send_buf_offset = 0;
736 SecBufferDesc BuffDesc;
738 SECURITY_STATUS sspi_ret;
740 SecBufferDesc outbuf_desc;
742 DWORD dwshut = SCHANNEL_SHUTDOWN;
751 sspi_ret = ApplyControlToken(&
c->ctxt_handle, &BuffDesc);
752 if (sspi_ret != SEC_E_OK)
760 sspi_ret = AcceptSecurityContext(&
c->cred_handle, &
c->ctxt_handle,
NULL,
c->request_flags, 0,
761 &
c->ctxt_handle, &outbuf_desc, &
c->context_flags,
764 sspi_ret = InitializeSecurityContext(&
c->cred_handle, &
c->ctxt_handle,
s->host,
765 c->request_flags, 0, 0,
NULL, 0, &
c->ctxt_handle,
766 &outbuf_desc, &
c->context_flags, &
c->ctxt_timestamp);
768 if (outbuf.pvBuffer) {
769 if (outbuf.cbBuffer > 0) {
771 if (
ret < 0 ||
ret != outbuf.cbBuffer)
774 FreeContextBuffer(outbuf.pvBuffer);
777 #ifdef SEC_I_MESSAGE_FRAGMENT
778 sspi_ret == SEC_I_MESSAGE_FRAGMENT ||
780 sspi_ret == SEC_I_CONTINUE_NEEDED);
796 DeleteSecurityContext(&
c->ctxt_handle);
797 FreeCredentialsHandle(&
c->cred_handle);
800 c->enc_buf_size =
c->enc_buf_offset = 0;
803 c->dec_buf_size =
c->dec_buf_offset = 0;
806 c->send_buf_size =
c->send_buf_offset = 0;
809 if (!
s->external_sock)
823 SECURITY_STATUS sspi_ret;
824 SecBuffer outbuf[3] = { 0 };
825 SecBufferDesc outbuf_desc;
827 SecBufferDesc inbuf_desc;
829 socklen_t recv_addr_len = 0;
832 if (
c->enc_buf ==
NULL) {
833 c->enc_buf_offset = 0;
840 if (
c->dec_buf ==
NULL) {
841 c->dec_buf_offset = 0;
855 c->enc_buf_size =
c->enc_buf_offset = 0;
861 ret =
ffurl_read(uc,
c->enc_buf +
c->enc_buf_offset,
c->enc_buf_size -
c->enc_buf_offset);
866 c->enc_buf_offset +=
ret;
867 if (
s->is_dtls && !recv_addr_len) {
884 if (
s->listen &&
s->is_dtls) {
885 init_sec_buffer(&inbuf[2], SECBUFFER_EXTRA, &recv_addr, recv_addr_len);
891 if (inbuf[0].pvBuffer ==
NULL) {
897 memcpy(inbuf[0].pvBuffer,
c->enc_buf,
c->enc_buf_offset);
906 sspi_ret = AcceptSecurityContext(&
c->cred_handle,
c->have_context ? &
c->ctxt_handle :
NULL, &inbuf_desc,
907 c->request_flags, 0, &
c->ctxt_handle, &outbuf_desc,
908 &
c->context_flags, &
c->ctxt_timestamp);
910 sspi_ret = InitializeSecurityContext(&
c->cred_handle,
c->have_context ? &
c->ctxt_handle :
NULL,
911 s->host,
c->request_flags, 0, 0, &inbuf_desc, 0, &
c->ctxt_handle,
912 &outbuf_desc, &
c->context_flags, &
c->ctxt_timestamp);
915 av_log(
h,
AV_LOG_TRACE,
"Handshake res with %d bytes of data: 0x%lx\n",
c->enc_buf_offset, sspi_ret);
917 if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
926 if (sspi_ret == SEC_I_INCOMPLETE_CREDENTIALS &&
927 !(
c->request_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
929 c->request_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
935 if (sspi_ret == SEC_I_CONTINUE_NEEDED ||
936 #ifdef SEC_I_MESSAGE_FRAGMENT
937 sspi_ret == SEC_I_MESSAGE_FRAGMENT ||
939 sspi_ret == SEC_E_OK) {
940 for (
i = 0;
i < 3;
i++) {
941 if (outbuf[
i].BufferType == SECBUFFER_TOKEN && outbuf[
i].cbBuffer > 0) {
943 if (
ret < 0 ||
ret != outbuf[
i].cbBuffer) {
950 if (outbuf[
i].pvBuffer !=
NULL) {
951 FreeContextBuffer(outbuf[
i].pvBuffer);
952 outbuf[
i].pvBuffer =
NULL;
956 if (sspi_ret == SEC_E_WRONG_PRINCIPAL)
964 #ifdef SEC_I_MESSAGE_FRAGMENT
965 if (sspi_ret == SEC_I_MESSAGE_FRAGMENT) {
972 if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
973 if (
c->enc_buf_offset > inbuf[1].cbBuffer) {
974 memmove(
c->enc_buf, (
c->enc_buf +
c->enc_buf_offset) - inbuf[1].cbBuffer,
976 c->enc_buf_offset = inbuf[1].cbBuffer;
977 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
978 av_log(
h,
AV_LOG_TRACE,
"Sent reply, handshake continues. %d extra bytes\n", (
int)inbuf[1].cbBuffer);
984 c->enc_buf_offset = 0;
987 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
1002 for (
i = 0;
i < 3;
i++) {
1003 if (outbuf[
i].pvBuffer !=
NULL) {
1004 FreeContextBuffer(outbuf[
i].pvBuffer);
1005 outbuf[
i].pvBuffer =
NULL;
1020 SecBufferDesc outbuf_desc;
1021 SECURITY_STATUS sspi_ret;
1027 c->request_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
1028 ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY;
1030 c->request_flags |= ISC_REQ_DATAGRAM;
1032 c->request_flags |= ISC_REQ_STREAM;
1034 sspi_ret = InitializeSecurityContext(&
c->cred_handle,
NULL,
s->host,
c->request_flags, 0, 0,
1035 NULL, 0, &
c->ctxt_handle, &outbuf_desc, &
c->context_flags,
1036 &
c->ctxt_timestamp);
1037 if (sspi_ret != SEC_I_CONTINUE_NEEDED) {
1043 c->have_context = 1;
1047 FreeContextBuffer(outbuf.pvBuffer);
1048 if (
ret < 0 ||
ret != outbuf.cbBuffer) {
1057 DeleteSecurityContext(&
c->ctxt_handle);
1066 c->request_flags = ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
1067 ASC_REQ_CONFIDENTIALITY | ASC_REQ_ALLOCATE_MEMORY;
1069 c->request_flags |= ASC_REQ_DATAGRAM;
1071 c->request_flags |= ASC_REQ_STREAM;
1073 c->have_context = 0;
1082 SECURITY_STATUS sspi_ret;
1093 #if CONFIG_DTLS_PROTOCOL
1094 if (
s->is_dtls &&
s->mtu > 0) {
1096 sspi_ret = SetContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_DTLS_MTU, &mtu,
sizeof(mtu));
1097 if (sspi_ret != SEC_E_OK) {
1116 SECURITY_STATUS sspi_ret;
1117 SCHANNEL_CRED schannel_cred = { 0 };
1118 PCCERT_CONTEXT crtctx =
NULL;
1119 NCRYPT_KEY_HANDLE
key = 0;
1122 if (!
s->external_sock) {
1128 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
1131 if (
c->cert_store_name &&
c->cert_store_subject) {
1133 }
else if (
s->key_buf &&
s->cert_buf) {
1135 }
else if (
s->key_file &&
s->cert_file) {
1145 schannel_cred.cCreds = 1;
1146 schannel_cred.paCred = &crtctx;
1148 schannel_cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER | SCH_CRED_MANUAL_CRED_VALIDATION;
1150 #if CONFIG_DTLS_PROTOCOL
1152 schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_SERVER;
1156 schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
1157 SCH_CRED_REVOCATION_CHECK_CHAIN;
1159 schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
1160 SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
1161 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
1163 #if CONFIG_DTLS_PROTOCOL
1165 schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT;
1170 sspi_ret = AcquireCredentialsHandle(
NULL, (TCHAR *)UNISP_NAME,
1171 s->listen ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
1173 &
c->cred_timestamp);
1174 if (sspi_ret != SEC_E_OK) {
1180 if (!
s->external_sock) {
1193 CertFreeCertificateContext(crtctx);
1195 if (NCryptDeleteKey(
key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
1196 NCryptFreeObject(
key);
1201 #if CONFIG_DTLS_PROTOCOL
1218 SECURITY_STATUS sspi_ret = SEC_E_OK;
1220 SecBufferDesc inbuf_desc;
1229 if (
c->dec_buf_offset > 0)
1232 if (
c->sspi_close_notify)
1235 if (!
c->connection_closed) {
1236 size =
c->enc_buf_size -
c->enc_buf_offset;
1237 if (size < SCHANNEL_FREE_BUFFER_SIZE || c->enc_buf_size < min_enc_buf_size) {
1239 if (
c->enc_buf_size < min_enc_buf_size)
1240 c->enc_buf_size = min_enc_buf_size;
1243 c->enc_buf_size =
c->enc_buf_offset = 0;
1252 c->enc_buf_size -
c->enc_buf_offset);
1254 c->connection_closed = 1;
1258 }
else if (
ret < 0) {
1263 c->enc_buf_offset +=
ret;
1266 while (
c->enc_buf_offset > 0 && sspi_ret == SEC_E_OK) {
1276 sspi_ret = DecryptMessage(&
c->ctxt_handle, &inbuf_desc, 0,
NULL);
1277 if (sspi_ret == SEC_E_OK || sspi_ret == SEC_I_RENEGOTIATE ||
1278 sspi_ret == SEC_I_CONTEXT_EXPIRED) {
1280 if (inbuf[1].BufferType == SECBUFFER_DATA) {
1284 if (
c->dec_buf_size -
c->dec_buf_offset <
size ||
c->dec_buf_size <
len) {
1285 c->dec_buf_size =
c->dec_buf_offset +
size;
1286 if (
c->dec_buf_size <
len)
1287 c->dec_buf_size =
len;
1290 c->dec_buf_size =
c->dec_buf_offset = 0;
1296 size = inbuf[1].cbBuffer;
1298 memcpy(
c->dec_buf +
c->dec_buf_offset, inbuf[1].pvBuffer,
size);
1299 c->dec_buf_offset +=
size;
1302 if (inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
1303 if (
c->enc_buf_offset > inbuf[3].cbBuffer) {
1304 memmove(
c->enc_buf, (
c->enc_buf +
c->enc_buf_offset) - inbuf[3].cbBuffer,
1306 c->enc_buf_offset = inbuf[3].cbBuffer;
1309 c->enc_buf_offset = 0;
1311 if (sspi_ret == SEC_I_RENEGOTIATE) {
1312 if (
c->enc_buf_offset) {
1323 sspi_ret = SEC_E_OK;
1327 c->send_buf_size =
c->send_buf_offset = 0;
1330 }
else if (sspi_ret == SEC_I_CONTEXT_EXPIRED) {
1331 c->sspi_close_notify = 1;
1332 if (!
c->connection_closed) {
1333 c->connection_closed = 1;
1339 }
else if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
1354 memcpy(buf,
c->dec_buf,
size);
1355 memmove(
c->dec_buf,
c->dec_buf +
size,
c->dec_buf_offset -
size);
1356 c->dec_buf_offset -=
size;
1361 if (
ret == 0 && !
c->connection_closed)
1372 SECURITY_STATUS sspi_ret;
1373 SecBuffer outbuf[4];
1374 SecBufferDesc outbuf_desc;
1384 if (
c->sizes.cbMaximumMessage == 0) {
1385 sspi_ret = QueryContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_STREAM_SIZES, &
c->sizes);
1386 if (sspi_ret != SEC_E_OK)
1391 len =
FFMIN(
len,
c->sizes.cbMaximumMessage -
c->sizes.cbHeader -
c->sizes.cbTrailer);
1393 c->send_buf_size =
c->sizes.cbHeader +
len +
c->sizes.cbTrailer;
1395 if (
c->send_buf ==
NULL)
1399 c->send_buf,
c->sizes.cbHeader);
1401 c->send_buf +
c->sizes.cbHeader,
len);
1403 c->send_buf +
c->sizes.cbHeader +
len,
1404 c->sizes.cbTrailer);
1408 memcpy(outbuf[1].pvBuffer, buf,
len);
1410 sspi_ret = EncryptMessage(&
c->ctxt_handle, 0, &outbuf_desc, 0);
1411 if (sspi_ret != SEC_E_OK) {
1414 if (sspi_ret == SEC_E_INSUFFICIENT_MEMORY)
1419 c->send_buf_size = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
1420 c->send_buf_offset = 0;
1427 return outbuf[1].cbBuffer;
1428 }
else if (
ret < 0) {
1432 return outbuf[1].cbBuffer;
1449 #define OFFSET(x) offsetof(TLSContext, x)
1452 {
"cert_store_subject",
"Load certificate (and associated key) from users keystore by subject",
1454 {
"cert_store_name",
"Name of the specific cert store to search in (for cert_store_subject)",
1459 #if CONFIG_TLS_PROTOCOL
1481 #if CONFIG_DTLS_PROTOCOL