tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

util.c (5254B)


      1 /*
      2 * util.c
      3 *
      4 * Utilities used by the test apps
      5 *
      6 * John A. Foley
      7 * Cisco Systems, Inc.
      8 */
      9 /*
     10 *
     11 * Copyright (c) 2014-2017, Cisco Systems, Inc.
     12 * All rights reserved.
     13 *
     14 * Redistribution and use in source and binary forms, with or without
     15 * modification, are permitted provided that the following conditions
     16 * are met:
     17 *
     18 *   Redistributions of source code must retain the above copyright
     19 *   notice, this list of conditions and the following disclaimer.
     20 *
     21 *   Redistributions in binary form must reproduce the above
     22 *   copyright notice, this list of conditions and the following
     23 *   disclaimer in the documentation and/or other materials provided
     24 *   with the distribution.
     25 *
     26 *   Neither the name of the Cisco Systems, Inc. nor the names of its
     27 *   contributors may be used to endorse or promote products derived
     28 *   from this software without specific prior written permission.
     29 *
     30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     41 * OF THE POSSIBILITY OF SUCH DAMAGE.
     42 *
     43 */
     44 
     45 #include "config.h"
     46 #include "util.h"
     47 
     48 #include <string.h>
     49 #include <stdint.h>
     50 
     51 /* include space for null terminator */
     52 static char bit_string[MAX_PRINT_STRING_LEN + 1];
     53 
     54 static inline int hex_char_to_nibble(uint8_t c)
     55 {
     56    switch (c) {
     57    case ('0'):
     58        return 0x0;
     59    case ('1'):
     60        return 0x1;
     61    case ('2'):
     62        return 0x2;
     63    case ('3'):
     64        return 0x3;
     65    case ('4'):
     66        return 0x4;
     67    case ('5'):
     68        return 0x5;
     69    case ('6'):
     70        return 0x6;
     71    case ('7'):
     72        return 0x7;
     73    case ('8'):
     74        return 0x8;
     75    case ('9'):
     76        return 0x9;
     77    case ('a'):
     78        return 0xa;
     79    case ('A'):
     80        return 0xa;
     81    case ('b'):
     82        return 0xb;
     83    case ('B'):
     84        return 0xb;
     85    case ('c'):
     86        return 0xc;
     87    case ('C'):
     88        return 0xc;
     89    case ('d'):
     90        return 0xd;
     91    case ('D'):
     92        return 0xd;
     93    case ('e'):
     94        return 0xe;
     95    case ('E'):
     96        return 0xe;
     97    case ('f'):
     98        return 0xf;
     99    case ('F'):
    100        return 0xf;
    101    default:
    102        return -1; /* this flags an error */
    103    }
    104 }
    105 
    106 uint8_t nibble_to_hex_char(uint8_t nibble)
    107 {
    108    char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
    109                     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    110 
    111    return buf[nibble & 0xF];
    112 }
    113 
    114 /*
    115 * hex_string_to_octet_string converts a hexadecimal string
    116 * of length 2 * len to a raw octet string of length len
    117 */
    118 int hex_string_to_octet_string(char *raw, char *hex, int len)
    119 {
    120    uint8_t x;
    121    int tmp;
    122    int hex_len;
    123 
    124    hex_len = 0;
    125    while (hex_len < len) {
    126        tmp = hex_char_to_nibble(hex[0]);
    127        if (tmp == -1) {
    128            return hex_len;
    129        }
    130        x = (uint8_t)(tmp << 4);
    131        hex_len++;
    132        tmp = hex_char_to_nibble(hex[1]);
    133        if (tmp == -1) {
    134            return hex_len;
    135        }
    136        x |= (tmp & 0xff);
    137        hex_len++;
    138        *raw++ = x;
    139        hex += 2;
    140    }
    141    return hex_len;
    142 }
    143 
    144 char *octet_string_hex_string(const void *s, int length)
    145 {
    146    const uint8_t *str = (const uint8_t *)s;
    147    int i;
    148 
    149    /* double length, since one octet takes two hex characters */
    150    length *= 2;
    151 
    152    /* truncate string if it would be too long */
    153    if (length > MAX_PRINT_STRING_LEN) {
    154        length = MAX_PRINT_STRING_LEN;
    155    }
    156 
    157    for (i = 0; i < length; i += 2) {
    158        bit_string[i] = nibble_to_hex_char(*str >> 4);
    159        bit_string[i + 1] = nibble_to_hex_char(*str++ & 0xF);
    160    }
    161    bit_string[i] = 0; /* null terminate string */
    162    return bit_string;
    163 }
    164 
    165 static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    166                               "abcdefghijklmnopqrstuvwxyz0123456789+/";
    167 
    168 static int base64_block_to_octet_triple(char *out, char *in)
    169 {
    170    unsigned char sextets[4] = { 0 };
    171    int j = 0;
    172    int i;
    173 
    174    for (i = 0; i < 4; i++) {
    175        char *p = strchr(b64chars, in[i]);
    176        if (p != NULL) {
    177            sextets[i] = (unsigned char)(p - b64chars);
    178        } else {
    179            j++;
    180        }
    181    }
    182 
    183    out[0] = (sextets[0] << 2) | (sextets[1] >> 4);
    184    if (j < 2) {
    185        out[1] = (sextets[1] << 4) | (sextets[2] >> 2);
    186    }
    187    if (j < 1) {
    188        out[2] = (sextets[2] << 6) | sextets[3];
    189    }
    190    return j;
    191 }
    192 
    193 int base64_string_to_octet_string(char *out, int *pad, char *in, int len)
    194 {
    195    int k = 0;
    196    int i = 0;
    197    int j = 0;
    198 
    199    if (len % 4 != 0) {
    200        return 0;
    201    }
    202 
    203    while (i < len && j == 0) {
    204        j = base64_block_to_octet_triple(out + k, in + i);
    205        k += 3;
    206        i += 4;
    207    }
    208    *pad = j;
    209    return i;
    210 }