6

I have a x509 certificate loaded into mbedtls and I can get the entire subject field via:

mbedtls_x509_dn_gets(p, n, cert.subject);

It is possible to string tokenize the output to extract the particular fields but this seems error prone.

Is there an easy way to get individual OID values of this field, such as the CN or OU entries?

Chris Morgan
  • 1,277
  • 1
  • 13
  • 33

2 Answers2

2

Usage:

const mbedtls_x509_name *name = &cert_ctx.subject;
char value[64];
size_t value_len;

value_len = find_oid_value_in_name(name, "CN", value, sizeof(value));
if(value_len)
{
    printf("CN: %s\n", value);
} else
{
    printf("Unable to find OID\n");
}

Function:

size_t find_oid_value_in_name(const mbedtls_x509_name *name, const char* target_short_name, char *value, size_t value_length)
{
    const char* short_name = NULL;
    bool found = false;
    size_t retval = 0;

    while((name != NULL) && !found)
    {
        // if there is no data for this name go to the next one
        if(!name->oid.p)
        {
            name = name->next;
            continue;
        }

        int ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name);
        if((ret == 0) && (strcmp(short_name, target_short_name) == 0))
        {
            found = true;
        }

        if(found)
        {
            size_t bytes_to_write = (name->val.len >= value_length) ? value_length - 1 : name->val.len;

            for(size_t i = 0; i < bytes_to_write; i++)
            {
                char c = name->val.p[i];
                if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
                {
                    value[i] = '?';
                } else
                {
                    value[i] = c;
                }
            }

            // null terminate
            value[bytes_to_write] = 0;

            retval = name->val.len;
        }

        name = name->next;
    }

    return retval;
}
Chris Morgan
  • 1,277
  • 1
  • 13
  • 33
0

Doesn't mbedtls_x509_dn_gets work on a parsed ASN.1 structure, of type mbedtls_asn1_named_data? You should be able to iterate through that until you find the OID you are interested in. You can use the function mbedtls_asn1_find_named_data to automate this.

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92