Reputation: 1339
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
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
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