convert a PKCS 12 cert to PEM format
来源:互联网 发布:上海网络广告公司铭心 编辑:程序博客网 时间:2024/04/30 01:51
利用OpenSSL的PKCS12_parse函数进行证书格式转换的参考代码。
目前这个函数还存在内存泄漏,这是OpenSSL 的Bug,做法上完全可以参考。
EVP_CIPHER *g_pEncAlg = NULL;ESMTRESULT OsPEMCredConvert(FILE *fIn, char *pszP12Password, char *pszPassword, char /*pszFilename, BOOL fMakeCertChain){ ESMTRESULT hr = NF_S_OK; PKCS12 *p12 = NULL; EVP_PKEY *pPkey = NULL; X509 *pCert = NULL; BIO *pBIO = NULL; STACK_OF(X509) *pCaCerts=NULL; char abFilename[MAXPATHLEN] = ""; FILE *fOut = NULL; int fCerts = INFO; NfCtx nfCtx; nfCtx.fIn = fIn; nfCtx.fOut = stdout; CRYPTO_malloc_debug_init(); MemCheck_start(); do { if (fMakeCertChain && g_fOutputCaCerts) { hr = CRED_E_INCOMPATIBLE_FLAGS; break; } if (fMakeCertChain) fCerts |= CLCERTS; else if (g_fOutputCaCerts) fCerts |= CACERTS | NOKEYS; if ((pBIO = BIO_new(NfBIO())) == NULL) { hr = CRED_E_BIO; break; } BIO_ctrl(pBIO, BIO_CTRL_SET, BIO_NOCLOSE, (char *)&nfCtx); if ((p12 = d2i_PKCS12_bio(pBIO, &p12)) == NULL) { hr = CRED_E_P12_OPEN; break; } if (PKCS12_parse(p12, pszP12Password ? pszP12Password : "", &pPkey, &pCert, /(STACK **)&pCaCerts) <= 0) { hr = CRED_E_P12_PARSE; break; } if (pszP12Password == NULL) { if (!PKCS12_verify_mac(p12, NULL, 0)) { hr = CRED_E_P12_BAD_PWD; break; } } else if (!PKCS12_verify_mac(p12, pszP12Password, -1)) { hr = CRED_E_P12_BAD_PWD; break; } /* Encrypt private key with 3DES if required */ g_pEncAlg = pszPassword != NULL ? EVP_des_ede3_cbc() : NULL; if (!dump_certs_keys_p12 (pBIO, p12, pszP12Password, -1, fCerts, pszPassword)) { hr = CRED_E_P12_PARSE;break; } } while (0); if (fOut) fclose(fOut); if (pCaCerts) sk_X509_free(pCaCerts); if (pCert) X509_free(pCert); if (pPkey)EVP_PKEY_free(pPkey); if (p12) PKCS12_free(p12); if (pBIO) BIO_free(pBIO); ERR_free_strings(); ERR_remove_state(0); EVP_cleanup(); MemCheck_stop(); CRYPTO_mem_leaks(stdout); return (hr);}