aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c843
1 files changed, 598 insertions, 245 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 736bce323..9c05364ea 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -10,27 +10,19 @@
10//Config.src also defines FEATURE_TLS_SHA1 option 10//Config.src also defines FEATURE_TLS_SHA1 option
11 11
12//kbuild:lib-$(CONFIG_TLS) += tls.o 12//kbuild:lib-$(CONFIG_TLS) += tls.o
13//kbuild:lib-$(CONFIG_TLS) += tls_pstm.o 13//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm.o
14//kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o 14//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm_montgomery_reduce.o
15//kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o 15//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm_mul_comba.o
16//kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o 16//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_pstm_sqr_comba.o
17//kbuild:lib-$(CONFIG_TLS) += tls_aes.o 17//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_aes.o
18//kbuild:lib-$(CONFIG_TLS) += tls_aesgcm.o 18//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_aesgcm.o
19//kbuild:lib-$(CONFIG_TLS) += tls_rsa.o 19//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_rsa.o
20//kbuild:lib-$(CONFIG_TLS) += tls_fe.o 20//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_fe.o
21//kbuild:lib-$(CONFIG_TLS) += tls_sp_c32.o 21//kbuild:lib-$(CONFIG_FEATURE_TLS_INTERNAL) += tls_sp_c32.o
22 22
23#include "tls.h" 23#include "tls.h"
24 24
25#if ENABLE_FEATURE_USE_CNG_API 25#if !ENABLE_FEATURE_TLS_SCHANNEL
26# include <windows.h>
27# include <bcrypt.h>
28
29// these work on Windows >= 10
30# define BCRYPT_HMAC_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000a1)
31# define BCRYPT_HMAC_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000b1)
32#endif
33
34// Usually enabled. You can disable some of them to force only 26// Usually enabled. You can disable some of them to force only
35// specific ciphers to be advertized to server. 27// specific ciphers to be advertized to server.
36// (this would not exclude code to handle disabled ciphers, no code size win) 28// (this would not exclude code to handle disabled ciphers, no code size win)
@@ -197,8 +189,6 @@
197#define TLS_MAX_OUTBUF (1 << 14) 189#define TLS_MAX_OUTBUF (1 << 14)
198 190
199enum { 191enum {
200 SHA_INSIZE = 64,
201
202 AES128_KEYSIZE = 16, 192 AES128_KEYSIZE = 16,
203 AES256_KEYSIZE = 32, 193 AES256_KEYSIZE = 32,
204 194
@@ -344,34 +334,6 @@ void FAST_FUNC tls_get_random(void *buf, unsigned len)
344 xfunc_die(); 334 xfunc_die();
345} 335}
346 336
347static void xorbuf3(void *dst, const void *src1, const void *src2, unsigned count)
348{
349 uint8_t *d = dst;
350 const uint8_t *s1 = src1;
351 const uint8_t* s2 = src2;
352 while (count--)
353 *d++ = *s1++ ^ *s2++;
354}
355
356void FAST_FUNC xorbuf(void *dst, const void *src, unsigned count)
357{
358 xorbuf3(dst, dst, src, count);
359}
360
361void FAST_FUNC xorbuf_aligned_AES_BLOCK_SIZE(void *dst, const void *src)
362{
363 unsigned long *d = dst;
364 const unsigned long *s = src;
365 d[0] ^= s[0];
366#if ULONG_MAX <= 0xffffffffffffffff
367 d[1] ^= s[1];
368 #if ULONG_MAX == 0xffffffff
369 d[2] ^= s[2];
370 d[3] ^= s[3];
371 #endif
372#endif
373}
374
375#if !TLS_DEBUG_HASH 337#if !TLS_DEBUG_HASH
376# define hash_handshake(tls, fmt, buffer, len) \ 338# define hash_handshake(tls, fmt, buffer, len) \
377 hash_handshake(tls, buffer, len) 339 hash_handshake(tls, buffer, len)
@@ -402,191 +364,6 @@ static void hash_handshake(tls_state_t *tls, const char *fmt, const void *buffer
402# define TLS_MAC_SIZE(tls) (tls)->MAC_size 364# define TLS_MAC_SIZE(tls) (tls)->MAC_size
403#endif 365#endif
404 366
405// RFC 2104:
406// HMAC(key, text) based on a hash H (say, sha256) is:
407// ipad = [0x36 x INSIZE]
408// opad = [0x5c x INSIZE]
409// HMAC(key, text) = H((key XOR opad) + H((key XOR ipad) + text))
410//
411// H(key XOR opad) and H(key XOR ipad) can be precomputed
412// if we often need HMAC hmac with the same key.
413//
414// text is often given in disjoint pieces.
415#if !ENABLE_FEATURE_USE_CNG_API
416typedef struct hmac_precomputed {
417 md5sha_ctx_t hashed_key_xor_ipad;
418 md5sha_ctx_t hashed_key_xor_opad;
419} hmac_precomputed_t;
420
421typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC;
422
423#define sha1_begin_hmac sha1_begin
424#define sha256_begin_hmac sha256_begin
425#define hmac_uninit(...) ((void)0)
426
427#if !ENABLE_FEATURE_TLS_SHA1
428#define hmac_begin(pre,key,key_size,begin) \
429 hmac_begin(pre,key,key_size)
430#define begin sha256_begin
431#endif
432
433static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin)
434{
435 uint8_t key_xor_ipad[SHA_INSIZE];
436 uint8_t key_xor_opad[SHA_INSIZE];
437// uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE];
438 unsigned i;
439
440 // "The authentication key can be of any length up to INSIZE, the
441 // block length of the hash function. Applications that use keys longer
442 // than INSIZE bytes will first hash the key using H and then use the
443 // resultant OUTSIZE byte string as the actual key to HMAC."
444 if (key_size > SHA_INSIZE) {
445 bb_simple_error_msg_and_die("HMAC key>64"); //does not happen (yet?)
446// md5sha_ctx_t ctx;
447// begin(&ctx);
448// md5sha_hash(&ctx, key, key_size);
449// key_size = sha_end(&ctx, tempkey);
450// //key = tempkey; - right? RIGHT? why does it work without this?
451// // because SHA_INSIZE is 64, but hmac() is always called with
452// // key_size = tls->MAC_size = SHA1/256_OUTSIZE (20 or 32),
453// // and prf_hmac_sha256() -> hmac_sha256() key sizes are:
454// // - RSA_PREMASTER_SIZE is 48
455// // - CURVE25519_KEYSIZE is 32
456// // - master_secret[] is 48
457 }
458
459 for (i = 0; i < key_size; i++) {
460 key_xor_ipad[i] = key[i] ^ 0x36;
461 key_xor_opad[i] = key[i] ^ 0x5c;
462 }
463 for (; i < SHA_INSIZE; i++) {
464 key_xor_ipad[i] = 0x36;
465 key_xor_opad[i] = 0x5c;
466 }
467
468 begin(&pre->hashed_key_xor_ipad);
469 begin(&pre->hashed_key_xor_opad);
470 md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE);
471 md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE);
472}
473#undef begin
474
475static unsigned hmac_sha_precomputed_v(
476 hmac_precomputed_t *pre,
477 uint8_t *out,
478 va_list va)
479{
480 uint8_t *text;
481 unsigned len;
482
483 /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */
484 /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */
485
486 /* calculate out = H((key XOR ipad) + text) */
487 while ((text = va_arg(va, uint8_t*)) != NULL) {
488 unsigned text_size = va_arg(va, unsigned);
489 md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size);
490 }
491 len = sha_end(&pre->hashed_key_xor_ipad, out);
492
493 /* out = H((key XOR opad) + out) */
494 md5sha_hash(&pre->hashed_key_xor_opad, out, len);
495 return sha_end(&pre->hashed_key_xor_opad, out);
496}
497#else
498#define sha1_begin_hmac BCRYPT_HMAC_SHA1_ALG_HANDLE
499#define sha256_begin_hmac BCRYPT_HMAC_SHA256_ALG_HANDLE
500
501#if !ENABLE_FEATURE_TLS_SHA1
502#define hmac_begin(pre,key,key_size,begin) _hmac_begin(pre, key, key_size, sha256_begin_hmac)
503#else
504#define hmac_begin _hmac_begin
505#endif
506
507typedef struct bcrypt_hash_ctx_t hmac_precomputed_t;
508
509static void _hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, BCRYPT_ALG_HANDLE alg_handle) {
510 DWORD hash_object_length = 0;
511 ULONG _unused;
512 NTSTATUS status;
513
514 status = BCryptGetProperty(alg_handle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hash_object_length, sizeof(DWORD), &_unused, 0);
515 mingw_die_if_error(status, "BCryptGetProperty");
516 status = BCryptGetProperty(alg_handle, BCRYPT_HASH_LENGTH, (PUCHAR)&pre->output_size, sizeof(DWORD), &_unused, 0);
517 mingw_die_if_error(status, "BCryptGetProperty");
518
519
520 pre->hash_obj = xmalloc(hash_object_length);
521
522 status = BCryptCreateHash(alg_handle, &pre->handle, pre->hash_obj, hash_object_length, key, key_size, BCRYPT_HASH_REUSABLE_FLAG);
523 mingw_die_if_error(status, "BCryptCreateHash");
524}
525
526static unsigned hmac_sha_precomputed_v(
527 hmac_precomputed_t *pre,
528 uint8_t *out,
529 va_list va)
530{
531 uint8_t *text;
532 NTSTATUS status;
533
534 while ((text = va_arg(va, uint8_t*)) != NULL) {
535 unsigned text_size = va_arg(va, unsigned);
536 /*status = */ BCryptHashData(pre->handle, text, text_size, 0);
537 //mingw_die_if_error(status, "BCryptHashData");
538 }
539
540 status = BCryptFinishHash(pre->handle, out, pre->output_size, 0);
541 mingw_die_if_error(status, "BCryptFinishHash");
542
543 return pre->output_size;
544}
545
546static void hmac_uninit(hmac_precomputed_t *pre) {
547 BCryptDestroyHash(pre->handle);
548 free(pre->hash_obj);
549}
550
551#endif
552
553static unsigned hmac_sha_precomputed(hmac_precomputed_t *pre_init, uint8_t *out, ...)
554{
555 hmac_precomputed_t pre;
556 va_list va;
557 unsigned len;
558
559 va_start(va, out);
560 pre = *pre_init; /* struct copy */
561 len = hmac_sha_precomputed_v(&pre, out, va);
562 va_end(va);
563 return len;
564}
565
566#if !ENABLE_FEATURE_TLS_SHA1
567#define hmac(tls,out,key,key_size,...) \
568 hmac(out,key,key_size, __VA_ARGS__)
569#endif
570static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...)
571{
572 hmac_precomputed_t pre;
573 va_list va;
574 unsigned len;
575
576 va_start(va, key_size);
577
578 hmac_begin(&pre, key, key_size,
579 (ENABLE_FEATURE_TLS_SHA1 && tls->MAC_size == SHA1_OUTSIZE)
580 ? sha1_begin_hmac
581 : sha256_begin_hmac
582 );
583 len = hmac_sha_precomputed_v(&pre, out, va);
584
585 va_end(va);
586 hmac_uninit(&pre);
587 return len;
588}
589
590// RFC 5246: 367// RFC 5246:
591// 5. HMAC and the Pseudorandom Function 368// 5. HMAC and the Pseudorandom Function
592//... 369//...
@@ -631,7 +408,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
631 const char *label, 408 const char *label,
632 uint8_t *seed, unsigned seed_size) 409 uint8_t *seed, unsigned seed_size)
633{ 410{
634 hmac_precomputed_t pre; 411 hmac_ctx_t ctx;
635 uint8_t a[TLS_MAX_MAC_SIZE]; 412 uint8_t a[TLS_MAX_MAC_SIZE];
636 uint8_t *out_p = outbuf; 413 uint8_t *out_p = outbuf;
637 unsigned label_size = strlen(label); 414 unsigned label_size = strlen(label);
@@ -641,29 +418,28 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
641#define SEED label, label_size, seed, seed_size 418#define SEED label, label_size, seed, seed_size
642#define A a, MAC_size 419#define A a, MAC_size
643 420
644 hmac_begin(&pre, secret, secret_size, sha256_begin_hmac); 421 hmac_begin(&ctx, secret, secret_size, sha256_begin_hmac);
645 422
646 /* A(1) = HMAC_hash(secret, seed) */ 423 /* A(1) = HMAC_hash(secret, seed) */
647 hmac_sha_precomputed(&pre, a, SEED, NULL); 424 hmac_peek_hash(&ctx, a, SEED, NULL);
648 425
649 for (;;) { 426 for (;;) {
650 /* HMAC_hash(secret, A(1) + seed) */ 427 /* HMAC_hash(secret, A(1) + seed) */
651 if (outbuf_size <= MAC_size) { 428 if (outbuf_size <= MAC_size) {
652 /* Last, possibly incomplete, block */ 429 /* Last, possibly incomplete, block */
653 /* (use a[] as temp buffer) */ 430 /* (use a[] as temp buffer) */
654 hmac_sha_precomputed(&pre, a, A, SEED, NULL); 431 hmac_peek_hash(&ctx, a, A, SEED, NULL);
655 memcpy(out_p, a, outbuf_size); 432 memcpy(out_p, a, outbuf_size);
433 hmac_uninit(&ctx);
656 return; 434 return;
657 } 435 }
658 /* Not last block. Store directly to result buffer */ 436 /* Not last block. Store directly to result buffer */
659 hmac_sha_precomputed(&pre, out_p, A, SEED, NULL); 437 hmac_peek_hash(&ctx, out_p, A, SEED, NULL);
660 out_p += MAC_size; 438 out_p += MAC_size;
661 outbuf_size -= MAC_size; 439 outbuf_size -= MAC_size;
662 /* A(2) = HMAC_hash(secret, A(1)) */ 440 /* A(2) = HMAC_hash(secret, A(1)) */
663 hmac_sha_precomputed(&pre, a, A, NULL); 441 hmac_peek_hash(&ctx, a, A, NULL);
664 } 442 }
665
666 hmac_uninit(&pre);
667#undef A 443#undef A
668#undef SECRET 444#undef SECRET
669#undef SEED 445#undef SEED
@@ -729,6 +505,32 @@ static void *tls_get_zeroed_outbuf(tls_state_t *tls, int len)
729 return record; 505 return record;
730} 506}
731 507
508/* Calculate the HMAC over the list of blocks */
509#if !ENABLE_FEATURE_TLS_SHA1
510#define hmac_blocks(tls,out,key,key_size,...) \
511 hmac_blocks(out,key,key_size, __VA_ARGS__)
512#endif
513static unsigned hmac_blocks(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...)
514{
515 hmac_ctx_t ctx;
516 va_list va;
517 unsigned len;
518
519 hmac_begin(&ctx, key, key_size,
520 (ENABLE_FEATURE_TLS_SHA1 && tls->MAC_size == SHA1_OUTSIZE)
521 ? sha1_begin_hmac
522 : sha256_begin_hmac
523 );
524
525 va_start(va, key_size);
526 hmac_hash_v(&ctx, va);
527 va_end(va);
528
529 len = hmac_end(&ctx, out);
530 hmac_uninit(&ctx);
531 return len;
532}
533
732static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type) 534static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type)
733{ 535{
734 uint8_t *buf = tls->outbuf + OUTBUF_PFX; 536 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
@@ -750,7 +552,7 @@ static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, un
750 xhdr->len16_lo = size & 0xff; 552 xhdr->len16_lo = size & 0xff;
751 553
752 /* Calculate MAC signature */ 554 /* Calculate MAC signature */
753 hmac(tls, buf + size, /* result */ 555 hmac_blocks(tls, buf + size, /* result */
754 tls->client_write_MAC_key, TLS_MAC_SIZE(tls), 556 tls->client_write_MAC_key, TLS_MAC_SIZE(tls),
755 &tls->write_seq64_be, sizeof(tls->write_seq64_be), 557 &tls->write_seq64_be, sizeof(tls->write_seq64_be),
756 xhdr, RECHDR_LEN, 558 xhdr, RECHDR_LEN,
@@ -939,8 +741,13 @@ static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned ty
939 cnt++; 741 cnt++;
940 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 742 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
941 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); 743 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch);
942 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 744 if (remaining >= AES_BLOCK_SIZE) {
943 xorbuf(buf, scratch, n); 745 n = AES_BLOCK_SIZE;
746 xorbuf_AES_BLOCK_SIZE(buf, scratch);
747 } else {
748 n = remaining;
749 xorbuf(buf, scratch, n);
750 }
944 buf += n; 751 buf += n;
945 remaining -= n; 752 remaining -= n;
946 } 753 }
@@ -1098,7 +905,7 @@ static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size)
1098 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 905 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
1099 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch); 906 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch);
1100 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 907 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining;
1101 xorbuf3(buf, scratch, buf + 8, n); 908 xorbuf_3(buf, scratch, buf + 8, n);
1102 buf += n; 909 buf += n;
1103 remaining -= n; 910 remaining -= n;
1104 } 911 }
@@ -2555,3 +2362,549 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
2555 } 2362 }
2556 } 2363 }
2557} 2364}
2365#else
2366
2367#if ENABLE_FEATURE_TLS_SCHANNEL_1_3
2368#include <subauth.h>
2369#endif
2370
2371#define SCHANNEL_USE_BLACKLISTS
2372
2373#include <security.h>
2374#include <schannel.h>
2375
2376
2377#define BB_SCHANNEL_ISC_FLAGS \
2378 (ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | \
2379 ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS)
2380
2381static char *hresult_to_error_string(HRESULT result) {
2382 char *output = NULL;
2383
2384 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
2385 | FORMAT_MESSAGE_IGNORE_INSERTS |
2386 FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, result,
2387 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2388 (char *) &output, 0, NULL);
2389 return output;
2390}
2391
2392static ssize_t tls_read(struct tls_state *state, char *buf, ssize_t len) {
2393 ssize_t amount_read = 0;
2394
2395 if (state->closed) {
2396 return 0;
2397 }
2398
2399 while (len > 0) {
2400 if (state->out_buffer && (state->out_buffer_size > 0)) {
2401 unsigned long copy_amount =
2402 min(len, (ssize_t) state->out_buffer_size);
2403 memcpy(buf, state->out_buffer, copy_amount);
2404
2405 amount_read += copy_amount;
2406 buf += copy_amount;
2407 len -= copy_amount;
2408
2409 if (copy_amount == state->out_buffer_size) {
2410 // We've used all the decrypted data
2411 // Move extra data to the front
2412 memmove(state->in_buffer,
2413 state->in_buffer + state->out_buffer_used,
2414 state->in_buffer_size - state->out_buffer_used);
2415 state->in_buffer_size -= state->out_buffer_used;
2416
2417 state->out_buffer = NULL;
2418 state->out_buffer_used = 0;
2419 state->out_buffer_size = 0;
2420 } else {
2421 state->out_buffer_size -= copy_amount;
2422 state->out_buffer += copy_amount;
2423 }
2424 } else {
2425 SECURITY_STATUS status;
2426
2427 int received;
2428
2429 SecBuffer buffers[4];
2430
2431 SecBufferDesc desc;
2432
2433 buffers[0].BufferType = SECBUFFER_DATA;
2434 buffers[0].pvBuffer = state->in_buffer;
2435 buffers[0].cbBuffer = state->in_buffer_size;
2436
2437 buffers[1].BufferType = SECBUFFER_EMPTY;
2438 buffers[1].pvBuffer = NULL;
2439 buffers[1].cbBuffer = 0;
2440
2441 buffers[2].BufferType = SECBUFFER_EMPTY;
2442 buffers[2].pvBuffer = NULL;
2443 buffers[2].cbBuffer = 0;
2444
2445 buffers[3].BufferType = SECBUFFER_EMPTY;
2446 buffers[3].pvBuffer = NULL;
2447 buffers[3].cbBuffer = 0;
2448
2449 desc.ulVersion = SECBUFFER_VERSION;
2450 desc.pBuffers = buffers;
2451 desc.cBuffers = _countof(buffers);
2452
2453 status = DecryptMessage(&state->ctx_handle, &desc, 0, NULL);
2454
2455 switch (status) {
2456 case SEC_E_OK:{
2457 state->out_buffer = buffers[1].pvBuffer;
2458 state->out_buffer_size = buffers[1].cbBuffer;
2459
2460 state->out_buffer_used = state->in_buffer_size;
2461 if (buffers[3].BufferType == SECBUFFER_EXTRA) {
2462 state->out_buffer_used -= buffers[3].cbBuffer;
2463 }
2464
2465 continue;
2466 }
2467 case SEC_I_CONTEXT_EXPIRED:{
2468 state->closed = 1;
2469 goto Success;
2470 }
2471 case SEC_I_RENEGOTIATE:{
2472 // Renegotiate the TLS connection.
2473 // Microsoft repurposed this flag
2474 // for TLS 1.3 support.
2475 int i;
2476
2477 DWORD flags;
2478
2479 SecBuffer in_buffers[2];
2480
2481 SecBuffer out_buffers[2];
2482
2483 SecBufferDesc in_desc;
2484
2485 SecBufferDesc out_desc;
2486
2487
2488 for (i = 0; i < 4; i++) {
2489 if (buffers[i].BufferType == SECBUFFER_EXTRA)
2490 break;
2491 }
2492
2493 flags = BB_SCHANNEL_ISC_FLAGS;
2494
2495 in_buffers[0].BufferType = SECBUFFER_TOKEN;
2496 in_buffers[0].pvBuffer = buffers[i].pvBuffer;
2497 in_buffers[0].cbBuffer = buffers[i].cbBuffer;
2498
2499 in_buffers[1].BufferType = SECBUFFER_EMPTY;
2500 in_buffers[1].pvBuffer = NULL;
2501 in_buffers[1].cbBuffer = 0;
2502
2503 out_buffers[0].BufferType = SECBUFFER_TOKEN;
2504 out_buffers[0].pvBuffer = NULL;
2505 out_buffers[0].cbBuffer = 0;
2506
2507 out_buffers[1].BufferType = SECBUFFER_ALERT;
2508 out_buffers[1].pvBuffer = NULL;
2509 out_buffers[1].cbBuffer = 0;
2510
2511 in_desc.ulVersion = SECBUFFER_VERSION;
2512 in_desc.pBuffers = in_buffers;
2513 in_desc.cBuffers = _countof(in_buffers);
2514
2515 out_desc.ulVersion = SECBUFFER_VERSION;
2516 out_desc.pBuffers = out_buffers;
2517 out_desc.cBuffers = _countof(out_buffers);
2518
2519 status = InitializeSecurityContext(&state->cred_handle,
2520 state->initialized ?
2521 &state->ctx_handle : NULL,
2522 state->initialized ? NULL :
2523 state->hostname, flags, 0,
2524 0,
2525 state->initialized ?
2526 &in_desc : NULL, 0,
2527 state->initialized ? NULL :
2528 &state->ctx_handle,
2529 &out_desc, &flags, 0);
2530
2531 if (status != SEC_E_OK) {
2532 bb_error_msg_and_die("schannel: renegotiate failed: (0x%08lx): %s",
2533 status, hresult_to_error_string(status));
2534 }
2535
2536 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) {
2537 memmove(state->in_buffer,
2538 state->in_buffer + (state->in_buffer_size -
2539 in_buffers[1].cbBuffer),
2540 in_buffers[1].cbBuffer);
2541 }
2542
2543 state->out_buffer_used =
2544 state->in_buffer_size - in_buffers[1].cbBuffer;
2545 state->in_buffer_size = in_buffers[1].cbBuffer;
2546
2547 continue;
2548 }
2549 case SEC_E_INCOMPLETE_MESSAGE:{
2550 break;
2551 }
2552 default:{
2553 bb_error_msg_and_die("schannel: DecryptMessage failed: (0x%08lx): %s", status,
2554 hresult_to_error_string(status));
2555 }
2556 }
2557
2558 received =
2559 safe_read(state->ifd,
2560 state->in_buffer + state->in_buffer_size,
2561 sizeof(state->in_buffer) - state->in_buffer_size);
2562 if (received == 0) {
2563 state->closed = 1;
2564 goto Success;
2565 } else if (received < 0) {
2566 bb_error_msg_and_die("schannel: read() failed");
2567 }
2568
2569 state->in_buffer_size += received;
2570 }
2571 }
2572
2573 Success:
2574 return amount_read;
2575}
2576
2577static void tls_write(struct tls_state *state, char *buf, size_t len) {
2578 if (state->closed) {
2579 bb_error_msg_and_die("schannel: attempted to write to a closed connection");
2580 }
2581
2582 while (len > 0) {
2583 unsigned long copy_amount =
2584 min(len, (size_t) state->stream_sizes.cbMaximumMessage);
2585 char *write_buffer = _alloca(sizeof(state->in_buffer));
2586
2587 SECURITY_STATUS status;
2588
2589 SecBuffer buffers[4];
2590
2591 SecBufferDesc desc;
2592
2593 buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
2594 buffers[0].pvBuffer = write_buffer;
2595 buffers[0].cbBuffer = state->stream_sizes.cbHeader;
2596
2597 buffers[1].BufferType = SECBUFFER_DATA;
2598 buffers[1].pvBuffer = write_buffer + state->stream_sizes.cbHeader;
2599 buffers[1].cbBuffer = copy_amount;
2600
2601 buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
2602 buffers[2].pvBuffer =
2603 write_buffer + state->stream_sizes.cbHeader + copy_amount;
2604 buffers[2].cbBuffer = state->stream_sizes.cbTrailer;
2605
2606 buffers[3].BufferType = SECBUFFER_EMPTY;
2607 buffers[3].pvBuffer = NULL;
2608 buffers[3].cbBuffer = 0;
2609
2610 memcpy(buffers[1].pvBuffer, buf, copy_amount);
2611
2612 desc.ulVersion = SECBUFFER_VERSION;
2613 desc.pBuffers = buffers;
2614 desc.cBuffers = _countof(buffers);
2615
2616 status = EncryptMessage(&state->ctx_handle, 0, &desc, 0);
2617 if (status != SEC_E_OK) {
2618 bb_error_msg_and_die("schannel: EncryptMessage failed: (0x%08lx): %s", status,
2619 hresult_to_error_string(status));
2620 }
2621
2622 xwrite(state->ofd, write_buffer,
2623 buffers[0].cbBuffer + buffers[1].cbBuffer +
2624 buffers[2].cbBuffer);
2625
2626 len -= copy_amount;
2627 }
2628}
2629
2630static void tls_disconnect(tls_state_t * state) {
2631 SECURITY_STATUS status;
2632 DWORD token = SCHANNEL_SHUTDOWN;
2633 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2634
2635 SecBuffer buf_token;
2636
2637 SecBufferDesc buf_token_desc;
2638
2639 SecBuffer in_buffers[2];
2640 SecBuffer out_buffers[2];
2641
2642 SecBufferDesc in_desc;
2643 SecBufferDesc out_desc;
2644
2645 buf_token.BufferType = SECBUFFER_TOKEN;
2646 buf_token.pvBuffer = &token;
2647 buf_token.cbBuffer = sizeof(token);
2648
2649 buf_token_desc.ulVersion = SECBUFFER_VERSION;
2650 buf_token_desc.pBuffers = &buf_token;
2651 buf_token_desc.cBuffers = 1;
2652
2653 ApplyControlToken(&state->ctx_handle, &buf_token_desc);
2654
2655 // attempt to send any final data
2656
2657 in_buffers[0].BufferType = SECBUFFER_TOKEN;
2658 in_buffers[0].pvBuffer = state->in_buffer;
2659 in_buffers[0].cbBuffer = state->in_buffer_size;
2660
2661 in_buffers[1].BufferType = SECBUFFER_EMPTY;
2662 in_buffers[1].pvBuffer = NULL;
2663 in_buffers[1].cbBuffer = 0;
2664
2665 out_buffers[0].BufferType = SECBUFFER_TOKEN;
2666 out_buffers[0].pvBuffer = NULL;
2667 out_buffers[0].cbBuffer = 0;
2668
2669 out_buffers[1].BufferType = SECBUFFER_ALERT;
2670 out_buffers[1].pvBuffer = NULL;
2671 out_buffers[1].cbBuffer = 0;
2672
2673 in_desc.ulVersion = SECBUFFER_VERSION;
2674 in_desc.pBuffers = in_buffers;
2675 in_desc.cBuffers = _countof(in_buffers);
2676
2677 out_desc.ulVersion = SECBUFFER_VERSION;
2678 out_desc.pBuffers = out_buffers;
2679 out_desc.cBuffers = _countof(out_buffers);
2680
2681 status = InitializeSecurityContext(&state->cred_handle,
2682 state->
2683 initialized ? &state->ctx_handle :
2684 NULL,
2685 state->
2686 initialized ? NULL : state->hostname,
2687 flags, 0, 0,
2688 state->initialized ? &in_desc : NULL,
2689 0,
2690 state->
2691 initialized ? NULL :
2692 &state->ctx_handle, &out_desc, &flags,
2693 0);
2694
2695 if (status == SEC_E_OK) {
2696 // attempt to write any extra data
2697 write(state->ofd, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
2698 }
2699
2700 DeleteSecurityContext(&state->ctx_handle);
2701 FreeCredentialsHandle(&state->cred_handle);
2702 free(state->hostname);
2703}
2704
2705
2706void FAST_FUNC tls_handshake(tls_state_t * state, const char *hostname) {
2707 SECURITY_STATUS status;
2708 int received;
2709
2710#if ENABLE_FEATURE_TLS_SCHANNEL_1_3
2711 SCH_CREDENTIALS credential = {.dwVersion = SCH_CREDENTIALS_VERSION,
2712 .dwCredFormat = 0,
2713 .cCreds = 0,
2714 .paCred = NULL,
2715 .hRootStore = NULL,
2716 .cMappers = 0,
2717 .aphMappers = NULL,
2718 .dwSessionLifespan = 0,
2719 .dwFlags =
2720 SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
2721 SCH_USE_STRONG_CRYPTO,
2722 .cTlsParameters = 0,
2723 .pTlsParameters = NULL
2724 };
2725#else
2726 SCHANNEL_CRED credential = {.dwVersion = SCHANNEL_CRED_VERSION,
2727 .cCreds = 0,
2728 .paCred = NULL,
2729 .hRootStore = NULL,
2730 .cMappers = 0,
2731 .aphMappers = NULL,
2732 .cSupportedAlgs = 0,
2733 .palgSupportedAlgs = NULL,
2734 .grbitEnabledProtocols =
2735 SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_1_CLIENT |
2736 SP_PROT_TLS1_2_CLIENT,
2737 .dwMinimumCipherStrength = 0,
2738 .dwMaximumCipherStrength = 0,
2739 .dwSessionLifespan = 0,
2740 .dwFlags =
2741 SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
2742 SCH_USE_STRONG_CRYPTO,
2743 .dwCredFormat = 0
2744 };
2745#endif
2746
2747 if ((status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *) UNISP_NAME_A,
2748 SECPKG_CRED_OUTBOUND, NULL,
2749 &credential,
2750 NULL, NULL, &state->cred_handle,
2751 NULL)) != SEC_E_OK) {
2752 bb_error_msg_and_die("schannel: AcquireCredentialsHandleA failed: (0x%08lx): %s",
2753 status, hresult_to_error_string(status));
2754 }
2755
2756 state->in_buffer_size = 0;
2757 state->out_buffer_size = 0;
2758 state->out_buffer_used = 0;
2759
2760 state->out_buffer = NULL;
2761
2762 state->hostname = strdup(hostname);
2763
2764 state->initialized = 0;
2765 state->closed = 0;
2766
2767 while (1) {
2768 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2769
2770 SecBuffer in_buffers[2];
2771 SecBuffer out_buffers[2];
2772
2773 SecBufferDesc in_desc;
2774 SecBufferDesc out_desc;
2775
2776 in_buffers[0].BufferType = SECBUFFER_TOKEN;
2777 in_buffers[0].pvBuffer = state->in_buffer;
2778 in_buffers[0].cbBuffer = state->in_buffer_size;
2779
2780 in_buffers[1].BufferType = SECBUFFER_EMPTY;
2781 in_buffers[1].pvBuffer = NULL;
2782 in_buffers[1].cbBuffer = 0;
2783
2784 out_buffers[0].BufferType = SECBUFFER_TOKEN;
2785 out_buffers[0].pvBuffer = NULL;
2786 out_buffers[0].cbBuffer = 0;
2787
2788 out_buffers[1].BufferType = SECBUFFER_ALERT;
2789 out_buffers[1].pvBuffer = NULL;
2790 out_buffers[1].cbBuffer = 0;
2791
2792 in_desc.ulVersion = SECBUFFER_VERSION;
2793 in_desc.pBuffers = in_buffers;
2794 in_desc.cBuffers = _countof(in_buffers);
2795
2796 out_desc.ulVersion = SECBUFFER_VERSION;
2797 out_desc.pBuffers = out_buffers;
2798 out_desc.cBuffers = _countof(out_buffers);
2799
2800 status = InitializeSecurityContext(&state->cred_handle,
2801 state->
2802 initialized ? &state->ctx_handle :
2803 NULL,
2804 state->
2805 initialized ? NULL :
2806 state->hostname, flags, 0, 0,
2807 state->initialized ? &in_desc :
2808 NULL, 0,
2809 state->initialized ? NULL :
2810 &state->ctx_handle, &out_desc,
2811 &flags, 0);
2812
2813 state->initialized = 1;
2814
2815 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) {
2816 memmove(state->in_buffer,
2817 state->in_buffer + (state->in_buffer_size -
2818 in_buffers[1].cbBuffer),
2819 in_buffers[1].cbBuffer);
2820 state->in_buffer_size = in_buffers[1].cbBuffer;
2821 } else if (status != SEC_E_INCOMPLETE_MESSAGE) {
2822 state->in_buffer_size = 0;
2823 }
2824
2825 switch (status) {
2826 case SEC_E_OK:{
2827 if (out_buffers[0].cbBuffer > 0) {
2828 xwrite(state->ofd, out_buffers[0].pvBuffer,
2829 out_buffers[0].cbBuffer);
2830 FreeContextBuffer(out_buffers[0].pvBuffer);
2831 }
2832 goto Success;
2833 }
2834 case SEC_I_CONTINUE_NEEDED:{
2835 xwrite(state->ofd, out_buffers[0].pvBuffer,
2836 out_buffers[0].cbBuffer);
2837 FreeContextBuffer(out_buffers[0].pvBuffer);
2838 break;
2839 }
2840 case SEC_I_INCOMPLETE_CREDENTIALS:{
2841 // we don't support this
2842 bb_error_msg_and_die("schannel: client certificates not supported");
2843 }
2844 case SEC_E_INCOMPLETE_MESSAGE:{
2845 break;
2846 }
2847 default:{
2848 bb_error_msg_and_die("schannel: handshake failed: (0x%08lx): %s",
2849 status, hresult_to_error_string(status));
2850 }
2851 }
2852
2853 received =
2854 safe_read(state->ifd, state->in_buffer + state->in_buffer_size,
2855 sizeof(state->in_buffer) - state->in_buffer_size);
2856 if (received <= 0) {
2857 bb_error_msg_and_die("schannel: handshake read() failed");
2858 }
2859 state->in_buffer_size += received;
2860 }
2861
2862 Success:
2863 QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_STREAM_SIZES,
2864 &state->stream_sizes);
2865
2866 //SecPkgContext_ConnectionInfo info;
2867 //QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_CONNECTION_INFO,
2868 // &info);
2869 //
2870 //fprintf(stderr, "TLS 1.%d\n", (((uint32_t)(8 * sizeof(unsigned long long) - __builtin_clzll((info.dwProtocol)) - 1)) - 7)/2);
2871}
2872
2873void FAST_FUNC tls_run_copy_loop(tls_state_t * tls, unsigned flags) {
2874 char buffer[65536];
2875
2876 struct pollfd pfds[2];
2877
2878 pfds[0].fd = STDIN_FILENO;
2879 pfds[0].events = POLLIN;
2880 pfds[1].fd = tls->ifd;
2881 pfds[1].events = POLLIN;
2882
2883 for (;;) {
2884 int nread;
2885
2886 if (safe_poll(pfds, 2, -1) < 0)
2887 bb_simple_perror_msg_and_die("poll");
2888
2889 if (pfds[0].revents) {
2890 nread = safe_read(STDIN_FILENO, buffer, sizeof(buffer));
2891 if (nread < 1) {
2892 pfds[0].fd = -1;
2893 tls_disconnect(tls);
2894 if (flags & TLSLOOP_EXIT_ON_LOCAL_EOF)
2895 break;
2896 } else {
2897 tls_write(tls, buffer, nread);
2898 }
2899 }
2900 if (pfds[1].revents) {
2901 nread = tls_read(tls, buffer, sizeof(buffer));
2902 if (nread < 1) {
2903 tls_disconnect(tls);
2904 break;
2905 }
2906 xwrite(STDOUT_FILENO, buffer, nread);
2907 }
2908 }
2909}
2910#endif