• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #if defined(HITLS_PKI_X509_CSR) || defined(HITLS_PKI_PKCS12)
18 #include <stdint.h>
19 #include "securec.h"
20 #include "hitls_x509_local.h"
21 #include "bsl_obj.h"
22 #include "bsl_sal.h"
23 #include "bsl_obj_internal.h"
24 #include "bsl_err_internal.h"
25 #include "crypt_errno.h"
26 #include "crypt_eal_pkey.h"
27 #include "hitls_pki_errno.h"
28 #include "hitls_pki_utils.h"
29 
30 #if defined(HITLS_PKI_X509_CSR_PARSE) || defined(HITLS_PKI_PKCS12_PARSE)
31 /**
32  * RFC 2985: section-5.4.2
33  *  extensionRequest ATTRIBUTE ::= {
34  *          WITH SYNTAX ExtensionRequest
35  *          SINGLE VALUE TRUE
36  *          ID pkcs-9-at-extensionRequest
37  *  }
38  * ExtensionRequest ::= Extensions
39  */
40 static BSL_ASN1_TemplateItem g_x509AttrTempl[] = {
41     {BSL_ASN1_TAG_OBJECT_ID, 0, 0},
42     {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, BSL_ASN1_FLAG_HEADERONLY, 0},
43 };
44 
45 typedef enum {
46     HITLS_X509_ATTR_OID_IDX,
47     HITLS_X509_ATTR_SET_IDX,
48     HITLS_X509_ATTR_INDEX_MAX
49 } HITLS_X509_ATTR_IDX;
50 #endif
51 
52 #define HITLS_X509_ATTR_MAX_NUM  20
53 #define HITLS_X509_ATTRS_PARSE_FLAG  0x01
54 #define HITLS_X509_ATTRS_GEN_FLAG    0x02
55 
HITLS_X509_AttrsNew(void)56 HITLS_X509_Attrs *HITLS_X509_AttrsNew(void)
57 {
58     HITLS_X509_Attrs *attrs = (HITLS_X509_Attrs *)BSL_SAL_Calloc(1, sizeof(HITLS_X509_Attrs));
59     if (attrs == NULL) {
60         return NULL;
61     }
62     attrs->list = BSL_LIST_New(sizeof(HITLS_X509_AttrEntry *));
63     if (attrs->list == NULL) {
64         BSL_SAL_Free(attrs);
65         return NULL;
66     }
67 
68     attrs->flag = HITLS_X509_ATTRS_GEN_FLAG;
69     return attrs;
70 }
71 
72 /*
73 * For pkcs12, parsing and encoding operation uses deep copy, and it use callback function to free
74 * For csr, parsing operation uses shallow copy, and encoding operation uses deep copy
75 */
HITLS_X509_AttrsFree(HITLS_X509_Attrs * attrs,HITLS_X509_FreeAttrItemCb freeItem)76 void HITLS_X509_AttrsFree(HITLS_X509_Attrs *attrs, HITLS_X509_FreeAttrItemCb freeItem)
77 {
78     if (attrs == NULL) {
79         return;
80     }
81     if (freeItem != NULL) {
82         BSL_LIST_FREE(attrs->list, (BSL_LIST_PFUNC_FREE)freeItem);
83         BSL_SAL_Free(attrs);
84         return;
85     }
86 
87     if ((attrs->flag & HITLS_X509_ATTRS_PARSE_FLAG) != 0) {
88         BSL_LIST_FREE(attrs->list, NULL);
89     } else {
90         BSL_LIST_FREE(attrs->list, (BSL_LIST_PFUNC_FREE)HITLS_X509_AttrEntryFree);
91     }
92     BSL_SAL_Free(attrs);
93 }
94 
95 #if defined(HITLS_PKI_X509_CSR_GEN) || defined(HITLS_PKI_PKCS12_GEN)
HITLS_X509_EncodeObjIdentity(BslCid cid,BSL_ASN1_Buffer * asnBuff)96 int32_t HITLS_X509_EncodeObjIdentity(BslCid cid, BSL_ASN1_Buffer *asnBuff)
97 {
98     BslOidString *oidStr = BSL_OBJ_GetOID(cid);
99     if (oidStr == NULL) {
100         BSL_ERR_PUSH_ERROR(CRYPT_ERR_ALGID);
101         return CRYPT_ERR_ALGID;
102     }
103     asnBuff->tag = BSL_ASN1_TAG_OBJECT_ID;
104     asnBuff->buff = (uint8_t *)oidStr->octs;
105     asnBuff->len = oidStr->octetLen;
106 
107     return HITLS_PKI_SUCCESS;
108 }
109 #endif
110 
111 #ifdef HITLS_PKI_PKCS12_GEN
HITLS_X509_AttrsDup(const HITLS_X509_Attrs * src,HITLS_X509_DupAttrItemCb dupCb,HITLS_X509_FreeAttrItemCb freeCb)112 HITLS_X509_Attrs *HITLS_X509_AttrsDup(const HITLS_X509_Attrs *src, HITLS_X509_DupAttrItemCb dupCb,
113     HITLS_X509_FreeAttrItemCb freeCb)
114 {
115     if (src == NULL || BSL_LIST_COUNT(src->list) <= 0 ||
116         dupCb == NULL || freeCb == NULL) {
117         return NULL;
118     }
119     HITLS_X509_Attrs *dst = HITLS_X509_AttrsNew();
120     if (dst == NULL) {
121         return NULL;
122     }
123     void *node = NULL;
124     for (node = BSL_LIST_GET_FIRST(src->list); node != NULL; node = BSL_LIST_GET_NEXT(src->list)) {
125         void *dstEntry = dupCb(node);
126         if (dstEntry == NULL) {
127             HITLS_X509_AttrsFree(dst, freeCb);
128             return NULL;
129         }
130         int32_t ret = BSL_LIST_AddElement(dst->list, dstEntry, BSL_LIST_POS_END);
131         if (ret != BSL_SUCCESS) {
132             freeCb(dstEntry);
133             HITLS_X509_AttrsFree(dst, freeCb);
134             return NULL;
135         }
136     }
137     dst->flag = src->flag;
138     return dst;
139 }
140 #endif
141 
HITLS_X509_AttrEntryFree(HITLS_X509_AttrEntry * attr)142 void HITLS_X509_AttrEntryFree(HITLS_X509_AttrEntry *attr)
143 {
144     if (attr == NULL) {
145         return;
146     }
147     BSL_SAL_Free(attr->attrValue.buff);
148     BSL_SAL_Free(attr);
149 }
150 
151 #if defined(HITLS_PKI_X509_CSR_PARSE) || defined(HITLS_PKI_PKCS12_PARSE)
HITLS_X509_ParseAttr(BSL_ASN1_Buffer * attrItem,HITLS_X509_AttrEntry * attrEntry)152 int32_t HITLS_X509_ParseAttr(BSL_ASN1_Buffer *attrItem, HITLS_X509_AttrEntry *attrEntry)
153 {
154     uint8_t *temp = attrItem->buff;
155     uint32_t tempLen = attrItem->len;
156     BSL_ASN1_Buffer asnArr[HITLS_X509_ATTR_INDEX_MAX] = {0};
157     BSL_ASN1_Template templ = {g_x509AttrTempl, sizeof(g_x509AttrTempl) / sizeof(g_x509AttrTempl[0])};
158     int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_ATTR_INDEX_MAX);
159     if (tempLen != 0) {
160         ret = HITLS_X509_ERR_PARSE_ATTR_BUF;
161     }
162     if (ret != BSL_SUCCESS) {
163         BSL_ERR_PUSH_ERROR(ret);
164         return ret;
165     }
166     /* parse attribute id */
167     BslOidString oid = {asnArr[HITLS_X509_ATTR_OID_IDX].len, (char *)asnArr[HITLS_X509_ATTR_OID_IDX].buff, 0};
168     attrEntry->cid = BSL_OBJ_GetCID(&oid);
169     if (attrEntry->cid == BSL_CID_UNKNOWN) {
170         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_OBJ_ID);
171         return HITLS_X509_ERR_PARSE_OBJ_ID;
172     }
173     /* set id and value asn1 buffer */
174     attrEntry->attrId = asnArr[HITLS_X509_ATTR_OID_IDX];
175     attrEntry->attrValue = asnArr[HITLS_X509_ATTR_SET_IDX];
176     return ret;
177 }
178 
HITLS_X509_ParseAttrsListAsnItem(uint32_t layer,BSL_ASN1_Buffer * asn,void * cbParam,BSL_ASN1_List * list)179 int32_t HITLS_X509_ParseAttrsListAsnItem(uint32_t layer, BSL_ASN1_Buffer *asn, void *cbParam, BSL_ASN1_List *list)
180 {
181     (void)layer;
182     HITLS_X509_ParseAttrItemCb parseCb = cbParam;
183     HITLS_X509_AttrEntry *node = BSL_SAL_Calloc(1, sizeof(HITLS_X509_AttrEntry));
184     if (node == NULL) {
185         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
186         return BSL_MALLOC_FAIL;
187     }
188 
189     /* parse attribute entry */
190     int32_t ret = HITLS_X509_ParseAttr(asn, node);
191     if (ret != BSL_SUCCESS) {
192         BSL_ERR_PUSH_ERROR(ret);
193         goto ERR;
194     }
195     if (parseCb != NULL) {
196         ret = parseCb(list, node);
197         if (ret != BSL_SUCCESS) {
198             BSL_ERR_PUSH_ERROR(ret);
199         }
200         goto ERR;
201     }
202 
203     ret = BSL_LIST_AddElement(list, node, BSL_LIST_POS_AFTER);
204     if (ret != BSL_SUCCESS) {
205         BSL_ERR_PUSH_ERROR(ret);
206         goto ERR;
207     }
208 
209     return ret;
210 ERR:
211     BSL_SAL_FREE(node);
212     return ret;
213 }
214 
HITLS_X509_ParseAttrList(BSL_ASN1_Buffer * attrBuff,HITLS_X509_Attrs * attrs,HITLS_X509_ParseAttrItemCb parseCb,HITLS_X509_FreeAttrItemCb freeItem)215 int32_t HITLS_X509_ParseAttrList(BSL_ASN1_Buffer *attrBuff, HITLS_X509_Attrs *attrs, HITLS_X509_ParseAttrItemCb parseCb,
216     HITLS_X509_FreeAttrItemCb freeItem)
217 {
218     if (attrBuff->tag == 0 || attrBuff->buff == NULL || attrBuff->len == 0) {
219         return HITLS_PKI_SUCCESS;
220     }
221 
222     uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE};
223     BSL_ASN1_DecodeListParam listParam = {1, expTag};
224     int32_t ret = BSL_ASN1_DecodeListItem(&listParam, attrBuff, &HITLS_X509_ParseAttrsListAsnItem, parseCb,
225         attrs->list);
226     if (ret != BSL_SUCCESS) {
227         BSL_LIST_DeleteAll(attrs->list, freeItem);
228         return ret;
229     }
230     attrs->flag = HITLS_X509_ATTRS_PARSE_FLAG;
231     return ret;
232 }
233 #endif
234 
CmpAttrEntryByCid(const void * attrEntry,const void * cid)235 static int32_t CmpAttrEntryByCid(const void *attrEntry, const void *cid)
236 {
237     const HITLS_X509_AttrEntry *node = attrEntry;
238     return node->cid == *(const BslCid *)cid ? 0 : 1;
239 }
240 
241 typedef int32_t (*DecodeAttrCb)(HITLS_X509_Attrs *attributes, HITLS_X509_AttrEntry *attrEntry, void *val,
242     uint32_t valLen);
243 
244 #if defined(HITLS_PKI_X509_CSR_GEN) || defined(HITLS_PKI_PKCS12_GEN)
245 
246 typedef int32_t (*EncodeAttrCb)(HITLS_X509_Attrs *attributes, void *val, uint32_t valLen, BSL_ASN1_Buffer *attrValue);
247 
EncodeReqExtAttr(HITLS_X509_Attrs * attributes,void * val,uint32_t valLen,BSL_ASN1_Buffer * attrValue)248 static int32_t EncodeReqExtAttr(HITLS_X509_Attrs *attributes, void *val, uint32_t valLen, BSL_ASN1_Buffer *attrValue)
249 {
250     (void)valLen;
251     (void)attributes;
252     HITLS_X509_Ext *ext = (HITLS_X509_Ext *)val;
253     return HITLS_X509_EncodeExt(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, ext->extList, attrValue);
254 }
255 
SetAttr(HITLS_X509_Attrs * attributes,BslCid cid,void * val,uint32_t valLen,EncodeAttrCb encodeAttrCb)256 static int32_t SetAttr(HITLS_X509_Attrs *attributes, BslCid cid, void *val, uint32_t valLen, EncodeAttrCb encodeAttrCb)
257 {
258     if (val == NULL) {
259         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
260         return HITLS_X509_ERR_INVALID_PARAM;
261     }
262 
263     /* Check if the attribute already exists. */
264     if (BSL_LIST_Search(attributes->list, &cid, CmpAttrEntryByCid, NULL) != NULL) {
265         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_ATTR_REPEAT);
266         return HITLS_X509_ERR_SET_ATTR_REPEAT;
267     }
268 
269     HITLS_X509_AttrEntry *attrEntry = BSL_SAL_Calloc(1, sizeof(HITLS_X509_AttrEntry));
270     if (attrEntry == NULL) {
271         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
272         return BSL_MALLOC_FAIL;
273     }
274     int32_t ret = HITLS_X509_EncodeObjIdentity(cid, &attrEntry->attrId);
275     if (ret != HITLS_PKI_SUCCESS) {
276         BSL_ERR_PUSH_ERROR(ret);
277         goto ERR;
278     }
279 
280     ret = encodeAttrCb(attributes, val, valLen, &attrEntry->attrValue);
281     if (ret != HITLS_PKI_SUCCESS) {
282         BSL_ERR_PUSH_ERROR(ret);
283         goto ERR;
284     }
285     attrEntry->cid = cid;
286     ret = BSL_LIST_AddElement(attributes->list, attrEntry, BSL_LIST_POS_END);
287     if (ret != BSL_SUCCESS) {
288         BSL_ERR_PUSH_ERROR(ret);
289         goto ERR;
290     }
291 
292     return ret;
293 
294 ERR:
295     HITLS_X509_AttrEntryFree(attrEntry);
296     return ret;
297 }
298 #endif // HITLS_PKI_X509_CSR_GEN || HITLS_PKI_PKCS12_GEN
299 
DecodeReqExtAttr(HITLS_X509_Attrs * attributes,HITLS_X509_AttrEntry * attrEntry,void * val,uint32_t valLen)300 static int32_t DecodeReqExtAttr(HITLS_X509_Attrs *attributes, HITLS_X509_AttrEntry *attrEntry, void *val,
301     uint32_t valLen)
302 {
303     (void)attributes;
304     if (valLen != sizeof(HITLS_X509_Ext *)) {
305         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
306         return HITLS_X509_ERR_INVALID_PARAM;
307     }
308     HITLS_X509_Ext *ext = HITLS_X509_ExtNew(HITLS_X509_EXT_TYPE_CSR);
309     if (ext == NULL) {
310         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
311         return BSL_MALLOC_FAIL;
312     }
313     int32_t ret = HITLS_X509_ParseExt(&attrEntry->attrValue, ext);
314     if (ret != BSL_SUCCESS) {
315         HITLS_X509_ExtFree(ext);
316         BSL_ERR_PUSH_ERROR(ret);
317         return ret;
318     }
319     *(HITLS_X509_Ext **)val = ext;
320     return HITLS_PKI_SUCCESS;
321 }
322 
GetAttr(HITLS_X509_Attrs * attributes,BslCid cid,void * val,uint32_t valLen,DecodeAttrCb decodeAttrCb)323 static int32_t GetAttr(HITLS_X509_Attrs *attributes, BslCid cid, void *val, uint32_t valLen, DecodeAttrCb decodeAttrCb)
324 {
325     if (val == NULL) {
326         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
327         return HITLS_X509_ERR_INVALID_PARAM;
328     }
329 
330     HITLS_X509_AttrEntry *attrEntry = BSL_LIST_Search(attributes->list, &cid, CmpAttrEntryByCid, NULL);
331     if (attrEntry == NULL) {
332         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_ATTR_NOT_FOUND);
333         return HITLS_X509_ERR_ATTR_NOT_FOUND;
334     }
335 
336     return decodeAttrCb(attributes, attrEntry, val, valLen);
337 }
338 
HITLS_X509_AttrCtrl(HITLS_X509_Attrs * attributes,HITLS_X509_AttrCmd cmd,void * val,uint32_t valLen)339 int32_t HITLS_X509_AttrCtrl(HITLS_X509_Attrs *attributes, HITLS_X509_AttrCmd cmd, void *val, uint32_t valLen)
340 {
341     if (attributes == NULL || val == NULL) {
342         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
343         return HITLS_X509_ERR_INVALID_PARAM;
344     }
345     switch (cmd) {
346 #if defined(HITLS_PKI_X509_CSR_GEN) || defined(HITLS_PKI_PKCS12_GEN)
347         case HITLS_X509_ATTR_SET_REQUESTED_EXTENSIONS:
348             return SetAttr(attributes, BSL_CID_EXTENSIONREQUEST, val, valLen, EncodeReqExtAttr);
349 #endif
350         case HITLS_X509_ATTR_GET_REQUESTED_EXTENSIONS:
351             return GetAttr(attributes, BSL_CID_EXTENSIONREQUEST, val, valLen, DecodeReqExtAttr);
352         default:
353             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
354             return HITLS_X509_ERR_INVALID_PARAM;
355     }
356 }
357 
358 #if defined(HITLS_PKI_X509_CSR_GEN) || defined(HITLS_PKI_PKCS12_GEN)
359 
360 #define X509_CSR_ATTR_ELEM_NUMBER 2
361 static BSL_ASN1_TemplateItem g_x509AttrEntryTempl[] = {
362     {BSL_ASN1_TAG_OBJECT_ID, 0, 0},
363     {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SET, 0, 0},
364 };
365 
HITLS_X509_EncodeAttrEntry(HITLS_X509_AttrEntry * node,BSL_ASN1_Buffer * attrBuff)366 int32_t HITLS_X509_EncodeAttrEntry(HITLS_X509_AttrEntry *node, BSL_ASN1_Buffer *attrBuff)
367 {
368     BSL_ASN1_Buffer asnBuf[X509_CSR_ATTR_ELEM_NUMBER] = {0};
369     asnBuf[0] = node->attrId;
370     asnBuf[1] = node->attrValue;
371     BSL_ASN1_Template templ = {g_x509AttrEntryTempl, sizeof(g_x509AttrEntryTempl) / sizeof(g_x509AttrEntryTempl[0])};
372     int32_t ret = BSL_ASN1_EncodeTemplate(&templ, asnBuf, X509_CSR_ATTR_ELEM_NUMBER, &attrBuff->buff, &attrBuff->len);
373     if (ret != HITLS_PKI_SUCCESS) {
374         BSL_ERR_PUSH_ERROR(ret);
375         return ret;
376     }
377     attrBuff->tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE;
378     return ret;
379 }
380 
FreeAsnAttrsBuff(BSL_ASN1_Buffer * asnBuf,uint32_t count)381 void FreeAsnAttrsBuff(BSL_ASN1_Buffer *asnBuf, uint32_t count)
382 {
383     for (uint32_t i = 0; i < count; i++) {
384         BSL_SAL_FREE(asnBuf[i].buff);
385     }
386     BSL_SAL_FREE(asnBuf);
387 }
388 
HITLS_X509_EncodeAttrList(uint8_t tag,HITLS_X509_Attrs * attrs,HITLS_X509_EncodeAttrItemCb encodeCb,BSL_ASN1_Buffer * attrAsn1)389 int32_t HITLS_X509_EncodeAttrList(uint8_t tag, HITLS_X509_Attrs *attrs, HITLS_X509_EncodeAttrItemCb encodeCb,
390     BSL_ASN1_Buffer *attrAsn1)
391 {
392     if (attrs == NULL || attrs->list == NULL || BSL_LIST_COUNT(attrs->list) <= 0) {
393         attrAsn1->tag = tag;
394         attrAsn1->buff = NULL;
395         attrAsn1->len = 0;
396         return HITLS_PKI_SUCCESS;
397     }
398     uint32_t count = (uint32_t)BSL_LIST_COUNT(attrs->list);
399     /* no attribute */
400     BSL_ASN1_Buffer *asnBuf = BSL_SAL_Calloc(count, sizeof(BSL_ASN1_Buffer));
401     if (asnBuf == NULL) {
402         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
403         return BSL_MALLOC_FAIL;
404     }
405     uint32_t iter = 0;
406     int32_t ret;
407     void *node = NULL;
408     for (node = BSL_LIST_GET_FIRST(attrs->list); node != NULL; node = BSL_LIST_GET_NEXT(attrs->list), iter++) {
409         HITLS_X509_AttrEntry attrEntry = {};
410         if (encodeCb != NULL) {
411             ret = encodeCb(node, &attrEntry);
412             if (ret != HITLS_PKI_SUCCESS) {
413                 FreeAsnAttrsBuff(asnBuf, count);
414                 return ret;
415             }
416         } else {
417             attrEntry = *(HITLS_X509_AttrEntry *)node;
418         }
419         ret = HITLS_X509_EncodeAttrEntry(&attrEntry, &asnBuf[iter]);
420         if (encodeCb != NULL) {
421             BSL_SAL_FREE(attrEntry.attrValue.buff);
422         }
423         if (ret != HITLS_PKI_SUCCESS) {
424             FreeAsnAttrsBuff(asnBuf, count);
425             return ret;
426         }
427     }
428     static BSL_ASN1_TemplateItem attrSeqTempl = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0 };
429     BSL_ASN1_Template templ = {&attrSeqTempl, 1};
430     ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, count, &templ, asnBuf, iter, attrAsn1);
431     FreeAsnAttrsBuff(asnBuf, count);
432     if (ret != HITLS_PKI_SUCCESS) {
433         BSL_ERR_PUSH_ERROR(ret);
434         return ret;
435     }
436 
437     attrAsn1->tag = tag;
438     return ret;
439 }
440 #endif // HITLS_PKI_X509_CSR_GEN || HITLS_PKI_PKCS12_GEN
441 
442 #endif // HITLS_PKI_X509_CSR || HITLS_PKI_PKCS12
443