Chris Morgan
Chris Morgan

Reputation: 1339

How can you extract individual OIDs from a certificate with mbedtls?

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?

Upvotes: 6

Views: 1810

Answers (2)

Chris Morgan
Chris Morgan

Reputation: 1339

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;
}

Upvotes: 2

Florian Weimer
Florian Weimer

Reputation: 33717

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.

Upvotes: 0

Related Questions