liveserver

simple live web server for local developments
git clone https://noulin.net/git/liveserver.git
Log | Files | Refs | README | LICENSE

utilities.c (13003B)


      1 /*
      2   utilities.c
      3 
      4     Jonathan D. Hall - jhall@futuresouth.us
      5     Copyright 2015 Future South Technologies
      6 
      7     This file is part of libwebsock2.
      8 
      9     libwebsock2 is free software: you can redistribute it and/or modify
     10     it under the terms of the GNU General Public License as published by
     11     the Free Software Foundation, either version 3 of the License, or
     12     (at your option) any later version.
     13 
     14     libwebsock2 is distributed in the hope that it will be useful,
     15     but WITHOUT ANY WARRANTY; without even the implied warranty of
     16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17     GNU General Public License for more details.
     18 
     19     You should have received a copy of the GNU General Public License
     20     along with libwebsock2.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 */
     23 
     24 #include "utilities.h"
     25 
     26 #define UTF8_ACCEPT 0
     27 #define UTF8_REJECT 1
     28 
     29 #define SHA1CircularShift(bits,word) \
     30 ((((word) << (bits)) & 0xFFFFFFFF) | \
     31 ((word) >> (32-(bits))))
     32 
     33 uint32_t decode(uint32_t *state, uint32_t *codep, uint32_t byte);
     34 
     35 //these functions assume little endian machine as they're only used on windows
     36 uint16_t lws_htobe16(uint16_t x)
     37 {
     38     return ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
     39 }
     40 
     41 uint16_t lws_be16toh(uint16_t x)
     42 {
     43     return ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
     44 }
     45 
     46 uint64_t lws_htobe64(uint64_t x)
     47 {
     48     return (x >> 56) |
     49     ((x << 40) & 0x00ff000000000000LL) |
     50     ((x << 24) & 0x0000ff0000000000LL) |
     51     ((x << 8) & 0x000000ff00000000LL) |
     52     ((x >> 8) & 0x00000000ff000000LL) |
     53     ((x >> 24) & 0x0000000000ff0000LL) |
     54     ((x >> 40) & 0x000000000000ff00LL) |
     55     (x << 56);
     56 }
     57 
     58 uint64_t lws_be64toh(uint64_t x)
     59 {
     60     return (x >> 56) |
     61     ((x << 40) & 0x00ff000000000000LL) |
     62     ((x << 24) & 0x0000ff0000000000LL) |
     63     ((x << 8) & 0x000000ff00000000LL) |
     64     ((x >> 8) & 0x00000000ff000000LL) |
     65     ((x >> 24) & 0x0000000000ff0000LL) |
     66     ((x >> 40) & 0x000000000000ff00LL) |
     67     (x << 56);
     68 }
     69 
     70 int validate_utf8_sequence(uint8_t *s)
     71 {
     72     uint32_t codepoint;
     73     uint32_t state = 0;
     74 
     75     for(; *s; ++s) {
     76         decode(&state, &codepoint, *s);
     77     }
     78 
     79     return state == UTF8_ACCEPT;
     80 }
     81 
     82 const uint8_t utf8d[] = {
     83     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, // 00..1f
     84     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, // 20..3f
     85     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, // 40..5f
     86     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, // 60..7f
     87     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
     88     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
     89     8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
     90     0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
     91     0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
     92     0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
     93     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
     94     1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
     95     1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
     96     1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
     97 };
     98 
     99 uint32_t decode(uint32_t* state, uint32_t* codep, uint32_t byte)
    100 {
    101     uint32_t type = utf8d[byte];
    102 
    103     *codep = (*state != UTF8_ACCEPT) ?
    104     (byte & 0x3fu) | (*codep << 6) :
    105     (0xff >> type) & (byte);
    106 
    107     *state = utf8d[256 + *state*16 + type];
    108     return *state;
    109 }
    110 
    111 const char *BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    112 
    113 void _base64_encode_triple(unsigned char triple[3], char result[4])
    114 {
    115     int tripleValue, i;
    116 
    117     tripleValue = triple[0];
    118     tripleValue *= 256;
    119     tripleValue += triple[1];
    120     tripleValue *= 256;
    121     tripleValue += triple[2];
    122 
    123     for (i=0; i<4; i++)
    124     {
    125         result[3-i] = BASE64_CHARS[tripleValue%64];
    126         tripleValue /= 64;
    127     }
    128 }
    129 
    130 int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen)
    131 {
    132     if ((sourcelen+2)/3*4 > targetlen-1)
    133         return 0;
    134 
    135     while (sourcelen >= 3)
    136     {
    137         _base64_encode_triple(source, target);
    138         sourcelen -= 3;
    139         source += 3;
    140         target += 4;
    141     }
    142 
    143     if (sourcelen > 0)
    144     {
    145         unsigned char temp[3];
    146         memset(temp, 0, sizeof(temp));
    147         memcpy(temp, source, sourcelen);
    148         _base64_encode_triple(temp, target);
    149         target[3] = '=';
    150         if (sourcelen == 1)
    151             target[2] = '=';
    152 
    153         target += 4;
    154     }
    155 
    156     target[0] = 0;
    157 
    158     return 1;
    159 }
    160 
    161 int _base64_char_value(char base64char)
    162 {
    163     if (base64char >= 'A' && base64char <= 'Z')
    164         return base64char-'A';
    165     if (base64char >= 'a' && base64char <= 'z')
    166         return base64char-'a'+26;
    167     if (base64char >= '0' && base64char <= '9')
    168         return base64char-'0'+2*26;
    169     if (base64char == '+')
    170         return 2*26+10;
    171     if (base64char == '/')
    172         return 2*26+11;
    173     return -1;
    174 }
    175 
    176 int _base64_decode_triple(char quadruple[4], unsigned char *result)
    177 {
    178     int i, triple_value, bytes_to_decode = 3, only_equals_yet = 1;
    179     int char_value[4];
    180 
    181     for (i=0; i<4; i++)
    182         char_value[i] = _base64_char_value(quadruple[i]);
    183 
    184     for (i=3; i>=0; i--)
    185     {
    186         if (char_value[i]<0)
    187         {
    188             if (only_equals_yet && quadruple[i]=='=')
    189             {
    190                 char_value[i]=0;
    191                 bytes_to_decode--;
    192                 continue;
    193             }
    194             return 0;
    195         }
    196         only_equals_yet = 0;
    197     }
    198 
    199     if (bytes_to_decode < 0)
    200         bytes_to_decode = 0;
    201 
    202     triple_value = char_value[0];
    203     triple_value *= 64;
    204     triple_value += char_value[1];
    205     triple_value *= 64;
    206     triple_value += char_value[2];
    207     triple_value *= 64;
    208     triple_value += char_value[3];
    209 
    210     for (i=bytes_to_decode; i<3; i++)
    211         triple_value /= 256;
    212     for (i=bytes_to_decode-1; i>=0; i--)
    213     {
    214         result[i] = triple_value%256;
    215         triple_value /= 256;
    216     }
    217 
    218     return bytes_to_decode;
    219 }
    220 
    221 size_t base64_decode(char *source, unsigned char *target, size_t targetlen)
    222 {
    223     char *src, *tmpptr;
    224     char quadruple[4];
    225     unsigned char tmpresult[3];
    226     int i, tmplen = 3;
    227     size_t converted = 0;
    228 
    229     src = (char *)malloc(strlen(source)+5);
    230     if (src == NULL)
    231         return -1;
    232     strcpy(src, source);
    233     strcat(src, "====");
    234     tmpptr = src;
    235 
    236     while (tmplen == 3)
    237     {
    238         for (i=0; i<4; i++)
    239         {
    240             while (*tmpptr != '=' && _base64_char_value(*tmpptr)<0)
    241                 tmpptr++;
    242 
    243             quadruple[i] = *(tmpptr++);
    244         }
    245 
    246         tmplen = _base64_decode_triple(quadruple, tmpresult);
    247 
    248         if (targetlen < tmplen)
    249         {
    250             free(src);
    251             return -1;
    252         }
    253 
    254         memcpy(target, tmpresult, tmplen);
    255         target += tmplen;
    256         targetlen -= tmplen;
    257         converted += tmplen;
    258     }
    259 
    260     free(src);
    261     return converted;
    262 }
    263 
    264 void SHA1Reset(SHA1Context *context)
    265 {
    266     context->Length_Low             = 0;
    267     context->Length_High            = 0;
    268     context->Message_Block_Index    = 0;
    269 
    270     context->Message_Digest[0]      = 0x67452301;
    271     context->Message_Digest[1]      = 0xEFCDAB89;
    272     context->Message_Digest[2]      = 0x98BADCFE;
    273     context->Message_Digest[3]      = 0x10325476;
    274     context->Message_Digest[4]      = 0xC3D2E1F0;
    275 
    276     context->Computed   = 0;
    277     context->Corrupted  = 0;
    278 }
    279 
    280 int SHA1Result(SHA1Context *context)
    281 {
    282 
    283     if (context->Corrupted)
    284     {
    285         return 0;
    286     }
    287 
    288     if (!context->Computed)
    289     {
    290         SHA1PadMessage(context);
    291         context->Computed = 1;
    292     }
    293 
    294     return 1;
    295 }
    296 
    297 void SHA1Input(     SHA1Context         *context,
    298                const unsigned char *message_array,
    299                unsigned            length)
    300 {
    301     if (!length)
    302     {
    303         return;
    304     }
    305 
    306     if (context->Computed || context->Corrupted)
    307     {
    308         context->Corrupted = 1;
    309         return;
    310     }
    311 
    312     while(length-- && !context->Corrupted)
    313     {
    314         context->Message_Block[context->Message_Block_Index++] =
    315         (*message_array & 0xFF);
    316 
    317         context->Length_Low += 8;
    318         /* Force it to 32 bits */
    319         context->Length_Low &= 0xFFFFFFFF;
    320         if (context->Length_Low == 0)
    321         {
    322             context->Length_High++;
    323             /* Force it to 32 bits */
    324             context->Length_High &= 0xFFFFFFFF;
    325             if (context->Length_High == 0)
    326             {
    327                 /* Message is too long */
    328                 context->Corrupted = 1;
    329             }
    330         }
    331 
    332         if (context->Message_Block_Index == 64)
    333         {
    334             SHA1ProcessMessageBlock(context);
    335         }
    336 
    337         message_array++;
    338     }
    339 }
    340 
    341 void SHA1ProcessMessageBlock(SHA1Context *context)
    342 {
    343     const unsigned K[] =            /* Constants defined in SHA-1   */
    344     {
    345         0x5A827999,
    346         0x6ED9EBA1,
    347         0x8F1BBCDC,
    348         0xCA62C1D6
    349     };
    350     int         t;                  /* Loop counter                 */
    351     unsigned    temp;               /* Temporary word value         */
    352     unsigned    W[80];              /* Word sequence                */
    353     unsigned    A, B, C, D, E;      /* Word buffers                 */
    354 
    355     /*
    356      *  Initialize the first 16 words in the array W
    357      */
    358     for(t = 0; t < 16; t++)
    359     {
    360         W[t]  = ((unsigned) context->Message_Block[t * 4]) << 24;
    361         W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
    362         W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
    363         W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
    364     }
    365 
    366     for(t = 16; t < 80; t++)
    367     {
    368         W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    369     }
    370 
    371     A = context->Message_Digest[0];
    372     B = context->Message_Digest[1];
    373     C = context->Message_Digest[2];
    374     D = context->Message_Digest[3];
    375     E = context->Message_Digest[4];
    376 
    377     for(t = 0; t < 20; t++)
    378     {
    379         temp =  SHA1CircularShift(5,A) +
    380         ((B & C) | ((~B) & D)) + E + W[t] + K[0];
    381         temp &= 0xFFFFFFFF;
    382         E = D;
    383         D = C;
    384         C = SHA1CircularShift(30,B);
    385         B = A;
    386         A = temp;
    387     }
    388 
    389     for(t = 20; t < 40; t++)
    390     {
    391         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
    392         temp &= 0xFFFFFFFF;
    393         E = D;
    394         D = C;
    395         C = SHA1CircularShift(30,B);
    396         B = A;
    397         A = temp;
    398     }
    399 
    400     for(t = 40; t < 60; t++)
    401     {
    402         temp = SHA1CircularShift(5,A) +
    403         ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
    404         temp &= 0xFFFFFFFF;
    405         E = D;
    406         D = C;
    407         C = SHA1CircularShift(30,B);
    408         B = A;
    409         A = temp;
    410     }
    411 
    412     for(t = 60; t < 80; t++)
    413     {
    414         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
    415         temp &= 0xFFFFFFFF;
    416         E = D;
    417         D = C;
    418         C = SHA1CircularShift(30,B);
    419         B = A;
    420         A = temp;
    421     }
    422 
    423     context->Message_Digest[0] =
    424     (context->Message_Digest[0] + A) & 0xFFFFFFFF;
    425     context->Message_Digest[1] =
    426     (context->Message_Digest[1] + B) & 0xFFFFFFFF;
    427     context->Message_Digest[2] =
    428     (context->Message_Digest[2] + C) & 0xFFFFFFFF;
    429     context->Message_Digest[3] =
    430     (context->Message_Digest[3] + D) & 0xFFFFFFFF;
    431     context->Message_Digest[4] =
    432     (context->Message_Digest[4] + E) & 0xFFFFFFFF;
    433 
    434     context->Message_Block_Index = 0;
    435 }
    436 
    437 void SHA1PadMessage(SHA1Context *context)
    438 {
    439     /*
    440      *  Check to see if the current message block is too small to hold
    441      *  the initial padding bits and length.  If so, we will pad the
    442      *  block, process it, and then continue padding into a second
    443      *  block.
    444      */
    445     if (context->Message_Block_Index > 55)
    446     {
    447         context->Message_Block[context->Message_Block_Index++] = 0x80;
    448         while(context->Message_Block_Index < 64)
    449         {
    450             context->Message_Block[context->Message_Block_Index++] = 0;
    451         }
    452 
    453         SHA1ProcessMessageBlock(context);
    454 
    455         while(context->Message_Block_Index < 56)
    456         {
    457             context->Message_Block[context->Message_Block_Index++] = 0;
    458         }
    459     }
    460     else
    461     {
    462         context->Message_Block[context->Message_Block_Index++] = 0x80;
    463         while(context->Message_Block_Index < 56)
    464         {
    465             context->Message_Block[context->Message_Block_Index++] = 0;
    466         }
    467     }
    468 
    469     /*
    470      *  Store the message length as the last 8 octets
    471      */
    472     context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
    473     context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
    474     context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
    475     context->Message_Block[59] = (context->Length_High) & 0xFF;
    476     context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
    477     context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
    478     context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
    479     context->Message_Block[63] = (context->Length_Low) & 0xFF;
    480 
    481     SHA1ProcessMessageBlock(context);
    482 }