avcodec/x86/h264_idct: Fix ff_h264_luma_dc_dequant_idct_sse2 checkasm failures
[ffmpeg.git] / libavformat / tls_schannel.c
1 /*
2 * Copyright (c) 2015 Hendrik Leppkes
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /** Based on the CURL SChannel module */
22
23 #include "config.h"
24 #include "config_components.h"
25
26 #include "libavutil/mem.h"
27 #include "avformat.h"
28 #include "internal.h"
29 #include "network.h"
30 #include "os_support.h"
31 #include "url.h"
32 #include "tls.h"
33
34 #define SECURITY_WIN32
35 #include <windows.h>
36 #include <security.h>
37 #include <schnlsp.h>
38 #include <sddl.h>
39
40 #define SCHANNEL_INITIAL_BUFFER_SIZE 4096
41 #define SCHANNEL_FREE_BUFFER_SIZE 1024
42
43 /* mingw does not define this symbol */
44 #ifndef SECBUFFER_ALERT
45 #define SECBUFFER_ALERT 17
46 #endif
47
48 /* This is the name used for the private key in the MS Keystore.
49 * There is as of time of writing no way to use schannel without
50 * persisting the private key. Which usually means the default MS
51 * keystore will write it to disk unencrypted, user-read/writable.
52 * To combat this as much as possible, the code makes sure to
53 * delete the private key ASAP once SChannel has gotten ahold of
54 * it.
55 * Apparently this is because SChannel neglects marshaling the
56 * private key alongside the certificate for the out-of-process
57 * tls handler.
58 * See this GitHub issue for the most detailed explanation out there:
59 * https://github.com/dotnet/runtime/issues/23749#issuecomment-485947319
60 */
61 #define FF_NCRYPT_TEMP_KEY_NAME L"FFMPEG_TEMP_TLS_KEY"
62
63 static int der_to_pem(const char *data, size_t len, const char *header, char *buf, size_t bufsize)
64 {
65 const int line_length = 64;
66 AVBPrint pem;
67 DWORD base64len = 0;
68 char *base64 = NULL;
69 int ret = 0;
70
71 if (!CryptBinaryToStringA(data, len, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &base64len)) {
72 av_log(NULL, AV_LOG_ERROR, "CryptBinaryToString failed\n");
73 ret = AVERROR_EXTERNAL;
74 goto end;
75 }
76
77 base64 = av_malloc(base64len);
78
79 if (!CryptBinaryToStringA(data, len, CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, base64, &base64len)) {
80 av_log(NULL, AV_LOG_ERROR, "CryptBinaryToString failed\n");
81 ret = AVERROR_EXTERNAL;
82 goto end;
83 }
84
85 av_bprint_init_for_buffer(&pem, buf, bufsize);
86 av_bprintf(&pem, "-----BEGIN %s-----\n", header);
87
88 for (DWORD i = 0; i < base64len; i += line_length) {
89 av_bprintf(&pem, "%.*s\n", line_length, base64 + i);
90 }
91
92 av_bprintf(&pem, "-----END %s-----\n", header);
93
94 if (!av_bprint_is_complete(&pem)) {
95 ret = AVERROR(ENOSPC);
96 goto end;
97 }
98
99 end:
100 av_free(base64);
101 return ret;
102 }
103
104 static int pem_to_der(const char *pem, char **buf, int *out_len)
105 {
106 DWORD derlen = 0;
107
108 if (!CryptStringToBinaryA(pem, 0, CRYPT_STRING_BASE64HEADER, NULL, &derlen, NULL, NULL)) {
109 av_log(NULL, AV_LOG_ERROR, "CryptStringToBinaryA failed\n");
110 return AVERROR(EINVAL);
111 }
112
113 *buf = av_malloc(derlen);
114 if (!*buf)
115 return AVERROR(ENOMEM);
116
117 if (!CryptStringToBinaryA(pem, 0, CRYPT_STRING_BASE64HEADER, *buf, &derlen, NULL, NULL)) {
118 av_log(NULL, AV_LOG_ERROR, "CryptStringToBinaryA failed\n");
119 return AVERROR(EINVAL);
120 }
121
122 *out_len = derlen;
123
124 return 0;
125 }
126
127 static int der_to_fingerprint(const char *data, size_t len, char **fingerprint)
128 {
129 AVBPrint buf;
130 unsigned char hash[32];
131 DWORD hashsize = sizeof(hash);
132
133 if (!CryptHashCertificate2(BCRYPT_SHA256_ALGORITHM, 0, NULL, data, len, hash, &hashsize))
134 {
135 av_log(NULL, AV_LOG_ERROR, "CryptHashCertificate2 failed\n");
136 return AVERROR_EXTERNAL;
137 }
138
139 av_bprint_init(&buf, hashsize*3, hashsize*3);
140
141 for (int i = 0; i < hashsize - 1; i++)
142 av_bprintf(&buf, "%02X:", hash[i]);
143 av_bprintf(&buf, "%02X", hash[hashsize - 1]);
144
145 return av_bprint_finalize(&buf, fingerprint);
146 }
147
148 static int tls_gen_self_signed(NCRYPT_KEY_HANDLE *key, PCCERT_CONTEXT *crtctx)
149 {
150 NCRYPT_PROV_HANDLE provider = 0;
151 CERT_NAME_BLOB subject = { 0 };
152
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";
167
168 SECURITY_STATUS sspi_ret;
169 int ret = 0;
170
171 *crtctx = NULL;
172
173 sspi_ret = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0);
174 if (sspi_ret != ERROR_SUCCESS) {
175 av_log(NULL, AV_LOG_ERROR, "NCryptOpenStorageProvider failed(0x%lx)\n", sspi_ret);
176 ret = AVERROR_EXTERNAL;
177 goto fail;
178 }
179
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) {
182 av_log(NULL, AV_LOG_ERROR, "NCryptCreatePersistedKey failed(0x%lx)\n", sspi_ret);
183 ret = AVERROR_EXTERNAL;
184 goto fail;
185 }
186
187 sspi_ret = NCryptSetProperty(*key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)&export_props, sizeof(export_props), 0);
188 if (sspi_ret != ERROR_SUCCESS) {
189 av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_EXPORT_POLICY_PROPERTY) failed(0x%lx)\n", sspi_ret);
190 ret = AVERROR_EXTERNAL;
191 goto fail;
192 }
193
194 sspi_ret = NCryptSetProperty(*key, NCRYPT_KEY_USAGE_PROPERTY, (PBYTE)&usage_props, sizeof(usage_props), 0);
195 if (sspi_ret != ERROR_SUCCESS) {
196 av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_KEY_USAGE_PROPERTY) failed(0x%lx)\n", sspi_ret);
197 ret = AVERROR_EXTERNAL;
198 goto fail;
199 }
200
201 sspi_ret = NCryptFinalizeKey(*key, 0);
202 if (sspi_ret != ERROR_SUCCESS) {
203 av_log(NULL, AV_LOG_ERROR, "NCryptFinalizeKey failed(0x%lx)\n", sspi_ret);
204 ret = AVERROR_EXTERNAL;
205 goto fail;
206 }
207
208 if (!CertStrToNameA(X509_ASN_ENCODING, subj_str, 0, NULL, NULL, &subject.cbData, NULL))
209 {
210 av_log(NULL, AV_LOG_ERROR, "Initial subj init failed\n");
211 ret = AVERROR_EXTERNAL;
212 goto fail;
213 }
214
215 subject.pbData = av_malloc(subject.cbData);
216 if (!subject.pbData) {
217 ret = AVERROR(ENOMEM);
218 goto fail;
219 }
220
221 if (!CertStrToNameA(X509_ASN_ENCODING, subj_str, 0, NULL, subject.pbData, &subject.cbData, NULL))
222 {
223 av_log(NULL, AV_LOG_ERROR, "Subj init failed\n");
224 ret = AVERROR_EXTERNAL;
225 goto fail;
226 }
227
228 // Extended Key Usage extension
229 eku.cUsageIdentifier = 1;
230 eku.rgpszUsageIdentifier = (LPSTR*)ext_usages;
231
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)) {
234 av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for EKU failed\n");
235 ret = AVERROR_EXTERNAL;
236 goto fail;
237 }
238
239 ext[0].pszObjId = (LPSTR)szOID_ENHANCED_KEY_USAGE;
240 ext[0].fCritical = TRUE;
241
242 // Key usage extension
243 key_usage_blob.cbData = sizeof(key_usage);
244 key_usage_blob.pbData = &key_usage;
245
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)) {
248 av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for KU failed\n");
249 ret = AVERROR_EXTERNAL;
250 goto fail;
251 }
252
253 ext[1].pszObjId = (LPSTR)szOID_KEY_USAGE;
254 ext[1].fCritical = TRUE;
255
256 // Cert Basic Constraints
257 basic_constraints.fCA = FALSE;
258
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)) {
261 av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for KU failed\n");
262 ret = AVERROR_EXTERNAL;
263 goto fail;
264 }
265
266 ext[2].pszObjId = (LPSTR)szOID_BASIC_CONSTRAINTS2;
267 ext[2].fCritical = TRUE;
268
269 // Subject Alt Names
270 san_entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
271 san_entry.pwszDNSName = (LPWSTR)L"localhost";
272
273 san_info.cAltEntry = 1;
274 san_info.rgAltEntry = &san_entry;
275
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)) {
278 av_log(NULL, AV_LOG_ERROR, "CryptEncodeObjectEx for KU failed\n");
279 ret = AVERROR_EXTERNAL;
280 goto fail;
281 }
282
283 ext[3].pszObjId = (LPSTR)szOID_SUBJECT_ALT_NAME2;
284 ext[3].fCritical = TRUE;
285
286 exts.cExtension = 4;
287 exts.rgExtension = ext;
288
289 prov_info.pwszProvName = (LPWSTR)MS_KEY_STORAGE_PROVIDER;
290 prov_info.pwszContainerName = (LPWSTR)FF_NCRYPT_TEMP_KEY_NAME;
291 prov_info.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
292
293 *crtctx = CertCreateSelfSignCertificate(*key, &subject, 0, &prov_info, &sig_alg, NULL, NULL, &exts);
294 if (!*crtctx) {
295 av_log(NULL, AV_LOG_ERROR, "CertCreateSelfSignCertificate failed: %lu\n", GetLastError());
296 ret = AVERROR_EXTERNAL;
297 goto fail;
298 }
299
300 NCryptFreeObject(provider);
301 av_free(subject.pbData);
302 for (int i = 0; i < FF_ARRAY_ELEMS(ext); i++)
303 LocalFree(ext[i].Value.pbData);
304
305 return 0;
306
307 fail:
308 if (*crtctx)
309 CertFreeCertificateContext(*crtctx);
310 if (*key)
311 if (NCryptDeleteKey(*key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
312 NCryptFreeObject(*key);
313 if (provider)
314 NCryptFreeObject(provider);
315 if (subject.pbData)
316 av_free(subject.pbData);
317 for (int i = 0; i < FF_ARRAY_ELEMS(ext); i++)
318 if (ext[i].Value.pbData)
319 LocalFree(ext[i].Value.pbData);
320
321 *key = 0;
322 *crtctx = NULL;
323
324 return ret;
325 }
326
327 static int tls_export_key_cert(NCRYPT_KEY_HANDLE key, PCCERT_CONTEXT crtctx,
328 char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
329 {
330 DWORD keysize = 0;
331 char *keybuf = NULL;
332
333 SECURITY_STATUS sspi_ret;
334 int ret = 0;
335
336 sspi_ret = NCryptExportKey(key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, NULL, 0, &keysize, 0);
337 if (sspi_ret != ERROR_SUCCESS) {
338 av_log(NULL, AV_LOG_ERROR, "Initial NCryptExportKey failed(0x%lx)\n", sspi_ret);
339 ret = AVERROR_EXTERNAL;
340 goto end;
341 }
342
343 keybuf = av_malloc(keysize);
344 if (!keybuf) {
345 ret = AVERROR(ENOMEM);
346 goto end;
347 }
348
349 sspi_ret = NCryptExportKey(key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB, NULL, keybuf, keysize, &keysize, 0);
350 if (sspi_ret != ERROR_SUCCESS) {
351 av_log(NULL, AV_LOG_ERROR, "Initial NCryptExportKey failed(0x%lx)\n", sspi_ret);
352 ret = AVERROR_EXTERNAL;
353 goto end;
354 }
355
356 ret = der_to_pem(keybuf, keysize, "PRIVATE KEY", key_buf, key_sz);
357 if (ret < 0)
358 goto end;
359
360 ret = der_to_pem(crtctx->pbCertEncoded, crtctx->cbCertEncoded, "CERTIFICATE", cert_buf, cert_sz);
361 if (ret < 0)
362 goto end;
363
364 ret = der_to_fingerprint(crtctx->pbCertEncoded, crtctx->cbCertEncoded, fingerprint);
365 if (ret < 0)
366 goto end;
367
368 end:
369 av_free(keybuf);
370 return ret;
371 }
372
373 int ff_ssl_gen_key_cert(char *key_buf, size_t key_sz, char *cert_buf, size_t cert_sz, char **fingerprint)
374 {
375 NCRYPT_KEY_HANDLE key = 0;
376 PCCERT_CONTEXT crtctx = NULL;
377
378 int ret = tls_gen_self_signed(&key, &crtctx);
379 if (ret < 0)
380 goto end;
381
382 ret = tls_export_key_cert(key, crtctx, key_buf, key_sz, cert_buf, cert_sz, fingerprint);
383 if (ret < 0)
384 goto end;
385
386 end:
387 if (key)
388 if (NCryptDeleteKey(key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
389 NCryptFreeObject(key);
390 if (crtctx)
391 CertFreeCertificateContext(crtctx);
392
393 return ret;
394 }
395
396 static int tls_import_key_cert(char *key_buf, char *cert_buf, NCRYPT_KEY_HANDLE *key, PCCERT_CONTEXT *crtctx)
397 {
398 NCRYPT_PROV_HANDLE provider = 0;
399
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 };
405
406 int key_der_len = 0, cert_der_len = 0;
407 char *key_der = NULL, *cert_der = NULL;
408
409 SECURITY_STATUS sspi_ret;
410 int ret = 0;
411
412 ret = pem_to_der(key_buf, &key_der, &key_der_len);
413 if (ret < 0)
414 goto fail;
415
416 ret = pem_to_der(cert_buf, &cert_der, &cert_der_len);
417 if (ret < 0)
418 goto fail;
419
420 sspi_ret = NCryptOpenStorageProvider(&provider, MS_KEY_STORAGE_PROVIDER, 0);
421 if (sspi_ret != ERROR_SUCCESS) {
422 av_log(NULL, AV_LOG_ERROR, "NCryptOpenStorageProvider failed(0x%lx)\n", sspi_ret);
423 ret = AVERROR_EXTERNAL;
424 goto fail;
425 }
426
427 buffer_desc.ulVersion = NCRYPTBUFFER_VERSION;
428 buffer_desc.cBuffers = 1;
429 buffer_desc.pBuffers = &buffer;
430
431 buffer.BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;
432 buffer.pvBuffer = (LPWSTR)FF_NCRYPT_TEMP_KEY_NAME;
433 buffer.cbBuffer = sizeof(FF_NCRYPT_TEMP_KEY_NAME);
434
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) {
437 av_log(NULL, AV_LOG_ERROR, "NCryptImportKey failed(0x%lx)\n", sspi_ret);
438 ret = AVERROR_EXTERNAL;
439 goto fail;
440 }
441
442 sspi_ret = NCryptSetProperty(*key, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE)&export_props, sizeof(export_props), 0);
443 if (sspi_ret != ERROR_SUCCESS) {
444 av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_EXPORT_POLICY_PROPERTY) failed(0x%lx)\n", sspi_ret);
445 ret = AVERROR_EXTERNAL;
446 goto fail;
447 }
448
449 sspi_ret = NCryptSetProperty(*key, NCRYPT_KEY_USAGE_PROPERTY, (PBYTE)&usage_props, sizeof(usage_props), 0);
450 if (sspi_ret != ERROR_SUCCESS) {
451 av_log(NULL, AV_LOG_ERROR, "NCryptSetProperty(NCRYPT_KEY_USAGE_PROPERTY) failed(0x%lx)\n", sspi_ret);
452 ret = AVERROR_EXTERNAL;
453 goto fail;
454 }
455
456 sspi_ret = NCryptFinalizeKey(*key, 0);
457 if (sspi_ret != ERROR_SUCCESS) {
458 av_log(NULL, AV_LOG_ERROR, "NCryptFinalizeKey failed(0x%lx)\n", sspi_ret);
459 ret = AVERROR_EXTERNAL;
460 goto fail;
461 }
462
463 *crtctx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert_der, cert_der_len);
464 if (!*crtctx) {
465 av_log(NULL, AV_LOG_ERROR, "CertCreateCertificateContext failed: %lu\n", GetLastError());
466 ret = AVERROR_EXTERNAL;
467 goto fail;
468 }
469
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());
472 ret = AVERROR_EXTERNAL;
473 goto fail;
474 }
475
476 prov_info.pwszProvName = (LPWSTR)MS_KEY_STORAGE_PROVIDER;
477 prov_info.pwszContainerName = (LPWSTR)FF_NCRYPT_TEMP_KEY_NAME;
478 prov_info.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
479
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());
482 ret = AVERROR_EXTERNAL;
483 goto fail;
484 }
485
486 goto end;
487
488 fail:
489 if (*key)
490 if (NCryptDeleteKey(*key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
491 NCryptFreeObject(*key);
492 if (*crtctx)
493 CertFreeCertificateContext(*crtctx);
494
495 *key = 0;
496 *crtctx = NULL;
497
498 end:
499 if (key_der)
500 av_free(key_der);
501 if (cert_der)
502 av_free(cert_der);
503 if (provider)
504 NCryptFreeObject(provider);
505 return ret;
506 }
507
508 static int tls_cert_from_store(void *logctx, const char *cert_store_name, const char *cert_subj, PCCERT_CONTEXT *crtctx)
509 {
510 HCERTSTORE cert_store = NULL;
511 int ret = 0;
512
513 cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, cert_store_name);
514 if (!cert_store) {
515 av_log(logctx, AV_LOG_ERROR, "Opening user cert store %s failed\n", cert_store_name);
516 ret = AVERROR_EXTERNAL;
517 goto end;
518 }
519
520 *crtctx = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, cert_subj, NULL);
521 if (!*crtctx) {
522 av_log(logctx, AV_LOG_ERROR, "Could not find certificate in store\n");
523 ret = AVERROR_EXTERNAL;
524 goto end;
525 }
526
527 end:
528 if (cert_store)
529 CertCloseStore(cert_store, 0);
530
531 return ret;
532 }
533
534 static int tls_load_key_cert(char *key_url, char *cert_url, NCRYPT_KEY_HANDLE *key, PCCERT_CONTEXT *crtctx)
535 {
536 AVBPrint key_bp, cert_bp;
537 int ret = 0;
538
539 av_bprint_init(&key_bp, 1, MAX_CERTIFICATE_SIZE);
540 av_bprint_init(&cert_bp, 1, MAX_CERTIFICATE_SIZE);
541
542 /* Read key file. */
543 ret = ff_url_read_all(key_url, &key_bp);
544 if (ret < 0) {
545 av_log(NULL, AV_LOG_ERROR, "Failed to open key file %s\n", key_url);
546 goto end;
547 }
548
549 ret = ff_url_read_all(cert_url, &cert_bp);
550 if (ret < 0) {
551 av_log(NULL, AV_LOG_ERROR, "Failed to open cert file %s\n", cert_url);
552 goto end;
553 }
554
555 ret = tls_import_key_cert(key_bp.str, cert_bp.str, key, crtctx);
556 if (ret < 0)
557 goto end;
558
559 end:
560 av_bprint_finalize(&key_bp, NULL);
561 av_bprint_finalize(&cert_bp, NULL);
562
563 return ret;
564 }
565
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)
567 {
568 NCRYPT_KEY_HANDLE key = 0;
569 PCCERT_CONTEXT crtctx = NULL;
570
571 int ret = tls_load_key_cert(key_url, cert_url, &key, &crtctx);
572 if (ret < 0)
573 goto end;
574
575 ret = tls_export_key_cert(key, crtctx, key_buf, key_sz, cert_buf, cert_sz, fingerprint);
576 if (ret < 0)
577 goto end;
578
579 end:
580 if (key)
581 if (NCryptDeleteKey(key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
582 NCryptFreeObject(key);
583 if (crtctx)
584 CertFreeCertificateContext(crtctx);
585
586 return ret;
587 }
588
589 typedef struct TLSContext {
590 TLSShared tls_shared;
591
592 char *cert_store_subject;
593 char *cert_store_name;
594
595 CredHandle cred_handle;
596 TimeStamp cred_timestamp;
597
598 CtxtHandle ctxt_handle;
599 int have_context;
600 TimeStamp ctxt_timestamp;
601
602 ULONG request_flags;
603 ULONG context_flags;
604
605 uint8_t *enc_buf;
606 int enc_buf_size;
607 int enc_buf_offset;
608
609 uint8_t *dec_buf;
610 int dec_buf_size;
611 int dec_buf_offset;
612
613 char *send_buf;
614 int send_buf_size;
615 int send_buf_offset;
616
617 SecPkgContext_StreamSizes sizes;
618
619 int connected;
620 int connection_closed;
621 int sspi_close_notify;
622 } TLSContext;
623
624 int ff_tls_set_external_socket(URLContext *h, URLContext *sock)
625 {
626 TLSContext *c = h->priv_data;
627 TLSShared *s = &c->tls_shared;
628
629 if (s->is_dtls)
630 c->tls_shared.udp = sock;
631 else
632 c->tls_shared.tcp = sock;
633
634 return 0;
635 }
636
637 int ff_dtls_export_materials(URLContext *h, char *dtls_srtp_materials, size_t materials_sz)
638 {
639 #if HAVE_SECPKGCONTEXT_KEYINGMATERIALINFO
640 TLSContext *c = h->priv_data;
641
642 SecPkgContext_KeyingMaterialInfo keying_info = { 0 };
643 SecPkgContext_KeyingMaterial keying_material = { 0 };
644
645 const char* dst = "EXTRACTOR-dtls_srtp";
646 SECURITY_STATUS sspi_ret;
647
648 if (!c->have_context)
649 return AVERROR(EINVAL);
650
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;
656
657 sspi_ret = SetContextAttributes(&c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL_INFO, &keying_info, sizeof(keying_info));
658 if (sspi_ret != SEC_E_OK) {
659 av_log(h, AV_LOG_ERROR, "Setting keying material info failed: %lx\n", sspi_ret);
660 return AVERROR_EXTERNAL;
661 }
662
663 sspi_ret = QueryContextAttributes(&c->ctxt_handle, SECPKG_ATTR_KEYING_MATERIAL, &keying_material);
664 if (sspi_ret != SEC_E_OK) {
665 av_log(h, AV_LOG_ERROR, "Querying keying material failed: %lx\n", sspi_ret);
666 return AVERROR_EXTERNAL;
667 }
668
669 memcpy(dtls_srtp_materials, keying_material.pbKeyingMaterial, FFMIN(materials_sz, keying_material.cbKeyingMaterial));
670 FreeContextBuffer(keying_material.pbKeyingMaterial);
671
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);
674 return AVERROR(ENOSPC);
675 }
676
677 return 0;
678 #else
679 return AVERROR(ENOSYS);
680 #endif
681 }
682
683 static void init_sec_buffer(SecBuffer *buffer, unsigned long type,
684 void *data, unsigned long size)
685 {
686 buffer->cbBuffer = size;
687 buffer->BufferType = type;
688 buffer->pvBuffer = data;
689 }
690
691 static void init_sec_buffer_desc(SecBufferDesc *desc, SecBuffer *buffers,
692 unsigned long buffer_count)
693 {
694 desc->ulVersion = SECBUFFER_VERSION;
695 desc->pBuffers = buffers;
696 desc->cBuffers = buffer_count;
697 }
698
699 static int tls_process_send_buffer(URLContext *h)
700 {
701 TLSContext *c = h->priv_data;
702 TLSShared *s = &c->tls_shared;
703 URLContext *uc = s->is_dtls ? s->udp : s->tcp;
704 int ret;
705
706 if (!c->send_buf)
707 return 0;
708
709 ret = ffurl_write(uc, c->send_buf + c->send_buf_offset, c->send_buf_size - c->send_buf_offset);
710 if (ret == AVERROR(EAGAIN)) {
711 return AVERROR(EAGAIN);
712 } else if (ret < 0) {
713 av_log(h, AV_LOG_ERROR, "Writing encrypted data to socket failed\n");
714 return AVERROR(EIO);
715 }
716
717 c->send_buf_offset += ret;
718
719 if (c->send_buf_offset < c->send_buf_size)
720 return AVERROR(EAGAIN);
721
722 av_freep(&c->send_buf);
723 c->send_buf_size = c->send_buf_offset = 0;
724
725 return 0;
726 }
727
728 static int tls_shutdown_client(URLContext *h)
729 {
730 TLSContext *c = h->priv_data;
731 TLSShared *s = &c->tls_shared;
732 URLContext *uc = s->is_dtls ? s->udp : s->tcp;
733 int ret;
734
735 if (c->connected) {
736 SecBufferDesc BuffDesc;
737 SecBuffer Buffer;
738 SECURITY_STATUS sspi_ret;
739 SecBuffer outbuf;
740 SecBufferDesc outbuf_desc;
741
742 DWORD dwshut = SCHANNEL_SHUTDOWN;
743 init_sec_buffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
744 init_sec_buffer_desc(&BuffDesc, &Buffer, 1);
745
746 uc->flags &= ~AVIO_FLAG_NONBLOCK;
747 ret = tls_process_send_buffer(h);
748 if (ret < 0)
749 return ret;
750
751 sspi_ret = ApplyControlToken(&c->ctxt_handle, &BuffDesc);
752 if (sspi_ret != SEC_E_OK)
753 av_log(h, AV_LOG_ERROR, "ApplyControlToken failed\n");
754
755 init_sec_buffer(&outbuf, SECBUFFER_TOKEN, NULL, 0);
756 init_sec_buffer_desc(&outbuf_desc, &outbuf, 1);
757
758 do {
759 if (s->listen)
760 sspi_ret = AcceptSecurityContext(&c->cred_handle, &c->ctxt_handle, NULL, c->request_flags, 0,
761 &c->ctxt_handle, &outbuf_desc, &c->context_flags,
762 &c->ctxt_timestamp);
763 else
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);
767
768 if (outbuf.pvBuffer) {
769 if (outbuf.cbBuffer > 0) {
770 ret = ffurl_write(uc, outbuf.pvBuffer, outbuf.cbBuffer);
771 if (ret < 0 || ret != outbuf.cbBuffer)
772 av_log(h, AV_LOG_ERROR, "Failed to send close message\n");
773 }
774 FreeContextBuffer(outbuf.pvBuffer);
775 }
776 } while(
777 #ifdef SEC_I_MESSAGE_FRAGMENT
778 sspi_ret == SEC_I_MESSAGE_FRAGMENT ||
779 #endif
780 sspi_ret == SEC_I_CONTINUE_NEEDED);
781
782 av_log(h, AV_LOG_DEBUG, "Close session result: 0x%lx\n", sspi_ret);
783
784 c->connected = 0;
785 }
786 return 0;
787 }
788
789 static int tls_close(URLContext *h)
790 {
791 TLSContext *c = h->priv_data;
792 TLSShared *s = &c->tls_shared;
793
794 tls_shutdown_client(h);
795
796 DeleteSecurityContext(&c->ctxt_handle);
797 FreeCredentialsHandle(&c->cred_handle);
798
799 av_freep(&c->enc_buf);
800 c->enc_buf_size = c->enc_buf_offset = 0;
801
802 av_freep(&c->dec_buf);
803 c->dec_buf_size = c->dec_buf_offset = 0;
804
805 av_freep(&c->send_buf);
806 c->send_buf_size = c->send_buf_offset = 0;
807
808 if (s->is_dtls) {
809 if (!s->external_sock)
810 ffurl_closep(&c->tls_shared.udp);
811 } else {
812 ffurl_closep(&c->tls_shared.tcp);
813 }
814
815 return 0;
816 }
817
818 static int tls_handshake_loop(URLContext *h, int initial)
819 {
820 TLSContext *c = h->priv_data;
821 TLSShared *s = &c->tls_shared;
822 URLContext *uc = s->is_dtls ? s->udp : s->tcp;
823 SECURITY_STATUS sspi_ret;
824 SecBuffer outbuf[3] = { 0 };
825 SecBufferDesc outbuf_desc;
826 SecBuffer inbuf[3];
827 SecBufferDesc inbuf_desc;
828 struct sockaddr_storage recv_addr = { 0 };
829 socklen_t recv_addr_len = 0;
830 int i, ret = 0, read_data = initial;
831
832 if (c->enc_buf == NULL) {
833 c->enc_buf_offset = 0;
834 ret = av_reallocp(&c->enc_buf, SCHANNEL_INITIAL_BUFFER_SIZE);
835 if (ret < 0)
836 goto fail;
837 c->enc_buf_size = SCHANNEL_INITIAL_BUFFER_SIZE;
838 }
839
840 if (c->dec_buf == NULL) {
841 c->dec_buf_offset = 0;
842 ret = av_reallocp(&c->dec_buf, SCHANNEL_INITIAL_BUFFER_SIZE);
843 if (ret < 0)
844 goto fail;
845 c->dec_buf_size = SCHANNEL_INITIAL_BUFFER_SIZE;
846 }
847
848 uc->flags &= ~AVIO_FLAG_NONBLOCK;
849
850 while (1) {
851 if (c->enc_buf_size - c->enc_buf_offset < SCHANNEL_FREE_BUFFER_SIZE) {
852 c->enc_buf_size = c->enc_buf_offset + SCHANNEL_FREE_BUFFER_SIZE;
853 ret = av_reallocp(&c->enc_buf, c->enc_buf_size);
854 if (ret < 0) {
855 c->enc_buf_size = c->enc_buf_offset = 0;
856 goto fail;
857 }
858 }
859
860 if (read_data) {
861 ret = ffurl_read(uc, c->enc_buf + c->enc_buf_offset, c->enc_buf_size - c->enc_buf_offset);
862 if (ret < 0) {
863 av_log(h, AV_LOG_ERROR, "Failed to read handshake response\n");
864 goto fail;
865 }
866 c->enc_buf_offset += ret;
867 if (s->is_dtls && !recv_addr_len) {
868 ff_udp_get_last_recv_addr(uc, &recv_addr, &recv_addr_len);
869
870 if (s->listen) {
871 ret = ff_udp_set_remote_addr(uc, (struct sockaddr *)&recv_addr, recv_addr_len, 1);
872 if (ret < 0) {
873 av_log(h, AV_LOG_ERROR, "Failed connecting udp context\n");
874 goto fail;
875 }
876 av_log(h, AV_LOG_TRACE, "Set UDP remote addr on UDP socket, now 'connected'\n");
877 }
878 }
879 }
880
881 /* input buffers */
882 init_sec_buffer(&inbuf[0], SECBUFFER_TOKEN, av_malloc(c->enc_buf_offset), c->enc_buf_offset);
883 init_sec_buffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
884 if (s->listen && s->is_dtls) {
885 init_sec_buffer(&inbuf[2], SECBUFFER_EXTRA, &recv_addr, recv_addr_len);
886 init_sec_buffer_desc(&inbuf_desc, inbuf, 3);
887 } else {
888 init_sec_buffer_desc(&inbuf_desc, inbuf, 2);
889 }
890
891 if (inbuf[0].pvBuffer == NULL) {
892 av_log(h, AV_LOG_ERROR, "Failed to allocate input buffer\n");
893 ret = AVERROR(ENOMEM);
894 goto fail;
895 }
896
897 memcpy(inbuf[0].pvBuffer, c->enc_buf, c->enc_buf_offset);
898
899 /* output buffers */
900 init_sec_buffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
901 init_sec_buffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0);
902 init_sec_buffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
903 init_sec_buffer_desc(&outbuf_desc, outbuf, 3);
904
905 if (s->listen)
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);
909 else
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);
913 av_freep(&inbuf[0].pvBuffer);
914
915 av_log(h, AV_LOG_TRACE, "Handshake res with %d bytes of data: 0x%lx\n", c->enc_buf_offset, sspi_ret);
916
917 if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
918 av_log(h, AV_LOG_TRACE, "Received incomplete handshake, need more data\n");
919 read_data = 1;
920 continue;
921 }
922
923 c->have_context = 1;
924
925 /* remote requests a client certificate - attempt to continue without one anyway */
926 if (sspi_ret == SEC_I_INCOMPLETE_CREDENTIALS &&
927 !(c->request_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
928 av_log(h, AV_LOG_VERBOSE, "Client certificate has been requested, ignoring\n");
929 c->request_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
930 read_data = 0;
931 continue;
932 }
933
934 /* continue handshake */
935 if (sspi_ret == SEC_I_CONTINUE_NEEDED ||
936 #ifdef SEC_I_MESSAGE_FRAGMENT
937 sspi_ret == SEC_I_MESSAGE_FRAGMENT ||
938 #endif
939 sspi_ret == SEC_E_OK) {
940 for (i = 0; i < 3; i++) {
941 if (outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
942 ret = ffurl_write(uc, outbuf[i].pvBuffer, outbuf[i].cbBuffer);
943 if (ret < 0 || ret != outbuf[i].cbBuffer) {
944 av_log(h, AV_LOG_VERBOSE, "Failed to send handshake data\n");
945 ret = AVERROR(EIO);
946 goto fail;
947 }
948 }
949
950 if (outbuf[i].pvBuffer != NULL) {
951 FreeContextBuffer(outbuf[i].pvBuffer);
952 outbuf[i].pvBuffer = NULL;
953 }
954 }
955 } else {
956 if (sspi_ret == SEC_E_WRONG_PRINCIPAL)
957 av_log(h, AV_LOG_ERROR, "SNI or certificate check failed\n");
958 else
959 av_log(h, AV_LOG_ERROR, "Creating security context failed (0x%lx)\n", sspi_ret);
960 ret = AVERROR_UNKNOWN;
961 goto fail;
962 }
963
964 #ifdef SEC_I_MESSAGE_FRAGMENT
965 if (sspi_ret == SEC_I_MESSAGE_FRAGMENT) {
966 av_log(h, AV_LOG_TRACE, "Writing fragmented output message part\n");
967 read_data = 0;
968 continue;
969 }
970 #endif
971
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,
975 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);
979 read_data = 0;
980 continue;
981 }
982 }
983 } else {
984 c->enc_buf_offset = 0;
985 }
986
987 if (sspi_ret == SEC_I_CONTINUE_NEEDED) {
988 av_log(h, AV_LOG_TRACE, "Handshake continues\n");
989 read_data = 1;
990 continue;
991 }
992
993 break;
994 }
995
996 av_log(h, AV_LOG_TRACE, "Handshake completed\n");
997
998 return 0;
999
1000 fail:
1001 /* free any remaining output data */
1002 for (i = 0; i < 3; i++) {
1003 if (outbuf[i].pvBuffer != NULL) {
1004 FreeContextBuffer(outbuf[i].pvBuffer);
1005 outbuf[i].pvBuffer = NULL;
1006 }
1007 }
1008
1009 av_log(h, AV_LOG_TRACE, "Handshake failed\n");
1010
1011 return ret;
1012 }
1013
1014 static int tls_client_handshake(URLContext *h)
1015 {
1016 TLSContext *c = h->priv_data;
1017 TLSShared *s = &c->tls_shared;
1018 URLContext *uc = s->is_dtls ? s->udp : s->tcp;
1019 SecBuffer outbuf;
1020 SecBufferDesc outbuf_desc;
1021 SECURITY_STATUS sspi_ret;
1022 int ret;
1023
1024 init_sec_buffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
1025 init_sec_buffer_desc(&outbuf_desc, &outbuf, 1);
1026
1027 c->request_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
1028 ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY;
1029 if (s->is_dtls)
1030 c->request_flags |= ISC_REQ_DATAGRAM;
1031 else
1032 c->request_flags |= ISC_REQ_STREAM;
1033
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) {
1038 av_log(h, AV_LOG_ERROR, "Unable to create initial security context (0x%lx)\n", sspi_ret);
1039 ret = AVERROR_UNKNOWN;
1040 goto fail;
1041 }
1042
1043 c->have_context = 1;
1044
1045 uc->flags &= ~AVIO_FLAG_NONBLOCK;
1046 ret = ffurl_write(uc, outbuf.pvBuffer, outbuf.cbBuffer);
1047 FreeContextBuffer(outbuf.pvBuffer);
1048 if (ret < 0 || ret != outbuf.cbBuffer) {
1049 av_log(h, AV_LOG_ERROR, "Failed to send initial handshake data\n");
1050 ret = AVERROR(EIO);
1051 goto fail;
1052 }
1053
1054 return tls_handshake_loop(h, 1);
1055
1056 fail:
1057 DeleteSecurityContext(&c->ctxt_handle);
1058 return ret;
1059 }
1060
1061 static int tls_server_handshake(URLContext *h)
1062 {
1063 TLSContext *c = h->priv_data;
1064 TLSShared *s = &c->tls_shared;
1065
1066 c->request_flags = ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
1067 ASC_REQ_CONFIDENTIALITY | ASC_REQ_ALLOCATE_MEMORY;
1068 if (s->is_dtls)
1069 c->request_flags |= ASC_REQ_DATAGRAM;
1070 else
1071 c->request_flags |= ASC_REQ_STREAM;
1072
1073 c->have_context = 0;
1074
1075 return tls_handshake_loop(h, 1);
1076 }
1077
1078 static int tls_handshake(URLContext *h)
1079 {
1080 TLSContext *c = h->priv_data;
1081 TLSShared *s = &c->tls_shared;
1082 SECURITY_STATUS sspi_ret;
1083 int ret = 0;
1084
1085 if (s->listen)
1086 ret = tls_server_handshake(h);
1087 else
1088 ret = tls_client_handshake(h);
1089
1090 if (ret < 0)
1091 goto fail;
1092
1093 #if CONFIG_DTLS_PROTOCOL
1094 if (s->is_dtls && s->mtu > 0) {
1095 ULONG mtu = s->mtu;
1096 sspi_ret = SetContextAttributes(&c->ctxt_handle, SECPKG_ATTR_DTLS_MTU, &mtu, sizeof(mtu));
1097 if (sspi_ret != SEC_E_OK) {
1098 av_log(h, AV_LOG_ERROR, "Failed setting DTLS MTU to %d.\n", s->mtu);
1099 ret = AVERROR(EINVAL);
1100 goto fail;
1101 }
1102 av_log(h, AV_LOG_VERBOSE, "Set DTLS MTU to %d\n", s->mtu);
1103 }
1104 #endif
1105
1106 c->connected = 1;
1107
1108 fail:
1109 return ret;
1110 }
1111
1112 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
1113 {
1114 TLSContext *c = h->priv_data;
1115 TLSShared *s = &c->tls_shared;
1116 SECURITY_STATUS sspi_ret;
1117 SCHANNEL_CRED schannel_cred = { 0 };
1118 PCCERT_CONTEXT crtctx = NULL;
1119 NCRYPT_KEY_HANDLE key = 0;
1120 int ret = 0;
1121
1122 if (!s->external_sock) {
1123 if ((ret = ff_tls_open_underlying(s, h, uri, options)) < 0)
1124 goto fail;
1125 }
1126
1127 /* SChannel Options */
1128 schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
1129
1130 if (s->listen) {
1131 if (c->cert_store_name && c->cert_store_subject) {
1132 ret = tls_cert_from_store(h, c->cert_store_name, c->cert_store_subject, &crtctx);
1133 } else if (s->key_buf && s->cert_buf) {
1134 ret = tls_import_key_cert(s->key_buf, s->cert_buf, &key, &crtctx);
1135 } else if (s->key_file && s->cert_file) {
1136 ret = tls_load_key_cert(s->key_file, s->cert_file, &key, &crtctx);
1137 } else {
1138 av_log(h, AV_LOG_VERBOSE, "No server certificate provided, using self-signed\n");
1139 ret = tls_gen_self_signed(&key, &crtctx);
1140 }
1141
1142 if (ret < 0)
1143 goto fail;
1144
1145 schannel_cred.cCreds = 1;
1146 schannel_cred.paCred = &crtctx;
1147
1148 schannel_cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER | SCH_CRED_MANUAL_CRED_VALIDATION;
1149
1150 #if CONFIG_DTLS_PROTOCOL
1151 if (s->is_dtls)
1152 schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_SERVER;
1153 #endif
1154 } else {
1155 if (s->verify)
1156 schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION |
1157 SCH_CRED_REVOCATION_CHECK_CHAIN;
1158 else
1159 schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
1160 SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
1161 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
1162
1163 #if CONFIG_DTLS_PROTOCOL
1164 if (s->is_dtls)
1165 schannel_cred.grbitEnabledProtocols = SP_PROT_DTLS1_X_CLIENT;
1166 #endif
1167 }
1168
1169 /* Get credential handle */
1170 sspi_ret = AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
1171 s->listen ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
1172 NULL, &schannel_cred, NULL, NULL, &c->cred_handle,
1173 &c->cred_timestamp);
1174 if (sspi_ret != SEC_E_OK) {
1175 av_log(h, AV_LOG_ERROR, "Unable to acquire security credentials (0x%lx)\n", sspi_ret);
1176 ret = AVERROR_UNKNOWN;
1177 goto fail;
1178 }
1179
1180 if (!s->external_sock) {
1181 ret = tls_handshake(h);
1182 if (ret < 0)
1183 goto fail;
1184 }
1185
1186 goto end;
1187
1188 fail:
1189 tls_close(h);
1190
1191 end:
1192 if (crtctx)
1193 CertFreeCertificateContext(crtctx);
1194 if (key)
1195 if (NCryptDeleteKey(key, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)
1196 NCryptFreeObject(key);
1197
1198 return ret;
1199 }
1200
1201 #if CONFIG_DTLS_PROTOCOL
1202 static int dtls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
1203 {
1204 TLSContext *c = h->priv_data;
1205 TLSShared *s = &c->tls_shared;
1206
1207 s->is_dtls = 1;
1208
1209 return tls_open(h, uri, flags, options);
1210 }
1211 #endif
1212
1213 static int tls_read(URLContext *h, uint8_t *buf, int len)
1214 {
1215 TLSContext *c = h->priv_data;
1216 TLSShared *s = &c->tls_shared;
1217 URLContext *uc = s->is_dtls ? s->udp : s->tcp;
1218 SECURITY_STATUS sspi_ret = SEC_E_OK;
1219 SecBuffer inbuf[4];
1220 SecBufferDesc inbuf_desc;
1221 int size, ret = 0;
1222 int min_enc_buf_size = len + SCHANNEL_FREE_BUFFER_SIZE;
1223
1224 /* If we have some left-over data from previous network activity,
1225 * return it first in case it is enough. It may contain
1226 * data that is required to know whether this connection
1227 * is still required or not, esp. in case of HTTP keep-alive
1228 * connections. */
1229 if (c->dec_buf_offset > 0)
1230 goto cleanup;
1231
1232 if (c->sspi_close_notify)
1233 goto cleanup;
1234
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) {
1238 c->enc_buf_size = c->enc_buf_offset + SCHANNEL_FREE_BUFFER_SIZE;
1239 if (c->enc_buf_size < min_enc_buf_size)
1240 c->enc_buf_size = min_enc_buf_size;
1241 ret = av_reallocp(&c->enc_buf, c->enc_buf_size);
1242 if (ret < 0) {
1243 c->enc_buf_size = c->enc_buf_offset = 0;
1244 return ret;
1245 }
1246 }
1247
1248 uc->flags &= ~AVIO_FLAG_NONBLOCK;
1249 uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1250
1251 ret = ffurl_read(uc, c->enc_buf + c->enc_buf_offset,
1252 c->enc_buf_size - c->enc_buf_offset);
1253 if (ret == AVERROR_EOF) {
1254 c->connection_closed = 1;
1255 ret = 0;
1256 } else if (ret == AVERROR(EAGAIN)) {
1257 ret = 0;
1258 } else if (ret < 0) {
1259 av_log(h, AV_LOG_ERROR, "Unable to read from socket\n");
1260 return ret;
1261 }
1262
1263 c->enc_buf_offset += ret;
1264 }
1265
1266 while (c->enc_buf_offset > 0 && sspi_ret == SEC_E_OK) {
1267 /* input buffer */
1268 init_sec_buffer(&inbuf[0], SECBUFFER_DATA, c->enc_buf, c->enc_buf_offset);
1269
1270 /* additional buffers for possible output */
1271 init_sec_buffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
1272 init_sec_buffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
1273 init_sec_buffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
1274 init_sec_buffer_desc(&inbuf_desc, inbuf, 4);
1275
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) {
1279 /* handle decrypted data */
1280 if (inbuf[1].BufferType == SECBUFFER_DATA) {
1281 /* grow buffer if needed */
1282 size = inbuf[1].cbBuffer > SCHANNEL_FREE_BUFFER_SIZE ?
1283 inbuf[1].cbBuffer : SCHANNEL_FREE_BUFFER_SIZE;
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;
1288 ret = av_reallocp(&c->dec_buf, c->dec_buf_size);
1289 if (ret < 0) {
1290 c->dec_buf_size = c->dec_buf_offset = 0;
1291 return ret;
1292 }
1293 }
1294
1295 /* copy decrypted data to buffer */
1296 size = inbuf[1].cbBuffer;
1297 if (size) {
1298 memcpy(c->dec_buf + c->dec_buf_offset, inbuf[1].pvBuffer, size);
1299 c->dec_buf_offset += size;
1300 }
1301 }
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,
1305 inbuf[3].cbBuffer);
1306 c->enc_buf_offset = inbuf[3].cbBuffer;
1307 }
1308 } else
1309 c->enc_buf_offset = 0;
1310
1311 if (sspi_ret == SEC_I_RENEGOTIATE) {
1312 if (c->enc_buf_offset) {
1313 av_log(h, AV_LOG_ERROR, "Cannot renegotiate, encrypted data buffer not empty\n");
1314 ret = AVERROR_UNKNOWN;
1315 goto cleanup;
1316 }
1317
1318 av_log(h, AV_LOG_VERBOSE, "Re-negotiating security context\n");
1319 ret = tls_handshake_loop(h, 0);
1320 if (ret < 0) {
1321 goto cleanup;
1322 }
1323 sspi_ret = SEC_E_OK;
1324
1325 /* if somehow any send data was left, it is now invalid */
1326 av_freep(&c->send_buf);
1327 c->send_buf_size = c->send_buf_offset = 0;
1328
1329 continue;
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;
1334 av_log(h, AV_LOG_VERBOSE, "Server closed the connection\n");
1335 }
1336 ret = 0;
1337 goto cleanup;
1338 }
1339 } else if (sspi_ret == SEC_E_INCOMPLETE_MESSAGE) {
1340 ret = AVERROR(EAGAIN);
1341 goto cleanup;
1342 } else {
1343 av_log(h, AV_LOG_ERROR, "Unable to decrypt message (error 0x%x)\n", (unsigned)sspi_ret);
1344 ret = AVERROR(EIO);
1345 goto cleanup;
1346 }
1347 }
1348
1349 ret = 0;
1350
1351 cleanup:
1352 size = FFMIN(len, c->dec_buf_offset);
1353 if (size) {
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;
1357
1358 return size;
1359 }
1360
1361 if (ret == 0 && !c->connection_closed)
1362 ret = AVERROR(EAGAIN);
1363
1364 return ret < 0 ? ret : AVERROR_EOF;
1365 }
1366
1367 static int tls_write(URLContext *h, const uint8_t *buf, int len)
1368 {
1369 TLSContext *c = h->priv_data;
1370 TLSShared *s = &c->tls_shared;
1371 URLContext *uc = s->is_dtls ? s->udp : s->tcp;
1372 SECURITY_STATUS sspi_ret;
1373 SecBuffer outbuf[4];
1374 SecBufferDesc outbuf_desc;
1375 int ret = 0;
1376
1377 uc->flags &= ~AVIO_FLAG_NONBLOCK;
1378 uc->flags |= h->flags & AVIO_FLAG_NONBLOCK;
1379
1380 ret = tls_process_send_buffer(h);
1381 if (ret < 0)
1382 return ret;
1383
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)
1387 return AVERROR_UNKNOWN;
1388 }
1389
1390 /* limit how much data we can consume */
1391 len = FFMIN(len, c->sizes.cbMaximumMessage - c->sizes.cbHeader - c->sizes.cbTrailer);
1392
1393 c->send_buf_size = c->sizes.cbHeader + len + c->sizes.cbTrailer;
1394 c->send_buf = av_malloc(c->send_buf_size);
1395 if (c->send_buf == NULL)
1396 return AVERROR(ENOMEM);
1397
1398 init_sec_buffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
1399 c->send_buf, c->sizes.cbHeader);
1400 init_sec_buffer(&outbuf[1], SECBUFFER_DATA,
1401 c->send_buf + c->sizes.cbHeader, len);
1402 init_sec_buffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
1403 c->send_buf + c->sizes.cbHeader + len,
1404 c->sizes.cbTrailer);
1405 init_sec_buffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
1406 init_sec_buffer_desc(&outbuf_desc, outbuf, 4);
1407
1408 memcpy(outbuf[1].pvBuffer, buf, len);
1409
1410 sspi_ret = EncryptMessage(&c->ctxt_handle, 0, &outbuf_desc, 0);
1411 if (sspi_ret != SEC_E_OK) {
1412 av_freep(&c->send_buf);
1413 av_log(h, AV_LOG_ERROR, "Encrypting data failed\n");
1414 if (sspi_ret == SEC_E_INSUFFICIENT_MEMORY)
1415 return AVERROR(ENOMEM);
1416 return AVERROR(EIO);
1417 }
1418
1419 c->send_buf_size = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
1420 c->send_buf_offset = 0;
1421
1422 ret = tls_process_send_buffer(h);
1423 if (ret == AVERROR(EAGAIN)) {
1424 /* We always need to signal that we consumed all (encrypted) data since schannel must not
1425 be fed the same data again. Sending will then be completed next call to this function,
1426 and EAGAIN returned until all remaining buffer is sent. */
1427 return outbuf[1].cbBuffer;
1428 } else if (ret < 0) {
1429 return ret;
1430 }
1431
1432 return outbuf[1].cbBuffer;
1433 }
1434
1435 static int tls_get_file_handle(URLContext *h)
1436 {
1437 TLSContext *c = h->priv_data;
1438 TLSShared *s = &c->tls_shared;
1439 return ffurl_get_file_handle(s->is_dtls ? s->udp : s->tcp);
1440 }
1441
1442 static int tls_get_short_seek(URLContext *h)
1443 {
1444 TLSContext *c = h->priv_data;
1445 TLSShared *s = &c->tls_shared;
1446 return ffurl_get_short_seek(s->is_dtls ? s->udp : s->tcp);
1447 }
1448
1449 #define OFFSET(x) offsetof(TLSContext, x)
1450 static const AVOption options[] = {
1451 TLS_COMMON_OPTIONS(TLSContext, tls_shared),
1452 { "cert_store_subject", "Load certificate (and associated key) from users keystore by subject",
1453 OFFSET(cert_store_subject), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL },
1454 { "cert_store_name", "Name of the specific cert store to search in (for cert_store_subject)",
1455 OFFSET(cert_store_name), AV_OPT_TYPE_STRING, { .str = "MY" }, .flags = TLS_OPTFL },
1456 { NULL }
1457 };
1458
1459 #if CONFIG_TLS_PROTOCOL
1460 static const AVClass tls_class = {
1461 .class_name = "tls",
1462 .item_name = av_default_item_name,
1463 .option = options,
1464 .version = LIBAVUTIL_VERSION_INT,
1465 };
1466
1467 const URLProtocol ff_tls_protocol = {
1468 .name = "tls",
1469 .url_open2 = tls_open,
1470 .url_read = tls_read,
1471 .url_write = tls_write,
1472 .url_close = tls_close,
1473 .url_get_file_handle = tls_get_file_handle,
1474 .url_get_short_seek = tls_get_short_seek,
1475 .priv_data_size = sizeof(TLSContext),
1476 .flags = URL_PROTOCOL_FLAG_NETWORK,
1477 .priv_data_class = &tls_class,
1478 };
1479 #endif
1480
1481 #if CONFIG_DTLS_PROTOCOL
1482 static const AVClass dtls_class = {
1483 .class_name = "dtls",
1484 .item_name = av_default_item_name,
1485 .option = options,
1486 .version = LIBAVUTIL_VERSION_INT,
1487 };
1488
1489 const URLProtocol ff_dtls_protocol = {
1490 .name = "dtls",
1491 .url_open2 = dtls_open,
1492 .url_handshake = tls_handshake,
1493 .url_close = tls_close,
1494 .url_read = tls_read,
1495 .url_write = tls_write,
1496 .url_get_file_handle = tls_get_file_handle,
1497 .url_get_short_seek = tls_get_short_seek,
1498 .priv_data_size = sizeof(TLSContext),
1499 .flags = URL_PROTOCOL_FLAG_NETWORK,
1500 .priv_data_class = &dtls_class,
1501 };
1502 #endif