diff --git a/library/oid.c b/library/oid.c index e7c12248a3..5668e2aa56 100644 --- a/library/oid.c +++ b/library/oid.c @@ -834,14 +834,39 @@ int mbedtls_oid_get_numeric_string(char *buf, size_t size, p = buf; n = size; - /* First byte contains first two dots */ - if (oid->len > 0) { - ret = mbedtls_snprintf(p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40); - OID_SAFE_SNPRINTF; + /* First subidentifier contains first two OID components */ + i = 0; + value = 0; + while (i < oid->len && ((oid->p[i] & 0x80) != 0)) { + /* Prevent overflow in value. */ + if (((value << 7) >> 7) != value) { + return MBEDTLS_ERR_OID_BUF_TOO_SMALL; + } + + value += oid->p[i] & 0x7F; + value <<= 7; + i++; } + if (i >= oid->len) { + return MBEDTLS_ERR_OID_BUF_TOO_SMALL; + } + /* Last byte of first subidentifier */ + value += oid->p[i] & 0x7F; + i++; + + unsigned int component1 = value / 40; + if (component1 > 2) { + /* The first component can only be 0, 1 or 2. + * If oid->p[0] / 40 is greater than 2, the leftover belongs to + * the second component. */ + component1 = 2; + } + unsigned int component2 = value - (40 * component1); + ret = mbedtls_snprintf(p, n, "%u.%u", component1, component2); + OID_SAFE_SNPRINTF; value = 0; - for (i = 1; i < oid->len; i++) { + for (; i < oid->len; i++) { /* Prevent overflow in value. */ if (((value << 7) >> 7) != value) { return MBEDTLS_ERR_OID_BUF_TOO_SMALL;