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