Extract private key and certificate (PEM) from PKCS#12 archive
Summary
I created the PKCS#12 archive by doing:
openssl genrsa -out private_key.pem 2048
openssl req -new -x509 -key private_key.pem -out certificate.pem -days 365 -subj “/CN=key-app”
openssl pkcs12 -export -inkey private_key.pem -in certificate.pem -out pkcs12.key -name “key-app”
I’ve cloned the MBedTLS project an built the programs. Then i navigated to mbedtls/build/programs/pkey and gave the following command: ./key_app mode=private filename=pkcs12.key password=“…”
This gives me the following output/error:
./key_app mode=private filename=pkcs12.key password=“…”
. Loading the private key … failed
! mbedtls_pk_parse_keyfile returned -0x3d00
! Last error was: PK - Invalid key tag or value
So my question is, is this feature supported by MBedTLS ? To me it is confusing, there is an pkcs12.h and implementation but from reading the code it is only meant to e.g. decrypt a pkcs8 archive?
Side node, i repeat the above steps with “openssl pkcs8 -in private_key.pem -out pkcs8.key -topk8” then it seems to be able to disect the archive.
System information
Mbed TLS version (number or commit id): e21e9c33c52c91830cee31315b000c1c647e042b
Operating system and version: Linux (debian)
Configuration (if not default, please attach mbedtls_config.h): default
Compiler and options (if you used a pre-built binary, please indicate how you obtained it): default
Additional environment information: Used program key_app
Expected behavior
I expected that the private key would be successfully parsed.
Actual behavior
Failed, with error -0x3d00. As I traced back if complains
Steps to reproduce
openssl genrsa -out private_key.pem 2048
openssl req -new -x509 -key private_key.pem -out certificate.pem -days 365 -subj “/CN=key-app”
openssl pkcs12 -export -inkey private_key.pem -in certificate.pem -out pkcs12.key -name “key-app”
./key_app mode=private filename=pkcs12.key password=“…”
. Loading the private key … failed
! mbedtls_pk_parse_keyfile returned -0x3d00
! Last error was: PK - Invalid key tag or value
Additional information
I'm not very familiar with the PKCS#12 ecosystem, but definitely, yes,
there is an pkcs12.h and implementation but from reading the code it is only meant to e.g. decrypt a pkcs8 archive
is correct. Mbed TLS doesn't aim to implement all of PKCS#12, just the cryptographic part of it, and the goal is to load PKCS#8 encrypted keys.
Definitely yes, Mbed TLS must be able to extract a private key from a PKCS#12 archive?
Is it within the scope of Mbed TLS to extract a certificate (and private key) from a PKCS#12 archive?
Uh, sorry, we might be talking at cross-purposes. I meant yes to “the code it is only meant to e.g. decrypt a pkcs8 archive”. (PKCS#8 is not really an archive format, it's very specialized for private keys, but the PKCS#8 specification says to optionally use encryption mechanisms defined by the PKCS#12 specification.) Supporting PKCS#12 as a whole was not a design goal.
To take a more extreme example, zip files can be encrypted, and it would be reasonable to expect Mbed TLS to implement the zip encryption algorithm, but not the zip compression algorithm. PKCS12 is different because it's a generic container format, but mostly used for cryptography-related data.
Implementing (a subset of) PKCS12 in Mbed TLS wouldn't be out of the question, but it's not a given either. We're focusing on cryptographic primitives (which will soon be in a separate project TF-PSA-Crypto), and on TLS (+DTLS and possibly QUIC) (plus what it needs from X.509).
Thank you for the clarification. A bit of bad news for me but I understand the reasoning. I'll be monitoring the thread to see if it leads to anything.
I am working on the feature myself. I had the idea to foresee a similar interface as for PKCS#7, but this seems to break the build system as PKCS#12 module is part of the crypto lib (without cmake mbedx509_target). This got me in a fight with cmake that I've lost....
PKCS#12 and PKCS#5 are today part by the crypto (lib) to encrypt/decrypt. The feature I am adding is to extract a certificate + private key from a PKCS#12 (similar as the interface for PKCS#7). The parsing of a PKCS12 requires linkage with x509 cmake target ( and others) that are not part of the cmake crypto target.
So i need some advice on how to structure this feature into Mbed-TLS ?
pkcs12.h and pkcs12.c today are about the encryption part of PKCS12. pkcs12.h is becoming a private interface, so we can rename it to something like pkcs12_crypto, which would free the name pkcs12 for a PKCS12 archive module.
Please note that even if you're willing to contribute the feature (thank you), I know we won't have bandwidth to review it for at least a year, and I'm not even sure we would want to maintain the feature in Mbed TLS (it's outside our typical use cases). It might make more sense as a separate project.
Thank you, okay the naming scheme sounds good to me. I was hoping for something like this.
Maybe someone should decide if this is a desired feature or not. It will take less of my time if I add this feature directly in my application.
I do not get why PKCS#12 isn't a wanted feature. I love using this lib as I can simply give a file of "any" format (read: not PKCS#12 files) to mbedtls_pk_parse_key and it magically gets a key context back without having to worry/know about the file format. Basically, it enables users to do (m)TLS/SSL without having to be an expert ... Then saying that parsing PKCS#12 is not a wanted feature, breaks all of this ...
However, I might not fully understand/agree on whether it is desired feature or not, still I am very pleased that the PKCS#5 and PKCS#12 decryption are provided and working. So really thank you for that!
I am also looking forward to someone supplementing this feature or providing some example program. In some scenarios, we use MbedTLS instead of OPENSSL, so this feature is necessary.