diff --git a/src/convert.c b/src/convert.c index 11919107..6417c6d1 100644 --- a/src/convert.c +++ b/src/convert.c @@ -1204,6 +1204,63 @@ static int _jsmn_get_ipdict(struct mem_funcs *mf, const char *js, jsmntok_t *t, return *value != NULL; } +static int _jsmn_get_base64_data(struct mem_funcs *mf, const char *js, jsmntok_t *t, + getdns_bindata **value) +{ + int e, i; + int size = t->end - t->start; + char value_str_buf[1025]; + char *value_str; + size_t target_buf_size; + + assert(size >= 4); + + if (size % 4 != 0) + return 0; + + e = t->end; + if (js[e - 1] == '=') e -= 1; + if (js[e - 1] == '=') e -= 1; + + for (i = t->start; i < e; i++) + if (!((js[i] >= '0' && js[i] <= '9') + ||(js[i] >= 'a' && js[i] <= 'z') + ||(js[i] >= 'A' && js[i] <= 'Z') + || js[i] == '+' || js[i] == '/')) + return 0; + + target_buf_size = gldns_b64_pton_calculate_size(size); + if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) + return 0; + + else if (!((*value)->data = GETDNS_XMALLOC( + *mf, uint8_t, target_buf_size))) { + GETDNS_FREE(*mf, *value); + return 0; + } + if ((size_t)size >= sizeof(value_str_buf)) + value_str = GETDNS_XMALLOC(*mf, char, size + 1); + else value_str = value_str_buf; + + if (value_str) { + (void) memcpy(value_str, js + t->start, size); + value_str[size] = '\0'; + + e = gldns_b64_pton(value_str, (*value)->data, target_buf_size); + + if (value_str != value_str_buf) + GETDNS_FREE(*mf, value_str); + + if (e > 0) { + (*value)->size = e; + return 1; + } + } + GETDNS_FREE(*mf, (*value)->data); + GETDNS_FREE(*mf, *value); + return 0; +} + static int _jsmn_get_data(struct mem_funcs *mf, const char *js, jsmntok_t *t, getdns_bindata **value) { @@ -1211,15 +1268,17 @@ static int _jsmn_get_data(struct mem_funcs *mf, const char *js, jsmntok_t *t, size_t j; uint8_t h, l; - if ((t->end - t->start) < 4 || (t->end - t->start) % 2 == 1 || - js[t->start] != '0' || js[t->start + 1] != 'x') + if ((t->end - t->start) < 4 || (t->end - t->start) % 2 == 1) return 0; + if (js[t->start] != '0' || js[t->start + 1] != 'x') + return _jsmn_get_base64_data(mf, js, t, value); + for (i = t->start + 2; i < t->end; i++) if (!((js[i] >= '0' && js[i] <= '9') ||(js[i] >= 'a' && js[i] <= 'f') ||(js[i] >= 'A' && js[i] <= 'F'))) - return 0; + return _jsmn_get_base64_data(mf, js, t, value); if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata))) return 0; diff --git a/src/dict.c b/src/dict.c index 23b42531..b8c9db99 100644 --- a/src/dict.c +++ b/src/dict.c @@ -51,6 +51,7 @@ #include "const-info.h" #include "gldns/gbuffer.h" #include "gldns/wire2str.h" +#include "gldns/parseutil.h" static char *_json_ptr_first(const struct mem_funcs *mf, @@ -731,6 +732,33 @@ _getdns_bindata_is_dname(getdns_bindata *bindata) bindata->data[bindata->size - 1] == 0; } +static int +getdns_pp_base64(gldns_buffer *buf, getdns_bindata *bindata) +{ + size_t p = gldns_buffer_position(buf); + size_t base64str_sz; + char *target; + size_t avail; + + if (gldns_buffer_printf(buf, " size); + target = (char *)gldns_buffer_current(buf); + avail = gldns_buffer_remaining(buf); + if (avail >= base64str_sz) + gldns_buffer_skip(buf, gldns_b64_ntop( + bindata->data, bindata->size, + target, base64str_sz)); + else + gldns_buffer_skip(buf, base64str_sz); + + if (gldns_buffer_printf(buf, ">") < 0) + return -1; + + return gldns_buffer_position(buf) - p; +} + /*---------------------------------------- getdns_pp_bindata */ /** * private function to pretty print bindata to a gldns_buffer @@ -1094,6 +1122,16 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent, )) < 0) return -1; + } else if (!json && + (strcmp(item->node.key, "pin-sha256") == 0 || + strcmp(item->node.key, "value") == 0) && + item->i.data.bindata->size > 0 && + item->i.data.bindata->size % 4 == 0) { + + if (getdns_pp_base64(buf, + item->i.data.bindata) < 0) + return -1; + } else if (getdns_pp_bindata( buf, item->i.data.bindata, (strcmp(item->node.key, "rdata_raw") == 0), diff --git a/src/tools/stubby.conf b/src/tools/stubby.conf index 054a9256..1055e277 100644 --- a/src/tools/stubby.conf +++ b/src/tools/stubby.conf @@ -5,54 +5,54 @@ , tls_auth_name: "dnsovertls.sinodun.com" , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0xEB694ABBD1EC0D56F288F7A70299DCE2C7E64984C73957C580BDE9C81F9C04BE + , value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4= } ] }, { address_data: 145.100.185.16 , tls_auth_name: "dnsovertls1.sinodun.com" , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0x704D9E7002DE13907EBAB2610EB26554599FDFC7092C0BEA7A438DBE3BE9A940 + , value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA= } ] }, { address_data: 185.49.141.38 , tls_auth_name: "getdnsapi.net" , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0x7e8c59467221f606695a797ecc488a6b4109dab7421aba0c5a6d3681ac5273d4 + , value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q= } ] }, { address_data: 2001:610:1:40ba:145:100:185:15 , tls_auth_name: "dnsovertls.sinodun.com" , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0xEB694ABBD1EC0D56F288F7A70299DCE2C7E64984C73957C580BDE9C81F9C04BE + , value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4= } ] }, { address_data: 2001:610:1:40ba:145:100:185:16 , tls_auth_name: "dnsovertls1.sinodun.com" , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0x704D9E7002DE13907EBAB2610EB26554599FDFC7092C0BEA7A438DBE3BE9A940 + , value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA= } ] }, { address_data: 2a04:b900:0:100::38 , tls_auth_name: "getdnsapi.net" , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0x7e8c59467221f606695a797ecc488a6b4109dab7421aba0c5a6d3681ac5273d4 + , value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q= } ] }, { address_data: 184.105.193.78 , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0xA4E5EBA54B7D9203E06D6C411457014DB447DA17A8DB01F05E9D5F7780045572 + , value: pOXrpUt9kgPgbWxBFFcBTbRH2heo2wHwXp1fd4AEVXI= } ] }, { address_data: 2620:ff:c000:0:1::64:25 , tls_pubkey_pinset: [ { digest: "sha256" - , value: 0xA4E5EBA54B7D9203E06D6C411457014DB447DA17A8DB01F05E9D5F7780045572 + , value: pOXrpUt9kgPgbWxBFFcBTbRH2heo2wHwXp1fd4AEVXI= } ] } ]