Use better IP parsing in x509 programs
Remove unnecessary duplicated code. Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
This commit is contained in:
parent
13230a4ad3
commit
cd17ecfe85
5 changed files with 37 additions and 88 deletions
|
@ -500,6 +500,23 @@ int mbedtls_x509_info_cert_type(char **buf, size_t *size,
|
||||||
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
|
int mbedtls_x509_info_key_usage(char **buf, size_t *size,
|
||||||
unsigned int key_usage);
|
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 \
|
#define MBEDTLS_X509_SAFE_SNPRINTF \
|
||||||
do { \
|
do { \
|
||||||
if (ret < 0 || (size_t) ret >= n) \
|
if (ret < 0 || (size_t) ret >= n) \
|
||||||
|
|
|
@ -2862,7 +2862,6 @@ static int x509_inet_pton_ipv4(const char *src, void *dst)
|
||||||
|
|
||||||
#endif /* !AF_INET6 || MBEDTLS_TEST_SW_INET_PTON */ //no-check-names
|
#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)
|
size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst)
|
||||||
{
|
{
|
||||||
return strchr(cn, ':') == NULL
|
return strchr(cn, ':') == 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 */
|
|
|
@ -116,18 +116,6 @@ struct options {
|
||||||
mbedtls_md_type_t md_alg; /* Hash algorithm used for signature. */
|
mbedtls_md_type_t md_alg; /* Hash algorithm used for signature. */
|
||||||
} opt;
|
} 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 write_certificate_request(mbedtls_x509write_csr *req, const char *output_file,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t),
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
void *p_rng)
|
void *p_rng)
|
||||||
|
@ -165,12 +153,13 @@ int main(int argc, char *argv[])
|
||||||
mbedtls_pk_context key;
|
mbedtls_pk_context key;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int i;
|
int i;
|
||||||
char *p, *q, *r, *r2;
|
char *p, *q, *r, *subtype_value;
|
||||||
mbedtls_x509write_csr req;
|
mbedtls_x509write_csr req;
|
||||||
mbedtls_entropy_context entropy;
|
mbedtls_entropy_context entropy;
|
||||||
mbedtls_ctr_drbg_context ctr_drbg;
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
const char *pers = "csr example app";
|
const char *pers = "csr example app";
|
||||||
mbedtls_x509_san_list *cur, *prev;
|
mbedtls_x509_san_list *cur, *prev;
|
||||||
|
uint8_t ip[4] = { 0 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set to sane values
|
* Set to sane values
|
||||||
|
@ -231,8 +220,6 @@ usage:
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
|
|
||||||
while (q != NULL) {
|
while (q != NULL) {
|
||||||
uint8_t ip[4] = { 0 };
|
|
||||||
|
|
||||||
if ((r = strchr(q, ';')) != NULL) {
|
if ((r = strchr(q, ';')) != NULL) {
|
||||||
*r++ = '\0';
|
*r++ = '\0';
|
||||||
}
|
}
|
||||||
|
@ -245,8 +232,8 @@ usage:
|
||||||
|
|
||||||
cur->next = NULL;
|
cur->next = NULL;
|
||||||
|
|
||||||
if ((r2 = strchr(q, ':')) != NULL) {
|
if ((subtype_value = strchr(q, ':')) != NULL) {
|
||||||
*r2++ = '\0';
|
*subtype_value++ = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(q, "URI") == 0) {
|
if (strcmp(q, "URI") == 0) {
|
||||||
|
@ -254,8 +241,12 @@ usage:
|
||||||
} else if (strcmp(q, "DNS") == 0) {
|
} else if (strcmp(q, "DNS") == 0) {
|
||||||
cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
|
cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
|
||||||
} else if (strcmp(q, "IP") == 0) {
|
} else if (strcmp(q, "IP") == 0) {
|
||||||
|
size_t ip_len = 0;
|
||||||
cur->node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
|
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 {
|
} else {
|
||||||
mbedtls_free(cur);
|
mbedtls_free(cur);
|
||||||
goto usage;
|
goto usage;
|
||||||
|
@ -265,7 +256,7 @@ usage:
|
||||||
cur->node.san.unstructured_name.p = (unsigned char *) ip;
|
cur->node.san.unstructured_name.p = (unsigned char *) ip;
|
||||||
cur->node.san.unstructured_name.len = sizeof(ip);
|
cur->node.san.unstructured_name.len = sizeof(ip);
|
||||||
} else {
|
} else {
|
||||||
q = r2;
|
q = subtype_value;
|
||||||
cur->node.san.unstructured_name.p = (unsigned char *) q;
|
cur->node.san.unstructured_name.p = (unsigned char *) q;
|
||||||
cur->node.san.unstructured_name.len = strlen(q);
|
cur->node.san.unstructured_name.len = strlen(q);
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,18 +216,6 @@ struct options {
|
||||||
int format; /* format */
|
int format; /* format */
|
||||||
} opt;
|
} 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 write_certificate(mbedtls_x509write_cert *crt, const char *output_file,
|
||||||
int (*f_rng)(void *, unsigned char *, size_t),
|
int (*f_rng)(void *, unsigned char *, size_t),
|
||||||
void *p_rng)
|
void *p_rng)
|
||||||
|
@ -601,8 +589,14 @@ usage:
|
||||||
} else if (strcmp(q, "DNS") == 0) {
|
} else if (strcmp(q, "DNS") == 0) {
|
||||||
cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
|
cur->node.type = MBEDTLS_X509_SAN_DNS_NAME;
|
||||||
} else if (strcmp(q, "IP") == 0) {
|
} else if (strcmp(q, "IP") == 0) {
|
||||||
|
size_t ip_len = 0;
|
||||||
cur->node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
|
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.p = (unsigned char *) ip;
|
||||||
cur->node.san.unstructured_name.len = sizeof(ip);
|
cur->node.san.unstructured_name.len = sizeof(ip);
|
||||||
} else if (strcmp(q, "DN") == 0) {
|
} else if (strcmp(q, "DN") == 0) {
|
||||||
|
@ -625,8 +619,9 @@ usage:
|
||||||
if (cur->node.type == MBEDTLS_X509_SAN_RFC822_NAME ||
|
if (cur->node.type == MBEDTLS_X509_SAN_RFC822_NAME ||
|
||||||
cur->node.type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER ||
|
cur->node.type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER ||
|
||||||
cur->node.type == MBEDTLS_X509_SAN_DNS_NAME) {
|
cur->node.type == MBEDTLS_X509_SAN_DNS_NAME) {
|
||||||
cur->node.san.unstructured_name.p = (unsigned char *) subtype_value;
|
q = subtype_value;
|
||||||
cur->node.san.unstructured_name.len = strlen(subtype_value);
|
cur->node.san.unstructured_name.p = (unsigned char *) q;
|
||||||
|
cur->node.san.unstructured_name.len = strlen(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev == NULL) {
|
if (prev == NULL) {
|
||||||
|
|
Loading…
Reference in a new issue