Move common functions for crt/csr parsing to x509.c

Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
diff --git a/library/x509.c b/library/x509.c
index 1b3701c..9869b05 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -1107,4 +1107,490 @@
     return 0;
 }
 #endif /* MBEDTLS_HAVE_TIME_DATE */
+
+/* Common functions for parsing CRT and CSR. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C)
+/*
+ * OtherName ::= SEQUENCE {
+ *      type-id    OBJECT IDENTIFIER,
+ *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * HardwareModuleName ::= SEQUENCE {
+ *                           hwType OBJECT IDENTIFIER,
+ *                           hwSerialNum OCTET STRING }
+ *
+ * NOTE: we currently only parse and use otherName of type HwModuleName,
+ * as defined in RFC 4108.
+ */
+static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
+                               mbedtls_x509_san_other_name *other_name)
+{
+    int ret = 0;
+    size_t len;
+    unsigned char *p = subject_alt_name->p;
+    const unsigned char *end = p + subject_alt_name->len;
+    mbedtls_x509_buf cur_oid;
+
+    if ((subject_alt_name->tag &
+         (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
+        (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
+        /*
+         * The given subject alternative name is not of type "othername".
+         */
+        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
+    }
+
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_OID)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    cur_oid.tag = MBEDTLS_ASN1_OID;
+    cur_oid.p = p;
+    cur_oid.len = len;
+
+    /*
+     * Only HwModuleName is currently supported.
+     */
+    if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
+        return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+    }
+
+    if (p + len >= end) {
+        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+    p += len;
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
+        0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
+    other_name->value.hardware_module_name.oid.p = p;
+    other_name->value.hardware_module_name.oid.len = len;
+
+    if (p + len >= end) {
+        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+    p += len;
+    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+                                    MBEDTLS_ASN1_OCTET_STRING)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
+    other_name->value.hardware_module_name.val.p = p;
+    other_name->value.hardware_module_name.val.len = len;
+    p += len;
+    if (p != end) {
+        mbedtls_platform_zeroize(other_name,
+                                 sizeof(*other_name));
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+    return 0;
+}
+
+/*
+ * SubjectAltName ::= GeneralNames
+ *
+ * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+ *
+ * GeneralName ::= CHOICE {
+ *      otherName                       [0]     OtherName,
+ *      rfc822Name                      [1]     IA5String,
+ *      dNSName                         [2]     IA5String,
+ *      x400Address                     [3]     ORAddress,
+ *      directoryName                   [4]     Name,
+ *      ediPartyName                    [5]     EDIPartyName,
+ *      uniformResourceIdentifier       [6]     IA5String,
+ *      iPAddress                       [7]     OCTET STRING,
+ *      registeredID                    [8]     OBJECT IDENTIFIER }
+ *
+ * OtherName ::= SEQUENCE {
+ *      type-id    OBJECT IDENTIFIER,
+ *      value      [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * EDIPartyName ::= SEQUENCE {
+ *      nameAssigner            [0]     DirectoryString OPTIONAL,
+ *      partyName               [1]     DirectoryString }
+ *
+ * NOTE: we list all types, but only use dNSName and otherName
+ * of type HwModuleName, as defined in RFC 4108, at this point.
+ */
+int mbedtls_x509_get_subject_alt_name(unsigned char **p,
+                                      const unsigned char *end,
+                                      mbedtls_x509_sequence *subject_alt_name)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t len, tag_len;
+    mbedtls_asn1_buf *buf;
+    unsigned char tag;
+    mbedtls_asn1_sequence *cur = subject_alt_name;
+
+    /* Get main sequence tag */
+    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
+                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if (*p + len != end) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+
+    while (*p < end) {
+        mbedtls_x509_subject_alternative_name dummy_san_buf;
+        memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
+
+        tag = **p;
+        (*p)++;
+        if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+        }
+
+        if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
+            MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
+            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
+        }
+
+        /*
+         * Check that the SAN is structured correctly.
+         */
+        ret = mbedtls_x509_parse_subject_alt_name(&(cur->buf), &dummy_san_buf);
+        /*
+         * In case the extension is malformed, return an error,
+         * and clear the allocated sequences.
+         */
+        if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
+            mbedtls_asn1_sequence_free(subject_alt_name->next);
+            subject_alt_name->next = NULL;
+            return ret;
+        }
+
+        /* Allocate and assign next pointer */
+        if (cur->buf.p != NULL) {
+            if (cur->next != NULL) {
+                return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
+            }
+
+            cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
+
+            if (cur->next == NULL) {
+                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                         MBEDTLS_ERR_ASN1_ALLOC_FAILED);
+            }
+
+            cur = cur->next;
+        }
+
+        buf = &(cur->buf);
+        buf->tag = tag;
+        buf->p = *p;
+        buf->len = tag_len;
+        *p += buf->len;
+    }
+
+    /* Set final sequence entry's next pointer to NULL */
+    cur->next = NULL;
+
+    if (*p != end) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
+    }
+
+    return 0;
+}
+
+int mbedtls_x509_get_ns_cert_type(unsigned char **p,
+                                  const unsigned char *end,
+                                  unsigned char *ns_cert_type)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
+
+    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if (bs.len == 0) {
+        *ns_cert_type = 0;
+        return 0;
+    }
+
+    if (bs.len != 1) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
+    }
+
+    /* Get actual bitstring */
+    *ns_cert_type = *bs.p;
+    return 0;
+}
+
+int mbedtls_x509_get_key_usage(unsigned char **p,
+                               const unsigned char *end,
+                               unsigned int *key_usage)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t i;
+    mbedtls_x509_bitstring bs = { 0, 0, NULL };
+
+    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
+    }
+
+    if (bs.len == 0) {
+        *key_usage = 0;
+        return 0;
+    }
+
+    if (bs.len < 1) {
+        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
+    }
+
+    /* Get actual bitstring */
+    *key_usage = 0;
+    for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
+        *key_usage |= (unsigned int) bs.p[i] << (8*i);
+    }
+
+    return 0;
+}
+
+int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
+                                        mbedtls_x509_subject_alternative_name *san)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    switch (san_buf->tag &
+            (MBEDTLS_ASN1_TAG_CLASS_MASK |
+             MBEDTLS_ASN1_TAG_VALUE_MASK)) {
+        /*
+         * otherName
+         */
+        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
+        {
+            mbedtls_x509_san_other_name other_name;
+
+            ret = x509_get_other_name(san_buf, &other_name);
+            if (ret != 0) {
+                return ret;
+            }
+
+            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
+            san->type = MBEDTLS_X509_SAN_OTHER_NAME;
+            memcpy(&san->san.other_name,
+                   &other_name, sizeof(other_name));
+
+        }
+        break;
+
+        /*
+         * dNSName
+         */
+        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
+        {
+            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
+            san->type = MBEDTLS_X509_SAN_DNS_NAME;
+
+            memcpy(&san->san.unstructured_name,
+                   san_buf, sizeof(*san_buf));
+
+        }
+        break;
+
+        /*
+         * Type not supported
+         */
+        default:
+            return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+    }
+    return 0;
+}
+
+#if !defined(MBEDTLS_X509_REMOVE_INFO)
+int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
+                                       const mbedtls_x509_sequence
+                                       *subject_alt_name,
+                                       const char *prefix)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t i;
+    size_t n = *size;
+    char *p = *buf;
+    const mbedtls_x509_sequence *cur = subject_alt_name;
+    mbedtls_x509_subject_alternative_name san;
+    int parse_ret;
+
+    while (cur != NULL) {
+        memset(&san, 0, sizeof(san));
+        parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
+        if (parse_ret != 0) {
+            if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
+                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+            } else {
+                ret = mbedtls_snprintf(p, n, "\n%s    <malformed>", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+            }
+            cur = cur->next;
+            continue;
+        }
+
+        switch (san.type) {
+            /*
+             * otherName
+             */
+            case MBEDTLS_X509_SAN_OTHER_NAME:
+            {
+                mbedtls_x509_san_other_name *other_name = &san.san.other_name;
+
+                ret = mbedtls_snprintf(p, n, "\n%s    otherName :", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+
+                if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
+                                    &other_name->value.hardware_module_name.oid) != 0) {
+                    ret = mbedtls_snprintf(p, n, "\n%s        hardware module name :", prefix);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+                    ret =
+                        mbedtls_snprintf(p, n, "\n%s            hardware type          : ", prefix);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+
+                    ret = mbedtls_oid_get_numeric_string(p,
+                                                         n,
+                                                         &other_name->value.hardware_module_name.oid);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+
+                    ret =
+                        mbedtls_snprintf(p, n, "\n%s            hardware serial number : ", prefix);
+                    MBEDTLS_X509_SAFE_SNPRINTF;
+
+                    for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
+                        ret = mbedtls_snprintf(p,
+                                               n,
+                                               "%02X",
+                                               other_name->value.hardware_module_name.val.p[i]);
+                        MBEDTLS_X509_SAFE_SNPRINTF;
+                    }
+                }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
+            }
+            break;
+
+            /*
+             * dNSName
+             */
+            case MBEDTLS_X509_SAN_DNS_NAME:
+            {
+                ret = mbedtls_snprintf(p, n, "\n%s    dNSName : ", prefix);
+                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;
+            }
+            break;
+
+            /*
+             * Type not supported, skip item.
+             */
+            default:
+                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
+                MBEDTLS_X509_SAFE_SNPRINTF;
+                break;
+        }
+
+        cur = cur->next;
+    }
+
+    *p = '\0';
+
+    *size = n;
+    *buf = p;
+
+    return 0;
+}
+
+#define PRINT_ITEM(i)                           \
+    {                                           \
+        ret = mbedtls_snprintf(p, n, "%s" i, sep);    \
+        MBEDTLS_X509_SAFE_SNPRINTF;                        \
+        sep = ", ";                             \
+    }
+
+#define CERT_TYPE(type, name)                    \
+    if (ns_cert_type & (type))                 \
+    PRINT_ITEM(name);
+
+int mbedtls_x509_info_cert_type(char **buf, size_t *size,
+                                unsigned char ns_cert_type)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t n = *size;
+    char *p = *buf;
+    const char *sep = "";
+
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA");
+    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA");
+
+    *size = n;
+    *buf = p;
+
+    return 0;
+}
+
+#define KEY_USAGE(code, name)    \
+    if (key_usage & (code))    \
+    PRINT_ITEM(name);
+
+int mbedtls_x509_info_key_usage(char **buf, size_t *size,
+                                unsigned int key_usage)
+{
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t n = *size;
+    char *p = *buf;
+    const char *sep = "";
+
+    KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature");
+    KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation");
+    KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment");
+    KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment");
+    KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement");
+    KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign");
+    KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign");
+    KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only");
+    KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only");
+
+    *size = n;
+    *buf = p;
+
+    return 0;
+}
+#endif /* MBEDTLS_X509_REMOVE_INFO */
+#endif /* MBEDTLS_X509_CRT_PARSE_C || MBEDTLS_X509_CSR_PARSE_C */
 #endif /* MBEDTLS_X509_USE_C */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index f77991e..5997c87 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -562,63 +562,6 @@
     return 0;
 }
 
