Arm Mbed and Pelion Device Management support forum

Parse CERT.RSA to get public key

Hi, I am android developer, I want to extract the public key from CERT.RSA which is stored in APK file.
I tried using mbedtls_x509_crt_parse, I get -8674 error code from x509_crt_parse_der_core.
Please help.

Hi @amit2008kashu
mbedtls_x509_crt_parse() can receive a PKCS#1 or PKCS#8 certificate, in PEM or DER format.
The CERT.RSA is not in the accepted format.
Looking at this post, you may consider doing the following:

openssl pkcs7 -in CERT.RSA -inform DER -out cert.pem

After that, you can you should send the content of cert.pem to mbedtls_x509_crt_parse()
Regards,
Mbed TLS Support
Ron

Hi @roneld01 , thanks for your response.
I am not able to covert to pem format as I don’t have command line available. I am doing this as of now but it does extract some extra info also in addition to public key bytes.

unsigned char *ptr = CertBytes;
unsigned char *end = ptr + CertLen;

if ((ret = mbedtls_asn1_get_tag(&ptr, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
return ret;
}
//get end ptr of cert
end = ptr + len;

//OID: signed data
if ((ret = mbedtls_asn1_get_tag(&ptr, end, &len, MBEDTLS_ASN1_OID)) != 0) {
    return ret;
}

//skip OID
ptr = ptr + len;

if ((ret = mbedtls_asn1_get_tag(&ptr, end, &len,
                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
    0) {
    return ret;
}

if ((ret = mbedtls_asn1_get_tag(&ptr, end, &len,
                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    return ret;
}

if ((ret = mbedtls_asn1_get_int(&ptr, end, &value)) != 0) {
    return ret;
}

if ((ret = mbedtls_asn1_get_tag(&ptr, end, &len,
                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
    return ret;
}

//skip SET
ptr = ptr + len;

if ((ret = mbedtls_asn1_get_tag(&ptr, end, &len,
                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    return ret;
}

//skip sequence
ptr = ptr + len;

//get the public key cert body
if ((ret = mbedtls_asn1_get_tag(&ptr, end, &len,
                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
    0) {
    return ret;
}

publicKeyCertLen = len;
publicKeyCert = (unsigned char *) calloc(1, publicKeyCertLen);
if (publicKeyCert == NULL) {
    ret =ERROR_INSUFFICIENT_MEMORY;
} else {
    memcpy(publicKeyCert, ptr, len);
} 

As I am not expert at it, I am not sure what exactly is being extracted in which tag. Please suggest if you have any idea.

As a side note I tried to extract public key from CERT.RSA using java’s crypto library and I was giving me exact public key bytes. But using above code it gave some extra bytes before and after public key bytes.

HI @amit2008kashu
I have used a sample apk file, and used the command on the CERT.RSA file.
The output was the pkcs7 file in Base64, which is not supported by Mbed TLS.
In order to convert it to a supported format, you will need to add the -print_certs to the openssl command.
Note that the output is suported, but it adds a couple of additional lines for subject and issuer.
The supported certificate format starts with -----BEGIN CERTIFICATE-----
Regards