SecPKCS12Import is failing to import P12 certificate.

Are you able to reproduce the issue? Yes

What software version(s) and hardware have you reproduced the issue on? iOS 14, iOS 15 iPhone XR, iPhone 12 simulator (On All iOS devices)

Description

When trying to import a P12 certificate using the API SecPKCS12Import, it is failing with error errSecDecode = -26275 since 09/23 in production. We tried to figure out the change in our code base (client as well as server side) that might have triggered this failure but there is no change on either side. The same P12 certificate is successfully validated using the below mentioned openssl command on the terminal.

openssl pkcs12 -in -passin pass:

Please can you tell us how we may debug the API SecPKCS12Import and understand what might be incorrect in P12 certificate format due to which it has started failing.

Note: The same code (with zero change) was working fine in production until 09/23.

If required, we may share the p12 certificate and associate password with you to debug it further.

If required, we may share the p12 certificate and associate password with you to debug it further.

You have a couple of choices here:

  • If you want to work in public, feel free to post a hex dump of your .p12 file and its password here.

  • If you’d prefer to work in private, open a DTS tech support incident and we can take this from there.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Because only .txt are allow to upload here

Indeed. That’s why I requested that you post a hex dump.

I tried downloading your .txt file but something went wrong. Compare this:

% openssl pkcs12 -in Frankie.p12 -nodes      
Enter Import Password:
MAC verified OK

where Frankie.p12 is a known good PKCS#12 with this:

% openssl pkcs12 -in pkcs12.p12 -nodes 
4513808044:error:0DFFF0A8:asn1 encoding routines:CRYPTO_internal:wrong …

when looking at your file.

Please post a hex dump of the PKCS#12 and I’ll take another look.

ps Use xxd -p to generate a compact hex dump:

% xxd -p Frankie.p12

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

And then I ran xxd -p myfile.p12 and the result is in hex.txt

Thanks. That’s exactly what I needed.

I converted your hex dump back to binary and put it in a file called test.p12. I tried importing this into Keychain Access on the Mac. That also failed. So something about this PKCS#12 data is not making Apple systems happy.

Unfortunately I’m not a PKCS#12 guru so I can’t point you to the exact problem. However, I do have some info to share.

I used openssl to convert the file to PEM and back again:

% openssl pkcs12 -in test.p12 -out test.pem
…
% openssl pkcs12 -export -in test.pem -out test-openssl.p12
…

The Mac can import this test-openssl.p12 file. I then dump the two files:

% openssl pkcs12 -info -in test-openssl.p12 
Enter Import Password:
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
    localKeyID: B1 52 93 3A FC DD B0 30 44 C8 A8 D4 CC 1E A7 4A 25 40 1B F8 
subject=/CN=cast_nearby_client_auth
issuer=/CN=cast_nearby_client_auth
-----BEGIN CERTIFICATE-----
MIIC/jCCAeagAwIBAgIIaFS1HFLdQrUwDQYJKoZIhvcNAQELBQAwIjEgMB4GA1UE
…
3BFewf6vISPnxGMb6ZHUrQJRv96Mtptx5lWdoTOcHC0J5Wgd0NedO3lYKBBixy32
U3U=
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048
Bag Attributes
    localKeyID: B1 52 93 3A FC DD B0 30 44 C8 A8 D4 CC 1E A7 4A 25 40 1B F8 
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIG6ZeBMFUmG0CAggA
…
QFIdCtz/tfQhgNfIZiLJBAEf/NHD7Tb1I6NuCujT4xH3yHHBO40Ldreu5xFekY3A
Sb8=
-----END ENCRYPTED PRIVATE KEY-----
%
%
% openssl pkcs12 -info -in test.p12
Enter Import Password:
MAC Iteration 100000
MAC verified OK
PKCS7 Data
Shrouded Keybag: Bag Attributes
    friendlyName: cast_nearby_client_auth
    localKeyID: 54 69 6D 65 20 31 36 34 30 30 33 31 38 32 34 32 31 32 
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIjQ3PJLW2KYwCAggA
…
QWCGyY3tmwNBBfzZUIhG/uDXgfPo4v4pyPPGGmig1A8rXyQdgW7v9JHsmtReiai6
NQE=
-----END ENCRYPTED PRIVATE KEY-----
PKCS7 Encrypted data: Certificate bag
Bag Attributes
    friendlyName: cast_nearby_client_auth
    localKeyID: 54 69 6D 65 20 31 36 34 30 30 33 31 38 32 34 32 31 32 
subject=/CN=cast_nearby_client_auth
issuer=/CN=cast_nearby_client_auth
-----BEGIN CERTIFICATE-----
MIIC/jCCAeagAwIBAgIIaFS1HFLdQrUwDQYJKoZIhvcNAQELBQAwIjEgMB4GA1UE
…
3BFewf6vISPnxGMb6ZHUrQJRv96Mtptx5lWdoTOcHC0J5Wgd0NedO3lYKBBixy32
U3U=
-----END CERTIFICATE-----

These two files have significant structural differences. Specifically, contrast this in the working case (test-openssl.p12):

PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
…
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2048

with this in the failing case (test.p12):

PKCS7 Data
Shrouded Keybag: Bag Attributes
…
PKCS7 Encrypted data: Certificate bag

The two PKCS#7 blobs are in different order, but that’s OK. But they also have completely different format, which is clearly not OK. Note that the first, working case has the encryption algorithms I’d expect to see in a PKCS#12.

