SecPKCS12Import is failing

software used: xcode: 14.1 swift: 4 openssl v3

when trying to import the p12 certificate with SecPKCS12Import, it is failing with the following error: Error Domain=NSOSStatusErrorDomain Code=-25293 "The user name or passphrase you entered is not correct." UserInfo={NSLocalizedDescription=The user name or passphrase you entered is not correct.})   -25293

The p12 certificate is created using AES-256-CBC. This p12 file is passed through the following method that returned Data and then sent to SecPKCS12Import API.

BIO* createPKCS12fromPKCS12(const unsigned char* data, long dataLength, char* originalPassphrase, char* newPassphrase) {

  OSSL_PROVIDER defaultProvider = OSSL_PROVIDER_try_load(NULL, "default", 1);       BIO bp = BIO_new_mem_buf(data, (int)dataLength);   PKCS12* originalPKCS12 = NULL;   d2i_PKCS12_bio(bp, &originalPKCS12);   BIO_free(bp);

  EVP_PKEY* privateKey;   X509* x509;   STACK_OF(X509)* caChain = NULL;   PKCS12_parse(originalPKCS12, originalPassphrase, &privateKey, &x509, &caChain);   PKCS12_free(originalPKCS12);       PKCS12* newPKCS12 = PKCS12_create(newPassphrase, "SAP Identity", privateKey, x509, caChain, 149, 146, 0, 0, 0);   unsigned long a = ERR_get_error();   printf("%lu", a);   EVP_PKEY_free(privateKey);   X509_free(x509);   sk_X509_free(caChain);   BIO* mem = NULL;   if (newPKCS12 != NULL) {     mem = BIO_new(BIO_s_mem());     i2d_PKCS12_bio(mem, newPKCS12);     PKCS12_free(newPKCS12);         }       return mem; }

     let err = SecPKCS12Import(pkcs12Data as CFData, query as CFDictionary, &items)     print("error in:: SecPKCS12Import", err.error, "\n", err)

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

     

Apple’s system do not support modern crypto in PKCS#12 (r. 50413452)-: If you want to build a PKCS#12 that’s compatible with SecPKCS12Import, I recommend that you do the following:

  1. In Keychain Access, find a digital identity that you have lying around, for example, the Apple Development identity you use for code signing.

  2. Export that as a PKCS#12.

  3. Dump it using your tool of choice.

  4. Use those parameters to set up your PKCS#12 code.

I’ve pasted an example of this below (using dumpasn1 [1]). As you can see, the key is protected by pbeWithSHAAnd40BitRC2-CBC O-:

Share and Enjoy

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

[1] https://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c


