-
Notifications
You must be signed in to change notification settings - Fork 911
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lightning_websocketd: simple proxy for websockets.
WebSocket is a bit weird: 1. It starts like an HTTP connection, but they send special headers. 2. We reply with special headers, one of which involves SHA1 of one of theirs. 3. We are then in WebSocket mode, where each frame starts with a 2-20 byte header. We relay data in a simplistic way: if either side sends something, we read it and relay it synchronously. That avoids any gratuitous buffering. Signed-off-by: Rusty Russell <[email protected]>
- Loading branch information
1 parent
f78184c
commit 80a47f1
Showing
7 changed files
with
741 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
/* hex variants removed -- RR */ | ||
#include <connectd/sha1.h> | ||
|
||
/******************************************************************************* | ||
* Teeny SHA-1 | ||
* | ||
* The below sha1digest() calculates a SHA-1 hash value for a | ||
* specified data buffer and generates a hex representation of the | ||
* result. This implementation is a re-forming of the SHA-1 code at | ||
* https://github.com/jinqiangshou/EncryptionLibrary. | ||
* | ||
* Copyright (c) 2017 CTrabant | ||
* | ||
* License: MIT, see included LICENSE file for details. | ||
* | ||
* To use the sha1digest() function either copy it into an existing | ||
* project source code file or include this file in a project and put | ||
* the declaration (example below) in the sources files where needed. | ||
******************************************************************************/ | ||
|
||
#include <string.h> | ||
|
||
/* Declaration: | ||
extern int sha1digest(uint8_t *digest, const uint8_t *data, size_t databytes); | ||
*/ | ||
|
||
/******************************************************************************* | ||
* sha1digest: https://github.com/CTrabant/teeny-sha1 | ||
* | ||
* Calculate the SHA-1 value for supplied data buffer and generate a | ||
* text representation in hexadecimal. | ||
* | ||
* Based on https://github.com/jinqiangshou/EncryptionLibrary, credit | ||
* goes to @jinqiangshou, all new bugs are mine. | ||
* | ||
* @input: | ||
* data -- data to be hashed | ||
* databytes -- bytes in data buffer to be hashed | ||
* | ||
* @output: | ||
* digest -- the result, MUST be at least 20 bytes | ||
* | ||
* @return: 0 on success and non-zero on error. | ||
******************************************************************************/ | ||
int | ||
sha1digest(uint8_t *digest, const uint8_t *data, size_t databytes) | ||
{ | ||
#define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) | ||
|
||
uint32_t W[80]; | ||
uint32_t H[] = {0x67452301, | ||
0xEFCDAB89, | ||
0x98BADCFE, | ||
0x10325476, | ||
0xC3D2E1F0}; | ||
uint32_t a; | ||
uint32_t b; | ||
uint32_t c; | ||
uint32_t d; | ||
uint32_t e; | ||
uint32_t f = 0; | ||
uint32_t k = 0; | ||
|
||
uint32_t idx; | ||
uint32_t lidx; | ||
uint32_t widx; | ||
uint32_t didx = 0; | ||
|
||
int32_t wcount; | ||
uint32_t temp; | ||
uint64_t databits = ((uint64_t)databytes) * 8; | ||
uint32_t loopcount = (databytes + 8) / 64 + 1; | ||
uint32_t tailbytes = 64 * loopcount - databytes; | ||
uint8_t datatail[128] = {0}; | ||
|
||
if (!digest) | ||
return -1; | ||
|
||
if (!data) | ||
return -1; | ||
|
||
/* Pre-processing of data tail (includes padding to fill out 512-bit chunk): | ||
Add bit '1' to end of message (big-endian) | ||
Add 64-bit message length in bits at very end (big-endian) */ | ||
datatail[0] = 0x80; | ||
datatail[tailbytes - 8] = (uint8_t) (databits >> 56 & 0xFF); | ||
datatail[tailbytes - 7] = (uint8_t) (databits >> 48 & 0xFF); | ||
datatail[tailbytes - 6] = (uint8_t) (databits >> 40 & 0xFF); | ||
datatail[tailbytes - 5] = (uint8_t) (databits >> 32 & 0xFF); | ||
datatail[tailbytes - 4] = (uint8_t) (databits >> 24 & 0xFF); | ||
datatail[tailbytes - 3] = (uint8_t) (databits >> 16 & 0xFF); | ||
datatail[tailbytes - 2] = (uint8_t) (databits >> 8 & 0xFF); | ||
datatail[tailbytes - 1] = (uint8_t) (databits >> 0 & 0xFF); | ||
|
||
/* Process each 512-bit chunk */ | ||
for (lidx = 0; lidx < loopcount; lidx++) | ||
{ | ||
/* Compute all elements in W */ | ||
memset (W, 0, 80 * sizeof (uint32_t)); | ||
|
||
/* Break 512-bit chunk into sixteen 32-bit, big endian words */ | ||
for (widx = 0; widx <= 15; widx++) | ||
{ | ||
wcount = 24; | ||
|
||
/* Copy byte-per byte from specified buffer */ | ||
while (didx < databytes && wcount >= 0) | ||
{ | ||
W[widx] += (((uint32_t)data[didx]) << wcount); | ||
didx++; | ||
wcount -= 8; | ||
} | ||
/* Fill out W with padding as needed */ | ||
while (wcount >= 0) | ||
{ | ||
W[widx] += (((uint32_t)datatail[didx - databytes]) << wcount); | ||
didx++; | ||
wcount -= 8; | ||
} | ||
} | ||
|
||
/* Extend the sixteen 32-bit words into eighty 32-bit words, with potential optimization from: | ||
"Improving the Performance of the Secure Hash Algorithm (SHA-1)" by Max Locktyukhin */ | ||
for (widx = 16; widx <= 31; widx++) | ||
{ | ||
W[widx] = SHA1ROTATELEFT ((W[widx - 3] ^ W[widx - 8] ^ W[widx - 14] ^ W[widx - 16]), 1); | ||
} | ||
for (widx = 32; widx <= 79; widx++) | ||
{ | ||
W[widx] = SHA1ROTATELEFT ((W[widx - 6] ^ W[widx - 16] ^ W[widx - 28] ^ W[widx - 32]), 2); | ||
} | ||
|
||
/* Main loop */ | ||
a = H[0]; | ||
b = H[1]; | ||
c = H[2]; | ||
d = H[3]; | ||
e = H[4]; | ||
|
||
for (idx = 0; idx <= 79; idx++) | ||
{ | ||
if (idx <= 19) | ||
{ | ||
f = (b & c) | ((~b) & d); | ||
k = 0x5A827999; | ||
} | ||
else if (idx >= 20 && idx <= 39) | ||
{ | ||
f = b ^ c ^ d; | ||
k = 0x6ED9EBA1; | ||
} | ||
else if (idx >= 40 && idx <= 59) | ||
{ | ||
f = (b & c) | (b & d) | (c & d); | ||
k = 0x8F1BBCDC; | ||
} | ||
else if (idx >= 60 && idx <= 79) | ||
{ | ||
f = b ^ c ^ d; | ||
k = 0xCA62C1D6; | ||
} | ||
temp = SHA1ROTATELEFT (a, 5) + f + e + k + W[idx]; | ||
e = d; | ||
d = c; | ||
c = SHA1ROTATELEFT (b, 30); | ||
b = a; | ||
a = temp; | ||
} | ||
|
||
H[0] += a; | ||
H[1] += b; | ||
H[2] += c; | ||
H[3] += d; | ||
H[4] += e; | ||
} | ||
|
||
/* Store binary digest in supplied buffer */ | ||
if (digest) | ||
{ | ||
for (idx = 0; idx < 5; idx++) | ||
{ | ||
digest[idx * 4 + 0] = (uint8_t) (H[idx] >> 24); | ||
digest[idx * 4 + 1] = (uint8_t) (H[idx] >> 16); | ||
digest[idx * 4 + 2] = (uint8_t) (H[idx] >> 8); | ||
digest[idx * 4 + 3] = (uint8_t) (H[idx]); | ||
} | ||
} | ||
|
||
return 0; | ||
} /* End of sha1digest() */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef LIGHTNING_CONNECTD_SHA1_H | ||
#define LIGHTNING_CONNECTD_SHA1_H | ||
#include "config.h" | ||
#include <stdint.h> | ||
#include <stdlib.h> | ||
|
||
extern int sha1digest(uint8_t *digest, const uint8_t *data, size_t databytes); | ||
|
||
#endif /* LIGHTNING_CONNECTD_SHA1_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.