2013-01-31 64 views
4

我從某處收到包含PEM編碼的X.509證書的字符串。我想將此證書導入iOS的KeyChain。將PEM編碼的X.509證書導入iOS KeyChain

我打算做到以下幾點:

  1. 轉換的NSString OpenSSL的X​​509
  2. 創建PKCS12
  3. 轉換PKCS12到NSData的
  4. 進口的NSData與SecPKCS12Import

所以我想出了以下代碼:

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's Cert", privateKey, cert, NULL, 0, 0, 0, 0, 0); 

不幸的是,即使X509_check_private_key成功並且X509_print_fp(stdout,cert)打印了有效的證書,p12也是零。

  1. 是我的做法正確
  2. 怎麼來PKCS12_create似乎失敗了呢?

更新:

呼叫PKCS12_create似乎在下面的方法失敗:

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; 
} 

檢索密碼

cipher = EVP_get_cipherbynid(cipher_nid); 

莫名其妙地返回nil爲「RC2-40 -CBC」。

回答

4

以下呼叫創建PKCS12前失蹤:

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

這些解決與丟失密碼的問題,也缺少消化的後續問題。

+0

謝謝!救了我! – karim