Merge pull request #9638 from gilles-peskine-arm/ssl-opt-sample-programs-dev
Test sample programs in ssl-opt.sh
diff --git a/ChangeLog.d/split-numeric-string-conversions-out-of-the-oid-module.txt b/ChangeLog.d/split-numeric-string-conversions-out-of-the-oid-module.txt
new file mode 100644
index 0000000..938e9ec
--- /dev/null
+++ b/ChangeLog.d/split-numeric-string-conversions-out-of-the-oid-module.txt
@@ -0,0 +1,4 @@
+Changes
+ * Functions regarding numeric string conversions for OIDs have been moved
+ from the OID module and now reside in X.509 module. This helps to reduce
+ the code size as these functions are not commonly used outside of X.509.
diff --git a/framework b/framework
index 8c488b1..4e9e839 160000
--- a/framework
+++ b/framework
@@ -1 +1 @@
-Subproject commit 8c488b1b8f86384450c922f22cd1bee0b996be13
+Subproject commit 4e9e8391cd64974d16234160532ef2d6dec9ced6
diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
index 453f598..18df19c 100644
--- a/include/mbedtls/x509.h
+++ b/include/mbedtls/x509.h
@@ -492,6 +492,38 @@
p += (size_t) ret; \
} while (0)
+/**
+ * \brief Translate an ASN.1 OID into its numeric representation
+ * (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549")
+ *
+ * \param buf buffer to put representation in
+ * \param size size of the buffer
+ * \param oid OID to translate
+ *
+ * \return Length of the string written (excluding final NULL) or
+ * MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error
+ */
+int mbedtls_oid_get_numeric_string(char *buf, size_t size, const mbedtls_asn1_buf *oid);
+
+/**
+ * \brief Translate a string containing a dotted-decimal
+ * representation of an ASN.1 OID into its encoded form
+ * (e.g. "1.2.840.113549" into "\x2A\x86\x48\x86\xF7\x0D").
+ * On success, this function allocates oid->buf from the
+ * heap. It must be freed by the caller using mbedtls_free().
+ *
+ * \param oid #mbedtls_asn1_buf to populate with the DER-encoded OID
+ * \param oid_str string representation of the OID to parse
+ * \param size length of the OID string, not including any null terminator
+ *
+ * \return 0 if successful
+ * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if \p oid_str does not
+ * represent a valid OID
+ * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if the function fails to
+ * allocate oid->buf
+ */
+int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid, const char *oid_str, size_t size);
+
#ifdef __cplusplus
}
#endif
diff --git a/library/x509.c b/library/x509.c
index a80ab53..be7b277 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -805,6 +805,75 @@
return (i < 10) ? (i + '0') : (i - 10 + 'A');
}
+/* Return the x.y.z.... style numeric string for the given OID */
+int mbedtls_oid_get_numeric_string(char *buf, size_t size,
+ const mbedtls_asn1_buf *oid)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ char *p = buf;
+ size_t n = size;
+ unsigned int value = 0;
+
+ if (size > INT_MAX) {
+ /* Avoid overflow computing return value */
+ return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
+ }
+
+ if (oid->len <= 0) {
+ /* OID must not be empty */
+ return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
+ }
+
+ for (size_t i = 0; i < oid->len; i++) {
+ /* Prevent overflow in value. */
+ if (value > (UINT_MAX >> 7)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ if ((value == 0) && ((oid->p[i]) == 0x80)) {
+ /* Overlong encoding is not allowed */
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+
+ value <<= 7;
+ value |= oid->p[i] & 0x7F;
+
+ if (!(oid->p[i] & 0x80)) {
+ /* Last byte */
+ if (n == size) {
+ int component1;
+ unsigned int component2;
+ /* First subidentifier contains first two OID components */
+ if (value >= 80) {
+ component1 = '2';
+ component2 = value - 80;
+ } else if (value >= 40) {
+ component1 = '1';
+ component2 = value - 40;
+ } else {
+ component1 = '0';
+ component2 = value;
+ }
+ ret = mbedtls_snprintf(p, n, "%c.%u", component1, component2);
+ } else {
+ ret = mbedtls_snprintf(p, n, ".%u", value);
+ }
+ if (ret < 2 || (size_t) ret >= n) {
+ return MBEDTLS_ERR_OID_BUF_TOO_SMALL;
+ }
+ n -= (size_t) ret;
+ p += ret;
+ value = 0;
+ }
+ }
+
+ if (value != 0) {
+ /* Unterminated subidentifier */
+ return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
+ }
+
+ return (int) (size - n);
+}
+
/*
* Store the name in printable form into buf; no more
* than size characters will be written
diff --git a/library/x509_create.c b/library/x509_create.c
index 839b5df..1309831 100644
--- a/library/x509_create.c
+++ b/library/x509_create.c
@@ -278,6 +278,182 @@
return MBEDTLS_ERR_X509_INVALID_NAME;
}
+static int oid_parse_number(unsigned int *num, const char **p, const char *bound)
+{
+ int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+
+ *num = 0;
+
+ while (*p < bound && **p >= '0' && **p <= '9') {
+ ret = 0;
+ if (*num > (UINT_MAX / 10)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ *num *= 10;
+ *num += **p - '0';
+ (*p)++;
+ }
+ return ret;
+}
+
+static size_t oid_subidentifier_num_bytes(unsigned int value)
+{
+ size_t num_bytes = 0;
+
+ do {
+ value >>= 7;
+ num_bytes++;
+ } while (value != 0);
+
+ return num_bytes;
+}
+
+static int oid_subidentifier_encode_into(unsigned char **p,
+ unsigned char *bound,
+ unsigned int value)
+{
+ size_t num_bytes = oid_subidentifier_num_bytes(value);
+
+ if ((size_t) (bound - *p) < num_bytes) {
+ return MBEDTLS_ERR_OID_BUF_TOO_SMALL;
+ }
+ (*p)[num_bytes - 1] = (unsigned char) (value & 0x7f);
+ value >>= 7;
+
+ for (size_t i = 2; i <= num_bytes; i++) {
+ (*p)[num_bytes - i] = 0x80 | (unsigned char) (value & 0x7f);
+ value >>= 7;
+ }
+ *p += num_bytes;
+
+ return 0;
+}
+
+/* Return the OID for the given x.y.z.... style numeric string */
+int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid,
+ const char *oid_str, size_t size)
+{
+ int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ const char *str_ptr = oid_str;
+ const char *str_bound = oid_str + size;
+ unsigned int val = 0;
+ unsigned int component1, component2;
+ size_t encoded_len;
+ unsigned char *resized_mem;
+
+ /* Count the number of dots to get a worst-case allocation size. */
+ size_t num_dots = 0;
+ for (size_t i = 0; i < size; i++) {
+ if (oid_str[i] == '.') {
+ num_dots++;
+ }
+ }
+ /* Allocate maximum possible required memory:
+ * There are (num_dots + 1) integer components, but the first 2 share the
+ * same subidentifier, so we only need num_dots subidentifiers maximum. */
+ if (num_dots == 0 || (num_dots > MBEDTLS_OID_MAX_COMPONENTS - 1)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ /* Each byte can store 7 bits, calculate number of bytes for a
+ * subidentifier:
+ *
+ * bytes = ceil(subidentifer_size * 8 / 7)
+ */
+ size_t bytes_per_subidentifier = (((sizeof(unsigned int) * 8) - 1) / 7)
+ + 1;
+ size_t max_possible_bytes = num_dots * bytes_per_subidentifier;
+ oid->p = mbedtls_calloc(max_possible_bytes, 1);
+ if (oid->p == NULL) {
+ return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
+ }
+ unsigned char *out_ptr = oid->p;
+ unsigned char *out_bound = oid->p + max_possible_bytes;
+
+ ret = oid_parse_number(&component1, &str_ptr, str_bound);
+ if (ret != 0) {
+ goto error;
+ }
+ if (component1 > 2) {
+ /* First component can't be > 2 */
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ if (str_ptr >= str_bound || *str_ptr != '.') {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ str_ptr++;
+
+ ret = oid_parse_number(&component2, &str_ptr, str_bound);
+ if (ret != 0) {
+ goto error;
+ }
+ if ((component1 < 2) && (component2 > 39)) {
+ /* Root nodes 0 and 1 may have up to 40 children, numbered 0-39 */
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ if (str_ptr < str_bound) {
+ if (*str_ptr == '.') {
+ str_ptr++;
+ } else {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ }
+
+ if (component2 > (UINT_MAX - (component1 * 40))) {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ ret = oid_subidentifier_encode_into(&out_ptr, out_bound,
+ (component1 * 40) + component2);
+ if (ret != 0) {
+ goto error;
+ }
+
+ while (str_ptr < str_bound) {
+ ret = oid_parse_number(&val, &str_ptr, str_bound);
+ if (ret != 0) {
+ goto error;
+ }
+ if (str_ptr < str_bound) {
+ if (*str_ptr == '.') {
+ str_ptr++;
+ } else {
+ ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
+ goto error;
+ }
+ }
+
+ ret = oid_subidentifier_encode_into(&out_ptr, out_bound, val);
+ if (ret != 0) {
+ goto error;
+ }
+ }
+
+ encoded_len = (size_t) (out_ptr - oid->p);
+ resized_mem = mbedtls_calloc(encoded_len, 1);
+ if (resized_mem == NULL) {
+ ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED;
+ goto error;
+ }
+ memcpy(resized_mem, oid->p, encoded_len);
+ mbedtls_free(oid->p);
+ oid->p = resized_mem;
+ oid->len = encoded_len;
+
+ oid->tag = MBEDTLS_ASN1_OID;
+
+ return 0;
+
+error:
+ mbedtls_free(oid->p);
+ oid->p = NULL;
+ oid->len = 0;
+ return ret;
+}
+
int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name)
{
int ret = MBEDTLS_ERR_X509_INVALID_NAME;
diff --git a/scripts/config.py b/scripts/config.py
index fff4233..580a4bb 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -19,26 +19,33 @@
from mbedtls_framework import config_common
-def is_full_section(section):
- """Is this section affected by "config.py full" and friends?
+def is_boolean_setting(name, value):
+ """Is this a boolean setting?
- In a config file where the sections are not used the whole config file
- is an empty section (with value None) and the whole file is affected.
+ Mbed TLS boolean settings are enabled if the preprocessor macro is
+ defined, and disabled if the preprocessor macro is not defined. The
+ macro definition line in the configuration file has an empty expansion.
+
+ PSA_WANT_xxx settings are also boolean, but when they are enabled,
+ they expand to a nonzero value. We leave them undefined when they
+ are disabled. (Setting them to 0 currently means to enable them, but
+ this might change to mean disabling them. Currently we just never set
+ them to 0.)
"""
- return section is None or section.endswith('support') or section.endswith('modules')
+ if name.startswith('PSA_WANT_'):
+ return True
+ if not value:
+ return True
+ return False
-def realfull_adapter(_name, active, section):
- """Activate all symbols found in the global and boolean feature sections.
+def realfull_adapter(_name, _value, _active):
+ """Activate all symbols.
This is intended for building the documentation, including the
documentation of settings that are activated by defining an optional
- preprocessor macro.
-
- Do not activate definitions in the section containing symbols that are
- supposed to be defined and documented in their own module.
+ preprocessor macro. There is no expectation that the resulting
+ configuration can be built.
"""
- if section == 'Module configuration options':
- return active
return True
PSA_UNSUPPORTED_FEATURE = frozenset([
@@ -138,9 +145,9 @@
return is_seamless_alt(name)
return True
-def full_adapter(name, active, section):
+def full_adapter(name, value, active):
"""Config adapter for "full"."""
- if not is_full_section(section):
+ if not is_boolean_setting(name, value):
return active
return include_in_full(name)
@@ -176,9 +183,9 @@
return False
return True
-def baremetal_adapter(name, active, section):
+def baremetal_adapter(name, value, active):
"""Config adapter for "baremetal"."""
- if not is_full_section(section):
+ if not is_boolean_setting(name, value):
return active
if name == 'MBEDTLS_NO_PLATFORM_ENTROPY':
# No OS-provided entropy source
@@ -195,10 +202,10 @@
'MBEDTLS_TEST_HOOKS', # only useful with the hosted test framework, increases code size
])
-def baremetal_size_adapter(name, active, section):
+def baremetal_size_adapter(name, value, active):
if name in EXCLUDE_FOR_SIZE:
return False
- return baremetal_adapter(name, active, section)
+ return baremetal_adapter(name, value, active)
def include_in_crypto(name):
"""Rules for symbols in a crypto configuration."""
@@ -219,15 +226,15 @@
def crypto_adapter(adapter):
"""Modify an adapter to disable non-crypto symbols.
- ``crypto_adapter(adapter)(name, active, section)`` is like
- ``adapter(name, active, section)``, but unsets all X.509 and TLS symbols.
+ ``crypto_adapter(adapter)(name, value, active)`` is like
+ ``adapter(name, value, active)``, but unsets all X.509 and TLS symbols.
"""
- def continuation(name, active, section):
+ def continuation(name, value, active):
if not include_in_crypto(name):
return False
if adapter is None:
return active
- return adapter(name, active, section)
+ return adapter(name, value, active)
return continuation
DEPRECATED = frozenset([
@@ -237,34 +244,34 @@
def no_deprecated_adapter(adapter):
"""Modify an adapter to disable deprecated symbols.
- ``no_deprecated_adapter(adapter)(name, active, section)`` is like
- ``adapter(name, active, section)``, but unsets all deprecated symbols
+ ``no_deprecated_adapter(adapter)(name, value, active)`` is like
+ ``adapter(name, value, active)``, but unsets all deprecated symbols
and sets ``MBEDTLS_DEPRECATED_REMOVED``.
"""
- def continuation(name, active, section):
+ def continuation(name, value, active):
if name == 'MBEDTLS_DEPRECATED_REMOVED':
return True
if name in DEPRECATED:
return False
if adapter is None:
return active
- return adapter(name, active, section)
+ return adapter(name, value, active)
return continuation
def no_platform_adapter(adapter):
"""Modify an adapter to disable platform symbols.
- ``no_platform_adapter(adapter)(name, active, section)`` is like
- ``adapter(name, active, section)``, but unsets all platform symbols other
+ ``no_platform_adapter(adapter)(name, value, active)`` is like
+ ``adapter(name, value, active)``, but unsets all platform symbols other
``than MBEDTLS_PLATFORM_C.
"""
- def continuation(name, active, section):
+ def continuation(name, value, active):
# Allow MBEDTLS_PLATFORM_C but remove all other platform symbols.
if name.startswith('MBEDTLS_PLATFORM_') and name != 'MBEDTLS_PLATFORM_C':
return False
if adapter is None:
return active
- return adapter(name, active, section)
+ return adapter(name, value, active)
return continuation
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 510b0a3..143d676 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -3439,3 +3439,52 @@
X509 CRT parse Authority Key Id - Wrong Issuer sequence
depends_on:PSA_WANT_ALG_MD5:MBEDTLS_RSA_C
x509_crt_parse_authoritykeyid:"../framework/data_files/clusterfuzz-testcase-minimized-fuzz_x509crt-6666050834661376.crt.der":"":"":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS+MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+OID get numeric string - hardware module name
+oid_get_numeric_string:"2B06010505070804":0:"1.3.6.1.5.5.7.8.4"
+
+OID get numeric string - multi-byte subidentifier
+oid_get_numeric_string:"29903C":0:"1.1.2108"
+
+OID get numeric string - second component greater than 39
+oid_get_numeric_string:"81010000863A00":0:"2.49.0.0.826.0"
+
+OID get numeric string - multi-byte first subidentifier
+oid_get_numeric_string:"8837":0:"2.999"
+
+OID get numeric string - second subidentifier not terminated
+oid_get_numeric_string:"0081":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
+
+OID get numeric string - empty oid buffer
+oid_get_numeric_string:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
+
+OID get numeric string - no final / all bytes have top bit set
+oid_get_numeric_string:"818181":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
+
+OID get numeric string - 0.39
+oid_get_numeric_string:"27":0:"0.39"
+
+OID get numeric string - 1.0
+oid_get_numeric_string:"28":0:"1.0"
+
+OID get numeric string - 1.39
+oid_get_numeric_string:"4f":0:"1.39"
+
+OID get numeric string - 2.0
+oid_get_numeric_string:"50":0:"2.0"
+
+OID get numeric string - 1 byte first subidentifier beyond 2.39
+oid_get_numeric_string:"7f":0:"2.47"
+
+# Encodes the number 0x0400000000 as a subidentifier which overflows 32-bits
+OID get numeric string - 32-bit overflow
+oid_get_numeric_string:"C080808000":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID get numeric string - 32-bit overflow, second subidentifier
+oid_get_numeric_string:"2BC080808000":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID get numeric string - overlong encoding
+oid_get_numeric_string:"8001":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID get numeric string - overlong encoding, second subidentifier
+oid_get_numeric_string:"2B8001":MBEDTLS_ERR_ASN1_INVALID_DATA:""
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 9fc0e55..fae3657 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -10,6 +10,8 @@
#include "mbedtls/base64.h"
#include "mbedtls/error.h"
#include "mbedtls/pk.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/asn1write.h"
#include "string.h"
#if MBEDTLS_X509_MAX_INTERMEDIATE_CA > 19
@@ -1747,3 +1749,27 @@
mbedtls_x509_crt_free(&crt);
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
+void oid_get_numeric_string(data_t *oid, int error_ret, char *result_str)
+{
+ char buf[256];
+ mbedtls_asn1_buf input_oid = { 0, 0, NULL };
+ int ret;
+
+ input_oid.tag = MBEDTLS_ASN1_OID;
+ /* Test that an empty OID is not dereferenced */
+ input_oid.p = oid->len ? oid->x : (void *) 1;
+ input_oid.len = oid->len;
+
+ ret = mbedtls_oid_get_numeric_string(buf, sizeof(buf), &input_oid);
+
+ if (error_ret == 0) {
+ TEST_EQUAL(ret, strlen(result_str));
+ TEST_ASSERT(ret >= 3);
+ TEST_EQUAL(strcmp(buf, result_str), 0);
+ } else {
+ TEST_EQUAL(ret, error_ret);
+ }
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
index 3fbb721..e4e08da 100644
--- a/tests/suites/test_suite_x509write.data
+++ b/tests/suites/test_suite_x509write.data
@@ -268,3 +268,52 @@
Check max extension length
x509_set_extension_length_check:
+
+OID from numeric string - hardware module name
+oid_from_numeric_string:"1.3.6.1.5.5.7.8.4":0:"2B06010505070804"
+
+OID from numeric string - multi-byte subidentifier
+oid_from_numeric_string:"1.1.2108":0:"29903C"
+
+OID from numeric string - second component greater than 39
+oid_from_numeric_string:"2.49.0.0.826.0":0:"81010000863A00"
+
+OID from numeric string - multi-byte first subidentifier
+oid_from_numeric_string:"2.999":0:"8837"
+
+OID from numeric string - empty string input
+oid_from_numeric_string:"":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - first component not a number
+oid_from_numeric_string:"abc.1.2":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - second component not a number
+oid_from_numeric_string:"1.abc.2":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - first component too large
+oid_from_numeric_string:"3.1":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - first component < 2, second > 39
+oid_from_numeric_string:"1.40":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - third component not a number
+oid_from_numeric_string:"1.2.abc":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - non-'.' separator between first and second
+oid_from_numeric_string:"1/2.3.4":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - non-'.' separator between second and third
+oid_from_numeric_string:"1.2/3.4":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - non-'.' separator between third and fourth
+oid_from_numeric_string:"1.2.3/4":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - OID greater than max length (129 components)
+oid_from_numeric_string:"1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
+OID from numeric string - OID with maximum subidentifier
+oid_from_numeric_string:"2.4294967215":0:"8FFFFFFF7F"
+
+OID from numeric string - OID with overflowing subidentifier
+oid_from_numeric_string:"2.4294967216":MBEDTLS_ERR_ASN1_INVALID_DATA:""
+
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index eb3c2f7..64b4e9e 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -6,6 +6,7 @@
#include "mbedtls/pem.h"
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
+#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/pk.h"
#include "mbedtls/psa_util.h"
@@ -761,3 +762,29 @@
TEST_ASSERT(MBEDTLS_ERR_X509_BAD_INPUT_DATA == ret);
}
/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_X509_USE_C */
+void oid_from_numeric_string(char *oid_str, int error_ret,
+ data_t *exp_oid_buf)
+{
+ mbedtls_asn1_buf oid = { 0, 0, NULL };
+ mbedtls_asn1_buf exp_oid = { 0, 0, NULL };
+ int ret;
+
+ exp_oid.tag = MBEDTLS_ASN1_OID;
+ exp_oid.p = exp_oid_buf->x;
+ exp_oid.len = exp_oid_buf->len;
+
+ ret = mbedtls_oid_from_numeric_string(&oid, oid_str, strlen(oid_str));
+
+ if (error_ret == 0) {
+ TEST_EQUAL(oid.len, exp_oid.len);
+ TEST_ASSERT(memcmp(oid.p, exp_oid.p, oid.len) == 0);
+ mbedtls_free(oid.p);
+ oid.p = NULL;
+ oid.len = 0;
+ } else {
+ TEST_EQUAL(ret, error_ret);
+ }
+}
+/* END_CASE */
diff --git a/tf-psa-crypto/drivers/builtin/include/mbedtls/oid.h b/tf-psa-crypto/drivers/builtin/include/mbedtls/oid.h
index 0366944..e0ad35e 100644
--- a/tf-psa-crypto/drivers/builtin/include/mbedtls/oid.h
+++ b/tf-psa-crypto/drivers/builtin/include/mbedtls/oid.h
@@ -483,38 +483,6 @@
} mbedtls_oid_descriptor_t;
/**
- * \brief Translate an ASN.1 OID into its numeric representation
- * (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549")
- *
- * \param buf buffer to put representation in
- * \param size size of the buffer
- * \param oid OID to translate
- *
- * \return Length of the string written (excluding final NULL) or
- * MBEDTLS_ERR_OID_BUF_TOO_SMALL in case of error
- */
-int mbedtls_oid_get_numeric_string(char *buf, size_t size, const mbedtls_asn1_buf *oid);
-
-/**
- * \brief Translate a string containing a dotted-decimal
- * representation of an ASN.1 OID into its encoded form
- * (e.g. "1.2.840.113549" into "\x2A\x86\x48\x86\xF7\x0D").
- * On success, this function allocates oid->buf from the
- * heap. It must be freed by the caller using mbedtls_free().
- *
- * \param oid #mbedtls_asn1_buf to populate with the DER-encoded OID
- * \param oid_str string representation of the OID to parse
- * \param size length of the OID string, not including any null terminator
- *
- * \return 0 if successful
- * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if \p oid_str does not
- * represent a valid OID
- * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if the function fails to
- * allocate oid->buf
- */
-int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid, const char *oid_str, size_t size);
-
-/**
* \brief Translate an X.509 extension OID into local values
*
* \param oid OID to use
diff --git a/tf-psa-crypto/drivers/builtin/src/oid.c b/tf-psa-crypto/drivers/builtin/src/oid.c
index 862f09d..ae30dfe 100644
--- a/tf-psa-crypto/drivers/builtin/src/oid.c
+++ b/tf-psa-crypto/drivers/builtin/src/oid.c
@@ -918,249 +918,4 @@
cipher_alg)
#endif /* MBEDTLS_PKCS12_C && MBEDTLS_CIPHER_C */
-/* Return the x.y.z.... style numeric string for the given OID */
-int mbedtls_oid_get_numeric_string(char *buf, size_t size,
- const mbedtls_asn1_buf *oid)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- char *p = buf;
- size_t n = size;
- unsigned int value = 0;
-
- if (size > INT_MAX) {
- /* Avoid overflow computing return value */
- return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
- }
-
- if (oid->len <= 0) {
- /* OID must not be empty */
- return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
- }
-
- for (size_t i = 0; i < oid->len; i++) {
- /* Prevent overflow in value. */
- if (value > (UINT_MAX >> 7)) {
- return MBEDTLS_ERR_ASN1_INVALID_DATA;
- }
- if ((value == 0) && ((oid->p[i]) == 0x80)) {
- /* Overlong encoding is not allowed */
- return MBEDTLS_ERR_ASN1_INVALID_DATA;
- }
-
- value <<= 7;
- value |= oid->p[i] & 0x7F;
-
- if (!(oid->p[i] & 0x80)) {
- /* Last byte */
- if (n == size) {
- int component1;
- unsigned int component2;
- /* First subidentifier contains first two OID components */
- if (value >= 80) {
- component1 = '2';
- component2 = value - 80;
- } else if (value >= 40) {
- component1 = '1';
- component2 = value - 40;
- } else {
- component1 = '0';
- component2 = value;
- }
- ret = mbedtls_snprintf(p, n, "%c.%u", component1, component2);
- } else {
- ret = mbedtls_snprintf(p, n, ".%u", value);
- }
- if (ret < 2 || (size_t) ret >= n) {
- return MBEDTLS_ERR_OID_BUF_TOO_SMALL;
- }
- n -= (size_t) ret;
- p += ret;
- value = 0;
- }
- }
-
- if (value != 0) {
- /* Unterminated subidentifier */
- return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
- }
-
- return (int) (size - n);
-}
-
-static int oid_parse_number(unsigned int *num, const char **p, const char *bound)
-{
- int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
-
- *num = 0;
-
- while (*p < bound && **p >= '0' && **p <= '9') {
- ret = 0;
- if (*num > (UINT_MAX / 10)) {
- return MBEDTLS_ERR_ASN1_INVALID_DATA;
- }
- *num *= 10;
- *num += **p - '0';
- (*p)++;
- }
- return ret;
-}
-
-static size_t oid_subidentifier_num_bytes(unsigned int value)
-{
- size_t num_bytes = 0;
-
- do {
- value >>= 7;
- num_bytes++;
- } while (value != 0);
-
- return num_bytes;
-}
-
-static int oid_subidentifier_encode_into(unsigned char **p,
- unsigned char *bound,
- unsigned int value)
-{
- size_t num_bytes = oid_subidentifier_num_bytes(value);
-
- if ((size_t) (bound - *p) < num_bytes) {
- return MBEDTLS_ERR_OID_BUF_TOO_SMALL;
- }
- (*p)[num_bytes - 1] = (unsigned char) (value & 0x7f);
- value >>= 7;
-
- for (size_t i = 2; i <= num_bytes; i++) {
- (*p)[num_bytes - i] = 0x80 | (unsigned char) (value & 0x7f);
- value >>= 7;
- }
- *p += num_bytes;
-
- return 0;
-}
-
-/* Return the OID for the given x.y.z.... style numeric string */
-int mbedtls_oid_from_numeric_string(mbedtls_asn1_buf *oid,
- const char *oid_str, size_t size)
-{
- int ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
- const char *str_ptr = oid_str;
- const char *str_bound = oid_str + size;
- unsigned int val = 0;
- unsigned int component1, component2;
- size_t encoded_len;
- unsigned char *resized_mem;
-
- /* Count the number of dots to get a worst-case allocation size. */
- size_t num_dots = 0;
- for (size_t i = 0; i < size; i++) {
- if (oid_str[i] == '.') {
- num_dots++;
- }
- }
- /* Allocate maximum possible required memory:
- * There are (num_dots + 1) integer components, but the first 2 share the
- * same subidentifier, so we only need num_dots subidentifiers maximum. */
- if (num_dots == 0 || (num_dots > MBEDTLS_OID_MAX_COMPONENTS - 1)) {
- return MBEDTLS_ERR_ASN1_INVALID_DATA;
- }
- /* Each byte can store 7 bits, calculate number of bytes for a
- * subidentifier:
- *
- * bytes = ceil(subidentifer_size * 8 / 7)
- */
- size_t bytes_per_subidentifier = (((sizeof(unsigned int) * 8) - 1) / 7)
- + 1;
- size_t max_possible_bytes = num_dots * bytes_per_subidentifier;
- oid->p = mbedtls_calloc(max_possible_bytes, 1);
- if (oid->p == NULL) {
- return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
- }
- unsigned char *out_ptr = oid->p;
- unsigned char *out_bound = oid->p + max_possible_bytes;
-
- ret = oid_parse_number(&component1, &str_ptr, str_bound);
- if (ret != 0) {
- goto error;
- }
- if (component1 > 2) {
- /* First component can't be > 2 */
- ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
- goto error;
- }
- if (str_ptr >= str_bound || *str_ptr != '.') {
- ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
- goto error;
- }
- str_ptr++;
-
- ret = oid_parse_number(&component2, &str_ptr, str_bound);
- if (ret != 0) {
- goto error;
- }
- if ((component1 < 2) && (component2 > 39)) {
- /* Root nodes 0 and 1 may have up to 40 children, numbered 0-39 */
- ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
- goto error;
- }
- if (str_ptr < str_bound) {
- if (*str_ptr == '.') {
- str_ptr++;
- } else {
- ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
- goto error;
- }
- }
-
- if (component2 > (UINT_MAX - (component1 * 40))) {
- ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
- goto error;
- }
- ret = oid_subidentifier_encode_into(&out_ptr, out_bound,
- (component1 * 40) + component2);
- if (ret != 0) {
- goto error;
- }
-
- while (str_ptr < str_bound) {
- ret = oid_parse_number(&val, &str_ptr, str_bound);
- if (ret != 0) {
- goto error;
- }
- if (str_ptr < str_bound) {
- if (*str_ptr == '.') {
- str_ptr++;
- } else {
- ret = MBEDTLS_ERR_ASN1_INVALID_DATA;
- goto error;
- }
- }
-
- ret = oid_subidentifier_encode_into(&out_ptr, out_bound, val);
- if (ret != 0) {
- goto error;
- }
- }
-
- encoded_len = (size_t) (out_ptr - oid->p);
- resized_mem = mbedtls_calloc(encoded_len, 1);
- if (resized_mem == NULL) {
- ret = MBEDTLS_ERR_ASN1_ALLOC_FAILED;
- goto error;
- }
- memcpy(resized_mem, oid->p, encoded_len);
- mbedtls_free(oid->p);
- oid->p = resized_mem;
- oid->len = encoded_len;
-
- oid->tag = MBEDTLS_ASN1_OID;
-
- return 0;
-
-error:
- mbedtls_free(oid->p);
- oid->p = NULL;
- oid->len = 0;
- return ret;
-}
-
#endif /* MBEDTLS_OID_C */
diff --git a/tf-psa-crypto/tests/suites/test_suite_oid.data b/tf-psa-crypto/tests/suites/test_suite_oid.data
index 8919d42..42b0505 100644
--- a/tf-psa-crypto/tests/suites/test_suite_oid.data
+++ b/tf-psa-crypto/tests/suites/test_suite_oid.data
@@ -105,103 +105,6 @@
OID hash id - invalid oid
oid_get_md_alg_id:"2B864886f70d0204":-1
-OID get numeric string - hardware module name
-oid_get_numeric_string:"2B06010505070804":0:"1.3.6.1.5.5.7.8.4"
-
-OID get numeric string - multi-byte subidentifier
-oid_get_numeric_string:"29903C":0:"1.1.2108"
-
-OID get numeric string - second component greater than 39
-oid_get_numeric_string:"81010000863A00":0:"2.49.0.0.826.0"
-
-OID get numeric string - multi-byte first subidentifier
-oid_get_numeric_string:"8837":0:"2.999"
-
-OID get numeric string - second subidentifier not terminated
-oid_get_numeric_string:"0081":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
-
-OID get numeric string - empty oid buffer
-oid_get_numeric_string:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
-
-OID get numeric string - no final / all bytes have top bit set
-oid_get_numeric_string:"818181":MBEDTLS_ERR_ASN1_OUT_OF_DATA:""
-
-OID get numeric string - 0.39
-oid_get_numeric_string:"27":0:"0.39"
-
-OID get numeric string - 1.0
-oid_get_numeric_string:"28":0:"1.0"
-
-OID get numeric string - 1.39
-oid_get_numeric_string:"4f":0:"1.39"
-
-OID get numeric string - 2.0
-oid_get_numeric_string:"50":0:"2.0"
-
-OID get numeric string - 1 byte first subidentifier beyond 2.39
-oid_get_numeric_string:"7f":0:"2.47"
-
-# Encodes the number 0x0400000000 as a subidentifier which overflows 32-bits
-OID get numeric string - 32-bit overflow
-oid_get_numeric_string:"C080808000":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID get numeric string - 32-bit overflow, second subidentifier
-oid_get_numeric_string:"2BC080808000":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID get numeric string - overlong encoding
-oid_get_numeric_string:"8001":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID get numeric string - overlong encoding, second subidentifier
-oid_get_numeric_string:"2B8001":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - hardware module name
-oid_from_numeric_string:"1.3.6.1.5.5.7.8.4":0:"2B06010505070804"
-
-OID from numeric string - multi-byte subidentifier
-oid_from_numeric_string:"1.1.2108":0:"29903C"
-
-OID from numeric string - second component greater than 39
-oid_from_numeric_string:"2.49.0.0.826.0":0:"81010000863A00"
-
-OID from numeric string - multi-byte first subidentifier
-oid_from_numeric_string:"2.999":0:"8837"
-
-OID from numeric string - empty string input
-oid_from_numeric_string:"":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - first component not a number
-oid_from_numeric_string:"abc.1.2":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - second component not a number
-oid_from_numeric_string:"1.abc.2":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - first component too large
-oid_from_numeric_string:"3.1":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - first component < 2, second > 39
-oid_from_numeric_string:"1.40":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - third component not a number
-oid_from_numeric_string:"1.2.abc":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - non-'.' separator between first and second
-oid_from_numeric_string:"1/2.3.4":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - non-'.' separator between second and third
-oid_from_numeric_string:"1.2/3.4":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - non-'.' separator between third and fourth
-oid_from_numeric_string:"1.2.3/4":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - OID greater than max length (129 components)
-oid_from_numeric_string:"1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1.2.3.4.5.6.7.8.1":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
-OID from numeric string - OID with maximum subidentifier
-oid_from_numeric_string:"2.4294967215":0:"8FFFFFFF7F"
-
-OID from numeric string - OID with overflowing subidentifier
-oid_from_numeric_string:"2.4294967216":MBEDTLS_ERR_ASN1_INVALID_DATA:""
-
mbedtls_oid_get_md_hmac - RIPEMD160
depends_on:PSA_WANT_ALG_RIPEMD160
mbedtls_oid_get_md_hmac:"2B06010505080104":MBEDTLS_MD_RIPEMD160
diff --git a/tf-psa-crypto/tests/suites/test_suite_oid.function b/tf-psa-crypto/tests/suites/test_suite_oid.function
index 337f843..e96425e 100644
--- a/tf-psa-crypto/tests/suites/test_suite_oid.function
+++ b/tf-psa-crypto/tests/suites/test_suite_oid.function
@@ -118,53 +118,3 @@
}
}
/* END_CASE */
-
-/* BEGIN_CASE */
-void oid_get_numeric_string(data_t *oid, int error_ret, char *result_str)
-{
- char buf[256];
- mbedtls_asn1_buf input_oid = { 0, 0, NULL };
- int ret;
-
- input_oid.tag = MBEDTLS_ASN1_OID;
- /* Test that an empty OID is not dereferenced */
- input_oid.p = oid->len ? oid->x : (void *) 1;
- input_oid.len = oid->len;
-
- ret = mbedtls_oid_get_numeric_string(buf, sizeof(buf), &input_oid);
-
- if (error_ret == 0) {
- TEST_EQUAL(ret, strlen(result_str));
- TEST_ASSERT(ret >= 3);
- TEST_EQUAL(strcmp(buf, result_str), 0);
- } else {
- TEST_EQUAL(ret, error_ret);
- }
-}
-/* END_CASE */
-
-/* BEGIN_CASE */
-void oid_from_numeric_string(char *oid_str, int error_ret,
- data_t *exp_oid_buf)
-{
- mbedtls_asn1_buf oid = { 0, 0, NULL };
- mbedtls_asn1_buf exp_oid = { 0, 0, NULL };
- int ret;
-
- exp_oid.tag = MBEDTLS_ASN1_OID;
- exp_oid.p = exp_oid_buf->x;
- exp_oid.len = exp_oid_buf->len;
-
- ret = mbedtls_oid_from_numeric_string(&oid, oid_str, strlen(oid_str));
-
- if (error_ret == 0) {
- TEST_EQUAL(oid.len, exp_oid.len);
- TEST_ASSERT(memcmp(oid.p, exp_oid.p, oid.len) == 0);
- mbedtls_free(oid.p);
- oid.p = NULL;
- oid.len = 0;
- } else {
- TEST_EQUAL(ret, error_ret);
- }
-}
-/* END_CASE */