5

I try to manage in a C library multiple RSA keys and certificates in a PKCS#12 structure. Managing a single key with the primitives PKCS12_create and PKCS12_parse works fine, but I can't find anything about managing multiple keys. I tried to use the safes and bags primitives but I only succeed to corrupt my PKCS12.

Does OpenSSL's PKCS#12 allow multiple keys and certificates in PKCS#12 structure? If so, then how do I manage multiple keys and certificates using the PKCS#12 API?

Thanks all

jww
  • 83,594
  • 69
  • 338
  • 732
Yann Delanoe
  • 119
  • 7
  • So you want to create a RSA key pair with libcrypto API ? Or do you want to store multiple key pairs ? – Badda Jun 16 '17 at 09:31
  • Hi Badda. I want to store and parse multiple key pairs in one PKCS12 structure/file. RSA key pair creation is ok. – Yann Delanoe Jun 16 '17 at 09:40

2 Answers2

3

PKCS#12 is a complicated data structure. All of the operations that PKCS12_parse use are public API, it just tries to simplify the simple case. The entire 245 lines of p12_kiss.c (one presumes Keep It Simple, Stupid) are PKCS12_parse and its (non-public) helper routines.

p12_crt.c is another 291 lines of "man, this file format is complicated", which is just PKCS12_create.

Managing multiple files is easier code, but if you want to take the complexity into your code you can simplify your file operations.

Don't forget to call PKCS12_SAFEBAG_create_pkcs8_encrypt on the private key bags. Your keys aren't encrypted unless you call it, and (IIRC) Apple's PFX reader won't load keys out of unencrypted bags (probably not an intentional decision, they just likely never experienced it).

bartonjs
  • 23,118
  • 2
  • 51
  • 90
  • 1
    Hi bartonjs. Thanks for your good answer. I finaly succeed to parse multiple keys (added with keytool) and select the one i need depending on its friendly name. I'm now stucked on the add a key to an existing PKCS#12. The `STACK_OF(PKCS7) safes` build should be ok (same as done in p12_crt.c, I use the `PKCS12_add_key` function that do the crypt thing), but what i miss is how to add this into the existing `PKCS12` object. The function `PKCS12_pack_authsafes`seems not to be the one I need. I think i have add it into a PKCS7 before ... ? – Yann Delanoe Jun 16 '17 at 15:17
  • Perhaps i need to get the PKCS7 stack of the existing PKCS12, adding a new bag for my new key and recreate a new PKCS12 with this updated stack ? I will try this and post if it succeed. – Yann Delanoe Jun 16 '17 at 15:39
2

I finally succeed to add/parse multiple RSA keys and they certs into/from a PKCS12 structure/file. My parse function is based on the OpenSSL parse_pk12 function in p12_kiss.c file. This function seems to return the last bag only. I adapt it to check each bags friendly name and return the one who match.

The add function begin with unpacking the safes (STACK_OF(PKCS7)) from the existing PKCS12, and then working on this safes in order to add a new stack of bags to it. I then create a new PKCS12 with the PKCS12_add_safes function and delete the previous one. Thanks all

Yann Delanoe
  • 119
  • 7
  • @DanielSzy complete code's too long to be added in comment. So mainly : `/* Get PKCS7 from PKCS12 */ safes = PKCS12_unpack_authsafes(*pkcs12)); bag = PKCS12_add_key(&bags, key, keytype, PKCS12_DEFAULT_ITER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, pp); cp_safebag_attribute(bag, key, NID_ms_csp_name); cp_safebag_attribute(bag, key, NID_LocalKeySet); PKCS12_add_friendlyname(bag, keyAlias, -1); PKCS12_add_localkeyid(bag, keyid, keyidlen); PKCS12_add_safe(&safes, bags, -1, 0, NULL); newpkcs12 = PKCS12_add_safes(safes, 0);` – Yann Delanoe Feb 24 '20 at 10:57