mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 12:15:34 +08:00
[fix] fix all unused variables and type conversions
This commit is contained in:
@@ -53,6 +53,8 @@
|
||||
Purschke <purschke@bnl.gov>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4267)
|
||||
|
||||
#ifndef WEBSOCKETPP_COMMON_MD5_HPP
|
||||
#define WEBSOCKETPP_COMMON_MD5_HPP
|
||||
@@ -68,120 +70,121 @@
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace websocketpp {
|
||||
/// Provides MD5 hashing functionality
|
||||
namespace md5 {
|
||||
|
||||
typedef unsigned char md5_byte_t; /* 8-bit byte */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
typedef unsigned int md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
/* Initialize the algorithm. */
|
||||
inline void md5_init(md5_state_t *pms);
|
||||
|
||||
/* Append a string to the message. */
|
||||
inline void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes);
|
||||
inline void md5_append(md5_state_t *pms, md5_byte_t const *data, size_t nbytes);
|
||||
|
||||
/* Finish the message and return the digest. */
|
||||
inline void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
|
||||
|
||||
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown \
|
||||
*/
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
# define ZSW_MD5_BYTE_ORDER 0
|
||||
#define ZSW_MD5_BYTE_ORDER 0
|
||||
#endif
|
||||
|
||||
#define ZSW_MD5_T_MASK ((md5_word_t)~0)
|
||||
#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87)
|
||||
#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9)
|
||||
#define ZSW_MD5_T3 0x242070db
|
||||
#define ZSW_MD5_T3 0x242070db
|
||||
#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111)
|
||||
#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050)
|
||||
#define ZSW_MD5_T6 0x4787c62a
|
||||
#define ZSW_MD5_T6 0x4787c62a
|
||||
#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec)
|
||||
#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe)
|
||||
#define ZSW_MD5_T9 0x698098d8
|
||||
#define ZSW_MD5_T9 0x698098d8
|
||||
#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850)
|
||||
#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e)
|
||||
#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841)
|
||||
#define ZSW_MD5_T13 0x6b901122
|
||||
#define ZSW_MD5_T13 0x6b901122
|
||||
#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c)
|
||||
#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71)
|
||||
#define ZSW_MD5_T16 0x49b40821
|
||||
#define ZSW_MD5_T16 0x49b40821
|
||||
#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d)
|
||||
#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf)
|
||||
#define ZSW_MD5_T19 0x265e5a51
|
||||
#define ZSW_MD5_T19 0x265e5a51
|
||||
#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855)
|
||||
#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2)
|
||||
#define ZSW_MD5_T22 0x02441453
|
||||
#define ZSW_MD5_T22 0x02441453
|
||||
#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e)
|
||||
#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437)
|
||||
#define ZSW_MD5_T25 0x21e1cde6
|
||||
#define ZSW_MD5_T25 0x21e1cde6
|
||||
#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829)
|
||||
#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278)
|
||||
#define ZSW_MD5_T28 0x455a14ed
|
||||
#define ZSW_MD5_T28 0x455a14ed
|
||||
#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa)
|
||||
#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07)
|
||||
#define ZSW_MD5_T31 0x676f02d9
|
||||
#define ZSW_MD5_T31 0x676f02d9
|
||||
#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375)
|
||||
#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd)
|
||||
#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e)
|
||||
#define ZSW_MD5_T35 0x6d9d6122
|
||||
#define ZSW_MD5_T35 0x6d9d6122
|
||||
#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3)
|
||||
#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb)
|
||||
#define ZSW_MD5_T38 0x4bdecfa9
|
||||
#define ZSW_MD5_T38 0x4bdecfa9
|
||||
#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f)
|
||||
#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f)
|
||||
#define ZSW_MD5_T41 0x289b7ec6
|
||||
#define ZSW_MD5_T41 0x289b7ec6
|
||||
#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805)
|
||||
#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a)
|
||||
#define ZSW_MD5_T44 0x04881d05
|
||||
#define ZSW_MD5_T44 0x04881d05
|
||||
#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6)
|
||||
#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a)
|
||||
#define ZSW_MD5_T47 0x1fa27cf8
|
||||
#define ZSW_MD5_T47 0x1fa27cf8
|
||||
#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a)
|
||||
#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb)
|
||||
#define ZSW_MD5_T50 0x432aff97
|
||||
#define ZSW_MD5_T50 0x432aff97
|
||||
#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58)
|
||||
#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6)
|
||||
#define ZSW_MD5_T53 0x655b59c3
|
||||
#define ZSW_MD5_T53 0x655b59c3
|
||||
#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d)
|
||||
#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82)
|
||||
#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e)
|
||||
#define ZSW_MD5_T57 0x6fa87e4f
|
||||
#define ZSW_MD5_T57 0x6fa87e4f
|
||||
#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f)
|
||||
#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb)
|
||||
#define ZSW_MD5_T60 0x4e0811a1
|
||||
#define ZSW_MD5_T60 0x4e0811a1
|
||||
#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d)
|
||||
#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca)
|
||||
#define ZSW_MD5_T63 0x2ad7d2bb
|
||||
#define ZSW_MD5_T63 0x2ad7d2bb
|
||||
#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e)
|
||||
|
||||
static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
static void md5_process(md5_state_t *pms, md5_byte_t const *data /*[64]*/) {
|
||||
md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
|
||||
d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if ZSW_MD5_BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
md5_word_t X[16];
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
md5_word_t X[16];
|
||||
#else
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
md5_word_t const * X;
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
md5_word_t xbuf[16];
|
||||
md5_word_t const *X;
|
||||
#endif
|
||||
|
||||
{
|
||||
{
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
@@ -192,257 +195,252 @@ static void md5_process(md5_state_t *pms, md5_byte_t const * data /*[64]*/) {
|
||||
|
||||
if (*((md5_byte_t const *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||
#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (md5_byte_t const *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (md5_word_t const *)data;
|
||||
} else {
|
||||
} else {
|
||||
/* not aligned */
|
||||
std::memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||
#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if ZSW_MD5_BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
#if ZSW_MD5_BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
#else
|
||||
#define xbuf X /* (static only) */
|
||||
#endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_F(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
|
||||
SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
|
||||
SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
|
||||
SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
|
||||
SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
|
||||
SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
|
||||
SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
|
||||
SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
|
||||
SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
|
||||
SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
|
||||
SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
|
||||
SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
|
||||
SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
|
||||
SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
|
||||
SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
|
||||
SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 7, ZSW_MD5_T1);
|
||||
SET(d, a, b, c, 1, 12, ZSW_MD5_T2);
|
||||
SET(c, d, a, b, 2, 17, ZSW_MD5_T3);
|
||||
SET(b, c, d, a, 3, 22, ZSW_MD5_T4);
|
||||
SET(a, b, c, d, 4, 7, ZSW_MD5_T5);
|
||||
SET(d, a, b, c, 5, 12, ZSW_MD5_T6);
|
||||
SET(c, d, a, b, 6, 17, ZSW_MD5_T7);
|
||||
SET(b, c, d, a, 7, 22, ZSW_MD5_T8);
|
||||
SET(a, b, c, d, 8, 7, ZSW_MD5_T9);
|
||||
SET(d, a, b, c, 9, 12, ZSW_MD5_T10);
|
||||
SET(c, d, a, b, 10, 17, ZSW_MD5_T11);
|
||||
SET(b, c, d, a, 11, 22, ZSW_MD5_T12);
|
||||
SET(a, b, c, d, 12, 7, ZSW_MD5_T13);
|
||||
SET(d, a, b, c, 13, 12, ZSW_MD5_T14);
|
||||
SET(c, d, a, b, 14, 17, ZSW_MD5_T15);
|
||||
SET(b, c, d, a, 15, 22, ZSW_MD5_T16);
|
||||
#undef SET
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_G(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
|
||||
SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
|
||||
SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
|
||||
SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
|
||||
SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
|
||||
SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
|
||||
SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
|
||||
SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
|
||||
SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
|
||||
SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
|
||||
SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
|
||||
SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
|
||||
SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
|
||||
SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
|
||||
SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
|
||||
SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 1, 5, ZSW_MD5_T17);
|
||||
SET(d, a, b, c, 6, 9, ZSW_MD5_T18);
|
||||
SET(c, d, a, b, 11, 14, ZSW_MD5_T19);
|
||||
SET(b, c, d, a, 0, 20, ZSW_MD5_T20);
|
||||
SET(a, b, c, d, 5, 5, ZSW_MD5_T21);
|
||||
SET(d, a, b, c, 10, 9, ZSW_MD5_T22);
|
||||
SET(c, d, a, b, 15, 14, ZSW_MD5_T23);
|
||||
SET(b, c, d, a, 4, 20, ZSW_MD5_T24);
|
||||
SET(a, b, c, d, 9, 5, ZSW_MD5_T25);
|
||||
SET(d, a, b, c, 14, 9, ZSW_MD5_T26);
|
||||
SET(c, d, a, b, 3, 14, ZSW_MD5_T27);
|
||||
SET(b, c, d, a, 8, 20, ZSW_MD5_T28);
|
||||
SET(a, b, c, d, 13, 5, ZSW_MD5_T29);
|
||||
SET(d, a, b, c, 2, 9, ZSW_MD5_T30);
|
||||
SET(c, d, a, b, 7, 14, ZSW_MD5_T31);
|
||||
SET(b, c, d, a, 12, 20, ZSW_MD5_T32);
|
||||
#undef SET
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_H(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
|
||||
SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
|
||||
SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
|
||||
SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
|
||||
SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
|
||||
SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
|
||||
SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
|
||||
SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
|
||||
SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
|
||||
SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
|
||||
SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
|
||||
SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
|
||||
SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
|
||||
SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
|
||||
SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
|
||||
SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 5, 4, ZSW_MD5_T33);
|
||||
SET(d, a, b, c, 8, 11, ZSW_MD5_T34);
|
||||
SET(c, d, a, b, 11, 16, ZSW_MD5_T35);
|
||||
SET(b, c, d, a, 14, 23, ZSW_MD5_T36);
|
||||
SET(a, b, c, d, 1, 4, ZSW_MD5_T37);
|
||||
SET(d, a, b, c, 4, 11, ZSW_MD5_T38);
|
||||
SET(c, d, a, b, 7, 16, ZSW_MD5_T39);
|
||||
SET(b, c, d, a, 10, 23, ZSW_MD5_T40);
|
||||
SET(a, b, c, d, 13, 4, ZSW_MD5_T41);
|
||||
SET(d, a, b, c, 0, 11, ZSW_MD5_T42);
|
||||
SET(c, d, a, b, 3, 16, ZSW_MD5_T43);
|
||||
SET(b, c, d, a, 6, 23, ZSW_MD5_T44);
|
||||
SET(a, b, c, d, 9, 4, ZSW_MD5_T45);
|
||||
SET(d, a, b, c, 12, 11, ZSW_MD5_T46);
|
||||
SET(c, d, a, b, 15, 16, ZSW_MD5_T47);
|
||||
SET(b, c, d, a, 2, 23, ZSW_MD5_T48);
|
||||
#undef SET
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti)\
|
||||
t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + ZSW_MD5_I(b, c, d) + X[k] + Ti; \
|
||||
a = ZSW_MD5_ROTATE_LEFT(t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
|
||||
SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
|
||||
SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
|
||||
SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
|
||||
SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
|
||||
SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
|
||||
SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
|
||||
SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
|
||||
SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
|
||||
SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
|
||||
SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
|
||||
SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
|
||||
SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
|
||||
SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
|
||||
SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
|
||||
SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
|
||||
/* Do the following 16 operations. */
|
||||
SET(a, b, c, d, 0, 6, ZSW_MD5_T49);
|
||||
SET(d, a, b, c, 7, 10, ZSW_MD5_T50);
|
||||
SET(c, d, a, b, 14, 15, ZSW_MD5_T51);
|
||||
SET(b, c, d, a, 5, 21, ZSW_MD5_T52);
|
||||
SET(a, b, c, d, 12, 6, ZSW_MD5_T53);
|
||||
SET(d, a, b, c, 3, 10, ZSW_MD5_T54);
|
||||
SET(c, d, a, b, 10, 15, ZSW_MD5_T55);
|
||||
SET(b, c, d, a, 1, 21, ZSW_MD5_T56);
|
||||
SET(a, b, c, d, 8, 6, ZSW_MD5_T57);
|
||||
SET(d, a, b, c, 15, 10, ZSW_MD5_T58);
|
||||
SET(c, d, a, b, 6, 15, ZSW_MD5_T59);
|
||||
SET(b, c, d, a, 13, 21, ZSW_MD5_T60);
|
||||
SET(a, b, c, d, 4, 6, ZSW_MD5_T61);
|
||||
SET(d, a, b, c, 11, 10, ZSW_MD5_T62);
|
||||
SET(c, d, a, b, 2, 15, ZSW_MD5_T63);
|
||||
SET(b, c, d, a, 9, 21, ZSW_MD5_T64);
|
||||
#undef SET
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
pms->abcd[0] += a;
|
||||
pms->abcd[1] += b;
|
||||
pms->abcd[2] += c;
|
||||
pms->abcd[3] += d;
|
||||
}
|
||||
|
||||
void md5_init(md5_state_t *pms) {
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void md5_append(md5_state_t *pms, md5_byte_t const * data, size_t nbytes) {
|
||||
md5_byte_t const * p = data;
|
||||
size_t left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
void md5_append(md5_state_t *pms, md5_byte_t const *data, size_t nbytes) {
|
||||
md5_byte_t const *p = data;
|
||||
size_t left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
if (nbytes <= 0) return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits) pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : static_cast<int>(nbytes));
|
||||
|
||||
std::memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
if (offset + copy < 64) return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64) md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
std::memcpy(pms->buf, p, left);
|
||||
/* Process a final partial block. */
|
||||
if (left) std::memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) {
|
||||
static md5_byte_t const pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
static md5_byte_t const pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
||||
|
||||
// some convenience c++ functions
|
||||
inline std::string md5_hash_string(std::string const & s) {
|
||||
char digest[16];
|
||||
inline std::string md5_hash_string(std::string const &s) {
|
||||
char digest[16];
|
||||
|
||||
md5_state_t state;
|
||||
md5_state_t state;
|
||||
|
||||
md5_init(&state);
|
||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||
md5_finish(&state, (md5_byte_t *)digest);
|
||||
md5_init(&state);
|
||||
md5_append(&state, (md5_byte_t const *)s.c_str(), s.size());
|
||||
md5_finish(&state, (md5_byte_t *)digest);
|
||||
|
||||
std::string ret;
|
||||
ret.resize(16);
|
||||
std::copy(digest,digest+16,ret.begin());
|
||||
std::string ret;
|
||||
ret.resize(16);
|
||||
std::copy(digest, digest + 16, ret.begin());
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
const char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
inline std::string md5_hash_hex(std::string const & input) {
|
||||
std::string hash = md5_hash_string(input);
|
||||
std::string hex;
|
||||
inline std::string md5_hash_hex(std::string const &input) {
|
||||
std::string hash = md5_hash_string(input);
|
||||
std::string hex;
|
||||
|
||||
for (size_t i = 0; i < hash.size(); i++) {
|
||||
hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
|
||||
hex.push_back(hexval[(hash[i]) & 0x0F]);
|
||||
}
|
||||
for (size_t i = 0; i < hash.size(); i++) {
|
||||
hex.push_back(hexval[((hash[i] >> 4) & 0xF)]);
|
||||
hex.push_back(hexval[(hash[i]) & 0x0F]);
|
||||
}
|
||||
|
||||
return hex;
|
||||
return hex;
|
||||
}
|
||||
|
||||
} // md5
|
||||
} // websocketpp
|
||||
} // namespace md5
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_COMMON_MD5_HPP
|
||||
#endif // WEBSOCKETPP_COMMON_MD5_HPP
|
||||
#pragma warning(pop)
|
||||
651
thirdparty/websocketpp/include/websocketpp/frame.hpp
vendored
651
thirdparty/websocketpp/include/websocketpp/frame.hpp
vendored
@@ -24,16 +24,17 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
#pragma warning(disable : 4267)
|
||||
|
||||
#ifndef WEBSOCKETPP_FRAME_HPP
|
||||
#define WEBSOCKETPP_FRAME_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/common/network.hpp>
|
||||
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/utilities.hpp>
|
||||
|
||||
namespace websocketpp {
|
||||
@@ -53,20 +54,20 @@ static unsigned int const MAX_EXTENDED_HEADER_LENGTH = 12;
|
||||
|
||||
/// Two byte conversion union
|
||||
union uint16_converter {
|
||||
uint16_t i;
|
||||
uint8_t c[2];
|
||||
uint16_t i;
|
||||
uint8_t c[2];
|
||||
};
|
||||
|
||||
/// Four byte conversion union
|
||||
union uint32_converter {
|
||||
uint32_t i;
|
||||
uint8_t c[4];
|
||||
uint32_t i;
|
||||
uint8_t c[4];
|
||||
};
|
||||
|
||||
/// Eight byte conversion union
|
||||
union uint64_converter {
|
||||
uint64_t i;
|
||||
uint8_t c[8];
|
||||
uint64_t i;
|
||||
uint8_t c[8];
|
||||
};
|
||||
|
||||
/// Constants and utility functions related to WebSocket opcodes
|
||||
@@ -74,101 +75,95 @@ union uint64_converter {
|
||||
* WebSocket Opcodes are 4 bits. See RFC6455 section 5.2.
|
||||
*/
|
||||
namespace opcode {
|
||||
enum value {
|
||||
continuation = 0x0,
|
||||
text = 0x1,
|
||||
binary = 0x2,
|
||||
rsv3 = 0x3,
|
||||
rsv4 = 0x4,
|
||||
rsv5 = 0x5,
|
||||
rsv6 = 0x6,
|
||||
rsv7 = 0x7,
|
||||
close = 0x8,
|
||||
ping = 0x9,
|
||||
pong = 0xA,
|
||||
control_rsvb = 0xB,
|
||||
control_rsvc = 0xC,
|
||||
control_rsvd = 0xD,
|
||||
control_rsve = 0xE,
|
||||
control_rsvf = 0xF,
|
||||
enum value {
|
||||
continuation = 0x0,
|
||||
text = 0x1,
|
||||
binary = 0x2,
|
||||
rsv3 = 0x3,
|
||||
rsv4 = 0x4,
|
||||
rsv5 = 0x5,
|
||||
rsv6 = 0x6,
|
||||
rsv7 = 0x7,
|
||||
close = 0x8,
|
||||
ping = 0x9,
|
||||
pong = 0xA,
|
||||
control_rsvb = 0xB,
|
||||
control_rsvc = 0xC,
|
||||
control_rsvd = 0xD,
|
||||
control_rsve = 0xE,
|
||||
control_rsvf = 0xF,
|
||||
|
||||
CONTINUATION = 0x0,
|
||||
TEXT = 0x1,
|
||||
BINARY = 0x2,
|
||||
RSV3 = 0x3,
|
||||
RSV4 = 0x4,
|
||||
RSV5 = 0x5,
|
||||
RSV6 = 0x6,
|
||||
RSV7 = 0x7,
|
||||
CLOSE = 0x8,
|
||||
PING = 0x9,
|
||||
PONG = 0xA,
|
||||
CONTROL_RSVB = 0xB,
|
||||
CONTROL_RSVC = 0xC,
|
||||
CONTROL_RSVD = 0xD,
|
||||
CONTROL_RSVE = 0xE,
|
||||
CONTROL_RSVF = 0xF
|
||||
};
|
||||
CONTINUATION = 0x0,
|
||||
TEXT = 0x1,
|
||||
BINARY = 0x2,
|
||||
RSV3 = 0x3,
|
||||
RSV4 = 0x4,
|
||||
RSV5 = 0x5,
|
||||
RSV6 = 0x6,
|
||||
RSV7 = 0x7,
|
||||
CLOSE = 0x8,
|
||||
PING = 0x9,
|
||||
PONG = 0xA,
|
||||
CONTROL_RSVB = 0xB,
|
||||
CONTROL_RSVC = 0xC,
|
||||
CONTROL_RSVD = 0xD,
|
||||
CONTROL_RSVE = 0xE,
|
||||
CONTROL_RSVF = 0xF
|
||||
};
|
||||
|
||||
/// Check if an opcode is reserved
|
||||
/**
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is reserved.
|
||||
*/
|
||||
inline bool reserved(value v) {
|
||||
return (v >= rsv3 && v <= rsv7) ||
|
||||
(v >= control_rsvb && v <= control_rsvf);
|
||||
}
|
||||
|
||||
/// Check if an opcode is invalid
|
||||
/**
|
||||
* Invalid opcodes are negative or require greater than 4 bits to store.
|
||||
*
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is invalid.
|
||||
*/
|
||||
inline bool invalid(value v) {
|
||||
return (v > 0xF || v < 0);
|
||||
}
|
||||
|
||||
/// Check if an opcode is for a control frame
|
||||
/**
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is a control opcode.
|
||||
*/
|
||||
inline bool is_control(value v) {
|
||||
return v >= 0x8;
|
||||
}
|
||||
/// Check if an opcode is reserved
|
||||
/**
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is reserved.
|
||||
*/
|
||||
inline bool reserved(value v) {
|
||||
return (v >= rsv3 && v <= rsv7) || (v >= control_rsvb && v <= control_rsvf);
|
||||
}
|
||||
|
||||
/// Check if an opcode is invalid
|
||||
/**
|
||||
* Invalid opcodes are negative or require greater than 4 bits to store.
|
||||
*
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is invalid.
|
||||
*/
|
||||
inline bool invalid(value v) { return (v > 0xF || v < 0); }
|
||||
|
||||
/// Check if an opcode is for a control frame
|
||||
/**
|
||||
* @param v The opcode to test.
|
||||
* @return Whether or not the opcode is a control opcode.
|
||||
*/
|
||||
inline bool is_control(value v) { return v >= 0x8; }
|
||||
} // namespace opcode
|
||||
|
||||
/// Constants related to frame and payload limits
|
||||
namespace limits {
|
||||
/// Minimum length of a WebSocket frame header.
|
||||
static unsigned int const basic_header_length = 2;
|
||||
/// Minimum length of a WebSocket frame header.
|
||||
static unsigned int const basic_header_length = 2;
|
||||
|
||||
/// Maximum length of a WebSocket header
|
||||
static unsigned int const max_header_length = 14;
|
||||
/// Maximum length of a WebSocket header
|
||||
static unsigned int const max_header_length = 14;
|
||||
|
||||
/// Maximum length of the variable portion of the WebSocket header
|
||||
static unsigned int const max_extended_header_length = 12;
|
||||
/// Maximum length of the variable portion of the WebSocket header
|
||||
static unsigned int const max_extended_header_length = 12;
|
||||
|
||||
/// Maximum size of a basic WebSocket payload
|
||||
static uint8_t const payload_size_basic = 125;
|
||||
/// Maximum size of a basic WebSocket payload
|
||||
static uint8_t const payload_size_basic = 125;
|
||||
|
||||
/// Maximum size of an extended WebSocket payload (basic payload = 126)
|
||||
static uint16_t const payload_size_extended = 0xFFFF; // 2^16, 65535
|
||||
/// Maximum size of an extended WebSocket payload (basic payload = 126)
|
||||
static uint16_t const payload_size_extended = 0xFFFF; // 2^16, 65535
|
||||
|
||||
/// Maximum size of a jumbo WebSocket payload (basic payload = 127)
|
||||
static uint64_t const payload_size_jumbo = 0x7FFFFFFFFFFFFFFFLL;//2^63
|
||||
|
||||
/// Maximum size of close frame reason
|
||||
/**
|
||||
* This is payload_size_basic - 2 bytes (as first two bytes are used for
|
||||
* the close code
|
||||
*/
|
||||
static uint8_t const close_reason_size = 123;
|
||||
}
|
||||
/// Maximum size of a jumbo WebSocket payload (basic payload = 127)
|
||||
static uint64_t const payload_size_jumbo = 0x7FFFFFFFFFFFFFFFLL; // 2^63
|
||||
|
||||
/// Maximum size of close frame reason
|
||||
/**
|
||||
* This is payload_size_basic - 2 bytes (as first two bytes are used for
|
||||
* the close code
|
||||
*/
|
||||
static uint8_t const close_reason_size = 123;
|
||||
} // namespace limits
|
||||
|
||||
// masks for fields in the basic header
|
||||
static uint8_t const BHB0_OPCODE = 0x0F;
|
||||
@@ -180,98 +175,97 @@ static uint8_t const BHB0_FIN = 0x80;
|
||||
static uint8_t const BHB1_PAYLOAD = 0x7F;
|
||||
static uint8_t const BHB1_MASK = 0x80;
|
||||
|
||||
static uint8_t const payload_size_code_16bit = 0x7E; // 126
|
||||
static uint8_t const payload_size_code_64bit = 0x7F; // 127
|
||||
static uint8_t const payload_size_code_16bit = 0x7E; // 126
|
||||
static uint8_t const payload_size_code_64bit = 0x7F; // 127
|
||||
|
||||
typedef uint32_converter masking_key_type;
|
||||
|
||||
/// The constant size component of a WebSocket frame header
|
||||
struct basic_header {
|
||||
basic_header() : b0(0x00),b1(0x00) {}
|
||||
basic_header() : b0(0x00), b1(0x00) {}
|
||||
|
||||
basic_header(uint8_t p0, uint8_t p1) : b0(p0), b1(p1) {}
|
||||
basic_header(uint8_t p0, uint8_t p1) : b0(p0), b1(p1) {}
|
||||
|
||||
basic_header(opcode::value op, uint64_t size, bool fin, bool mask,
|
||||
bool rsv1 = false, bool rsv2 = false, bool rsv3 = false) : b0(0x00),
|
||||
b1(0x00)
|
||||
{
|
||||
if (fin) {
|
||||
b0 |= BHB0_FIN;
|
||||
}
|
||||
if (rsv1) {
|
||||
b0 |= BHB0_RSV1;
|
||||
}
|
||||
if (rsv2) {
|
||||
b0 |= BHB0_RSV2;
|
||||
}
|
||||
if (rsv3) {
|
||||
b0 |= BHB0_RSV3;
|
||||
}
|
||||
b0 |= (op & BHB0_OPCODE);
|
||||
basic_header(opcode::value op, uint64_t size, bool fin, bool mask,
|
||||
bool rsv1 = false, bool rsv2 = false, bool rsv3 = false)
|
||||
: b0(0x00), b1(0x00) {
|
||||
if (fin) {
|
||||
b0 |= BHB0_FIN;
|
||||
}
|
||||
if (rsv1) {
|
||||
b0 |= BHB0_RSV1;
|
||||
}
|
||||
if (rsv2) {
|
||||
b0 |= BHB0_RSV2;
|
||||
}
|
||||
if (rsv3) {
|
||||
b0 |= BHB0_RSV3;
|
||||
}
|
||||
b0 |= (op & BHB0_OPCODE);
|
||||
|
||||
if (mask) {
|
||||
b1 |= BHB1_MASK;
|
||||
}
|
||||
|
||||
uint8_t basic_value;
|
||||
|
||||
if (size <= limits::payload_size_basic) {
|
||||
basic_value = static_cast<uint8_t>(size);
|
||||
} else if (size <= limits::payload_size_extended) {
|
||||
basic_value = payload_size_code_16bit;
|
||||
} else {
|
||||
basic_value = payload_size_code_64bit;
|
||||
}
|
||||
|
||||
|
||||
b1 |= basic_value;
|
||||
if (mask) {
|
||||
b1 |= BHB1_MASK;
|
||||
}
|
||||
|
||||
uint8_t b0;
|
||||
uint8_t b1;
|
||||
uint8_t basic_value;
|
||||
|
||||
if (size <= limits::payload_size_basic) {
|
||||
basic_value = static_cast<uint8_t>(size);
|
||||
} else if (size <= limits::payload_size_extended) {
|
||||
basic_value = payload_size_code_16bit;
|
||||
} else {
|
||||
basic_value = payload_size_code_64bit;
|
||||
}
|
||||
|
||||
b1 |= basic_value;
|
||||
}
|
||||
|
||||
uint8_t b0;
|
||||
uint8_t b1;
|
||||
};
|
||||
|
||||
/// The variable size component of a WebSocket frame header
|
||||
struct extended_header {
|
||||
extended_header() {
|
||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
||||
extended_header() {
|
||||
std::fill_n(this->bytes, MAX_EXTENDED_HEADER_LENGTH, 0x00);
|
||||
}
|
||||
|
||||
extended_header(uint64_t payload_size) {
|
||||
std::fill_n(this->bytes, MAX_EXTENDED_HEADER_LENGTH, 0x00);
|
||||
|
||||
copy_payload(payload_size);
|
||||
}
|
||||
|
||||
extended_header(uint64_t payload_size, uint32_t masking_key) {
|
||||
std::fill_n(this->bytes, MAX_EXTENDED_HEADER_LENGTH, 0x00);
|
||||
|
||||
// Copy payload size
|
||||
int offset = copy_payload(payload_size);
|
||||
|
||||
// Copy Masking Key
|
||||
uint32_converter temp32;
|
||||
temp32.i = masking_key;
|
||||
std::copy(temp32.c, temp32.c + 4, bytes + offset);
|
||||
}
|
||||
|
||||
uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH];
|
||||
|
||||
private:
|
||||
int copy_payload(uint64_t payload_size) {
|
||||
int payload_offset = 0;
|
||||
|
||||
if (payload_size <= limits::payload_size_basic) {
|
||||
payload_offset = 8;
|
||||
} else if (payload_size <= limits::payload_size_extended) {
|
||||
payload_offset = 6;
|
||||
}
|
||||
|
||||
extended_header(uint64_t payload_size) {
|
||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
||||
uint64_converter temp64;
|
||||
temp64.i = lib::net::_htonll(payload_size);
|
||||
std::copy(temp64.c + payload_offset, temp64.c + 8, bytes);
|
||||
|
||||
copy_payload(payload_size);
|
||||
}
|
||||
|
||||
extended_header(uint64_t payload_size, uint32_t masking_key) {
|
||||
std::fill_n(this->bytes,MAX_EXTENDED_HEADER_LENGTH,0x00);
|
||||
|
||||
// Copy payload size
|
||||
int offset = copy_payload(payload_size);
|
||||
|
||||
// Copy Masking Key
|
||||
uint32_converter temp32;
|
||||
temp32.i = masking_key;
|
||||
std::copy(temp32.c,temp32.c+4,bytes+offset);
|
||||
}
|
||||
|
||||
uint8_t bytes[MAX_EXTENDED_HEADER_LENGTH];
|
||||
private:
|
||||
int copy_payload(uint64_t payload_size) {
|
||||
int payload_offset = 0;
|
||||
|
||||
if (payload_size <= limits::payload_size_basic) {
|
||||
payload_offset = 8;
|
||||
} else if (payload_size <= limits::payload_size_extended) {
|
||||
payload_offset = 6;
|
||||
}
|
||||
|
||||
uint64_converter temp64;
|
||||
temp64.i = lib::net::_htonll(payload_size);
|
||||
std::copy(temp64.c+payload_offset,temp64.c+8,bytes);
|
||||
|
||||
return 8-payload_offset;
|
||||
}
|
||||
return 8 - payload_offset;
|
||||
}
|
||||
};
|
||||
|
||||
bool get_fin(basic_header const &h);
|
||||
@@ -295,31 +289,30 @@ uint16_t get_extended_size(extended_header const &);
|
||||
uint64_t get_jumbo_size(extended_header const &);
|
||||
uint64_t get_payload_size(basic_header const &, extended_header const &);
|
||||
|
||||
size_t prepare_masking_key(masking_key_type const & key);
|
||||
size_t prepare_masking_key(masking_key_type const &key);
|
||||
size_t circshift_prepared_key(size_t prepared_key, size_t offset);
|
||||
|
||||
// Functions for performing xor based masking and unmasking
|
||||
template <typename input_iter, typename output_iter>
|
||||
void byte_mask(input_iter b, input_iter e, output_iter o, masking_key_type
|
||||
const & key, size_t key_offset = 0);
|
||||
void byte_mask(input_iter b, input_iter e, output_iter o,
|
||||
masking_key_type const &key, size_t key_offset = 0);
|
||||
template <typename iter_type>
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const & key,
|
||||
size_t key_offset = 0);
|
||||
void word_mask_exact(uint8_t * input, uint8_t * output, size_t length,
|
||||
masking_key_type const & key);
|
||||
void word_mask_exact(uint8_t * data, size_t length, masking_key_type const &
|
||||
key);
|
||||
size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
size_t prepared_key);
|
||||
size_t word_mask_circ(uint8_t * data, size_t length, size_t prepared_key);
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const &key,
|
||||
size_t key_offset = 0);
|
||||
void word_mask_exact(uint8_t *input, uint8_t *output, size_t length,
|
||||
masking_key_type const &key);
|
||||
void word_mask_exact(uint8_t *data, size_t length, masking_key_type const &key);
|
||||
size_t word_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||
size_t prepared_key);
|
||||
size_t word_mask_circ(uint8_t *data, size_t length, size_t prepared_key);
|
||||
|
||||
/// Check whether the frame's FIN bit is set.
|
||||
/**
|
||||
* @param [in] h The basic header to extract from.
|
||||
* @return True if the header's fin bit is set.
|
||||
*/
|
||||
inline bool get_fin(basic_header const & h) {
|
||||
return ((h.b0 & BHB0_FIN) == BHB0_FIN);
|
||||
inline bool get_fin(basic_header const &h) {
|
||||
return ((h.b0 & BHB0_FIN) == BHB0_FIN);
|
||||
}
|
||||
|
||||
/// Set the frame's FIN bit
|
||||
@@ -327,8 +320,8 @@ inline bool get_fin(basic_header const & h) {
|
||||
* @param [out] h Header to set.
|
||||
* @param [in] value Value to set it to.
|
||||
*/
|
||||
inline void set_fin(basic_header & h, bool value) {
|
||||
h.b0 = (value ? h.b0 | BHB0_FIN : h.b0 & ~BHB0_FIN);
|
||||
inline void set_fin(basic_header &h, bool value) {
|
||||
h.b0 = (value ? h.b0 | BHB0_FIN : h.b0 & ~BHB0_FIN);
|
||||
}
|
||||
|
||||
/// check whether the frame's RSV1 bit is set
|
||||
@@ -337,7 +330,7 @@ inline void set_fin(basic_header & h, bool value) {
|
||||
* @return True if the header's RSV1 bit is set.
|
||||
*/
|
||||
inline bool get_rsv1(const basic_header &h) {
|
||||
return ((h.b0 & BHB0_RSV1) == BHB0_RSV1);
|
||||
return ((h.b0 & BHB0_RSV1) == BHB0_RSV1);
|
||||
}
|
||||
|
||||
/// Set the frame's RSV1 bit
|
||||
@@ -346,7 +339,7 @@ inline bool get_rsv1(const basic_header &h) {
|
||||
* @param [in] value Value to set it to.
|
||||
*/
|
||||
inline void set_rsv1(basic_header &h, bool value) {
|
||||
h.b0 = (value ? h.b0 | BHB0_RSV1 : h.b0 & ~BHB0_RSV1);
|
||||
h.b0 = (value ? h.b0 | BHB0_RSV1 : h.b0 & ~BHB0_RSV1);
|
||||
}
|
||||
|
||||
/// check whether the frame's RSV2 bit is set
|
||||
@@ -355,7 +348,7 @@ inline void set_rsv1(basic_header &h, bool value) {
|
||||
* @return True if the header's RSV2 bit is set.
|
||||
*/
|
||||
inline bool get_rsv2(const basic_header &h) {
|
||||
return ((h.b0 & BHB0_RSV2) == BHB0_RSV2);
|
||||
return ((h.b0 & BHB0_RSV2) == BHB0_RSV2);
|
||||
}
|
||||
|
||||
/// Set the frame's RSV2 bit
|
||||
@@ -364,7 +357,7 @@ inline bool get_rsv2(const basic_header &h) {
|
||||
* @param [in] value Value to set it to.
|
||||
*/
|
||||
inline void set_rsv2(basic_header &h, bool value) {
|
||||
h.b0 = (value ? h.b0 | BHB0_RSV2 : h.b0 & ~BHB0_RSV2);
|
||||
h.b0 = (value ? h.b0 | BHB0_RSV2 : h.b0 & ~BHB0_RSV2);
|
||||
}
|
||||
|
||||
/// check whether the frame's RSV3 bit is set
|
||||
@@ -373,7 +366,7 @@ inline void set_rsv2(basic_header &h, bool value) {
|
||||
* @return True if the header's RSV3 bit is set.
|
||||
*/
|
||||
inline bool get_rsv3(const basic_header &h) {
|
||||
return ((h.b0 & BHB0_RSV3) == BHB0_RSV3);
|
||||
return ((h.b0 & BHB0_RSV3) == BHB0_RSV3);
|
||||
}
|
||||
|
||||
/// Set the frame's RSV3 bit
|
||||
@@ -382,7 +375,7 @@ inline bool get_rsv3(const basic_header &h) {
|
||||
* @param [in] value Value to set it to.
|
||||
*/
|
||||
inline void set_rsv3(basic_header &h, bool value) {
|
||||
h.b0 = (value ? h.b0 | BHB0_RSV3 : h.b0 & ~BHB0_RSV3);
|
||||
h.b0 = (value ? h.b0 | BHB0_RSV3 : h.b0 & ~BHB0_RSV3);
|
||||
}
|
||||
|
||||
/// Extract opcode from basic header
|
||||
@@ -391,7 +384,7 @@ inline void set_rsv3(basic_header &h, bool value) {
|
||||
* @return The opcode value of the header.
|
||||
*/
|
||||
inline opcode::value get_opcode(const basic_header &h) {
|
||||
return opcode::value(h.b0 & BHB0_OPCODE);
|
||||
return opcode::value(h.b0 & BHB0_OPCODE);
|
||||
}
|
||||
|
||||
/// check whether the frame is masked
|
||||
@@ -399,8 +392,8 @@ inline opcode::value get_opcode(const basic_header &h) {
|
||||
* @param [in] h The basic header to extract from.
|
||||
* @return True if the header mask bit is set.
|
||||
*/
|
||||
inline bool get_masked(basic_header const & h) {
|
||||
return ((h.b1 & BHB1_MASK) == BHB1_MASK);
|
||||
inline bool get_masked(basic_header const &h) {
|
||||
return ((h.b1 & BHB1_MASK) == BHB1_MASK);
|
||||
}
|
||||
|
||||
/// Set the frame's MASK bit
|
||||
@@ -408,8 +401,8 @@ inline bool get_masked(basic_header const & h) {
|
||||
* @param [out] h Header to set.
|
||||
* @param value Value to set it to.
|
||||
*/
|
||||
inline void set_masked(basic_header & h, bool value) {
|
||||
h.b1 = (value ? h.b1 | BHB1_MASK : h.b1 & ~BHB1_MASK);
|
||||
inline void set_masked(basic_header &h, bool value) {
|
||||
h.b1 = (value ? h.b1 | BHB1_MASK : h.b1 & ~BHB1_MASK);
|
||||
}
|
||||
|
||||
/// Extracts the raw payload length specified in the basic header
|
||||
@@ -429,7 +422,7 @@ inline void set_masked(basic_header & h, bool value) {
|
||||
* @return The exact size encoded in h.
|
||||
*/
|
||||
inline uint8_t get_basic_size(const basic_header &h) {
|
||||
return h.b1 & BHB1_PAYLOAD;
|
||||
return h.b1 & BHB1_PAYLOAD;
|
||||
}
|
||||
|
||||
/// Calculates the full length of the header based on the first bytes.
|
||||
@@ -442,19 +435,19 @@ inline uint8_t get_basic_size(const basic_header &h) {
|
||||
* @param h Basic frame header to extract size from.
|
||||
* @return Full length of the extended header.
|
||||
*/
|
||||
inline size_t get_header_len(basic_header const & h) {
|
||||
// TODO: check extensions?
|
||||
inline size_t get_header_len(basic_header const &h) {
|
||||
// TODO: check extensions?
|
||||
|
||||
// masking key offset represents the space used for the extended length
|
||||
// fields
|
||||
size_t size = BASIC_HEADER_LENGTH + get_masking_key_offset(h);
|
||||
// masking key offset represents the space used for the extended length
|
||||
// fields
|
||||
size_t size = BASIC_HEADER_LENGTH + get_masking_key_offset(h);
|
||||
|
||||
// If the header is masked there is a 4 byte masking key
|
||||
if (get_masked(h)) {
|
||||
size += 4;
|
||||
}
|
||||
// If the header is masked there is a 4 byte masking key
|
||||
if (get_masked(h)) {
|
||||
size += 4;
|
||||
}
|
||||
|
||||
return size;
|
||||
return size;
|
||||
}
|
||||
|
||||
/// Calculate the offset location of the masking key within the extended header
|
||||
@@ -467,13 +460,13 @@ inline size_t get_header_len(basic_header const & h) {
|
||||
* @return byte offset of the first byte of the masking key
|
||||
*/
|
||||
inline unsigned int get_masking_key_offset(const basic_header &h) {
|
||||
if (get_basic_size(h) == payload_size_code_16bit) {
|
||||
return 2;
|
||||
} else if (get_basic_size(h) == payload_size_code_64bit) {
|
||||
return 8;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
if (get_basic_size(h) == payload_size_code_16bit) {
|
||||
return 2;
|
||||
} else if (get_basic_size(h) == payload_size_code_64bit) {
|
||||
return 8;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a properly sized contiguous string that encodes a full frame header
|
||||
@@ -486,19 +479,16 @@ inline unsigned int get_masking_key_offset(const basic_header &h) {
|
||||
*
|
||||
* @return A contiguous string containing h and e
|
||||
*/
|
||||
inline std::string prepare_header(const basic_header &h, const
|
||||
extended_header &e)
|
||||
{
|
||||
std::string ret;
|
||||
inline std::string prepare_header(const basic_header &h,
|
||||
const extended_header &e) {
|
||||
std::string ret;
|
||||
|
||||
ret.push_back(char(h.b0));
|
||||
ret.push_back(char(h.b1));
|
||||
ret.append(
|
||||
reinterpret_cast<const char*>(e.bytes),
|
||||
get_header_len(h)-BASIC_HEADER_LENGTH
|
||||
);
|
||||
ret.push_back(char(h.b0));
|
||||
ret.push_back(char(h.b1));
|
||||
ret.append(reinterpret_cast<const char *>(e.bytes),
|
||||
get_header_len(h) - BASIC_HEADER_LENGTH);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Extract the masking key from a frame header
|
||||
@@ -513,19 +503,18 @@ inline std::string prepare_header(const basic_header &h, const
|
||||
*
|
||||
* @return The masking key as an integer.
|
||||
*/
|
||||
inline masking_key_type get_masking_key(const basic_header &h, const
|
||||
extended_header &e)
|
||||
{
|
||||
masking_key_type temp32;
|
||||
inline masking_key_type get_masking_key(const basic_header &h,
|
||||
const extended_header &e) {
|
||||
masking_key_type temp32;
|
||||
|
||||
if (!get_masked(h)) {
|
||||
temp32.i = 0;
|
||||
} else {
|
||||
unsigned int offset = get_masking_key_offset(h);
|
||||
std::copy(e.bytes+offset,e.bytes+offset+4,temp32.c);
|
||||
}
|
||||
if (!get_masked(h)) {
|
||||
temp32.i = 0;
|
||||
} else {
|
||||
unsigned int offset = get_masking_key_offset(h);
|
||||
std::copy(e.bytes + offset, e.bytes + offset + 4, temp32.c);
|
||||
}
|
||||
|
||||
return temp32;
|
||||
return temp32;
|
||||
}
|
||||
|
||||
/// Extract the extended size field from an extended header
|
||||
@@ -538,9 +527,9 @@ inline masking_key_type get_masking_key(const basic_header &h, const
|
||||
* @return The size encoded in the extended header in host byte order
|
||||
*/
|
||||
inline uint16_t get_extended_size(const extended_header &e) {
|
||||
uint16_converter temp16;
|
||||
std::copy(e.bytes,e.bytes+2,temp16.c);
|
||||
return ntohs(temp16.i);
|
||||
uint16_converter temp16;
|
||||
std::copy(e.bytes, e.bytes + 2, temp16.c);
|
||||
return ntohs(temp16.i);
|
||||
}
|
||||
|
||||
/// Extract the jumbo size field from an extended header
|
||||
@@ -553,9 +542,9 @@ inline uint16_t get_extended_size(const extended_header &e) {
|
||||
* @return The size encoded in the extended header in host byte order
|
||||
*/
|
||||
inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||
uint64_converter temp64;
|
||||
std::copy(e.bytes,e.bytes+8,temp64.c);
|
||||
return lib::net::_ntohll(temp64.i);
|
||||
uint64_converter temp64;
|
||||
std::copy(e.bytes, e.bytes + 8, temp64.c);
|
||||
return lib::net::_ntohll(temp64.i);
|
||||
}
|
||||
|
||||
/// Extract the full payload size field from a WebSocket header
|
||||
@@ -570,18 +559,17 @@ inline uint64_t get_jumbo_size(const extended_header &e) {
|
||||
*
|
||||
* @return The size encoded in the combined header in host byte order.
|
||||
*/
|
||||
inline uint64_t get_payload_size(const basic_header &h, const
|
||||
extended_header &e)
|
||||
{
|
||||
uint8_t val = get_basic_size(h);
|
||||
inline uint64_t get_payload_size(const basic_header &h,
|
||||
const extended_header &e) {
|
||||
uint8_t val = get_basic_size(h);
|
||||
|
||||
if (val <= limits::payload_size_basic) {
|
||||
return val;
|
||||
} else if (val == payload_size_code_16bit) {
|
||||
return get_extended_size(e);
|
||||
} else {
|
||||
return get_jumbo_size(e);
|
||||
}
|
||||
if (val <= limits::payload_size_basic) {
|
||||
return val;
|
||||
} else if (val == payload_size_code_16bit) {
|
||||
return get_extended_size(e);
|
||||
} else {
|
||||
return get_jumbo_size(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract a masking key into a value the size of a machine word.
|
||||
@@ -592,15 +580,15 @@ inline uint64_t get_payload_size(const basic_header &h, const
|
||||
*
|
||||
* @return prepared key as a machine word
|
||||
*/
|
||||
inline size_t prepare_masking_key(const masking_key_type& key) {
|
||||
size_t low_bits = static_cast<size_t>(key.i);
|
||||
inline size_t prepare_masking_key(const masking_key_type &key) {
|
||||
size_t low_bits = static_cast<size_t>(key.i);
|
||||
|
||||
if (sizeof(size_t) == 8) {
|
||||
uint64_t high_bits = static_cast<size_t>(key.i);
|
||||
return static_cast<size_t>((high_bits << 32) | low_bits);
|
||||
} else {
|
||||
return low_bits;
|
||||
}
|
||||
if (sizeof(size_t) == 8) {
|
||||
uint64_t high_bits = static_cast<size_t>(key.i);
|
||||
return static_cast<size_t>((high_bits << 32) | low_bits);
|
||||
} else {
|
||||
return low_bits;
|
||||
}
|
||||
}
|
||||
|
||||
/// circularly shifts the supplied prepared masking key by offset bytes
|
||||
@@ -610,16 +598,16 @@ inline size_t prepare_masking_key(const masking_key_type& key) {
|
||||
* to zero and less than sizeof(size_t).
|
||||
*/
|
||||
inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
||||
if (offset == 0) {
|
||||
return prepared_key;
|
||||
}
|
||||
if (lib::net::is_little_endian()) {
|
||||
size_t temp = prepared_key << (sizeof(size_t)-offset)*8;
|
||||
return (prepared_key >> offset*8) | temp;
|
||||
} else {
|
||||
size_t temp = prepared_key >> (sizeof(size_t)-offset)*8;
|
||||
return (prepared_key << offset*8) | temp;
|
||||
}
|
||||
if (offset == 0) {
|
||||
return prepared_key;
|
||||
}
|
||||
if (lib::net::is_little_endian()) {
|
||||
size_t temp = prepared_key << (sizeof(size_t) - offset) * 8;
|
||||
return (prepared_key >> offset * 8) | temp;
|
||||
} else {
|
||||
size_t temp = prepared_key >> (sizeof(size_t) - offset) * 8;
|
||||
return (prepared_key << offset * 8) | temp;
|
||||
}
|
||||
}
|
||||
|
||||
/// Byte by byte mask/unmask
|
||||
@@ -643,15 +631,14 @@ inline size_t circshift_prepared_key(size_t prepared_key, size_t offset) {
|
||||
*/
|
||||
template <typename input_iter, typename output_iter>
|
||||
void byte_mask(input_iter first, input_iter last, output_iter result,
|
||||
masking_key_type const & key, size_t key_offset)
|
||||
{
|
||||
size_t key_index = key_offset%4;
|
||||
while (first != last) {
|
||||
*result = *first ^ key.c[key_index++];
|
||||
key_index %= 4;
|
||||
++result;
|
||||
++first;
|
||||
}
|
||||
masking_key_type const &key, size_t key_offset) {
|
||||
size_t key_index = key_offset % 4;
|
||||
while (first != last) {
|
||||
*result = *first ^ key.c[key_index++];
|
||||
key_index %= 4;
|
||||
++result;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
|
||||
/// Byte by byte mask/unmask (in place)
|
||||
@@ -672,10 +659,9 @@ void byte_mask(input_iter first, input_iter last, output_iter result,
|
||||
* @param key_offset offset value to start masking at.
|
||||
*/
|
||||
template <typename iter_type>
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const & key,
|
||||
size_t key_offset)
|
||||
{
|
||||
byte_mask(b,e,b,key,key_offset);
|
||||
void byte_mask(iter_type b, iter_type e, masking_key_type const &key,
|
||||
size_t key_offset) {
|
||||
byte_mask(b, e, b, key, key_offset);
|
||||
}
|
||||
|
||||
/// Exact word aligned mask/unmask
|
||||
@@ -699,21 +685,20 @@ void byte_mask(iter_type b, iter_type e, masking_key_type const & key,
|
||||
*
|
||||
* @param key Masking key to use
|
||||
*/
|
||||
inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length,
|
||||
const masking_key_type& key)
|
||||
{
|
||||
size_t prepared_key = prepare_masking_key(key);
|
||||
size_t n = length/sizeof(size_t);
|
||||
size_t* input_word = reinterpret_cast<size_t*>(input);
|
||||
size_t* output_word = reinterpret_cast<size_t*>(output);
|
||||
inline void word_mask_exact(uint8_t *input, uint8_t *output, size_t length,
|
||||
const masking_key_type &key) {
|
||||
size_t prepared_key = prepare_masking_key(key);
|
||||
size_t n = length / sizeof(size_t);
|
||||
size_t *input_word = reinterpret_cast<size_t *>(input);
|
||||
size_t *output_word = reinterpret_cast<size_t *>(output);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
output_word[i] = input_word[i] ^ prepared_key;
|
||||
}
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
output_word[i] = input_word[i] ^ prepared_key;
|
||||
}
|
||||
|
||||
for (size_t i = n*sizeof(size_t); i < length; i++) {
|
||||
output[i] = input[i] ^ key.c[i%4];
|
||||
}
|
||||
for (size_t i = n * sizeof(size_t); i < length; i++) {
|
||||
output[i] = input[i] ^ key.c[i % 4];
|
||||
}
|
||||
}
|
||||
|
||||
/// Exact word aligned mask/unmask (in place)
|
||||
@@ -728,10 +713,9 @@ inline void word_mask_exact(uint8_t* input, uint8_t* output, size_t length,
|
||||
*
|
||||
* @param key Masking key to use
|
||||
*/
|
||||
inline void word_mask_exact(uint8_t* data, size_t length, const
|
||||
masking_key_type& key)
|
||||
{
|
||||
word_mask_exact(data,data,length,key);
|
||||
inline void word_mask_exact(uint8_t *data, size_t length,
|
||||
const masking_key_type &key) {
|
||||
word_mask_exact(data, data, length, key);
|
||||
}
|
||||
|
||||
/// Circular word aligned mask/unmask
|
||||
@@ -765,27 +749,26 @@ inline void word_mask_exact(uint8_t* data, size_t length, const
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
size_t prepared_key)
|
||||
{
|
||||
size_t n = length / sizeof(size_t); // whole words
|
||||
size_t l = length - (n * sizeof(size_t)); // remaining bytes
|
||||
size_t * input_word = reinterpret_cast<size_t *>(input);
|
||||
size_t * output_word = reinterpret_cast<size_t *>(output);
|
||||
inline size_t word_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||
size_t prepared_key) {
|
||||
size_t n = length / sizeof(size_t); // whole words
|
||||
size_t l = length - (n * sizeof(size_t)); // remaining bytes
|
||||
size_t *input_word = reinterpret_cast<size_t *>(input);
|
||||
size_t *output_word = reinterpret_cast<size_t *>(output);
|
||||
|
||||
// mask word by word
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
output_word[i] = input_word[i] ^ prepared_key;
|
||||
}
|
||||
// mask word by word
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
output_word[i] = input_word[i] ^ prepared_key;
|
||||
}
|
||||
|
||||
// mask partial word at the end
|
||||
size_t start = length - l;
|
||||
uint8_t * byte_key = reinterpret_cast<uint8_t *>(&prepared_key);
|
||||
for (size_t i = 0; i < l; ++i) {
|
||||
output[start+i] = input[start+i] ^ byte_key[i];
|
||||
}
|
||||
// mask partial word at the end
|
||||
size_t start = length - l;
|
||||
uint8_t *byte_key = reinterpret_cast<uint8_t *>(&prepared_key);
|
||||
for (size_t i = 0; i < l; ++i) {
|
||||
output[start + i] = input[start + i] ^ byte_key[i];
|
||||
}
|
||||
|
||||
return circshift_prepared_key(prepared_key,l);
|
||||
return circshift_prepared_key(prepared_key, l);
|
||||
}
|
||||
|
||||
/// Circular word aligned mask/unmask (in place)
|
||||
@@ -802,8 +785,9 @@ inline size_t word_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
return word_mask_circ(data,data,length,prepared_key);
|
||||
inline size_t word_mask_circ(uint8_t *data, size_t length,
|
||||
size_t prepared_key) {
|
||||
return word_mask_circ(data, data, length, prepared_key);
|
||||
}
|
||||
|
||||
/// Circular byte aligned mask/unmask
|
||||
@@ -827,17 +811,16 @@ inline size_t word_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t byte_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
size_t prepared_key)
|
||||
{
|
||||
uint32_converter key;
|
||||
key.i = prepared_key;
|
||||
inline size_t byte_mask_circ(uint8_t *input, uint8_t *output, size_t length,
|
||||
size_t prepared_key) {
|
||||
uint32_converter key;
|
||||
key.i = prepared_key;
|
||||
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
output[i] = input[i] ^ key.c[i % 4];
|
||||
}
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
output[i] = input[i] ^ key.c[i % 4];
|
||||
}
|
||||
|
||||
return circshift_prepared_key(prepared_key,length % 4);
|
||||
return circshift_prepared_key(prepared_key, length % 4);
|
||||
}
|
||||
|
||||
/// Circular byte aligned mask/unmask (in place)
|
||||
@@ -854,11 +837,13 @@ inline size_t byte_mask_circ(uint8_t * input, uint8_t * output, size_t length,
|
||||
*
|
||||
* @return the prepared_key shifted to account for the input length
|
||||
*/
|
||||
inline size_t byte_mask_circ(uint8_t* data, size_t length, size_t prepared_key){
|
||||
return byte_mask_circ(data,data,length,prepared_key);
|
||||
inline size_t byte_mask_circ(uint8_t *data, size_t length,
|
||||
size_t prepared_key) {
|
||||
return byte_mask_circ(data, data, length, prepared_key);
|
||||
}
|
||||
|
||||
} // namespace frame
|
||||
} // namespace websocketpp
|
||||
} // namespace frame
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif //WEBSOCKETPP_FRAME_HPP
|
||||
#endif // WEBSOCKETPP_FRAME_HPP
|
||||
#pragma warning(pop)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,8 @@ under the same license as the original, which is listed below.
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4267)
|
||||
|
||||
#ifndef SHA1_DEFINED
|
||||
#define SHA1_DEFINED
|
||||
@@ -39,83 +41,74 @@ under the same license as the original, which is listed below.
|
||||
namespace websocketpp {
|
||||
namespace sha1 {
|
||||
|
||||
namespace { // local
|
||||
namespace { // local
|
||||
|
||||
// Rotate an integer value to left.
|
||||
inline unsigned int rol(unsigned int value, unsigned int steps) {
|
||||
return ((value << steps) | (value >> (32 - steps)));
|
||||
return ((value << steps) | (value >> (32 - steps)));
|
||||
}
|
||||
|
||||
// Sets the first 16 integers in the buffert to zero.
|
||||
// Used for clearing the W buffert.
|
||||
inline void clearWBuffert(unsigned int * buffert)
|
||||
{
|
||||
for (int pos = 16; --pos >= 0;)
|
||||
{
|
||||
buffert[pos] = 0;
|
||||
}
|
||||
inline void clearWBuffert(unsigned int *buffert) {
|
||||
for (int pos = 16; --pos >= 0;) {
|
||||
buffert[pos] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void innerHash(unsigned int * result, unsigned int * w)
|
||||
{
|
||||
unsigned int a = result[0];
|
||||
unsigned int b = result[1];
|
||||
unsigned int c = result[2];
|
||||
unsigned int d = result[3];
|
||||
unsigned int e = result[4];
|
||||
inline void innerHash(unsigned int *result, unsigned int *w) {
|
||||
unsigned int a = result[0];
|
||||
unsigned int b = result[1];
|
||||
unsigned int c = result[2];
|
||||
unsigned int d = result[3];
|
||||
unsigned int e = result[4];
|
||||
|
||||
int round = 0;
|
||||
int round = 0;
|
||||
|
||||
#define sha1macro(func,val) \
|
||||
{ \
|
||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||
e = d; \
|
||||
d = c; \
|
||||
c = rol(b, 30); \
|
||||
b = a; \
|
||||
a = t; \
|
||||
}
|
||||
#define sha1macro(func, val) \
|
||||
{ \
|
||||
const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
|
||||
e = d; \
|
||||
d = c; \
|
||||
c = rol(b, 30); \
|
||||
b = a; \
|
||||
a = t; \
|
||||
}
|
||||
|
||||
while (round < 16)
|
||||
{
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
}
|
||||
while (round < 20)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)
|
||||
++round;
|
||||
}
|
||||
while (round < 40)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)
|
||||
++round;
|
||||
}
|
||||
while (round < 60)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||
++round;
|
||||
}
|
||||
while (round < 80)
|
||||
{
|
||||
w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0xca62c1d6)
|
||||
++round;
|
||||
}
|
||||
while (round < 16) {
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)++ round;
|
||||
}
|
||||
while (round < 20) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (~b & d), 0x5a827999)++ round;
|
||||
}
|
||||
while (round < 40) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0x6ed9eba1)++ round;
|
||||
}
|
||||
while (round < 60) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)++ round;
|
||||
}
|
||||
while (round < 80) {
|
||||
w[round] =
|
||||
rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
|
||||
sha1macro(b ^ c ^ d, 0xca62c1d6)++ round;
|
||||
}
|
||||
|
||||
#undef sha1macro
|
||||
#undef sha1macro
|
||||
|
||||
result[0] += a;
|
||||
result[1] += b;
|
||||
result[2] += c;
|
||||
result[3] += d;
|
||||
result[4] += e;
|
||||
result[0] += a;
|
||||
result[1] += b;
|
||||
result[2] += c;
|
||||
result[3] += d;
|
||||
result[4] += e;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
/// Calculate a SHA1 hash
|
||||
/**
|
||||
@@ -124,66 +117,70 @@ inline void innerHash(unsigned int * result, unsigned int * w)
|
||||
* @param hash should point to a buffer of at least 20 bytes of size for storing
|
||||
* the sha1 result in.
|
||||
*/
|
||||
inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
|
||||
// Init the result array.
|
||||
unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
|
||||
0x10325476, 0xc3d2e1f0 };
|
||||
inline void calc(void const *src, size_t bytelength, unsigned char *hash) {
|
||||
// Init the result array.
|
||||
unsigned int result[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
|
||||
0xc3d2e1f0};
|
||||
|
||||
// Cast the void src pointer to be the byte array we can work with.
|
||||
unsigned char const * sarray = (unsigned char const *) src;
|
||||
// Cast the void src pointer to be the byte array we can work with.
|
||||
unsigned char const *sarray = (unsigned char const *)src;
|
||||
|
||||
// The reusable round buffer
|
||||
unsigned int w[80];
|
||||
// The reusable round buffer
|
||||
unsigned int w[80];
|
||||
|
||||
// Loop through all complete 64byte blocks.
|
||||
// Loop through all complete 64byte blocks.
|
||||
|
||||
size_t endCurrentBlock;
|
||||
size_t currentBlock = 0;
|
||||
size_t endCurrentBlock;
|
||||
size_t currentBlock = 0;
|
||||
|
||||
if (bytelength >= 64) {
|
||||
size_t const endOfFullBlocks = bytelength - 64;
|
||||
if (bytelength >= 64) {
|
||||
size_t const endOfFullBlocks = bytelength - 64;
|
||||
|
||||
while (currentBlock <= endOfFullBlocks) {
|
||||
endCurrentBlock = currentBlock + 64;
|
||||
while (currentBlock <= endOfFullBlocks) {
|
||||
endCurrentBlock = currentBlock + 64;
|
||||
|
||||
// Init the round buffer with the 64 byte block data.
|
||||
for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
|
||||
{
|
||||
// This line will swap endian on big endian and keep endian on
|
||||
// little endian.
|
||||
w[roundPos++] = (unsigned int) sarray[currentBlock + 3]
|
||||
| (((unsigned int) sarray[currentBlock + 2]) << 8)
|
||||
| (((unsigned int) sarray[currentBlock + 1]) << 16)
|
||||
| (((unsigned int) sarray[currentBlock]) << 24);
|
||||
}
|
||||
innerHash(result, w);
|
||||
}
|
||||
// Init the round buffer with the 64 byte block data.
|
||||
for (int roundPos = 0; currentBlock < endCurrentBlock;
|
||||
currentBlock += 4) {
|
||||
// This line will swap endian on big endian and keep endian on
|
||||
// little endian.
|
||||
w[roundPos++] = (unsigned int)sarray[currentBlock + 3] |
|
||||
(((unsigned int)sarray[currentBlock + 2]) << 8) |
|
||||
(((unsigned int)sarray[currentBlock + 1]) << 16) |
|
||||
(((unsigned int)sarray[currentBlock]) << 24);
|
||||
}
|
||||
innerHash(result, w);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the last and not full 64 byte block if existing.
|
||||
endCurrentBlock = bytelength - currentBlock;
|
||||
clearWBuffert(w);
|
||||
size_t lastBlockBytes = 0;
|
||||
for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||
w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
}
|
||||
// Handle the last and not full 64 byte block if existing.
|
||||
endCurrentBlock = bytelength - currentBlock;
|
||||
clearWBuffert(w);
|
||||
size_t lastBlockBytes = 0;
|
||||
for (; lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
|
||||
w[lastBlockBytes >> 2] |=
|
||||
(unsigned int)sarray[lastBlockBytes + currentBlock]
|
||||
<< ((3 - (lastBlockBytes & 3)) << 3);
|
||||
}
|
||||
|
||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
if (endCurrentBlock >= 56) {
|
||||
innerHash(result, w);
|
||||
clearWBuffert(w);
|
||||
}
|
||||
w[15] = bytelength << 3;
|
||||
w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
|
||||
if (endCurrentBlock >= 56) {
|
||||
innerHash(result, w);
|
||||
clearWBuffert(w);
|
||||
}
|
||||
w[15] = bytelength << 3;
|
||||
innerHash(result, w);
|
||||
|
||||
// Store hash in result pointer, and make sure we get in in the correct
|
||||
// order on both endian models.
|
||||
for (int hashByte = 20; --hashByte >= 0;) {
|
||||
hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||
}
|
||||
// Store hash in result pointer, and make sure we get in in the correct
|
||||
// order on both endian models.
|
||||
for (int hashByte = 20; --hashByte >= 0;) {
|
||||
hash[hashByte] =
|
||||
(result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sha1
|
||||
} // namespace websocketpp
|
||||
} // namespace sha1
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // SHA1_DEFINED
|
||||
#endif // SHA1_DEFINED
|
||||
#pragma warning(pop)
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user