c# - Get Apple Keychain to recognize Bouncy Castle .NET created PKCS12 (.p12) store -


our organization manages stable of ios applications multiple clients, means dealing lot of different developer identity certificates , push notification certificates.

i have had success bouncy castle c# crypto api in simplifying management of certificates , private keys push notifications, essentially eliminating need keychain our push notification certificates.

i extend developer identity certificates. goal store private key , certificate information in database each developer identity. when new developer or build machine needs provisioned, server side code wrap of certificates , private keys 1 p12 archive 1 password imported target mac's keychain.

unfortunately, mac keychain doesn't p12 files i'm generating. annoying since can import these files windows certificate manager fine.

the code i'm using (the important parts) looks this:

private byte[] getp12bytes(list<devidentity> identities, string password) {     pkcs12store store = new pkcs12store();      foreach(devidentity ident in identities)     {         // easiest create bouncy castle cert converting .net         var dotnetcert = new x509certificate2(ident.certificatebytes);         // method (not shown) parses cn= attribute out of cert's distinguished name         string friendlyname = getfriendlyname(dotnetcert.subject);           // reconstitute private key saved value strings         biginteger modulus = new biginteger(ident.privatekey.modulus);         biginteger publicexponent = new biginteger(ident.privatekey.publicexponent);         biginteger privateexponent = new biginteger(ident.privatekey.exponent);         biginteger p = new biginteger(ident.privatekey.p);         biginteger q = new biginteger(ident.privatekey.q);         biginteger dp = new biginteger(ident.privatekey.dp);         biginteger dq = new biginteger(ident.privatekey.dq);         biginteger qinv = new biginteger(ident.privatekey.qinv);         rsakeyparameters kp = new rsaprivatecrtkeyparameters(modulus, publicexponent, privateexponent, p, q, dp, dq, qinv);         asymmetrickeyentry privatekey = new asymmetrickeyentry(kp);          // let's convert bouncy castle cert , wrap packaging         org.bouncycastle.x509.x509certificate cert = dotnetutilities.fromx509certificate(dotnetcert);         x509certificateentry certentry = new x509certificateentry(cert);          // set private key , certificate store         store.setcertificateentry(friendlyname, certentry);         store.setkeyentry(ident.privatekeyname, privatekey, new x509certificateentry[] { certentry });     }      using (memorystream ms = new memorystream())     {         store.save(ms, password.tochararray(), new securerandom());         ms.flush();         byte[] p12bytes = ms.toarray();         return p12bytes;     } } 

like said, works great import on windows, fails generic error when importing mac keychain.

there 1 major difference can see when loading keychain-generated p12 , own generated p12 file, not know if cause.

if load mac keychain generated p12 bouncy castle pkcs12store, , examine keys, on keychain p12, both certificate , private key have attribute key "1.2.840.113549.1.9.21" equivalent values (a deroctetstring value #af8a1d6891efeb32756c12b7bdd96b5ec673e11e).

if same generated p12 file, private key contains "1.2.840.113549.1.9.21" attribute, certificate not.

if google "1.2.840.113549.1.9.21", find out oid means pkcs_12_local_key_id . theory keychain relies on match certificate , private key, , generated file not have this, fails.

however, i've tried adding these values hashtable , using certificateentry constructor takes attribute hashtable. if that, , save bytes, , reload bytes, attribute again missing.

so i'm flummoxed. maybe attribute glitch in bouncy castle api? maybe there's i'm doing wrong. maybe keychain has ridiculous non-standard requirements incoming p12 files. in case, provided appreciated.

bouncycastle's pkcs12store takes care of setting both friendly name , local key id attributes (or @ least in 1.7 release, circa april 2011). guess must have used older version didn't work.

here's how i'm saving iphone developer identity pkcs12store instance (extra stuff , security omitted):

var store = new pkcs12store();  // pairs ienumerable<tuple<x509certificate, asymmetrickeyparameter>> foreach (var pair in pairs) {     var cn = pair.item1.subjectdn          .getvaluelist(x509name.cn).oftype<string>().single();      var certentry = new x509certificateentry(pair.item1);     store.setcertificateentry(cn, certentry);      var keyentry = new asymmetrickeyentry(pair.item2);     store.setkeyentry("developer name", keyentry, new[] { certentry }); }  store.save(stream, string.empty.toarray(), new securerandom()); 

importing store in keychain access.app on os x 10.7 correctly places certificate , private key in keychain , places certificate within private key in ui, certificate , key generated keychain access itself.

on side note, seems pkcs12store uses public key of certificate generate value of localkeyid attribute shared certificate , key entries.

you can see relevant section of pkcs12store source here.


Comments

Popular posts from this blog

python - Scipy curvefit RuntimeError:Optimal parameters not found: Number of calls to function has reached maxfev = 1000 -

c# - How to add a new treeview at the selected node? -

java - netbeans "Please wait - classpath scanning in progress..." -