-int mbedtls_x509_get_ns_cert_type(unsigned char **p,
-                                  const unsigned char *end,
-                                  unsigned char *ns_cert_type)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    mbedtls_x509_bitstring bs = { 0, 0, NULL };
-
-    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if (bs.len == 0) {
-        *ns_cert_type = 0;
-        return 0;
-    }
-
-    if (bs.len != 1) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
-    }
-
-    /* Get actual bitstring */
-    *ns_cert_type = *bs.p;
-    return 0;
-}
-
-int mbedtls_x509_get_key_usage(unsigned char **p,
-                               const unsigned char *end,
-                               unsigned int *key_usage)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i;
-    mbedtls_x509_bitstring bs = { 0, 0, NULL };
-
-    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if (bs.len == 0) {
-        *key_usage = 0;
-        return 0;
-    }
-
-    if (bs.len < 1) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
-    }
-
-    /* Get actual bitstring */
-    *key_usage = 0;
-    for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
-        *key_usage |= (unsigned int) bs.p[i] << (8*i);
-    }
-
-    return 0;
-}
-
 /*
  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
  *
@@ -644,118 +587,6 @@
 }
 
 /*
- * SubjectAltName ::= GeneralNames
- *
- * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
- *
- * GeneralName ::= CHOICE {
- *      otherName                       [0]     OtherName,
- *      rfc822Name                      [1]     IA5String,
- *      dNSName                         [2]     IA5String,
- *      x400Address                     [3]     ORAddress,
- *      directoryName                   [4]     Name,
- *      ediPartyName                    [5]     EDIPartyName,
- *      uniformResourceIdentifier       [6]     IA5String,
- *      iPAddress                       [7]     OCTET STRING,
- *      registeredID                    [8]     OBJECT IDENTIFIER }
- *
- * OtherName ::= SEQUENCE {
- *      type-id    OBJECT IDENTIFIER,
- *      value      [0] EXPLICIT ANY DEFINED BY type-id }
- *
- * EDIPartyName ::= SEQUENCE {
- *      nameAssigner            [0]     DirectoryString OPTIONAL,
- *      partyName               [1]     DirectoryString }
- *
- * NOTE: we list all types, but only use dNSName and otherName
- * of type HwModuleName, as defined in RFC 4108, at this point.
- */
-int mbedtls_x509_get_subject_alt_name(unsigned char **p,
-                                      const unsigned char *end,
-                                      mbedtls_x509_sequence *subject_alt_name)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t len, tag_len;
-    mbedtls_asn1_buf *buf;
-    unsigned char tag;
-    mbedtls_asn1_sequence *cur = subject_alt_name;
-
-    /* Get main sequence tag */
-    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
-                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if (*p + len != end) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-
-    while (*p < end) {
-        mbedtls_x509_subject_alternative_name dummy_san_buf;
-        memset(&dummy_san_buf, 0, sizeof(dummy_san_buf));
-
-        tag = **p;
-        (*p)++;
-        if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
-            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-        }
-
-        if ((tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
-            MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
-            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
-        }
-
-        /*
-         * Check that the SAN is structured correctly.
-         */
-        ret = mbedtls_x509_parse_subject_alt_name(&(cur->buf), &dummy_san_buf);
-        /*
-         * In case the extension is malformed, return an error,
-         * and clear the allocated sequences.
-         */
-        if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
-            mbedtls_asn1_sequence_free(subject_alt_name->next);
-            subject_alt_name->next = NULL;
-            return ret;
-        }
-
-        /* Allocate and assign next pointer */
-        if (cur->buf.p != NULL) {
-            if (cur->next != NULL) {
-                return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
-            }
-
-            cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
-
-            if (cur->next == NULL) {
-                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                         MBEDTLS_ERR_ASN1_ALLOC_FAILED);
-            }
-
-            cur = cur->next;
-        }
-
-        buf = &(cur->buf);
-        buf->tag = tag;
-        buf->p = *p;
-        buf->len = tag_len;
-        *p += buf->len;
-    }
-
-    /* Set final sequence entry's next pointer to NULL */
-    cur->next = NULL;
-
-    if (*p != end) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-
-    return 0;
-}
-
-/*
  * id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }
  *
  * anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
@@ -1713,319 +1544,7 @@
 }
 #endif /* MBEDTLS_FS_IO */
 
