Import PEM encoded X.509 certificate into iOS KeyChain

I get a string containing the X.509 certificate encoded by PEM. I would like to import this certificate into KeyChain iOS.

I plan to do the following:

  • convert NSString to openssl X509
  • create PKCS12
  • convert PKCS12 to NSData li>
  • import NSData using SecPKCS12Import

So far I have come up with the following code:

const char *cert_chars = [certStr cStringUsingEncoding:NSUTF8StringEncoding];

BIO *buffer = BIO_new(BIO_s_mem());
BIO_puts(buffer, cert_chars);

X509 *cert;
cert = PEM_read_bio_X509(buffer, NULL, 0, NULL);
if (cert == NULL) {
    NSLog(@"error");
}
X509_print_fp(stdout, cert);


EVP_PKEY *privateKey;
const unsigned char *privateBits = (unsigned char *) [privateKeyData bytes];
int privateLength = [privateKeyData length];

privateKey = d2i_AutoPrivateKey(NULL, &privateBits, privateLength);

if (!X509_check_private_key(cert, privateKey)) {
    NSLog(@"PK error");
}

PKCS12 *p12 = PKCS12_create("test", "David Cert", privateKey, cert, NULL, 0, 0, 0, 0, 0);

Unfortunately, p12 is zero, although X509_check_private_key was successful, and X509_print_fp (stdout, cert) prints a valid certificate.

  • my approach is right
  • Why doesn't PKCS12_create seem to work?

Update:

Calling PKCS12_create will throw an error in the following way:

int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
           ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
{
const EVP_CIPHER *cipher;
const EVP_MD *md;
int cipher_nid, md_nid;
EVP_PBE_KEYGEN *keygen;

if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
                &cipher_nid, &md_nid, &keygen))
    {
    char obj_tmp[80];
    EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM);
    if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
    else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
    ERR_add_error_data(2, "TYPE=", obj_tmp);
    return 0;
    }

if(!pass)
    passlen = 0;
else if (passlen == -1)
    passlen = strlen(pass);

if (cipher_nid == -1)
    cipher = NULL;
else
    {
    cipher = EVP_get_cipherbynid(cipher_nid);
    if (!cipher)
        {
        EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER);
        return 0;
        }
    }

if (md_nid == -1)
    md = NULL;
else
    {
    md = EVP_get_digestbynid(md_nid);
    if (!md)
        {
        EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST);
        return 0;
        }
    }

if (!keygen(ctx, pass, passlen, param, cipher, md, en_de))
    {
    EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE);
    return 0;
    }
return 1;   
}

Receive encryption

cipher = EVP_get_cipherbynid(cipher_nid);

somehow returns nil for "RC2-40-CBC".

+4
source share
1

PKCS12 :

OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();

, .

+4

All Articles