Add support for parsing SAN IP address

Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
diff --git a/library/x509.c b/library/x509.c
index 8a44264..32846f9 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -1438,7 +1438,18 @@
                    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 @@
             memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf));
         }
         break;
-
         /*
          * directoryName
          */
@@ -1576,27 +1586,47 @@
             /*
              * 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;