So, I’m not entirely sure what’s going on here but I’m quite sure that you need to look at the code that generated the test.p12 file you posted, because it’s generating a file that’s quite strangely formatted.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hi There,

I am the teammate of Cheng.

I found something weird here, when I use the command openssl pkcs12 -info -in <p12 Cert> to dump the cert file which we sent to you before in Linux, I got this:

$ openssl pkcs12 -info -in test.p12
Enter Import Password:
MAC: sha1, Iteration 100000
MAC length: 20, salt length: 20
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Bag Attributes
    friendlyName: cast_nearby_client_auth
    localKeyID: 54 69 6D 65 20 31 36 34 30 30 33 31 38 32 34 32 31 32
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIxZdIjm+Omo0CAggA
...
DvpIBfgjs86tuXHOi4J4gBkTXOhYOKvuguXvtb8h8w33M/IOiB+KVziXBhW91LxA
K0AYFolhBd83xpekNYg5kQ==
-----END ENCRYPTED PRIVATE KEY-----
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256
Certificate bag
Bag Attributes
    friendlyName: cast_nearby_client_auth
    localKeyID: 54 69 6D 65 20 31 36 34 30 30 33 31 38 32 34 32 31 32
subject=CN = cast_nearby_client_auth

issuer=CN = cast_nearby_client_auth

-----BEGIN CERTIFICATE-----
MIIC/jCCAeagAwIBAgIIaFS1HFLdQrUwDQYJKoZIhvcNAQELBQAwIjEgMB4GA1UE
...
3BFewf6vISPnxGMb6ZHUrQJRv96Mtptx5lWdoTOcHC0J5Wgd0NedO3lYKBBixy32
U3U=
-----END CERTIFICATE-----

It seems matches the structure of file test-openssl.p12, but when I move this file to my Mac and run the same command, I got the same result as what you got.

Because our code hasn't been changed for a long time (~1 year), and it suddenly starts failing on around 9/23/2021, could you help to check if there is anything changed inside the SecPKCS12Import API (e.g. Add more restrictions, Start rejecting some kind of structure), so that we may be able to figure out which part of our cert fails this API call, currently we only know it fails. Thank you for your help!

could you help to check if there is anything changed inside the SecPKCS12Import API

No, sorry. SecPKCS12Import is the tip of a very large Security framework iceberg and there’s simply no way to see if “anything changed” inside it. However…

it suddenly starts failing on around 2021-09-23

In general our platforms don’t change by themselves [1]. Behavioural changes are almost always associated with OS updates that are clearly visible to the user. So, you can test your “something changed in iOS” theory by testing on an old version of iOS.

This can be tricky because you can’t roll back the iOS version on a device. But in your case that’s not a problem because you can reproduce the problem with the simulator, and you can install arbitrarily old simulators.

So, try this:

  1. Build a small test app that tries to import one of your PKCS#12 blobs.

  2. Run it on a modern device to confirm that it fails there.

  3. Run it on the matching simulator to confirm that it fails there too.

  4. Use Xcode > Preferences > Components to download an old simulator, one that significantly predates your 2021-09-23 cutoff.

  5. Run your test app there.

If it works there, it’s likely you’ve being affected by an iOS change and I can help you investigate that further. However, my expectation is that it’ll fail there as well, in which case this isn’t about iOS versions but about how you’re generating you PKCS#12.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] The one exception to this is for security-related stuff, where we occasionally push out changes via a channel that’s independent of OS version. You most commonly see this on the Mac with its malware protection facilities. Given that you’re targeting iOS, I think it’s reasonable to ignore that possibility for the moment.

we will try to test it on an old simulator.

Cool.

At the same time, I would like to check if you could help us to check the error details (e.g. Missing any parts, Structure isn't correct, etc)?

Let’s cross that bridge when we come to it, eh? If, as I suspect, your old simulator test shows that the change isn’t in iOS, then a better way to debug this is to look at changes that you deployed to your PKCS#12 generation code around 2021-09-23.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

SecPKCS12Import is not compatible with the default openssl pkcs12 encoding algorithm in openssl@3. Downgrade to openssl@1.1.

See: Change default algorithms in PKCS12_create() and PKCS12_set_mac()

Thanks to Quinn and i_82 for the helpful investigation above.

This can happen with modern Java. Perhaps the mysterious change was a Java upgrade and not a macOS change? The cause is Security.framework falling behind the evolution of PKCS#12 security standards. Newer tools generate key stores encrypted with "modern" algorithms like AES, but macOS/iOS only understand key stores encrypted with long since broken and obsolete algorithms like SHA1 and TripleDES.

To fix it you have to change the Java security properties file (or use Security.setProperty in code), as follows:

keystore.pkcs12.keyProtectionAlgorithm = PBEWithSHA1AndDESede
keystore.pkcs12.certProtectionAlgorithm = PBEWithSHA1AndRC2_40
keystore.pkcs12.macAlgorithm = HmacPBESHA1

Once these are set, generated p12 files will be Apple-compatible.

With openssl version 3.2.0, use:

openssl pkcs12 -legacy

https://github.com/openssl/openssl/issues/19495

You can get it working with using the -legacy -certpbe pbeWithSHA1And40BitRC2-CBC parameters with the openssl pkcs12 -export command with the OpenSSL 3.x.x Version.

I found this hint in their Github page (issues) and it worked on my side (OpenSSL 3.4.0)

SecPKCS12Import is failing to import P12 certificate.
 
 
Q