summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-03-29 15:04:11 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-03-31 13:30:42 +0200
commit007c1d9c0ab0f8d9a87d3f9bc8e134fd718cd284 (patch)
tree984eb2771772f34b168fe353ffccedcd3b50ed73 /lib
parentb63a96989d45a4e68622db24e15722a5138d963e (diff)
downloadgnutls-007c1d9c0ab0f8d9a87d3f9bc8e134fd718cd284.tar.gz
x509/output: print RFC5280 CIDRs in name constraints
Diffstat (limited to 'lib')
-rw-r--r--lib/x509/output.c107
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);