diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-03-29 15:04:11 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-03-31 13:30:42 +0200 |
commit | 007c1d9c0ab0f8d9a87d3f9bc8e134fd718cd284 (patch) | |
tree | 984eb2771772f34b168fe353ffccedcd3b50ed73 /lib | |
parent | b63a96989d45a4e68622db24e15722a5138d963e (diff) | |
download | gnutls-007c1d9c0ab0f8d9a87d3f9bc8e134fd718cd284.tar.gz |
x509/output: print RFC5280 CIDRs in name constraints
Diffstat (limited to 'lib')
-rw-r--r-- | lib/x509/output.c | 107 |
1 files changed, 98 insertions, 9 deletions
diff --git a/lib/x509/output.c b/lib/x509/output.c index 3398062460..4326debf08 100644 --- a/lib/x509/output.c +++ b/lib/x509/output.c @@ -69,8 +69,94 @@ char *ip_to_string(void *_ip, int ip_size, char *string, return inet_ntop(AF_INET6, _ip, string, string_size); } +static int bit_count(uint32_t i) +{ + int c = 0; + unsigned int seen_one = 0; + + while (i > 0) { + if (i & 1) { + seen_one = 1; + c++; + } else { + if (seen_one) { + return -1; + } + } + i >>= 1; + } + + return c; +} + +static unsigned mask_to_prefix(uint8_t mask[4]) +{ + uint32_t m; + + memcpy(&m, mask, 4); + m = ntohl(m); + return bit_count(m); +} + +static unsigned mask6_to_prefix(uint8_t mask[16]) +{ + unsigned i, c = 0; + for (i=0; i<16; i++) { + if (mask[i] == 0xFF) { + c += 8; + } else { + switch(mask[i]) { + case 0xFE: c += 7; break; + case 0xFC: c += 6; break; + case 0xF8: c += 5; break; + case 0xF0: c += 4; break; + case 0xE0: c += 3; break; + case 0xC0: c += 2; break; + case 0x80: c += 1; break; + case 0x00: break; + default: + return 0; + } + break; + } + } + + return c; +} + +static const +char *cidr_to_string(void *_ip, int ip_size, char *string, + int string_size) +{ + uint8_t *ip = _ip; + char tmp[64]; + const char *p; + + if (ip_size != 8 && ip_size != 32) { + gnutls_assert(); + return NULL; + } + + if (ip_size == 8) { + p = inet_ntop(AF_INET, ip, tmp, sizeof(tmp)); + + if (p) + snprintf(string, string_size, "%s/%u", tmp, mask_to_prefix(ip+4)); + } else { + p = inet_ntop(AF_INET6, ip, tmp, sizeof(tmp)); + + if (p) + snprintf(string, string_size, "%s/%u", tmp, mask6_to_prefix(ip+16)); + } + + if (p == NULL) + return NULL; + + return string; +} + static void -print_name(gnutls_buffer_st *str, const char *prefix, unsigned type, gnutls_datum_t *name) +print_name(gnutls_buffer_st *str, const char *prefix, unsigned type, gnutls_datum_t *name, unsigned ip_is_cidr) { char *sname = (char*)name->data; char str_ip[64]; @@ -127,7 +213,10 @@ unsigned i; break; case GNUTLS_SAN_IPADDRESS: - p = ip_to_string(name->data, name->size, str_ip, sizeof(str_ip)); + if (!ip_is_cidr) + p = ip_to_string(name->data, name->size, str_ip, sizeof(str_ip)); + else + p = cidr_to_string(name->data, name->size, str_ip, sizeof(str_ip)); if (p == NULL) p = ERROR_STR; addf(str, "%sIPAddress: %s\n", prefix, p); @@ -211,7 +300,7 @@ static void print_nc(gnutls_buffer_st * str, const char* prefix, gnutls_datum_t if (idx == 1) addf(str, _("%s\t\t\tPermitted:\n"), prefix); - print_name(str, new_prefix, type, &name); + print_name(str, new_prefix, type, &name, 1); } } while (ret == 0); @@ -223,7 +312,7 @@ static void print_nc(gnutls_buffer_st * str, const char* prefix, gnutls_datum_t if (idx == 1) addf(str, _("%s\t\t\tExcluded:\n"), prefix); - print_name(str, new_prefix, type, &name); + print_name(str, new_prefix, type, &name, 1); } } while (ret == 0); @@ -269,7 +358,7 @@ static void print_aia(gnutls_buffer_st * str, const gnutls_datum_t *der) } adds(str, "\t\t\tAccess Location "); - print_name(str, "", san_type, &san); + print_name(str, "", san_type, &san, 0); } return; @@ -320,7 +409,7 @@ print_aki_gn_serial(gnutls_buffer_st * str, gnutls_x509_aki_t aki) return; } - print_name(str, "\t\t\t", alt_type, &san); + print_name(str, "\t\t\t", alt_type, &san, 0); adds(str, "\t\t\tserial: "); _gnutls_buffer_hexprint(str, serial.data, serial.size); @@ -476,7 +565,7 @@ static void print_crldist(gnutls_buffer_st * str, gnutls_datum_t *der) return; } - print_name(str, "\t\t\t", type, &dist); + print_name(str, "\t\t\t", type, &dist, 0); } cleanup: gnutls_x509_crl_dist_points_deinit(dp); @@ -612,7 +701,7 @@ print_altname(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t *der) err = gnutls_x509_othername_to_virtual((char*)othername.data, &san, &vtype, &virt); if (err >= 0) { snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix); - print_name(str, pfx, vtype, &virt); + print_name(str, pfx, vtype, &virt, 0); gnutls_free(virt.data); continue; } @@ -630,7 +719,7 @@ print_altname(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t *der) } else { snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix); - print_name(str, pfx, type, &san); + print_name(str, pfx, type, &san, 0); } } gnutls_subject_alt_names_deinit(names); |