diff --git a/library/x509_crt.c b/library/x509_crt.c index d0b2a2aa7e..7def3e992c 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -49,6 +49,7 @@ #include "mbedtls/psa_util.h" #endif /* MBEDTLS_USE_PSA_CRYPTO */ #include "hash_info.h" +#include "x509_invasive.h" #include "mbedtls/platform.h" @@ -2656,7 +2657,8 @@ static int x509_inet_pton_ipv4(const char *src, void *dst) #endif /* AF_INET6 */ -static size_t x509_cn_inet_pton(const char *cn, void *dst) +MBEDTLS_STATIC_TESTABLE +size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst) { return strchr(cn, ':') == NULL ? x509_inet_pton_ipv4(cn, dst) == 0 ? 4 : 0 @@ -2687,7 +2689,7 @@ static int x509_crt_check_san_ip(const mbedtls_x509_sequence *san, const char *cn, size_t cn_len) { uint32_t ip[4]; - cn_len = x509_cn_inet_pton(cn, ip); + cn_len = mbedtls_x509_crt_parse_cn_inet_pton(cn, ip); if (cn_len == 0) { return -1; } diff --git a/library/x509_invasive.h b/library/x509_invasive.h new file mode 100644 index 0000000000..d8fd74be49 --- /dev/null +++ b/library/x509_invasive.h @@ -0,0 +1,53 @@ +/** + * \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/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 0966683f15..c1055f1270 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -1043,6 +1043,93 @@ X509 CRT verification: mismatching IPv6 in SubjectAltName depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C x509_verify:"data_files/server5-tricky-ip-san.crt":"data_files/server5-tricky-ip-san.crt":"data_files/crl_sha256.pem":"6162\:6364\:\:6F6D":MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:MBEDTLS_X509_BADCERT_CN_MISMATCH:"":"NULL" +X509 CRT parse CN: IPv4 valid address +x509_crt_parse_cn_inet_pton:"10.10.10.10":"0A0A0A0A":4 + +X509 CRT parse CN: IPv4 excess 0s +x509_crt_parse_cn_inet_pton:"10.0000.10.10":"":0 + +X509 CRT parse CN: IPv4 short address +x509_crt_parse_cn_inet_pton:"10.10.10":"":0 + +X509 CRT parse CN: IPv4 invalid ? char +x509_crt_parse_cn_inet_pton:"10.10?10.10":"":0 + +X509 CRT parse CN: IPv4 invalid - char +x509_crt_parse_cn_inet_pton:"10.-10.10.10":"":0 + +X509 CRT parse CN: IPv4 invalid + char +x509_crt_parse_cn_inet_pton:"10.+10.10.10":"":0 + +X509 CRT parse CN: IPv4 begin dot +x509_crt_parse_cn_inet_pton:".10.10.10.10":"":0 + +X509 CRT parse CN: IPv4 end dot +x509_crt_parse_cn_inet_pton:"10.10.10.10.":"":0 + +X509 CRT parse CN: IPv4 consecutive dots +x509_crt_parse_cn_inet_pton:"10.10..10.10.":"":0 + +X509 CRT parse CN: IPv4 overlarge octet 256 +x509_crt_parse_cn_inet_pton:"10.256.10.10":"":0 + +X509 CRT parse CN: IPv4 overlarge octet 1000 +x509_crt_parse_cn_inet_pton:"10.1000.10.10":"":0 + +X509 CRT parse CN: IPv4 additional octet +x509_crt_parse_cn_inet_pton:"10.10.10.10.10":"":0 + +X509 CRT parse CN: IPv6 valid address +x509_crt_parse_cn_inet_pton:"1\:2\:3\:4\:5\:6\:7\:8":"00010002000300040005000600070008":16 + +X509 CRT parse CN: IPv6 valid address shorthand +x509_crt_parse_cn_inet_pton:"6263\:\:1":"62630000000000000000000000000001":16 + +X509 CRT parse CN: IPv6 valid address shorthand start +x509_crt_parse_cn_inet_pton:"\:\:1":"00000000000000000000000000000001":16 + +X509 CRT parse CN: IPv6 valid address extra 0s +x509_crt_parse_cn_inet_pton:"0001\:\:0001\:0001":"00010000000000000000000000010001":16 + +X509 CRT parse CN: IPv6 invalid address excess 0s +x509_crt_parse_cn_inet_pton:"1\:00000\:1\:0":"":0 + +X509 CRT parse CN: IPv6 invalid address - start single colon +x509_crt_parse_cn_inet_pton:"\:6263\:\:1":"":0 + +X509 CRT parse CN: IPv6 invalid address - end single colon +x509_crt_parse_cn_inet_pton:"6263\:\:1\:":"":0 + +X509 CRT parse CN: IPv6 short address +x509_crt_parse_cn_inet_pton:"1\:1\:1":"":0 + +X509 CRT parse CN: IPv6 wildcard address +x509_crt_parse_cn_inet_pton:"\:\:":"00000000000000000000000000000000":16 + +X509 CRT parse CN: IPv6 address too long +x509_crt_parse_cn_inet_pton:"1\:2\:3\:4\:5\:6\:7\:8\:9":"":0 + +X509 CRT parse CN: IPv6 long hextet +x509_crt_parse_cn_inet_pton:"12345\:\:1":"":0 + +X509 CRT parse CN: IPv6 invalid char +x509_crt_parse_cn_inet_pton:"\:\:\:1":"":0 + +X509 CRT parse CN: IPv6 invalid - char +x509_crt_parse_cn_inet_pton:"\:\:-1\:1":"":0 + +X509 CRT parse CN: IPv6 invalid + char +x509_crt_parse_cn_inet_pton:"\:\:+1\:1":"":0 + +X509 CRT parse CN: IPv6 valid address IPv4-mapped +x509_crt_parse_cn_inet_pton:"\:\:ffff\:1.2.3.4":"00000000000000000000ffff01020304":16 + +X509 CRT parse CN: IPv6 invalid address IPv4-mapped #1 +x509_crt_parse_cn_inet_pton:"\:\:ffff\:999.2.3.4":"":0 + +X509 CRT parse CN: IPv6 invalid address IPv4-mapped #2 +x509_crt_parse_cn_inet_pton:"\:\:1.2.3.4\:ffff":"":0 + X509 CRT verification with ca callback: failure depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_MD_CAN_SHA1:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK x509_verify_ca_cb_failure:"data_files/server1.crt":"data_files/test-ca.crt":"NULL":MBEDTLS_ERR_X509_FATAL_ERROR diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index 177bc97ad3..905d62f500 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -11,6 +11,8 @@ #include "mbedtls/pk.h" #include "string.h" +#include "x509_invasive.h" + #if MBEDTLS_X509_MAX_INTERMEDIATE_CA > 19 #error "The value of MBEDTLS_X509_MAX_INTERMEDIATE_C is larger \ than the current threshold 19. To test larger values, please \ @@ -436,6 +438,19 @@ void x509_accessor_ext_types(int ext_type, int has_ext_type) } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_TEST_HOOKS */ +void x509_crt_parse_cn_inet_pton(const char *cn, data_t *exp, int ref_ret) +{ + uint32_t addr[4]; + size_t addrlen = mbedtls_x509_crt_parse_cn_inet_pton(cn, addr); + TEST_EQUAL(addrlen, (size_t) ref_ret); + + if (addrlen) { + ASSERT_COMPARE(exp->x, exp->len, addr, addrlen); + } +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */ void x509_parse_san(char *crt_file, char *result_str, int parse_result) {