Write RSA public key top PEM

New to mbedTLS - feel free to tell me where to find this answer.

1 - I have a raw RSA public key (e, n) that I want to write in PEM format. I found mbedtls_pk_write_pubkey_pem() but not a method to create the mbedtls_pk_context from n and e. Any hints?

I will eventually need PEM to RSA, and similar for ECC.

2 - mbedtls_pk_context is described as a public key context, but it seems to be used for private keys as well. Is that correct?

3 - What’s the difference between an mbedtls_rsa_context and an mbedtls_pk_context? Is there a way to convert between them?

Hi @kgoldman
Thank you for your interest in Mbed TLS!

I have a raw RSA public key (e, n) that I want to write in PEM format. I found mbedtls_pk_write_pubkey_pem() but not a method to create the mbedtls_pk_context from n and e. Any hints?

This article may have the answer for you, regarding RSA context. Regarding ECC, unfortunately, there is not a simple API for that, however, you can use the following to insert the public point Q(x and y. z is 1 in Mbed TLS) to the ec p context.

mbedtls_ecp_keypair ctx;
mbedtls_ecp_group_load();
mbedtls_ecp_point_read_binary() or mbedtls_ecp_point_read_string(); //depending on your point format

mbedtls_pk_context is described as a public key context, but it seems to be used for private keys as well. Is that correct?

correct. It’s named public key context, because it is for public key cryptography, which involves public and private keys. Note that the private key includes both private and public components, while the public key contains only the public components.

What’s the difference between an mbedtls_rsa_context and an mbedtls_pk_context? Is there a way to convert between them?

mbedtls_rsa_context \ mbedtls_ecp_keypair are the algorithm specific context. mbedtls_pk_context is a wrapper for the algorithm context, to supply a unified interface for users of the public key cryptography. in addition, the wrapper pk context is used for the Mbed TLS key parsing and writing API.

In key_app reference application you can see how to convert from mbedtls_pk_context to mbedtls_rsa_context (and to mbedtls_ecp_keypair a few lines after ). To convert from mbedtls_rsa_context to mbedtls_pk_context, there is no designated API, unfortunately, however you can do the following, given rsa_context:

mbedtls_pk_context pk;

mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA) );
memcpy( mbedtls_pk_rsa( pk ),  &rsa_context );

The example wa for RSA, but you can do similar with ECC key type(MBEDTLS_PK_ECKEY , MBEDTLS_PK_ECKEY_DH or MBEDTLS_PK_ECDSA, depending on what context you have, and your functionality needs)

Regards,
Mbed TLS Team member
Ron

1 Like

I’ve gotten into trouble on the mbedtls_pk_free(). I wonder if the memcpy() is copying pointers? Does the mbedtls_pk_free() then try to free those pointers?

If so, do I have to keep the copied mbedtls_rsa_context around and let the mbedtls_pk_free() free the wrapped structure.

@kgoldman I am sorry for misleading you.
I simple memcpy() will not do, as you need to a deep copy.
You will need to copy every mbedtls_mpi struct using mbedtls_mpi_copy() function.
For the public key in ECC, you will need ti use mbedtls_ecp_copy(). (The private key is an mbedtls_mpi struct, you will copy it as mentioned in previous sentence).

The rest of the members of the rsa context are primitives, so assigning their values to the copy is enough.
Regards,
Ron

For the record …

After mbedtls_rsa_import_raw(), the memcpy does work. It copies the mbedtls_rsa_context into the mbedtls_pk_context - including copying pointers.

The part I missed was that the mbedtls_rsa_context should not be explicitly freed. It gets implicitly freed when the mbedtls_pk_context is freed.

Yes, it works, but it would be cleaner if deep memcpy will be used, as it’s reasonable that the module that allocates the pointers will free the pointers.