-/*
- * OtherName ::= SEQUENCE {
- *      type-id    OBJECT IDENTIFIER,
- *      value      [0] EXPLICIT ANY DEFINED BY type-id }
- *
- * HardwareModuleName ::= SEQUENCE {
- *                           hwType OBJECT IDENTIFIER,
- *                           hwSerialNum OCTET STRING }
- *
- * NOTE: we currently only parse and use otherName of type HwModuleName,
- * as defined in RFC 4108.
- */
-static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
-                               mbedtls_x509_san_other_name *other_name)
-{
-    int ret = 0;
-    size_t len;
-    unsigned char *p = subject_alt_name->p;
-    const unsigned char *end = p + subject_alt_name->len;
-    mbedtls_x509_buf cur_oid;
-
-    if ((subject_alt_name->tag &
-         (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
-        (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
-        /*
-         * The given subject alternative name is not of type "othername".
-         */
-        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
-    }
-
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_OID)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    cur_oid.tag = MBEDTLS_ASN1_OID;
-    cur_oid.p = p;
-    cur_oid.len = len;
-
-    /*
-     * Only HwModuleName is currently supported.
-     */
-    if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
-        return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
-    }
-
-    if (p + len >= end) {
-        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-    p += len;
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
-        0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
-    other_name->value.hardware_module_name.oid.p = p;
-    other_name->value.hardware_module_name.oid.len = len;
-
-    if (p + len >= end) {
-        mbedtls_platform_zeroize(other_name, sizeof(*other_name));
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-    p += len;
-    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
-                                    MBEDTLS_ASN1_OCTET_STRING)) != 0) {
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
-    }
-
-    other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
-    other_name->value.hardware_module_name.val.p = p;
-    other_name->value.hardware_module_name.val.len = len;
-    p += len;
-    if (p != end) {
-        mbedtls_platform_zeroize(other_name,
-                                 sizeof(*other_name));
-        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
-                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
-    }
-    return 0;
-}
-
-int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
-                                        mbedtls_x509_subject_alternative_name *san)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    switch (san_buf->tag &
-            (MBEDTLS_ASN1_TAG_CLASS_MASK |
-             MBEDTLS_ASN1_TAG_VALUE_MASK)) {
-        /*
-         * otherName
-         */
-        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
-        {
-            mbedtls_x509_san_other_name other_name;
-
-            ret = x509_get_other_name(san_buf, &other_name);
-            if (ret != 0) {
-                return ret;
-            }
-
-            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
-            san->type = MBEDTLS_X509_SAN_OTHER_NAME;
-            memcpy(&san->san.other_name,
-                   &other_name, sizeof(other_name));
-
-        }
-        break;
-
-        /*
-         * dNSName
-         */
-        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
-        {
-            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
-            san->type = MBEDTLS_X509_SAN_DNS_NAME;
-
-            memcpy(&san->san.unstructured_name,
-                   san_buf, sizeof(*san_buf));
-
-        }
-        break;
-
-        /*
-         * Type not supported
-         */
-        default:
-            return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
-    }
-    return 0;
-}
-
 #if !defined(MBEDTLS_X509_REMOVE_INFO)
