aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--networking/tls.c695
1 files changed, 524 insertions, 171 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 9f1dd67ec..a28e87295 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -10,18 +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_TLS_SCHANNEL
25// Usually enabled. You can disable some of them to force only 26// Usually enabled. You can disable some of them to force only
26// specific ciphers to be advertized to server. 27// specific ciphers to be advertized to server.
27// (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)
@@ -188,8 +189,6 @@
188#define TLS_MAX_OUTBUF (1 << 14) 189#define TLS_MAX_OUTBUF (1 << 14)
189 190
190enum { 191enum {
191 SHA_INSIZE = 64,
192
193 AES128_KEYSIZE = 16, 192 AES128_KEYSIZE = 16,
194 AES256_KEYSIZE = 32, 193 AES256_KEYSIZE = 32,
195 194
@@ -335,34 +334,6 @@ void FAST_FUNC tls_get_random(void *buf, unsigned len)
335 xfunc_die(); 334 xfunc_die();
336} 335}
337 336
338static void xorbuf3(void *dst, const void *src1, const void *src2, unsigned count)
339{
340 uint8_t *d = dst;
341 const uint8_t *s1 = src1;
342 const uint8_t* s2 = src2;
343 while (count--)
344 *d++ = *s1++ ^ *s2++;
345}
346
347void FAST_FUNC xorbuf(void *dst, const void *src, unsigned count)
348{
349 xorbuf3(dst, dst, src, count);
350}
351
352void FAST_FUNC xorbuf_aligned_AES_BLOCK_SIZE(void *dst, const void *src)
353{
354 unsigned long *d = dst;
355 const unsigned long *s = src;
356 d[0] ^= s[0];
357#if ULONG_MAX <= 0xffffffffffffffff
358 d[1] ^= s[1];
359 #if ULONG_MAX == 0xffffffff
360 d[2] ^= s[2];
361 d[3] ^= s[3];
362 #endif
363#endif
364}
365
366#if !TLS_DEBUG_HASH 337#if !TLS_DEBUG_HASH
367# define hash_handshake(tls, fmt, buffer, len) \ 338# define hash_handshake(tls, fmt, buffer, len) \
368 hash_handshake(tls, buffer, len) 339 hash_handshake(tls, buffer, len)
@@ -393,128 +364,6 @@ static void hash_handshake(tls_state_t *tls, const char *fmt, const void *buffer
393# define TLS_MAC_SIZE(tls) (tls)->MAC_size 364# define TLS_MAC_SIZE(tls) (tls)->MAC_size
394#endif 365#endif
395 366
396// RFC 2104:
397// HMAC(key, text) based on a hash H (say, sha256) is:
398// ipad = [0x36 x INSIZE]
399// opad = [0x5c x INSIZE]
400// HMAC(key, text) = H((key XOR opad) + H((key XOR ipad) + text))
401//
402// H(key XOR opad) and H(key XOR ipad) can be precomputed
403// if we often need HMAC hmac with the same key.
404//
405// text is often given in disjoint pieces.
406typedef struct hmac_precomputed {
407 md5sha_ctx_t hashed_key_xor_ipad;
408 md5sha_ctx_t hashed_key_xor_opad;
409} hmac_precomputed_t;
410
411typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC;
412#if !ENABLE_FEATURE_TLS_SHA1
413#define hmac_begin(pre,key,key_size,begin) \
414 hmac_begin(pre,key,key_size)
415#define begin sha256_begin
416#endif
417static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin)
418{
419 uint8_t key_xor_ipad[SHA_INSIZE];
420 uint8_t key_xor_opad[SHA_INSIZE];
421// uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE];
422 unsigned i;
423
424 // "The authentication key can be of any length up to INSIZE, the
425 // block length of the hash function. Applications that use keys longer
426 // than INSIZE bytes will first hash the key using H and then use the
427 // resultant OUTSIZE byte string as the actual key to HMAC."
428 if (key_size > SHA_INSIZE) {
429 bb_simple_error_msg_and_die("HMAC key>64"); //does not happen (yet?)
430// md5sha_ctx_t ctx;
431// begin(&ctx);
432// md5sha_hash(&ctx, key, key_size);
433// key_size = sha_end(&ctx, tempkey);
434// //key = tempkey; - right? RIGHT? why does it work without this?
435// // because SHA_INSIZE is 64, but hmac() is always called with
436// // key_size = tls->MAC_size = SHA1/256_OUTSIZE (20 or 32),
437// // and prf_hmac_sha256() -> hmac_sha256() key sizes are:
438// // - RSA_PREMASTER_SIZE is 48
439// // - CURVE25519_KEYSIZE is 32
440// // - master_secret[] is 48
441 }
442
443 for (i = 0; i < key_size; i++) {
444 key_xor_ipad[i] = key[i] ^ 0x36;
445 key_xor_opad[i] = key[i] ^ 0x5c;
446 }
447 for (; i < SHA_INSIZE; i++) {
448 key_xor_ipad[i] = 0x36;
449 key_xor_opad[i] = 0x5c;
450 }
451
452 begin(&pre->hashed_key_xor_ipad);
453 begin(&pre->hashed_key_xor_opad);
454 md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE);
455 md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE);
456}
457#undef begin
458
459static unsigned hmac_sha_precomputed_v(
460 hmac_precomputed_t *pre,
461 uint8_t *out,
462 va_list va)
463{
464 uint8_t *text;
465 unsigned len;
466
467 /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */
468 /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */
469
470 /* calculate out = H((key XOR ipad) + text) */
471 while ((text = va_arg(va, uint8_t*)) != NULL) {
472 unsigned text_size = va_arg(va, unsigned);
473 md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size);
474 }
475 len = sha_end(&pre->hashed_key_xor_ipad, out);
476
477 /* out = H((key XOR opad) + out) */
478 md5sha_hash(&pre->hashed_key_xor_opad, out, len);
479 return sha_end(&pre->hashed_key_xor_opad, out);
480}
481
482static unsigned hmac_sha_precomputed(hmac_precomputed_t *pre_init, uint8_t *out, ...)
483{
484 hmac_precomputed_t pre;
485 va_list va;
486 unsigned len;
487
488 va_start(va, out);
489 pre = *pre_init; /* struct copy */
490 len = hmac_sha_precomputed_v(&pre, out, va);
491 va_end(va);
492 return len;
493}
494
495#if !ENABLE_FEATURE_TLS_SHA1
496#define hmac(tls,out,key,key_size,...) \
497 hmac(out,key,key_size, __VA_ARGS__)
498#endif
499static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...)
500{
501 hmac_precomputed_t pre;
502 va_list va;
503 unsigned len;
504
505 va_start(va, key_size);
506
507 hmac_begin(&pre, key, key_size,
508 (ENABLE_FEATURE_TLS_SHA1 && tls->MAC_size == SHA1_OUTSIZE)
509 ? sha1_begin
510 : sha256_begin
511 );
512 len = hmac_sha_precomputed_v(&pre, out, va);
513
514 va_end(va);
515 return len;
516}
517
518// RFC 5246: 367// RFC 5246:
519// 5. HMAC and the Pseudorandom Function 368// 5. HMAC and the Pseudorandom Function
520//... 369//...
@@ -559,7 +408,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
559 const char *label, 408 const char *label,
560 uint8_t *seed, unsigned seed_size) 409 uint8_t *seed, unsigned seed_size)
561{ 410{
562 hmac_precomputed_t pre; 411 hmac_ctx_t ctx;
563 uint8_t a[TLS_MAX_MAC_SIZE]; 412 uint8_t a[TLS_MAX_MAC_SIZE];
564 uint8_t *out_p = outbuf; 413 uint8_t *out_p = outbuf;
565 unsigned label_size = strlen(label); 414 unsigned label_size = strlen(label);
@@ -569,26 +418,27 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
569#define SEED label, label_size, seed, seed_size 418#define SEED label, label_size, seed, seed_size
570#define A a, MAC_size 419#define A a, MAC_size
571 420
572 hmac_begin(&pre, secret, secret_size, sha256_begin); 421 hmac_begin(&ctx, secret, secret_size, sha256_begin_hmac);
573 422
574 /* A(1) = HMAC_hash(secret, seed) */ 423 /* A(1) = HMAC_hash(secret, seed) */
575 hmac_sha_precomputed(&pre, a, SEED, NULL); 424 hmac_peek_hash(&ctx, a, SEED, NULL);
576 425
577 for (;;) { 426 for (;;) {
578 /* HMAC_hash(secret, A(1) + seed) */ 427 /* HMAC_hash(secret, A(1) + seed) */
579 if (outbuf_size <= MAC_size) { 428 if (outbuf_size <= MAC_size) {
580 /* Last, possibly incomplete, block */ 429 /* Last, possibly incomplete, block */
581 /* (use a[] as temp buffer) */ 430 /* (use a[] as temp buffer) */
582 hmac_sha_precomputed(&pre, a, A, SEED, NULL); 431 hmac_peek_hash(&ctx, a, A, SEED, NULL);
583 memcpy(out_p, a, outbuf_size); 432 memcpy(out_p, a, outbuf_size);
433 hmac_uninit(&ctx);
584 return; 434 return;
585 } 435 }
586 /* Not last block. Store directly to result buffer */ 436 /* Not last block. Store directly to result buffer */
587 hmac_sha_precomputed(&pre, out_p, A, SEED, NULL); 437 hmac_peek_hash(&ctx, out_p, A, SEED, NULL);
588 out_p += MAC_size; 438 out_p += MAC_size;
589 outbuf_size -= MAC_size; 439 outbuf_size -= MAC_size;
590 /* A(2) = HMAC_hash(secret, A(1)) */ 440 /* A(2) = HMAC_hash(secret, A(1)) */
591 hmac_sha_precomputed(&pre, a, A, NULL); 441 hmac_peek_hash(&ctx, a, A, NULL);
592 } 442 }
593#undef A 443#undef A
594#undef SECRET 444#undef SECRET
@@ -655,6 +505,32 @@ static void *tls_get_zeroed_outbuf(tls_state_t *tls, int len)
655 return record; 505 return record;
656} 506}
657 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
658static 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)
659{ 535{
660 uint8_t *buf = tls->outbuf + OUTBUF_PFX; 536 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
@@ -676,7 +552,7 @@ static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, un
676 xhdr->len16_lo = size & 0xff; 552 xhdr->len16_lo = size & 0xff;
677 553
678 /* Calculate MAC signature */ 554 /* Calculate MAC signature */
679 hmac(tls, buf + size, /* result */ 555 hmac_blocks(tls, buf + size, /* result */
680 tls->client_write_MAC_key, TLS_MAC_SIZE(tls), 556 tls->client_write_MAC_key, TLS_MAC_SIZE(tls),
681 &tls->write_seq64_be, sizeof(tls->write_seq64_be), 557 &tls->write_seq64_be, sizeof(tls->write_seq64_be),
682 xhdr, RECHDR_LEN, 558 xhdr, RECHDR_LEN,
@@ -865,8 +741,13 @@ static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned ty
865 cnt++; 741 cnt++;
866 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 742 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
867 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); 743 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch);
868 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 744 if (remaining >= AES_BLOCK_SIZE) {
869 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 }
870 buf += n; 751 buf += n;
871 remaining -= n; 752 remaining -= n;
872 } 753 }
@@ -1024,7 +905,7 @@ static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size)
1024 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 905 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
1025 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch); 906 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch);
1026 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 907 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining;
1027 xorbuf3(buf, scratch, buf + 8, n); 908 xorbuf_3(buf, scratch, buf + 8, n);
1028 buf += n; 909 buf += n;
1029 remaining -= n; 910 remaining -= n;
1030 } 911 }
@@ -2481,3 +2362,475 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
2481 } 2362 }
2482 } 2363 }
2483} 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 void init_sec_buffer(SecBuffer *buffer, void *pvBuffer, unsigned long cbBuffer, unsigned long BufferType) {
2393 buffer->BufferType = BufferType;
2394 buffer->cbBuffer = cbBuffer;
2395 buffer->pvBuffer = pvBuffer;
2396}
2397
2398static void init_sec_buffer_empty(SecBuffer *buffer, unsigned long BufferType) {
2399 init_sec_buffer(buffer, NULL, 0, BufferType);
2400}
2401
2402static void init_sec_buffer_desc(SecBufferDesc *desc, SecBuffer *buffers, unsigned long buffer_count) {
2403 desc->ulVersion = SECBUFFER_VERSION;
2404 desc->cBuffers = buffer_count;
2405 desc->pBuffers = buffers;
2406}
2407
2408static ssize_t tls_read(struct tls_state *state, char *buf, ssize_t len) {
2409 ssize_t amount_read = 0;
2410
2411 if (state->closed) {
2412 return 0;
2413 }
2414
2415 while (len > 0) {
2416 if (state->out_buffer && (state->out_buffer_size > 0)) {
2417 unsigned long copy_amount =
2418 min(len, (ssize_t) state->out_buffer_size);
2419 memcpy(buf, state->out_buffer, copy_amount);
2420
2421 amount_read += copy_amount;
2422 buf += copy_amount;
2423 len -= copy_amount;
2424
2425 if (copy_amount == state->out_buffer_size) {
2426 // We've used all the decrypted data
2427 // Move extra data to the front
2428 memmove(state->in_buffer,
2429 state->in_buffer + state->out_buffer_used,
2430 state->in_buffer_size - state->out_buffer_used);
2431 state->in_buffer_size -= state->out_buffer_used;
2432
2433 state->out_buffer = NULL;
2434 state->out_buffer_used = 0;
2435 state->out_buffer_size = 0;
2436 } else {
2437 state->out_buffer_size -= copy_amount;
2438 state->out_buffer += copy_amount;
2439 }
2440 } else {
2441 SECURITY_STATUS status;
2442 int received;
2443
2444 SecBuffer buffers[4];
2445 SecBufferDesc desc;
2446
2447 init_sec_buffer(&buffers[0], state->in_buffer, state->in_buffer_size, SECBUFFER_DATA);
2448 init_sec_buffer_empty(&buffers[1], SECBUFFER_EMPTY);
2449 init_sec_buffer_empty(&buffers[2], SECBUFFER_EMPTY);
2450 init_sec_buffer_empty(&buffers[3], SECBUFFER_EMPTY);
2451
2452 init_sec_buffer_desc(&desc, buffers, _countof(buffers));
2453
2454 status = DecryptMessage(&state->ctx_handle, &desc, 0, NULL);
2455
2456 switch (status) {
2457 case SEC_E_OK:{
2458 state->out_buffer = buffers[1].pvBuffer;
2459 state->out_buffer_size = buffers[1].cbBuffer;
2460
2461 state->out_buffer_used = state->in_buffer_size;
2462 if (buffers[3].BufferType == SECBUFFER_EXTRA) {
2463 state->out_buffer_used -= buffers[3].cbBuffer;
2464 }
2465
2466 continue;
2467 }
2468 case SEC_I_CONTEXT_EXPIRED:{
2469 state->closed = 1;
2470 goto Success;
2471 }
2472 case SEC_I_RENEGOTIATE:{
2473 // Renegotiate the TLS connection.
2474 // Microsoft repurposed this flag
2475 // for TLS 1.3 support.
2476 int i;
2477 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2478
2479 SecBuffer in_buffers[2];
2480 SecBuffer out_buffers[2];
2481
2482 SecBufferDesc in_desc;
2483 SecBufferDesc out_desc;
2484
2485 for (i = 0; i < 4; i++) {
2486 if (buffers[i].BufferType == SECBUFFER_EXTRA)
2487 break;
2488 }
2489
2490 init_sec_buffer(&in_buffers[0], buffers[i].pvBuffer, buffers[i].cbBuffer, SECBUFFER_TOKEN);
2491 init_sec_buffer_empty(&in_buffers[1], SECBUFFER_EMPTY);
2492
2493 init_sec_buffer_empty(&out_buffers[0], SECBUFFER_TOKEN);
2494 init_sec_buffer_empty(&out_buffers[1], SECBUFFER_ALERT);
2495
2496 init_sec_buffer_desc(&in_desc, in_buffers, _countof(in_buffers));
2497 init_sec_buffer_desc(&out_desc, out_buffers, _countof(out_buffers));
2498
2499 status = InitializeSecurityContext(&state->cred_handle,
2500 state->initialized ?
2501 &state->ctx_handle : NULL,
2502 state->initialized ? NULL :
2503 state->hostname, flags, 0,
2504 0,
2505 state->initialized ?
2506 &in_desc : NULL, 0,
2507 &state->ctx_handle,
2508 &out_desc, &flags, 0);
2509
2510 if (status != SEC_E_OK) {
2511 bb_error_msg_and_die("schannel: renegotiate failed: (0x%08lx): %s",
2512 status, hresult_to_error_string(status));
2513 }
2514
2515 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) {
2516 memmove(state->in_buffer,
2517 state->in_buffer + (state->in_buffer_size -
2518 in_buffers[1].cbBuffer),
2519 in_buffers[1].cbBuffer);
2520 }
2521
2522 state->out_buffer_used =
2523 state->in_buffer_size - in_buffers[1].cbBuffer;
2524 state->in_buffer_size = in_buffers[1].cbBuffer;
2525
2526 continue;
2527 }
2528 case SEC_E_INCOMPLETE_MESSAGE:{
2529 break;
2530 }
2531 default:{
2532 bb_error_msg_and_die("schannel: DecryptMessage failed: (0x%08lx): %s", status,
2533 hresult_to_error_string(status));
2534 }
2535 }
2536
2537 received =
2538 safe_read(state->ifd,
2539 state->in_buffer + state->in_buffer_size,
2540 sizeof(state->in_buffer) - state->in_buffer_size);
2541 if (received == 0) {
2542 state->closed = 1;
2543 goto Success;
2544 } else if (received < 0) {
2545 bb_error_msg_and_die("schannel: read() failed");
2546 }
2547
2548 state->in_buffer_size += received;
2549 }
2550 }
2551
2552 Success:
2553 return amount_read;
2554}
2555
2556static void tls_write(struct tls_state *state, char *buf, size_t len) {
2557 if (state->closed) {
2558 bb_error_msg_and_die("schannel: attempted to write to a closed connection");
2559 }
2560
2561 while (len > 0) {
2562 unsigned long copy_amount =
2563 min(len, (size_t) state->stream_sizes.cbMaximumMessage);
2564 char *write_buffer = _alloca(sizeof(state->in_buffer));
2565
2566 SECURITY_STATUS status;
2567
2568 SecBuffer buffers[4];
2569 SecBufferDesc desc;
2570
2571 init_sec_buffer(&buffers[0], write_buffer, state->stream_sizes.cbHeader, SECBUFFER_STREAM_HEADER);
2572 init_sec_buffer(&buffers[1], write_buffer + state->stream_sizes.cbHeader, copy_amount, SECBUFFER_DATA);
2573 init_sec_buffer(&buffers[2], write_buffer + state->stream_sizes.cbHeader + copy_amount, state->stream_sizes.cbTrailer, SECBUFFER_STREAM_TRAILER);
2574 init_sec_buffer_empty(&buffers[3], SECBUFFER_EMPTY);
2575
2576 init_sec_buffer_desc(&desc, buffers, _countof(buffers));
2577
2578 memcpy(buffers[1].pvBuffer, buf, copy_amount);
2579
2580 status = EncryptMessage(&state->ctx_handle, 0, &desc, 0);
2581 if (status != SEC_E_OK) {
2582 bb_error_msg_and_die("schannel: EncryptMessage failed: (0x%08lx): %s", status,
2583 hresult_to_error_string(status));
2584 }
2585
2586 xwrite(state->ofd, write_buffer,
2587 buffers[0].cbBuffer + buffers[1].cbBuffer +
2588 buffers[2].cbBuffer);
2589
2590 len -= copy_amount;
2591 }
2592}
2593
2594static void tls_disconnect(tls_state_t * state) {
2595 SECURITY_STATUS status;
2596 DWORD token = SCHANNEL_SHUTDOWN;
2597 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2598
2599 SecBuffer buf_token;
2600
2601 SecBufferDesc buf_token_desc;
2602
2603 SecBuffer in_buffers[2];
2604 SecBuffer out_buffers[2];
2605
2606 SecBufferDesc in_desc;
2607 SecBufferDesc out_desc;
2608
2609 init_sec_buffer(&buf_token, &token, sizeof(token), SECBUFFER_TOKEN);
2610 init_sec_buffer_desc(&buf_token_desc, &buf_token, 1);
2611
2612 ApplyControlToken(&state->ctx_handle, &buf_token_desc);
2613
2614 // attempt to send any final data
2615 init_sec_buffer(&in_buffers[0], state->in_buffer, state->in_buffer_size, SECBUFFER_TOKEN);
2616 init_sec_buffer_empty(&in_buffers[1], SECBUFFER_EMPTY);
2617
2618 init_sec_buffer_empty(&out_buffers[0], SECBUFFER_TOKEN);
2619 init_sec_buffer_empty(&out_buffers[1], SECBUFFER_ALERT);
2620
2621 init_sec_buffer_desc(&in_desc, in_buffers, _countof(in_buffers));
2622 init_sec_buffer_desc(&out_desc, out_buffers, _countof(out_buffers));
2623
2624 status = InitializeSecurityContext(&state->cred_handle,
2625 state->
2626 initialized ? &state->ctx_handle :
2627 NULL,
2628 state->
2629 initialized ? NULL : state->hostname,
2630 flags, 0, 0,
2631 state->initialized ? &in_desc : NULL,
2632 0,
2633 &state->ctx_handle, &out_desc, &flags,
2634 0);
2635
2636 if ((status == SEC_E_OK) || (status == SEC_I_CONTEXT_EXPIRED)) {
2637 // send the final shutdown message
2638 write(state->ofd, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
2639 FreeContextBuffer(out_buffers[0].pvBuffer);
2640 }
2641
2642 DeleteSecurityContext(&state->ctx_handle);
2643 FreeCredentialsHandle(&state->cred_handle);
2644 free(state->hostname);
2645}
2646
2647
2648void FAST_FUNC tls_handshake(tls_state_t * state, const char *hostname) {
2649 SECURITY_STATUS status;
2650 int received;
2651
2652#if ENABLE_FEATURE_TLS_SCHANNEL_1_3
2653 SCH_CREDENTIALS credential = {.dwVersion = SCH_CREDENTIALS_VERSION,
2654 .dwCredFormat = 0,
2655 .cCreds = 0,
2656 .paCred = NULL,
2657 .hRootStore = NULL,
2658 .cMappers = 0,
2659 .aphMappers = NULL,
2660 .dwSessionLifespan = 0,
2661 .dwFlags =
2662 SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
2663 SCH_USE_STRONG_CRYPTO,
2664 .cTlsParameters = 0,
2665 .pTlsParameters = NULL
2666 };
2667#else
2668 SCHANNEL_CRED credential = {.dwVersion = SCHANNEL_CRED_VERSION,
2669 .cCreds = 0,
2670 .paCred = NULL,
2671 .hRootStore = NULL,
2672 .cMappers = 0,
2673 .aphMappers = NULL,
2674 .cSupportedAlgs = 0,
2675 .palgSupportedAlgs = NULL,
2676 .grbitEnabledProtocols =
2677 SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_1_CLIENT |
2678 SP_PROT_TLS1_2_CLIENT,
2679 .dwMinimumCipherStrength = 0,
2680 .dwMaximumCipherStrength = 0,
2681 .dwSessionLifespan = 0,
2682 .dwFlags =
2683 SCH_CRED_AUTO_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS |
2684 SCH_USE_STRONG_CRYPTO,
2685 .dwCredFormat = 0
2686 };
2687#endif
2688
2689 if ((status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *) UNISP_NAME_A,
2690 SECPKG_CRED_OUTBOUND, NULL,
2691 &credential,
2692 NULL, NULL, &state->cred_handle,
2693 NULL)) != SEC_E_OK) {
2694 bb_error_msg_and_die("schannel: AcquireCredentialsHandleA failed: (0x%08lx): %s",
2695 status, hresult_to_error_string(status));
2696 }
2697
2698 state->in_buffer_size = 0;
2699 state->out_buffer_size = 0;
2700 state->out_buffer_used = 0;
2701
2702 state->out_buffer = NULL;
2703
2704 state->hostname = strdup(hostname);
2705
2706 state->initialized = 0;
2707 state->closed = 0;
2708
2709 while (1) {
2710 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2711
2712 SecBuffer in_buffers[2];
2713 SecBuffer out_buffers[2];
2714
2715 SecBufferDesc in_desc;
2716 SecBufferDesc out_desc;
2717
2718 init_sec_buffer(&in_buffers[0], state->in_buffer, state->in_buffer_size, SECBUFFER_TOKEN);
2719 init_sec_buffer_empty(&in_buffers[1], SECBUFFER_EMPTY);
2720
2721 init_sec_buffer_empty(&out_buffers[0], SECBUFFER_TOKEN);
2722 init_sec_buffer_empty(&out_buffers[1], SECBUFFER_ALERT);
2723
2724 init_sec_buffer_desc(&in_desc, in_buffers, _countof(in_buffers));
2725 init_sec_buffer_desc(&out_desc, out_buffers, _countof(out_buffers));
2726
2727 status = InitializeSecurityContext(&state->cred_handle,
2728 state->
2729 initialized ? &state->ctx_handle :
2730 NULL,
2731 state->
2732 initialized ? NULL :
2733 state->hostname, flags, 0, 0,
2734 state->initialized ? &in_desc :
2735 NULL, 0,
2736 &state->ctx_handle, &out_desc,
2737 &flags, 0);
2738
2739 state->initialized = 1;
2740
2741 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) {
2742 memmove(state->in_buffer,
2743 state->in_buffer + (state->in_buffer_size -
2744 in_buffers[1].cbBuffer),
2745 in_buffers[1].cbBuffer);
2746 state->in_buffer_size = in_buffers[1].cbBuffer;
2747 } else if (status != SEC_E_INCOMPLETE_MESSAGE) {
2748 state->in_buffer_size = 0;
2749 }
2750
2751 switch (status) {
2752 case SEC_E_OK:{
2753 if (out_buffers[0].cbBuffer > 0) {
2754 xwrite(state->ofd, out_buffers[0].pvBuffer,
2755 out_buffers[0].cbBuffer);
2756 FreeContextBuffer(out_buffers[0].pvBuffer);
2757 }
2758 goto Success;
2759 }
2760 case SEC_I_CONTINUE_NEEDED:{
2761 xwrite(state->ofd, out_buffers[0].pvBuffer,
2762 out_buffers[0].cbBuffer);
2763 FreeContextBuffer(out_buffers[0].pvBuffer);
2764 break;
2765 }
2766 case SEC_I_INCOMPLETE_CREDENTIALS:{
2767 // we don't support this
2768 bb_error_msg_and_die("schannel: client certificates not supported");
2769 }
2770 case SEC_E_INCOMPLETE_MESSAGE:{
2771 break;
2772 }
2773 default:{
2774 bb_error_msg_and_die("schannel: handshake failed: (0x%08lx): %s",
2775 status, hresult_to_error_string(status));
2776 }
2777 }
2778
2779 received =
2780 safe_read(state->ifd, state->in_buffer + state->in_buffer_size,
2781 sizeof(state->in_buffer) - state->in_buffer_size);
2782 if (received <= 0) {
2783 bb_error_msg_and_die("schannel: handshake read() failed");
2784 }
2785 state->in_buffer_size += received;
2786 }
2787
2788 Success:
2789 QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_STREAM_SIZES,
2790 &state->stream_sizes);
2791
2792 //SecPkgContext_ConnectionInfo info;
2793 //QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_CONNECTION_INFO,
2794 // &info);
2795 //
2796 //fprintf(stderr, "TLS 1.%d\n", (((uint32_t)(8 * sizeof(unsigned long long) - __builtin_clzll((info.dwProtocol)) - 1)) - 7)/2);
2797}
2798
2799void FAST_FUNC tls_run_copy_loop(tls_state_t * tls, unsigned flags) {
2800 char buffer[65536];
2801
2802 struct pollfd pfds[2];
2803
2804 pfds[0].fd = STDIN_FILENO;
2805 pfds[0].events = POLLIN;
2806 pfds[1].fd = tls->ifd;
2807 pfds[1].events = POLLIN;
2808
2809 for (;;) {
2810 int nread;
2811
2812 if (safe_poll(pfds, 2, -1) < 0)
2813 bb_simple_perror_msg_and_die("poll");
2814
2815 if (pfds[0].revents) {
2816 nread = safe_read(STDIN_FILENO, buffer, sizeof(buffer));
2817 if (nread < 1) {
2818 pfds[0].fd = -1;
2819 tls_disconnect(tls);
2820 if (flags & TLSLOOP_EXIT_ON_LOCAL_EOF)
2821 break;
2822 } else {
2823 tls_write(tls, buffer, nread);
2824 }
2825 }
2826 if (pfds[1].revents) {
2827 nread = tls_read(tls, buffer, sizeof(buffer));
2828 if (nread < 1) {
2829 tls_disconnect(tls);
2830 break;
2831 }
2832 xwrite(STDOUT_FILENO, buffer, nread);
2833 }
2834 }
2835}
2836#endif