Use better IP parsing in x509 programs
Remove unnecessary duplicated code.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index df6d762..d7777c9 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -500,6 +500,23 @@
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
unsigned int key_usage);
+/**
+ * \brief This function parses a CN string as an IP address.
+ *
+ * \param cn The CN string to parse. CN string MUST be NUL-terminated.
+ * \param dst The target buffer to populate with the binary IP address.
+ * The buffer MUST be 16 bytes to save IPv6, and should be
+ * 4-byte aligned if the result will be used as struct in_addr.
+ * e.g. uint32_t dst[4]
+ *
+ * \note \cn is parsed as an IPv6 address if string contains ':',
+ * else \cn is parsed as an IPv4 address.
+ *
+ * \return Length of binary IP address; num bytes written to target.
+ * \return \c 0 on failure to parse CN string as an IP address.
+ */
+size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst);
+
#define MBEDTLS_X509_SAFE_SNPRINTF \
do { \
if (ret < 0 || (size_t) ret >= n) \
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 9b3414a..edd5782 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -2862,7 +2862,6 @@
#endif /* !AF_INET6 || MBEDTLS_TEST_SW_INET_PTON */ //no-check-names
-MBEDTLS_STATIC_TESTABLE
size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst)
{
return strchr(cn, ':') == NULL
diff --git a/library/x509_invasive.h b/library/x509_invasive.h
deleted file mode 100644
index d8fd74b..0000000
--- a/library/x509_invasive.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * \file x509_invasive.h
- *
- * \brief x509 module: interfaces for invasive testing only.
- *
- * The interfaces in this file are intended for testing purposes only.
- * They SHOULD NOT be made available in library integrations except when
- * building the library for testing.
- */
-/*
- * Copyright The Mbed TLS Contributors
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MBEDTLS_X509_INVASIVE_H
-#define MBEDTLS_X509_INVASIVE_H
-
-#include "common.h"
-
-#if defined(MBEDTLS_TEST_HOOKS)
-
-/**
- * \brief This function parses a CN string as an IP address.
- *
- * \param cn The CN string to parse. CN string MUST be NUL-terminated.
- * \param dst The target buffer to populate with the binary IP address.
- * The buffer MUST be 16 bytes to save IPv6, and should be
- * 4-byte aligned if the result will be used as struct in_addr.
- * e.g. uint32_t dst[4]
- *
- * \note \cn is parsed as an IPv6 address if string contains ':',
- * else \cn is parsed as an IPv4 address.
- *
- * \return Length of binary IP address; num bytes written to target.
- * \return \c 0 on failure to parse CN string as an IP address.
- */
-size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst);
-
-#endif /* MBEDTLS_TEST_HOOKS */
-
-#endif /* MBEDTLS_X509_INVASIVE_H */
diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c
index fe060f3..531871b 100644
--- a/programs/x509/cert_req.c
+++ b/programs/x509/cert_req.c
@@ -116,18 +116,6 @@
mbedtls_md_type_t md_alg; /* Hash algorithm used for signature. */
} opt;
-static void ip_string_to_bytes(const char *str, uint8_t *bytes, int maxBytes)
-{
- for (int i = 0; i < maxBytes; i++) {
- bytes[i] = (uint8_t) strtoul(str, NULL, 10);
- str = strchr(str, '.');
- if (str == NULL || *str == '\0') {
- break;
- }
- str++;
- }
-}
-
int write_certificate_request(mbedtls_x509write_csr *req, const char *output_file,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
@@ -165,12 +153,13 @@
mbedtls_pk_context key;
char buf[1024];
int i;
- char *p, *q, *r, *r2;
+ char *p, *q, *r, *subtype_value;
mbedtls_x509write_csr req;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
const char *pers = "csr example app";
mbedtls_x509_san_list *cur, *prev;
+ uint8_t ip[4] = { 0 };
/*
* Set to sane values
@@ -231,8 +220,6 @@
prev = NULL;
while (q != NULL) {
- uint8_t ip[4] = { 0 };
-
if ((r = strchr(q, ';')) != NULL) {
*r++ = '\0';
}
@@ -245,8 +232,8 @@
cur->next = NULL;
- if ((r2 = strchr(q, ':')) != NULL) {
- *r2++ = '\0';
+ if ((subtype_value = strchr(q, ':')) != NULL) {
+ *subtype_value++ = '\0';
}
if (strcmp(q, "URI") == 0) {
@@ -254,8 +241,12 @@
} else if (strcmp(q, "DNS") == 0) {
cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
} else if (strcmp(q, "IP") == 0) {
+ size_t ip_len = 0;
cur->node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
- ip_string_to_bytes(r2, ip, 4);
+ ip_len = mbedtls_x509_crt_parse_cn_inet_pton(subtype_value, ip);
+ if (ip_len == 0) {
+ goto exit;
+ }
} else {
mbedtls_free(cur);
goto usage;
@@ -265,7 +256,7 @@
cur->node.san.unstructured_name.p = (unsigned char *) ip;
cur->node.san.unstructured_name.len = sizeof(ip);
} else {
- q = r2;
+ q = subtype_value;
cur->node.san.unstructured_name.p = (unsigned char *) q;
cur->node.san.unstructured_name.len = strlen(q);
}
diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
index e4f8886..e58f528 100644
--- a/programs/x509/cert_write.c
+++ b/programs/x509/cert_write.c
@@ -216,18 +216,6 @@
int format; /* format */
} opt;
-static void ip_string_to_bytes(const char *str, uint8_t *bytes, int maxBytes)
-{
- for (int i = 0; i < maxBytes; i++) {
- bytes[i] = (uint8_t) strtoul(str, NULL, 10);
- str = strchr(str, '.');
- if (str == NULL || *str == '\0') {
- break;
- }
- str++;
- }
-}
-
int write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
@@ -601,8 +589,14 @@
} else if (strcmp(q, "DNS") == 0) {
cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
} else if (strcmp(q, "IP") == 0) {
+ size_t ip_len = 0;
cur->node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
- ip_string_to_bytes(subtype_value, ip, 4);
+ ip_len = mbedtls_x509_crt_parse_cn_inet_pton(subtype_value, ip);
+ if (ip_len == 0) {
+ mbedtls_printf("mbedtls_x509_crt_parse_cn_inet_pton failed to parse %s\n",
+ subtype_value);
+ goto exit;
+ }
cur->node.san.unstructured_name.p = (unsigned char *) ip;
cur->node.san.unstructured_name.len = sizeof(ip);
} else if (strcmp(q, "DN") == 0) {
@@ -625,8 +619,9 @@
if (cur->node.type == MBEDTLS_X509_SAN_RFC822_NAME ||
cur->node.type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER ||
cur->node.type == MBEDTLS_X509_SAN_DNS_NAME) {
- cur->node.san.unstructured_name.p = (unsigned char *) subtype_value;
- cur->node.san.unstructured_name.len = strlen(subtype_value);
+ q = subtype_value;
+ cur->node.san.unstructured_name.p = (unsigned char *) q;
+ cur->node.san.unstructured_name.len = strlen(q);
}
if (prev == NULL) {