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);
631 c->tls_shared.udp = sock;
633 c->tls_shared.tcp = sock;
640 #if HAVE_SECPKGCONTEXT_KEYINGMATERIALINFO
643 SecPkgContext_KeyingMaterialInfo keying_info = { 0 };
644 SecPkgContext_KeyingMaterial keying_material = { 0 };
646 const char*
dst =
"EXTRACTOR-dtls_srtp";
647 SECURITY_STATUS sspi_ret;
649 if (!
c->have_context)
652 keying_info.cbLabel = strlen(
dst) + 1;
653 keying_info.pszLabel = (LPSTR)
dst;
654 keying_info.cbContextValue = 0;
655 keying_info.pbContextValue =
NULL;
656 keying_info.cbKeyingMaterial = materials_sz;
658 sspi_ret = SetContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL_INFO, &keying_info,
sizeof(keying_info));
659 if (sspi_ret != SEC_E_OK) {
664 sspi_ret = QueryContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL, &keying_material);
665 if (sspi_ret != SEC_E_OK) {
670 memcpy(dtls_srtp_materials, keying_material.pbKeyingMaterial,
FFMIN(materials_sz, keying_material.cbKeyingMaterial));
671 FreeContextBuffer(keying_material.pbKeyingMaterial);
673 if (keying_material.cbKeyingMaterial > materials_sz) {
674 av_log(
h,
AV_LOG_WARNING,
"Keying material size mismatch: %ld > %zu\n", keying_material.cbKeyingMaterial, materials_sz);
693 unsigned long buffer_count)
695 desc->ulVersion = SECBUFFER_VERSION;
696 desc->pBuffers = buffers;
697 desc->cBuffers = buffer_count;
710 ret =
ffurl_write(uc,
c->send_buf +
c->send_buf_offset,
c->send_buf_size -
c->send_buf_offset);
713 }
else if (
ret < 0) {
718 c->send_buf_offset +=
ret;
720 if (
c->send_buf_offset <
c->send_buf_size)
724 c->send_buf_size =
c->send_buf_offset = 0;
737 SecBufferDesc BuffDesc;
739 SECURITY_STATUS sspi_ret;
741 SecBufferDesc outbuf_desc;
743 DWORD dwshut = SCHANNEL_SHUTDOWN;
752 sspi_ret = ApplyControlToken(&
c->ctxt_handle, &BuffDesc);
753 if (sspi_ret != SEC_E_OK)
761 sspi_ret = AcceptSecurityContext(&
c->cred_handle, &
c->ctxt_handle,
NULL,
c->request_flags, 0,
762 &
c->ctxt_handle, &outbuf_desc, &
c->context_flags,
765 sspi_ret = InitializeSecurityContext(&
c->cred_handle, &
c->ctxt_handle,
s->host,
766 c->request_flags, 0, 0,
NULL, 0, &
c->ctxt_handle,
767 &outbuf_desc, &
c->context_flags, &
c->ctxt_timestamp);
769 if (outbuf.pvBuffer) {
770 if (outbuf.cbBuffer > 0) {
772 if (
ret < 0 ||
ret != outbuf.cbBuffer)
775 FreeContextBuffer(outbuf.pvBuffer);
778 #ifdef SEC_I_MESSAGE_FRAGMENT
779 sspi_ret == SEC_I_MESSAGE_FRAGMENT ||
781 sspi_ret == SEC_I_CONTINUE_NEEDED);
797 DeleteSecurityContext(&
c->ctxt_handle);
798 FreeCredentialsHandle(&
c->cred_handle);
801 c->enc_buf_size =
c->enc_buf_offset = 0;
804 c->dec_buf_size =
c->dec_buf_offset = 0;
807 c->send_buf_size =
c->send_buf_offset = 0;
810 if (!
s->external_sock)
824 SECURITY_STATUS sspi_ret;
825 SecBuffer outbuf[3] = { 0 };
826 SecBufferDesc outbuf_desc;
828 SecBufferDesc inbuf_desc;
830 socklen_t recv_addr_len = 0;
833 if (
c->enc_buf ==
NULL) {
834 c->enc_buf_offset = 0;
841 if (
c->dec_buf ==
NULL) {
842 c->dec_buf_offset = 0;
856 c->enc_buf_size =
c->enc_buf_offset = 0;
862 ret =
ffurl_read(uc,
c->enc_buf +
c->enc_buf_offset,
c->enc_buf_size -
c->enc_buf_offset);
867 c->enc_buf_offset +=
ret;
868 if (
s->is_dtls && !recv_addr_len) {
885 if (
s->listen &&
s->is_dtls) {
886 init_sec_buffer(&inbuf[2], SECBUFFER_EXTRA, &recv_addr, recv_addr_len);
892 if (inbuf[0].pvBuffer ==
NULL) {
898 memcpy(inbuf[0].pvBuffer,
c->enc_buf,
c->enc_buf_offset);
907 sspi_ret = AcceptSecurityContext(&
c->cred_handle,
c->have_context ? &
c->ctxt_handle :
NULL, &inbuf_desc,
908 c->request_flags, 0, &
c->ctxt_handle, &outbuf_desc,
909 &
c->context_flags, &
c->ctxt_timestamp);
911 sspi_ret = InitializeSecurityContext(&
c->cred_handle,
c->have_context ? &
c->ctxt_handle :
NULL,
912 s->host,
c->request_flags, 0, 0, &inbuf_desc, 0, &
c->ctxt_handle,
913 &outbuf_desc, &
c->context_flags, &
c->ctxt_timestamp);
916 av_log(
h,
AV_LOG_TRACE,
"Handshake res with %d bytes of data: 0x%lx\n",
c->enc_buf_offset, sspi_ret);
918 if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
927 if (sspi_ret == SEC_I_INCOMPLETE_CREDENTIALS &&
928 !(
c->request_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
930 c->request_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
936 if (sspi_ret == SEC_I_CONTINUE_NEEDED ||
937 #ifdef SEC_I_MESSAGE_FRAGMENT
938 sspi_ret == SEC_I_MESSAGE_FRAGMENT ||
940 sspi_ret == SEC_E_OK) {
941 for (
i = 0;
i < 3;
i++) {
942 if (outbuf[
i].BufferType == SECBUFFER_TOKEN && outbuf[
i].cbBuffer > 0) {
944 if (
ret < 0 ||
ret != outbuf[
i].cbBuffer) {
951 if (outbuf[
i].pvBuffer !=
NULL) {
952 FreeContextBuffer(outbuf[
i].pvBuffer);
953 outbuf[
i].pvBuffer =
NULL;
957 if (sspi_ret == SEC_E_WRONG_PRINCIPAL)
965 #ifdef SEC_I_MESSAGE_FRAGMENT
966 if (sspi_ret == SEC_I_MESSAGE_FRAGMENT) {
973 if (inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
974 if (
c->enc_buf_offset > inbuf[1].cbBuffer) {
975 memmove(
c->enc_buf, (
c->enc_buf +
c->enc_buf_offset) - inbuf[1].cbBuffer,
977 c->enc_buf_offset = inbuf[1].cbBuffer;
978 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
979 av_log(
h,
AV_LOG_TRACE,
"Sent reply, handshake continues. %d extra bytes\n", (
int)inbuf[1].cbBuffer);
985 c->enc_buf_offset = 0;
988 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
1003 for (
i = 0;
i < 3;
i++) {
1004 if (outbuf[
i].pvBuffer !=
NULL) {
1005 FreeContextBuffer(outbuf[
i].pvBuffer);
1006 outbuf[
i].pvBuffer =
NULL;
1021 SecBufferDesc outbuf_desc;
1022 SECURITY_STATUS sspi_ret;
1028 c->request_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
1029 ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY;
1031 c->request_flags |= ISC_REQ_DATAGRAM;
1033 c->request_flags |= ISC_REQ_STREAM;
1035 sspi_ret = InitializeSecurityContext(&
c->cred_handle,
NULL,
s->host,
c->request_flags, 0, 0,
1036 NULL, 0, &
c->ctxt_handle, &outbuf_desc, &
c->context_flags,
1037 &
c->ctxt_timestamp);
1038 if (sspi_ret != SEC_I_CONTINUE_NEEDED) {
1044 c->have_context = 1;
1048 FreeContextBuffer(outbuf.pvBuffer);
1049 if (
ret < 0 ||
ret != outbuf.cbBuffer) {
1058 DeleteSecurityContext(&
c->ctxt_handle);
1067 c->request_flags = ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
1068 ASC_REQ_CONFIDENTIALITY | ASC_REQ_ALLOCATE_MEMORY;
1070 c->request_flags |= ASC_REQ_DATAGRAM;
1072 c->request_flags |= ASC_REQ_STREAM;
1074 c->have_context = 0;
1083 SECURITY_STATUS sspi_ret;
1094 #if CONFIG_DTLS_PROTOCOL
1095 if (
s->is_dtls &&
s->mtu > 0) {
1097 sspi_ret = SetContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_DTLS_MTU, &mtu,
sizeof(mtu));
1098 if (sspi_ret != SEC_E_OK) {
1117 SECURITY_STATUS sspi_ret;
1118 SCHANNEL_CRED schannel_cred = { 0 };
1119 PCCERT_CONTEXT crtctx =
NULL;
1120 NCRYPT_KEY_HANDLE
key = 0;
1123 if (!
s->external_sock) {
1129 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
1132 if (
c->cert_store_name &&
c->cert_store_subject) {
1134 }
else if (
s->key_buf &&
s->cert_buf) {
1136 }
else if (
s->key_file &&
s->cert_file) {
1146 schannel_cred.cCreds = 1;
1147 schannel_cred.paCred = &crtctx;
1149 schannel_cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER | SCH_CRED_MANUAL_CRED_VALIDATION;
1151 #if CONFIG_DTLS_PROTOCOL
1153 schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_SERVER;
1157 schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
1158 SCH_CRED_REVOCATION_CHECK_CHAIN;
1160 schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
1161 SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
1162 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
1164 #if CONFIG_DTLS_PROTOCOL
1166 schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT;
1171 sspi_ret = AcquireCredentialsHandle(
NULL, (TCHAR *)UNISP_NAME,
1172 s->listen ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
1174 &
c->cred_timestamp);
1175 if (sspi_ret != SEC_E_OK) {
1181 if (!
s->external_sock) {
1194 CertFreeCertificateContext(crtctx);
1196 if (NCryptDeleteKey(
key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
1197 NCryptFreeObject(
key);
1202 #if CONFIG_DTLS_PROTOCOL
1219 SECURITY_STATUS sspi_ret = SEC_E_OK;
1221 SecBufferDesc inbuf_desc;
1230 if (
c->dec_buf_offset > 0)
1233 if (
c->sspi_close_notify)
1236 if (!
c->connection_closed) {
1237 size =
c->enc_buf_size -
c->enc_buf_offset;
1238 if (size < SCHANNEL_FREE_BUFFER_SIZE || c->enc_buf_size < min_enc_buf_size) {
1240 if (
c->enc_buf_size < min_enc_buf_size)
1241 c->enc_buf_size = min_enc_buf_size;
1244 c->enc_buf_size =
c->enc_buf_offset = 0;
1253 c->enc_buf_size -
c->enc_buf_offset);
1255 c->connection_closed = 1;
1259 }
else if (
ret < 0) {
1264 c->enc_buf_offset +=
ret;
1267 while (
c->enc_buf_offset > 0 && sspi_ret == SEC_E_OK) {
1277 sspi_ret = DecryptMessage(&
c->ctxt_handle, &inbuf_desc, 0,
NULL);
1278 if (sspi_ret == SEC_E_OK || sspi_ret == SEC_I_RENEGOTIATE ||
1279 sspi_ret == SEC_I_CONTEXT_EXPIRED) {
1281 if (inbuf[1].BufferType == SECBUFFER_DATA) {
1285 if (
c->dec_buf_size -
c->dec_buf_offset <
size ||
c->dec_buf_size <
len) {
1286 c->dec_buf_size =
c->dec_buf_offset +
size;
1287 if (
c->dec_buf_size <
len)
1288 c->dec_buf_size =
len;
1291 c->dec_buf_size =
c->dec_buf_offset = 0;
1297 size = inbuf[1].cbBuffer;
1299 memcpy(
c->dec_buf +
c->dec_buf_offset, inbuf[1].pvBuffer,
size);
1300 c->dec_buf_offset +=
size;
1303 if (inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
1304 if (
c->enc_buf_offset > inbuf[3].cbBuffer) {
1305 memmove(
c->enc_buf, (
c->enc_buf +
c->enc_buf_offset) - inbuf[3].cbBuffer,
1307 c->enc_buf_offset = inbuf[3].cbBuffer;
1310 c->enc_buf_offset = 0;
1312 if (sspi_ret == SEC_I_RENEGOTIATE) {
1313 if (
c->enc_buf_offset) {
1324 sspi_ret = SEC_E_OK;
1328 c->send_buf_size =
c->send_buf_offset = 0;
1331 }
else if (sspi_ret == SEC_I_CONTEXT_EXPIRED) {
1332 c->sspi_close_notify = 1;
1333 if (!
c->connection_closed) {
1334 c->connection_closed = 1;
1340 }
else if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
1355 memcpy(buf,
c->dec_buf,
size);
1356 memmove(
c->dec_buf,
c->dec_buf +
size,
c->dec_buf_offset -
size);
1357 c->dec_buf_offset -=
size;
1362 if (
ret == 0 && !
c->connection_closed)
1373 SECURITY_STATUS sspi_ret;
1374 SecBuffer outbuf[4];
1375 SecBufferDesc outbuf_desc;
1385 if (
c->sizes.cbMaximumMessage == 0) {
1386 sspi_ret = QueryContextAttributes(&
c->ctxt_handle, SECPKG_ATTR_STREAM_SIZES, &
c->sizes);
1387 if (sspi_ret != SEC_E_OK)
1392 len =
FFMIN(
len,
c->sizes.cbMaximumMessage -
c->sizes.cbHeader -
c->sizes.cbTrailer);
1394 c->send_buf_size =
c->sizes.cbHeader +
len +
c->sizes.cbTrailer;
1396 if (
c->send_buf ==
NULL)
1400 c->send_buf,
c->sizes.cbHeader);
1402 c->send_buf +
c->sizes.cbHeader,
len);
1404 c->send_buf +
c->sizes.cbHeader +
len,
1405 c->sizes.cbTrailer);
1409 memcpy(outbuf[1].pvBuffer, buf,
len);
1411 sspi_ret = EncryptMessage(&
c->ctxt_handle, 0, &outbuf_desc, 0);
1412 if (sspi_ret != SEC_E_OK) {
1415 if (sspi_ret == SEC_E_INSUFFICIENT_MEMORY)
1420 c->send_buf_size = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
1421 c->send_buf_offset = 0;
1428 return outbuf[1].cbBuffer;
1429 }
else if (
ret < 0) {
1433 return outbuf[1].cbBuffer;
1450 #define OFFSET(x) offsetof(TLSContext, x)
1453 {
"cert_store_subject",
"Load certificate (and associated key) from users keystore by subject",
1455 {
"cert_store_name",
"Name of the specific cert store to search in (for cert_store_subject)",
1460 #if CONFIG_TLS_PROTOCOL
1482 #if CONFIG_DTLS_PROTOCOL
1492 .url_open2 = dtls_open,