优化P12解析逻辑

Signed-off-by: lanming <lanming@huawei.com>
This commit is contained in:
lanming 2024-06-01 11:04:27 +08:00
parent 21409a12c4
commit 44f8ed8133
3 changed files with 110 additions and 46 deletions

View File

@ -2125,30 +2125,31 @@ static CfResult GetNameConstraintsFromP12(X509 *cert, CfBlob **name)
return CF_SUCCESS;
}
static CfResult ProcessP12Data(EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) * ca, HcfX509TrustAnchorArray **result)
static CfResult ProcessP12Data(STACK_OF(X509) *ca, HcfX509TrustAnchorArray *result)
{
CfResult ret = CF_SUCCESS;
for (int i = 0; i < sk_X509_num(ca); i++) {
X509 *x509 = sk_X509_value(ca, i);
// CACert
ret = X509ToHcfX509Certificate(sk_X509_value(ca, i), &((*result)->data[i]->CACert));
ret = X509ToHcfX509Certificate(x509, &(result->data[i]->CACert));
if (ret != CF_SUCCESS) {
LOGD("Failed to get %d CACert!", i);
}
// CAPubKey
ret = GetPubFromP12(X509_get_pubkey(sk_X509_value(ca, i)), &((*result)->data[i]->CAPubKey));
ret = GetPubFromP12(X509_get0_pubkey(x509), &(result->data[i]->CAPubKey));
if (ret != CF_SUCCESS) {
LOGD("Failed to get %d CAPubKey!", i);
}
// CASubject
ret = GetSubjectFromP12(cert, &((*result)->data[i]->CASubject));
ret = GetSubjectFromP12(x509, &(result->data[i]->CASubject));
if (ret != CF_SUCCESS) {
LOGD("Failed to get %d CASubject!", i);
}
// nameConstraints
ret = GetNameConstraintsFromP12(cert, &((*result)->data[i]->nameConstraints));
ret = GetNameConstraintsFromP12(x509, &(result->data[i]->nameConstraints));
if (ret != CF_SUCCESS) {
LOGD("Failed to get %d nameConstraints!", i);
}
@ -2179,6 +2180,69 @@ static void FreeHcfX509TrustAnchorArray(HcfX509TrustAnchorArray *trustAnchorArra
CfFree(trustAnchorArray);
}
static STACK_OF(X509) *GetCaFromP12(const CfBlob *keyStore, const CfBlob *pwd)
{
X509 *cert = NULL;
EVP_PKEY *pkey = NULL;
STACK_OF(X509) *caStack = NULL;
PKCS12 *p12 = NULL;
const unsigned char *in = (const unsigned char *)(keyStore->data);
p12 = d2i_PKCS12(NULL, &in, keyStore->size);
if (p12 == NULL) {
LOGE("Error convert pkcs12 data to inner struct!");
CfPrintOpensslError();
return NULL;
}
int ret = PKCS12_parse(p12, (const char *)pwd->data, &pkey, &cert, &caStack);
PKCS12_free(p12);
if (ret != 1) {
LOGE("PKCS12_parse failed!");
CfPrintOpensslError();
return NULL;
}
EVP_PKEY_free(pkey);
if (cert == NULL) {
LOGE("P12 dose not have a cert!");
return NULL;
}
X509_free(cert);
if (caStack == NULL) {
LOGE("P12 dose not have ca!");
}
return caStack;
}
static HcfX509TrustAnchorArray *MallocTrustAnchorArray(int32_t count)
{
HcfX509TrustAnchorArray *anchor = (HcfX509TrustAnchorArray *)(CfMalloc(sizeof(HcfX509TrustAnchorArray), 0));
if (anchor == NULL) {
LOGE("Failed to allocate trustAnchorArray memory!");
return NULL;
}
anchor->count = count;
anchor->data = (HcfX509TrustAnchor **)(CfMalloc(anchor->count * sizeof(HcfX509TrustAnchor *), 0));
if (anchor->data == NULL) {
LOGE("Failed to allocate data memory!");
CfFree(anchor);
return NULL;
}
for (uint32_t i = 0; i < anchor->count; i++) {
anchor->data[i] = (HcfX509TrustAnchor *)(CfMalloc(sizeof(HcfX509TrustAnchor), 0));
if (anchor->data[i] == NULL) {
LOGE("Failed to allocate data memory!");
FreeHcfX509TrustAnchorArray(anchor, false);
return NULL;
}
}
return anchor;
}
CfResult HcfX509CreateTrustAnchorWithKeyStoreFunc(
const CfBlob *keyStore, const CfBlob *pwd, HcfX509TrustAnchorArray **trustAnchorArray)
{
@ -2186,50 +2250,40 @@ CfResult HcfX509CreateTrustAnchorWithKeyStoreFunc(
LOGE("Invalid params!");
return CF_INVALID_PARAMS;
}
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
STACK_OF(X509) *ca = NULL;
PKCS12 *p12 = (PKCS12 *)ASN1_item_d2i_ex(
NULL, (const unsigned char **)&(keyStore->data), keyStore->size, ASN1_ITEM_rptr(PKCS12), NULL, NULL);
if (p12 == NULL) {
LOGE("Error reading PKCS#12 file!");
return CF_ERR_CRYPTO_OPERATION;
}
if (!PKCS12_parse(p12, (const char *)pwd->data, &pkey, &cert, &ca) || (ca == NULL) || (cert == NULL)) {
LOGE("PKCS12_parse cert ca failed!");
PKCS12_free(p12);
return CF_ERR_CRYPTO_OPERATION;
}
PKCS12_free(p12);
HcfX509TrustAnchorArray *anchor = (HcfX509TrustAnchorArray *)(CfMalloc(sizeof(HcfX509TrustAnchorArray), 0));
if (anchor == NULL) {
LOGE("Failed to allocate trustAnchorArray memory!");
return CF_ERR_MALLOC;
STACK_OF(X509) *ca = GetCaFromP12(keyStore, pwd);
if (ca == NULL) {
return CF_ERR_CRYPTO_OPERATION;
}
CfResult ret = CF_SUCCESS;
HcfX509TrustAnchorArray *anchor = NULL;
int32_t count = sk_X509_num(ca);
anchor->count = (uint32_t)(count < 0 ? 0 : count);
anchor->data = (HcfX509TrustAnchor **)(CfMalloc(anchor->count * sizeof(HcfX509TrustAnchor *), 0));
if (anchor->data == NULL) {
LOGE("Failed to allocate data memory!");
CfFree(anchor);
return CF_ERR_MALLOC;
}
for (uint32_t i = 0; i < anchor->count; i++) {
anchor->data[i] = (HcfX509TrustAnchor *)(CfMalloc(sizeof(HcfX509TrustAnchor), 0));
if (anchor->data[i] == NULL) {
LOGE("Failed to allocate data memory!");
FreeHcfX509TrustAnchorArray(anchor, true);
return CF_ERR_MALLOC;
}
if (count <= 0) {
LOGE("P12 ca num is 0!");
ret = CF_ERR_CRYPTO_OPERATION;
goto exit;
}
CfResult ret = ProcessP12Data(pkey, cert, ca, &anchor);
anchor = MallocTrustAnchorArray(count);
if (anchor == NULL) {
ret = CF_ERR_MALLOC;
goto exit;
}
ret = ProcessP12Data(ca, anchor);
if (ret != CF_SUCCESS) {
LOGE("Failed to Process P12 Data!");
FreeHcfX509TrustAnchorArray(anchor, true);
goto exit;
}
*trustAnchorArray = anchor;
anchor = NULL;
exit:
if (anchor != NULL) {
FreeHcfX509TrustAnchorArray(anchor, true);
}
sk_X509_pop_free(ca, X509_free);
return ret;
}

View File

@ -120,6 +120,10 @@ static void DeleteCertChainContext(napi_env env, CfCtx *&context, bool freeCertF
FreeX509CertChainValidateParams(context->params);
FreeX509CertChainValidateResult(context->result, freeCertFlag);
CfBlobFree(&(context->keyStore));
CfBlobDataClearAndFree(context->pwd);
CfFree(context->pwd);
CF_FREE_PTR(context);
}
@ -543,7 +547,7 @@ static napi_value ConvertX509CertToNapiValue(napi_env env, HcfX509Certificate *c
return instance;
}
static napi_value ConvertCfBlobToNapiValue(napi_env env, CfBlob *blob)
static napi_value ConvertBlobToUint8ArrayNapiValue(napi_env env, CfBlob *blob)
{
if (blob == NULL) {
LOGE("ConvertCfBlobToNapiValue:blob is nullptr.");
@ -570,7 +574,10 @@ static napi_value ConvertCfBlobToNapiValue(napi_env env, CfBlob *blob)
return nullptr;
}
buffer = nullptr;
return outBuffer;
napi_value outData = nullptr;
napi_create_typedarray(env, napi_uint8_array, blob->size, outBuffer, 0, &outData);
return outData;
}
static napi_value BuildCreateInstanceByTrustAnchorArray(napi_env env, HcfX509TrustAnchorArray *trustAnchorArray)
@ -591,22 +598,24 @@ static napi_value BuildCreateInstanceByTrustAnchorArray(napi_env env, HcfX509Tru
napi_value valueCACert = ConvertX509CertToNapiValue(env, trustAnchorArray->data[i]->CACert);
if (valueCACert == nullptr) {
LOGI("The CACert value is null, return to js is an enpty object!");
} else {
trustAnchorArray->data[i]->CACert = nullptr;
}
napi_set_named_property(env, element, CERT_CHAIN_TRUSTANCHOR_TAG_CACERT.c_str(), valueCACert);
napi_value valuePubKey = ConvertCfBlobToNapiValue(env, trustAnchorArray->data[i]->CAPubKey);
napi_value valuePubKey = ConvertBlobToUint8ArrayNapiValue(env, trustAnchorArray->data[i]->CAPubKey);
if (valuePubKey == nullptr) {
LOGI("The PubKey value is null, return to js is an enpty object!");
}
napi_set_named_property(env, element, CERT_CHAIN_TRUSTANCHOR_TAG_CAPUBKEY.c_str(), valuePubKey);
napi_value valueSub = ConvertCfBlobToNapiValue(env, trustAnchorArray->data[i]->CASubject);
napi_value valueSub = ConvertBlobToUint8ArrayNapiValue(env, trustAnchorArray->data[i]->CASubject);
if (valueSub == nullptr) {
LOGI("The CASubject value is null, return to js is an enpty object!");
}
napi_set_named_property(env, element, CERT_CHAIN_TRUSTANCHOR_TAG_CASUBJECT.c_str(), valueSub);
napi_value valueName = ConvertCfBlobToNapiValue(env, trustAnchorArray->data[i]->nameConstraints);
napi_value valueName = ConvertBlobToUint8ArrayNapiValue(env, trustAnchorArray->data[i]->nameConstraints);
if (valueName == nullptr) {
LOGI("The nameConsteaints value is null, return to js is an enpty object!");
}
@ -634,7 +643,7 @@ static void CreateTrustAnchorsWithKeyStoreComplete(napi_env env, napi_status sta
LOGE("Failed to create trust anchor with KeyStore");
}
ReturnJSResult(env, context->async, instance);
DeleteCertChainContext(env, context);
DeleteCertChainContext(env, context, true);
}
static napi_value CreateTrustAnchorsWithKeyStoreAsyncWork(napi_env env, CfCtx *context)

View File

@ -423,6 +423,7 @@ void FreeTrustAnchorArray(HcfX509TrustAnchorArray *trustAnchorArray, bool freeCe
CfObjDestroy(trustAnchorArray->data[i]->CACert);
}
trustAnchorArray->data[i]->CACert = NULL;
CfBlobFree(&trustAnchorArray->data[i]->CAPubKey);
CfBlobFree(&trustAnchorArray->data[i]->CASubject);
CfBlobFree(&trustAnchorArray->data[i]->nameConstraints);
CfFree(trustAnchorArray->data[i]);