% dumpasn1 -p Quinn.p12
SEQUENCE {
  INTEGER 3
  SEQUENCE {
    OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
    [0] {
      OCTET STRING, encapsulates {
        SEQUENCE {
          SEQUENCE {
            OBJECT IDENTIFIER encryptedData (1 2 840 113549 1 7 6)
            [0] {
              SEQUENCE {
                INTEGER 0
                SEQUENCE {
                  OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
                  SEQUENCE {
                    OBJECT IDENTIFIER
                      pbeWithSHAAnd40BitRC2-CBC (1 2 840 113549 1 12 1 6)
                    SEQUENCE {
                      OCTET STRING 3C 03 6C 5E 8A 05 0B 9A
                      INTEGER 2048
                      }
                    }
                  [0]
                    0A 16 62 2E 1E 80 36 94 EA 5C BF 31 6B C9 15 56
                    57 1C A6 DE 24 C7 77 4C D2 54 A8 84 76 22 68 0B
                    F3 EE D2 8A 41 D4 68 33 9C 71 BD 7D DA E6 73 41
                    CF D9 3C 07 04 39 3A 33 0A 02 9C 14 D0 29 9D 6A
                    D7 A8 DF 6F 98 FF 9F 13 05 E3 0B CD 3B 36 5A 3C
                    41 B8 70 00 C9 60 70 6C 14 53 78 25 91 FD C2 2D
                    DB 52 D9 A3 7B 4C F8 F5 DD 28 7F FA 90 76 27 54
                    94 2E 01 28 64 FE 78 3B 98 50 9D B8 E1 B4 65 EF
                            [ Another 1552 bytes skipped ]
                  }
                }
              }
            }
          SEQUENCE {
            OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
            [0] {
              OCTET STRING, encapsulates {
                SEQUENCE {
                  SEQUENCE {
                    OBJECT IDENTIFIER
                      pkcs-12-pkcs-8ShroudedKeyBag (1 2 840 113549 1 12 10 1 2)
                    [0] {
                      SEQUENCE {
                        SEQUENCE {
                          OBJECT IDENTIFIER
                            pbeWithSHAAnd3-KeyTripleDES-CBC (1 2 840 113549 1 12 1 3)
                          SEQUENCE {
                            OCTET STRING 27 4D F0 95 FD 4B D4 6B
                            INTEGER 2048
                            }
                          }
                        OCTET STRING
                          7E 63 7D 8D BE BF E5 00 19 DC BF E7 F5 63 E2 86
                          60 A0 07 5A 3D 21 16 F6 00 9A 3E B0 B6 2E CE 1D
                          69 F7 6E 1E D2 C9 5A B9 AB 93 1E DD 65 0D 05 CF
                          E8 1E 85 67 27 02 02 E3 6F B8 95 78 C4 B4 CA 7A
                          B7 87 67 F1 8E FD DA A1 05 08 92 89 7D 8A CC 87
                          72 84 68 F9 8E 70 EE F8 29 96 9A B5 FC 70 37 A5
                          DE 04 76 11 AE 93 E4 BC C4 83 7E 75 41 03 0E 13
                          48 DB D3 CA 94 1A E6 A4 BD BC DD 9A 0F DF D3 55
                                  [ Another 1096 bytes skipped ]
                        }
                      }
                    SET {
                      SEQUENCE {
                        OBJECT IDENTIFIER
                          friendlyName (for PKCS #12) (1 2 840 113549 1 9 20)
                        SET {
                          BMPString
                            '.A.p.p.l.e. .D.e.v.e.l.o.p.m.e.n.t.:. .Q.u.i.n.n'
                            '. .Q.u.i.n.n. .(.Q.u.i.n.n. .Q.u.i.n.n.)'
                          }
                        }
                      SEQUENCE {
                        OBJECT IDENTIFIER
                          localKeyID (for PKCS #12) (1 2 840 113549 1 9 21)
                        SET {
                          OCTET STRING
                            D3 E9 33 67 55 57 26 C0 10 D6 D0 A6 00 8A A9 A2
                            1E AF 1C 7E
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  SEQUENCE {
    SEQUENCE {
      SEQUENCE {
        OBJECT IDENTIFIER sha1 (1 3 14 3 2 26)
        NULL
        }
      OCTET STRING 66 1B F6 BD F2 25 75 37 9C 02 CC 02 51 E0 51 54 23 2D D6 39
      }
    OCTET STRING 78 61 A3 F3 B0 12 62 F2
    INTEGER 1
    }
  }

Still failing
used the apple development certificate(from keychain access) my code.
the certificate is protected with alogs:
pbeWithSHA1And3-KeyTripleDES-CBC
pbeWithSHA1And40BitRC2-CBC

in openssl PKCS12_create used the above algos for creating PKCS12. which is further passed to SecPKCS12Import

attaching my code below:

BIO* createPKCS12fromPKCS12(const unsigned char* data, long dataLength, char* originalPassphrase, char* newPassphrase) {

OSSL_PROVIDER legacy = OSSL_PROVIDER_try_load(NULL, "legacy", 1);
OSSL_PROVIDER defaultProvider = OSSL_PROVIDER_try_load(NULL, "default", 1);
int nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
int nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;

BIO
bp = BIO_new_mem_buf(data, (int)dataLength);
PKCS12
originalPKCS12 = NULL;
d2i_PKCS12_bio(bp, &originalPKCS12);
BIO_free(bp);

EVP_PKEY* privateKey;
X509* x509;
STACK_OF(X509)* caChain = NULL;
PKCS12_parse(originalPKCS12, originalPassphrase, &privateKey, &x509, &caChain);
PKCS12_free(originalPKCS12);

//  printf("%d", nid_key);
//  printf("%d", nid_cert);

PKCS12* newPKCS12 = PKCS12_create(newPassphrase, "SAP Identity", privateKey, x509, caChain, nid_key, nid_cert, 0,\ PKCS12_DEFAULT_ITER, 0);
unsigned long a = ERR_get_error();
printf("%lu", a);
EVP_PKEY_free(privateKey);
X509_free(x509);
sk_X509_free(caChain);
BIO* mem = NULL;
int verify = PKCS12_verify_mac(newPKCS12, newPassphrase, 0);
printf("%d", verify);

if (newPKCS12 != NULL) {
mem = BIO_new(BIO_s_mem());
i2d_PKCS12_bio(mem, newPKCS12);
PKCS12_free(newPKCS12);

}

return mem;
}\

public func obtainUserIdentity(completionHandler: @escaping (Data?, Error?) -> Void) {     logger.debug("Called: obtainUserIdentity(completionHandler:)")
let data = try Data(contentsOf: fileURL) // fileurl i spath of p12 file \     guard let pkcs12Data = OpenSSLHelperProxy.shared.createPKCS12fromPKCS12Data(data, passp\hraseOriginal: passphrase, passphraseNew: "") else {
logger.error("Create PKCS #12 from PKCS #12 data failed")
completionHandler(nil, IdentityError.failedToCreateIdentity)
return
}
completionHandler(pkcs12Data, nil)
}
\

-(NSData* _Nullable)createPKCS12fromPKCS12Data:(NSData* _Nonnull)PKCS12Data passphraseOriginal:(NSString* _Nonnull)passphraseOriginal passphraseNew:(NSString* _Nonnull)passphraseNew {/   BIO* mem = createPKCS12fromPKCS12([PKCS12Data bytes], [PKCS12Data length], (char*)[passphraseOriginal UTF8String], (char*)[passphraseNew UTF8String]);/   NSData* data = [OpenSSLHelperProxy NSDataFromBIO:mem];/   return data;/ }/ / +(NSData*)NSDataFromBIO:(BIO*)mem {/   NSData* data = nil;/   if (mem != NULL) {/     char* ptr = NULL;/     /     size_t size = BIO_get_mem_data(mem, &ptr);/     data = [NSData dataWithBytes:ptr length:size];/     BIO_free(mem);/   }/   return data;/ }/ /

this Data is sent to
SecPKCS12Import(pkcs12Data as CFData, query as CFDictionary, &items)
which isthrowingg error

   

hi,

sharing a project to reproduce the issue: https://github.com/NamrataKSAP/PKCS12TestApp

check the console log for error

I can’t really help you with OpenSSL code. I don’t maintain expertise in that. If you need help on that front, I recommend that you escalate this via the support resources for that library [1].

My advice is that you do the following:

  1. Export a PKCS#12 using Keychain Access.

  2. Generate a PKCS#12 using your OpenSSL code.

  3. Use your favourite ASN.1 dumping tool to compare the two.

If they both have the same structure, including the algorithms used, then that’s something I can help you with. If not, you’ll need to discuss this with folks who understand the OpenSSL API.

In the first case, for me to help out I need you to post a sample PKCS#12 blob. To make sure that this survives the trip to DevForums, post a hex dump inside a code block. See Quinn’s Top Ten DevForums Tips for advice on that last bit.

Share and Enjoy

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

[1] https://www.openssl.org/community/

As per your suggestion, I did compare the certificate data. I used an apple developer certificate taken from keychain access. I passed this certificate to my code and then created a new one using PKCS12_create API of OpenSSL(check project https://github.com/NamrataKSAP/PKCS12TestApp) I printed the certificate data/info in the console using code.

The SecPKCS12Import works for the same certificate if using OpenSSL version 1. but fails with OpenSSL version 3.

Attaching two files

  1. certificate info with OpenSSL 1.
  2. certificate info with OpenSSL 3
  3. certificate info fetch in terminal with OpenSSL 3

I find both similar.

Code to print certificate info:

PKCS12* newPKCS12 = PKCS12_create(newPassphrase, "SAP Identity", privateKey, x509, caChain, 0, 0, 0, 0, 0);
X509* x509crt;
STACK_OF(X509)* caChainw = NULL;
EVP_PKEY* privateKeyr;
int parse = PKCS12_parse(newPKCS12, newPassphrase, &privateKeyr, &x509crt, &caChainw);
BIO* mem = BIO_new(BIO_s_mem());
BIO_printf(mem2, "\n");

NSData* data = [OpenSSLHelperProxy NSDataFromBIO:mem];\

let certificateStr = String(data: data, encoding: .utf8)
print("certificate info\n\n", certificateStr)

Indeed. I can’t spot any meaningful differences either.

I’d like to try reproducing this here. Please post a hex dump of a test PKCS#12 blob and its password.

Share and Enjoy

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

Sharing the hex dump. I suppose this is what you want. Also, you can find the certificate and the password in git project itself. Password: 12345678

I suppose this is what you want.

No, I’m looking for a hex dump of the PKCS#12 data you’re passing to SecPKCS12Import. In the commands below, you see I first run dumpasn1 to confirm that this is a PKCS#12 blob and then run xxd to generate a hex dump. I just need the hex dump.

Share and Enjoy

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

Hello, I also stumbled on this issue recently with OpenSSL 3.X (3.0.5/3.0.8). After reading about the broken support between OpenSSL 3.X and Apple security API's got this to work by creating the P12 bundle maintaining the Apple API specs, following in the snippet from my C code to create the PKCS12 bundle:

Note.: You will first need to have the legacy provider module in place (either dynamic package or statically linked into OpenSSL libs by using "no-shared" & "no-modules" configure options.

int GeneratePKCS12(char* PassPhrase, char* FriendlyName, EVP_PKEY* PrivateKey, X509* Cert, STACK_OF(X509)* CaCerts, char** outPKCS12, int *outPKCS12Len) { //Load the legacy provider OSSL_PROVIDER *_legacy = OSSL_PROVIDER_load(NULL, "legacy"); OSSL_PROVIDER *_defaultProvider = OSSL_PROVIDER_load(NULL, "default"); if (_legacy != NULL) { p12OutCert = PKCS12_create_ex(PassPhrase, FriendlyName, PrivateKey, x509Cert, CaCerts, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NID_pbe_WithSHA1And40BitRC2_CBC, PKCS12_DEFAULT_ITER, -1, 0, NULL, NULL); if (p12OutCert) { if(1 == PKCS12_set_mac(p12OutCert, pswd, m_strlen(pswd), NULL, 0, 1, EVP_sha1())) { int nP12Len = 0; BIO *outBioP12 = BIO_new(BIO_s_mem()); i2d_PKCS12_bio(outBioP12, p12OutCert); nP12Len = BIO_pending(outBioP12); (outPKCS12) = (char)calloc(1, nP12Len + 1); BIO_read(outBioP12, *outPKCS12, nP12Len); outPKCS12Len = nP12Len; } else { printf("Failed to add P12 mac\n"); } } else { printf("Failed to create P12 \n"); } } else { char buf[256]; ERR_error_string_n(err, buf, sizeof(buf)); printf("Failed to load provider - %s\n", buf); } }

Thanks, @tejas22192 I will check this on my side

Big Thanks @tejas22192 your solution works for me

SecPKCS12Import is failing
 
 
Q