diff --git a/library/x509.c b/library/x509.c index 8a4426478..32846f9cf 100644 --- a/library/x509.c +++ b/library/x509.c @@ -1438,7 +1438,18 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, san_buf, sizeof(*san_buf)); } break; + /* + * IP address + */ + case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_IP_ADDRESS): + { + memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); + san->type = MBEDTLS_X509_SAN_IP_ADDRESS; + memcpy(&san->san.unstructured_name, + san_buf, sizeof(*san_buf)); + } + break; /* * rfc822Name */ @@ -1449,7 +1460,6 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf)); } break; - /* * directoryName */ @@ -1576,27 +1586,47 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size, /* * dNSName * RFC822 Name + * iPAddress */ case MBEDTLS_X509_SAN_DNS_NAME: case MBEDTLS_X509_SAN_RFC822_NAME: + case MBEDTLS_X509_SAN_IP_ADDRESS: { const char *dns_name = "dNSName"; const char *rfc822_name = "rfc822Name"; + const char *ip_name = "iPAddress"; + + const char *name = san.type == MBEDTLS_X509_SAN_DNS_NAME ? dns_name : san.type == + MBEDTLS_X509_SAN_RFC822_NAME ? rfc822_name : ip_name; ret = mbedtls_snprintf(p, n, "\n%s %s : ", prefix, - san.type == - MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name); + name); MBEDTLS_X509_SAFE_SNPRINTF; if (san.san.unstructured_name.len >= n) { *p = '\0'; return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; } - memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len); - p += san.san.unstructured_name.len; - n -= san.san.unstructured_name.len; + if (san.type == MBEDTLS_X509_SAN_IP_ADDRESS) { + int len = 0; + unsigned char *ip = san.san.unstructured_name.p; + // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported + if (san.san.unstructured_name.len == 4) { + len = sprintf(p, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + } else { + len = sprintf(p, "%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X", + ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], + ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]); + } + p += len; + n -= len; + } else { + memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len); + p += san.san.unstructured_name.len; + n -= san.san.unstructured_name.len; + } } break;