Post

Replies

Boosts

Views

Activity

Reply to Import resulting certificate to associate with private key
Hi Quinn, I ended up importing via SecPKCS12Import() instead. After stepping back a bit I decided to use OpenSSL to generate the keypair, and then PKCS12_create() to package it with the leaf cert and intermediate CAs, and extract the DER into a CFData and SecPKCS12Import() was quite happy with that, setting all the proper attributes for the key and certs. I then went further and found that even if I create the private key in the keychain directly using SecKeyCreateRandomKey() that I could generate the PKCS12 data without the key (it's just a container) and SecPKCS12Import() still created all the right bits for the certs. The biggest quirk I see is the inconsistency in that I need to use kSecAttrApplicationLabel for keys and kSecAttrPublicKeyHash for the cert when querying (and deleting!) by the public key hash (which is what we persist as its alias). Mess that up and you quickly find yourself deleting other keys unintentionally (I still need to recover my keychain)... Thanks, Erik
Topic: App & System Services SubTopic: Core OS Tags:
Jul ’23
Reply to Import resulting certificate to associate with private key
Hi Quinn, This just keeps getting weirder and weirder. I found another post you had made (https://developer.apple.com/forums/thread/69642) that states to set the public key hash into the private key kSecAttrLabel and kSecAttrApplicationLabel (which is weird since the kSecAttrLabel is expected to be text), and into kSecAttrPublicKeyHash in the certificate. In other Apple docs you pointed to it is stated that the kSecAttrPublicKeyHash attribute is read only, which is what was throwing me off. Once I set that in the SecItemAdd dictionary for the cert, then it seems to associate correctly. So to experiment I found that SecItemCopyMatching with kSecClassCertificate, kSecReturnAttributes and kSecMatchLimitAll returns lots of certificates, almost all of which have many attributes set, e.g. class, cenc, ctyp, subj, issr, labl, pkhh, slnr, etc. In my case I wasn't specifying these, assuming the OS would set them, and my cert just reported a minimal set: class = cert, ctyp = 0, pkhh = {length = 20, bytes = 0x8a95...c955}. Then I went to my dictionary and started adding the others, like cenc, ctyp, subj, etc, but then I got error -67866 = errSecFieldSpecifiedMultiple (Too many fields were specified). I started taking some off, and it seems some attributes always give me that error, like ctyp, issr, srln. I can set the cenc, subj, labl and pkhh ok, but that's about it. And then when I go to import the intermediate, setting the same set of attributes (but different values from the leaf cert for the labl, subject and pkhh), I get errSecDuplicateItem. Your pointers mention setting kSecAttrApplicationLabel and I've tried making that unique for the leaf and intermediate, but no effect; I don't see why it's indicating duplicate. Here are the results of querying after adding; the intermediate is the result only after I delete the leaf right before adding it in order to get it to add. Printing description of ((__NSDictionaryM *)0x0000600000227780): { cenc = 3; class = cert; ctyp = 0; labl = "Leaf Certificate"; pkhh = {length = 20, bytes = 0xec127a9329e63d6733672bbb40aaecafd091ec79}; subj = {length = 84, bytes = 0x30523150 304e0603 5504030c 4775726e ... 62754861 6a706145 }; } Printing description of ((__NSDictionaryM *)0x000060000023a400): { cenc = 3; class = cert; ctyp = 0; labl = "Intermediate Certificate"; pkhh = {length = 20, bytes = 0x1b73c2a805958e4698d7607b66b23a080f94703e}; subj = {length = 54, bytes = 0x30343132 30300603 5504030c 29444556 ... 4570686d 6572616c }; } Note that all of this is using the file-based keychain and currently in user space.
Topic: App & System Services SubTopic: Core OS Tags:
Jul ’23
Reply to Import resulting certificate to associate with private key
Ok, there was a residual certificate with the same subject (but different key and serial number), still trying to figure out why it thinks it's a duplicate as it has a different kSecAttrApplicationLabel. I'm experimenting with additional fields like kSecAttrApplicationTag, as it's not clear what is required to be set for (1) the private/public keys, and (b) the certificate, will update tomorrow.
Topic: App & System Services SubTopic: Core OS Tags:
Jun ’23
Reply to Import resulting certificate to associate with private key
Hi Quinn, so I am still having an issue with SecItemAdd() with the resulting certificate returned by the CA. I have created the public and private keys in the (file-based) keychain, and I can find them using SecItemCopyMatching by searching via kSecAttrApplicationLabel being the public key hash (kSecAttrCanSign=kCFBooleanTrue for the private key ref, kSecAttrCanSign=kCFBooleanFalse for the public key). However, SecItemAdd() with the cert data itself returns errSecDuplicateItem, even though kSecClass=kSecClassCertificate and the certificate certainly does not exist. I have tried specifying kSecAttrApplicationLabel and also without, no difference. What am I missing here? The intermediate certificate gets added with no problem, so it must have something to do with the existing keys...
Topic: App & System Services SubTopic: Core OS Tags:
Jun ’23
Reply to Import resulting certificate to associate with private key
Hi Quinn, I ended up importing via SecPKCS12Import() instead. After stepping back a bit I decided to use OpenSSL to generate the keypair, and then PKCS12_create() to package it with the leaf cert and intermediate CAs, and extract the DER into a CFData and SecPKCS12Import() was quite happy with that, setting all the proper attributes for the key and certs. I then went further and found that even if I create the private key in the keychain directly using SecKeyCreateRandomKey() that I could generate the PKCS12 data without the key (it's just a container) and SecPKCS12Import() still created all the right bits for the certs. The biggest quirk I see is the inconsistency in that I need to use kSecAttrApplicationLabel for keys and kSecAttrPublicKeyHash for the cert when querying (and deleting!) by the public key hash (which is what we persist as its alias). Mess that up and you quickly find yourself deleting other keys unintentionally (I still need to recover my keychain)... Thanks, Erik
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Jul ’23
Reply to Import resulting certificate to associate with private key
Hi Quinn, This just keeps getting weirder and weirder. I found another post you had made (https://developer.apple.com/forums/thread/69642) that states to set the public key hash into the private key kSecAttrLabel and kSecAttrApplicationLabel (which is weird since the kSecAttrLabel is expected to be text), and into kSecAttrPublicKeyHash in the certificate. In other Apple docs you pointed to it is stated that the kSecAttrPublicKeyHash attribute is read only, which is what was throwing me off. Once I set that in the SecItemAdd dictionary for the cert, then it seems to associate correctly. So to experiment I found that SecItemCopyMatching with kSecClassCertificate, kSecReturnAttributes and kSecMatchLimitAll returns lots of certificates, almost all of which have many attributes set, e.g. class, cenc, ctyp, subj, issr, labl, pkhh, slnr, etc. In my case I wasn't specifying these, assuming the OS would set them, and my cert just reported a minimal set: class = cert, ctyp = 0, pkhh = {length = 20, bytes = 0x8a95...c955}. Then I went to my dictionary and started adding the others, like cenc, ctyp, subj, etc, but then I got error -67866 = errSecFieldSpecifiedMultiple (Too many fields were specified). I started taking some off, and it seems some attributes always give me that error, like ctyp, issr, srln. I can set the cenc, subj, labl and pkhh ok, but that's about it. And then when I go to import the intermediate, setting the same set of attributes (but different values from the leaf cert for the labl, subject and pkhh), I get errSecDuplicateItem. Your pointers mention setting kSecAttrApplicationLabel and I've tried making that unique for the leaf and intermediate, but no effect; I don't see why it's indicating duplicate. Here are the results of querying after adding; the intermediate is the result only after I delete the leaf right before adding it in order to get it to add. Printing description of ((__NSDictionaryM *)0x0000600000227780): { cenc = 3; class = cert; ctyp = 0; labl = "Leaf Certificate"; pkhh = {length = 20, bytes = 0xec127a9329e63d6733672bbb40aaecafd091ec79}; subj = {length = 84, bytes = 0x30523150 304e0603 5504030c 4775726e ... 62754861 6a706145 }; } Printing description of ((__NSDictionaryM *)0x000060000023a400): { cenc = 3; class = cert; ctyp = 0; labl = "Intermediate Certificate"; pkhh = {length = 20, bytes = 0x1b73c2a805958e4698d7607b66b23a080f94703e}; subj = {length = 54, bytes = 0x30343132 30300603 5504030c 29444556 ... 4570686d 6572616c }; } Note that all of this is using the file-based keychain and currently in user space.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Jul ’23
Reply to Import resulting certificate to associate with private key
Ok, there was a residual certificate with the same subject (but different key and serial number), still trying to figure out why it thinks it's a duplicate as it has a different kSecAttrApplicationLabel. I'm experimenting with additional fields like kSecAttrApplicationTag, as it's not clear what is required to be set for (1) the private/public keys, and (b) the certificate, will update tomorrow.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Jun ’23
Reply to Import resulting certificate to associate with private key
Hi Quinn, so I am still having an issue with SecItemAdd() with the resulting certificate returned by the CA. I have created the public and private keys in the (file-based) keychain, and I can find them using SecItemCopyMatching by searching via kSecAttrApplicationLabel being the public key hash (kSecAttrCanSign=kCFBooleanTrue for the private key ref, kSecAttrCanSign=kCFBooleanFalse for the public key). However, SecItemAdd() with the cert data itself returns errSecDuplicateItem, even though kSecClass=kSecClassCertificate and the certificate certainly does not exist. I have tried specifying kSecAttrApplicationLabel and also without, no difference. What am I missing here? The intermediate certificate gets added with no problem, so it must have something to do with the existing keys...
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Jun ’23