quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

debug.c (14572B)


      1 /*
      2  *  Debugging routines
      3  *
      4  *  Copyright The Mbed TLS Contributors
      5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      6  */
      7 
      8 #include "common.h"
      9 
     10 #if defined(MBEDTLS_DEBUG_C)
     11 
     12 #include "mbedtls/platform.h"
     13 
     14 #include "debug_internal.h"
     15 #include "mbedtls/error.h"
     16 
     17 #include <stdarg.h>
     18 #include <stdio.h>
     19 #include <string.h>
     20 
     21 /* DEBUG_BUF_SIZE must be at least 2 */
     22 #define DEBUG_BUF_SIZE      512
     23 
     24 static int debug_threshold = 0;
     25 
     26 void mbedtls_debug_set_threshold(int threshold)
     27 {
     28     debug_threshold = threshold;
     29 }
     30 
     31 /*
     32  * All calls to f_dbg must be made via this function
     33  */
     34 static inline void debug_send_line(const mbedtls_ssl_context *ssl, int level,
     35                                    const char *file, int line,
     36                                    const char *str)
     37 {
     38     /*
     39      * If in a threaded environment, we need a thread identifier.
     40      * Since there is no portable way to get one, use the address of the ssl
     41      * context instead, as it shouldn't be shared between threads.
     42      */
     43 #if defined(MBEDTLS_THREADING_C)
     44     char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
     45     mbedtls_snprintf(idstr, sizeof(idstr), "%p: %s", (void *) ssl, str);
     46     ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, idstr);
     47 #else
     48     ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, str);
     49 #endif
     50 }
     51 
     52 MBEDTLS_PRINTF_ATTRIBUTE(5, 6)
     53 void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
     54                              const char *file, int line,
     55                              const char *format, ...)
     56 {
     57     va_list argp;
     58     char str[DEBUG_BUF_SIZE];
     59     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     60 
     61     MBEDTLS_STATIC_ASSERT(DEBUG_BUF_SIZE >= 2, "DEBUG_BUF_SIZE too small");
     62 
     63     if (NULL == ssl              ||
     64         NULL == ssl->conf        ||
     65         NULL == ssl->conf->f_dbg ||
     66         level > debug_threshold) {
     67         return;
     68     }
     69 
     70     va_start(argp, format);
     71     ret = mbedtls_vsnprintf(str, DEBUG_BUF_SIZE, format, argp);
     72     va_end(argp);
     73 
     74     if (ret < 0) {
     75         ret = 0;
     76     } else {
     77         if (ret >= DEBUG_BUF_SIZE - 1) {
     78             ret = DEBUG_BUF_SIZE - 2;
     79         }
     80     }
     81     str[ret]     = '\n';
     82     str[ret + 1] = '\0';
     83 
     84     debug_send_line(ssl, level, file, line, str);
     85 }
     86 
     87 void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
     88                              const char *file, int line,
     89                              const char *text, int ret)
     90 {
     91     char str[DEBUG_BUF_SIZE];
     92 
     93     if (NULL == ssl              ||
     94         NULL == ssl->conf        ||
     95         NULL == ssl->conf->f_dbg ||
     96         level > debug_threshold) {
     97         return;
     98     }
     99 
    100     /*
    101      * With non-blocking I/O and examples that just retry immediately,
    102      * the logs would be quickly flooded with WANT_READ, so ignore that.
    103      * Don't ignore WANT_WRITE however, since it is usually rare.
    104      */
    105     if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
    106         return;
    107     }
    108 
    109     mbedtls_snprintf(str, sizeof(str), "%s() returned %d (-0x%04x)\n",
    110                      text, ret, (unsigned int) -ret);
    111 
    112     debug_send_line(ssl, level, file, line, str);
    113 }
    114 
    115 void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
    116                              const char *file, int line, const char *text,
    117                              const unsigned char *buf, size_t len)
    118 {
    119     char str[DEBUG_BUF_SIZE];
    120     char txt[17];
    121     size_t i, idx = 0;
    122 
    123     if (NULL == ssl              ||
    124         NULL == ssl->conf        ||
    125         NULL == ssl->conf->f_dbg ||
    126         level > debug_threshold) {
    127         return;
    128     }
    129 
    130     mbedtls_snprintf(str + idx, sizeof(str) - idx, "dumping '%s' (%u bytes)\n",
    131                      text, (unsigned int) len);
    132 
    133     debug_send_line(ssl, level, file, line, str);
    134 
    135     memset(txt, 0, sizeof(txt));
    136     for (i = 0; i < len; i++) {
    137         if (i >= 4096) {
    138             break;
    139         }
    140 
    141         if (i % 16 == 0) {
    142             if (i > 0) {
    143                 mbedtls_snprintf(str + idx, sizeof(str) - idx, "  %s\n", txt);
    144                 debug_send_line(ssl, level, file, line, str);
    145 
    146                 idx = 0;
    147                 memset(txt, 0, sizeof(txt));
    148             }
    149 
    150             idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, "%04x: ",
    151                                     (unsigned int) i);
    152 
    153         }
    154 
    155         idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x",
    156                                 (unsigned int) buf[i]);
    157         txt[i % 16] = (buf[i] > 31 && buf[i] < 127) ? buf[i] : '.';
    158     }
    159 
    160     if (len > 0) {
    161         for (/* i = i */; i % 16 != 0; i++) {
    162             idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, "   ");
    163         }
    164 
    165         mbedtls_snprintf(str + idx, sizeof(str) - idx, "  %s\n", txt);
    166         debug_send_line(ssl, level, file, line, str);
    167     }
    168 }
    169 
    170 #if defined(MBEDTLS_ECP_LIGHT)
    171 void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
    172                              const char *file, int line,
    173                              const char *text, const mbedtls_ecp_point *X)
    174 {
    175     char str[DEBUG_BUF_SIZE];
    176 
    177     if (NULL == ssl              ||
    178         NULL == ssl->conf        ||
    179         NULL == ssl->conf->f_dbg ||
    180         level > debug_threshold) {
    181         return;
    182     }
    183 
    184     mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
    185     mbedtls_debug_print_mpi(ssl, level, file, line, str, &X->X);
    186 
    187     mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
    188     mbedtls_debug_print_mpi(ssl, level, file, line, str, &X->Y);
    189 }
    190 #endif /* MBEDTLS_ECP_LIGHT */
    191 
    192 #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
    193 static void mbedtls_debug_print_ec_coord(const mbedtls_ssl_context *ssl, int level,
    194                                          const char *file, int line, const char *text,
    195                                          const unsigned char *buf, size_t len)
    196 {
    197     char str[DEBUG_BUF_SIZE];
    198     size_t i, idx = 0;
    199 
    200     mbedtls_snprintf(str + idx, sizeof(str) - idx, "value of '%s' (%u bits) is:\n",
    201                      text, (unsigned int) len * 8);
    202 
    203     debug_send_line(ssl, level, file, line, str);
    204 
    205     for (i = 0; i < len; i++) {
    206         if (i >= 4096) {
    207             break;
    208         }
    209 
    210         if (i % 16 == 0) {
    211             if (i > 0) {
    212                 mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
    213                 debug_send_line(ssl, level, file, line, str);
    214 
    215                 idx = 0;
    216             }
    217         }
    218 
    219         idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x",
    220                                 (unsigned int) buf[i]);
    221     }
    222 
    223     if (len > 0) {
    224         for (/* i = i */; i % 16 != 0; i++) {
    225             idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, "   ");
    226         }
    227 
    228         mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
    229         debug_send_line(ssl, level, file, line, str);
    230     }
    231 }
    232 
    233 void mbedtls_debug_print_psa_ec(const mbedtls_ssl_context *ssl, int level,
    234                                 const char *file, int line,
    235                                 const char *text, const mbedtls_pk_context *pk)
    236 {
    237     char str[DEBUG_BUF_SIZE];
    238     const uint8_t *coord_start;
    239     size_t coord_len;
    240 
    241     if (NULL == ssl              ||
    242         NULL == ssl->conf        ||
    243         NULL == ssl->conf->f_dbg ||
    244         level > debug_threshold) {
    245         return;
    246     }
    247 
    248     /* For the description of pk->pk_raw content please refer to the description
    249      * psa_export_public_key() function. */
    250     coord_len = (pk->pub_raw_len - 1)/2;
    251 
    252     /* X coordinate */
    253     coord_start = pk->pub_raw + 1;
    254     mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
    255     mbedtls_debug_print_ec_coord(ssl, level, file, line, str, coord_start, coord_len);
    256 
    257     /* Y coordinate */
    258     coord_start = coord_start + coord_len;
    259     mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
    260     mbedtls_debug_print_ec_coord(ssl, level, file, line, str, coord_start, coord_len);
    261 }
    262 #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
    263 
    264 #if defined(MBEDTLS_BIGNUM_C)
    265 void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
    266                              const char *file, int line,
    267                              const char *text, const mbedtls_mpi *X)
    268 {
    269     char str[DEBUG_BUF_SIZE];
    270     size_t bitlen;
    271     size_t idx = 0;
    272 
    273     if (NULL == ssl              ||
    274         NULL == ssl->conf        ||
    275         NULL == ssl->conf->f_dbg ||
    276         NULL == X                ||
    277         level > debug_threshold) {
    278         return;
    279     }
    280 
    281     bitlen = mbedtls_mpi_bitlen(X);
    282 
    283     mbedtls_snprintf(str, sizeof(str), "value of '%s' (%u bits) is:\n",
    284                      text, (unsigned) bitlen);
    285     debug_send_line(ssl, level, file, line, str);
    286 
    287     if (bitlen == 0) {
    288         str[0] = ' '; str[1] = '0'; str[2] = '0';
    289         idx = 3;
    290     } else {
    291         int n;
    292         for (n = (int) ((bitlen - 1) / 8); n >= 0; n--) {
    293             size_t limb_offset = n / sizeof(mbedtls_mpi_uint);
    294             size_t offset_in_limb = n % sizeof(mbedtls_mpi_uint);
    295             unsigned char octet =
    296                 (X->p[limb_offset] >> (offset_in_limb * 8)) & 0xff;
    297             mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x", octet);
    298             idx += 3;
    299             /* Wrap lines after 16 octets that each take 3 columns */
    300             if (idx >= 3 * 16) {
    301                 mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
    302                 debug_send_line(ssl, level, file, line, str);
    303                 idx = 0;
    304             }
    305         }
    306     }
    307 
    308     if (idx != 0) {
    309         mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
    310         debug_send_line(ssl, level, file, line, str);
    311     }
    312 }
    313 #endif /* MBEDTLS_BIGNUM_C */
    314 
    315 #if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO)
    316 static void debug_print_pk(const mbedtls_ssl_context *ssl, int level,
    317                            const char *file, int line,
    318                            const char *text, const mbedtls_pk_context *pk)
    319 {
    320     size_t i;
    321     mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS];
    322     char name[16];
    323 
    324     memset(items, 0, sizeof(items));
    325 
    326     if (mbedtls_pk_debug(pk, items) != 0) {
    327         debug_send_line(ssl, level, file, line,
    328                         "invalid PK context\n");
    329         return;
    330     }
    331 
    332     for (i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++) {
    333         if (items[i].type == MBEDTLS_PK_DEBUG_NONE) {
    334             return;
    335         }
    336 
    337         mbedtls_snprintf(name, sizeof(name), "%s%s", text, items[i].name);
    338         name[sizeof(name) - 1] = '\0';
    339 
    340 #if defined(MBEDTLS_RSA_C)
    341         if (items[i].type == MBEDTLS_PK_DEBUG_MPI) {
    342             mbedtls_debug_print_mpi(ssl, level, file, line, name, items[i].value);
    343         } else
    344 #endif /* MBEDTLS_RSA_C */
    345 #if defined(MBEDTLS_ECP_LIGHT)
    346         if (items[i].type == MBEDTLS_PK_DEBUG_ECP) {
    347             mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value);
    348         } else
    349 #endif /* MBEDTLS_ECP_LIGHT */
    350 #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
    351         if (items[i].type == MBEDTLS_PK_DEBUG_PSA_EC) {
    352             mbedtls_debug_print_psa_ec(ssl, level, file, line, name, items[i].value);
    353         } else
    354 #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
    355         { debug_send_line(ssl, level, file, line,
    356                           "should not happen\n"); }
    357     }
    358 }
    359 
    360 static void debug_print_line_by_line(const mbedtls_ssl_context *ssl, int level,
    361                                      const char *file, int line, const char *text)
    362 {
    363     char str[DEBUG_BUF_SIZE];
    364     const char *start, *cur;
    365 
    366     start = text;
    367     for (cur = text; *cur != '\0'; cur++) {
    368         if (*cur == '\n') {
    369             size_t len = (size_t) (cur - start) + 1;
    370             if (len > DEBUG_BUF_SIZE - 1) {
    371                 len = DEBUG_BUF_SIZE - 1;
    372             }
    373 
    374             memcpy(str, start, len);
    375             str[len] = '\0';
    376 
    377             debug_send_line(ssl, level, file, line, str);
    378 
    379             start = cur + 1;
    380         }
    381     }
    382 }
    383 
    384 void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
    385                              const char *file, int line,
    386                              const char *text, const mbedtls_x509_crt *crt)
    387 {
    388     char str[DEBUG_BUF_SIZE];
    389     int i = 0;
    390 
    391     if (NULL == ssl              ||
    392         NULL == ssl->conf        ||
    393         NULL == ssl->conf->f_dbg ||
    394         NULL == crt              ||
    395         level > debug_threshold) {
    396         return;
    397     }
    398 
    399     while (crt != NULL) {
    400         char buf[1024];
    401 
    402         mbedtls_snprintf(str, sizeof(str), "%s #%d:\n", text, ++i);
    403         debug_send_line(ssl, level, file, line, str);
    404 
    405         mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
    406         debug_print_line_by_line(ssl, level, file, line, buf);
    407 
    408         debug_print_pk(ssl, level, file, line, "crt->", &crt->pk);
    409 
    410         crt = crt->next;
    411     }
    412 }
    413 #endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_X509_REMOVE_INFO */
    414 
    415 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \
    416     defined(MBEDTLS_ECDH_C)
    417 static void mbedtls_debug_printf_ecdh_internal(const mbedtls_ssl_context *ssl,
    418                                                int level, const char *file,
    419                                                int line,
    420                                                const mbedtls_ecdh_context *ecdh,
    421                                                mbedtls_debug_ecdh_attr attr)
    422 {
    423 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
    424     const mbedtls_ecdh_context *ctx = ecdh;
    425 #else
    426     const mbedtls_ecdh_context_mbed *ctx = &ecdh->ctx.mbed_ecdh;
    427 #endif
    428 
    429     switch (attr) {
    430         case MBEDTLS_DEBUG_ECDH_Q:
    431             mbedtls_debug_print_ecp(ssl, level, file, line, "ECDH: Q",
    432                                     &ctx->Q);
    433             break;
    434         case MBEDTLS_DEBUG_ECDH_QP:
    435             mbedtls_debug_print_ecp(ssl, level, file, line, "ECDH: Qp",
    436                                     &ctx->Qp);
    437             break;
    438         case MBEDTLS_DEBUG_ECDH_Z:
    439             mbedtls_debug_print_mpi(ssl, level, file, line, "ECDH: z",
    440                                     &ctx->z);
    441             break;
    442         default:
    443             break;
    444     }
    445 }
    446 
    447 void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
    448                                const char *file, int line,
    449                                const mbedtls_ecdh_context *ecdh,
    450                                mbedtls_debug_ecdh_attr attr)
    451 {
    452 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
    453     mbedtls_debug_printf_ecdh_internal(ssl, level, file, line, ecdh, attr);
    454 #else
    455     switch (ecdh->var) {
    456         default:
    457             mbedtls_debug_printf_ecdh_internal(ssl, level, file, line, ecdh,
    458                                                attr);
    459     }
    460 #endif
    461 }
    462 #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED &&
    463           MBEDTLS_ECDH_C */
    464 
    465 #endif /* MBEDTLS_DEBUG_C */