-int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
-                                       const mbedtls_x509_sequence
-                                       *subject_alt_name,
-                                       const char *prefix)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t i;
-    size_t n = *size;
-    char *p = *buf;
-    const mbedtls_x509_sequence *cur = subject_alt_name;
-    mbedtls_x509_subject_alternative_name san;
-    int parse_ret;
-
-    while (cur != NULL) {
-        memset(&san, 0, sizeof(san));
-        parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
-        if (parse_ret != 0) {
-            if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
-                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-            } else {
-                ret = mbedtls_snprintf(p, n, "\n%s    <malformed>", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-            }
-            cur = cur->next;
-            continue;
-        }
-
-        switch (san.type) {
-            /*
-             * otherName
-             */
-            case MBEDTLS_X509_SAN_OTHER_NAME:
-            {
-                mbedtls_x509_san_other_name *other_name = &san.san.other_name;
-
-                ret = mbedtls_snprintf(p, n, "\n%s    otherName :", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-
-                if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
-                                    &other_name->value.hardware_module_name.oid) != 0) {
-                    ret = mbedtls_snprintf(p, n, "\n%s        hardware module name :", prefix);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-                    ret =
-                        mbedtls_snprintf(p, n, "\n%s            hardware type          : ", prefix);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-
-                    ret = mbedtls_oid_get_numeric_string(p,
-                                                         n,
-                                                         &other_name->value.hardware_module_name.oid);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-
-                    ret =
-                        mbedtls_snprintf(p, n, "\n%s            hardware serial number : ", prefix);
-                    MBEDTLS_X509_SAFE_SNPRINTF;
-
-                    for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
-                        ret = mbedtls_snprintf(p,
-                                               n,
-                                               "%02X",
-                                               other_name->value.hardware_module_name.val.p[i]);
-                        MBEDTLS_X509_SAFE_SNPRINTF;
-                    }
-                }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
-            }
-            break;
-
-            /*
-             * dNSName
-             */
-            case MBEDTLS_X509_SAN_DNS_NAME:
-            {
-                ret = mbedtls_snprintf(p, n, "\n%s    dNSName : ", prefix);
-                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;
-            }
-            break;
-
-            /*
-             * Type not supported, skip item.
-             */
-            default:
-                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
-                MBEDTLS_X509_SAFE_SNPRINTF;
-                break;
-        }
-
-        cur = cur->next;
-    }
-
-    *p = '\0';
-
-    *size = n;
-    *buf = p;
-
-    return 0;
-}
-
-#define PRINT_ITEM(i)                           \
-    {                                           \
-        ret = mbedtls_snprintf(p, n, "%s" i, sep);    \
-        MBEDTLS_X509_SAFE_SNPRINTF;                        \
-        sep = ", ";                             \
-    }
-
-#define CERT_TYPE(type, name)                    \
-    if (ns_cert_type & (type))                 \
-    PRINT_ITEM(name);
-
-int mbedtls_x509_info_cert_type(char **buf, size_t *size,
-                                unsigned char ns_cert_type)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t n = *size;
-    char *p = *buf;
-    const char *sep = "";
-
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA");
-    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA");
-
-    *size = n;
-    *buf = p;
-
-    return 0;
-}
-
-#define KEY_USAGE(code, name)    \
-    if (key_usage & (code))    \
-    PRINT_ITEM(name);
-
-int mbedtls_x509_info_key_usage(char **buf, size_t *size,
-                                unsigned int key_usage)
-{
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
-    size_t n = *size;
-    char *p = *buf;
-    const char *sep = "";
-
-    KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature");
-    KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation");
-    KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment");
-    KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment");
-    KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement");
-    KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign");
-    KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign");
-    KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only");
-    KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only");
-
-    *size = n;
-    *buf = p;
-
-    return 0;
-}
-
 static int x509_info_ext_key_usage(char **buf, size_t *size,
                                    const mbedtls_x509_sequence *extended_key_usage)
 {