• 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 #ifdef HITLS_PKI_X509
18 
19 #include "securec.h"
20 #include "bsl_obj.h"
21 #include "bsl_obj_internal.h"
22 #include "bsl_sal.h"
23 #include "bsl_types.h"
24 #include "bsl_err_internal.h"
25 #include "hitls_pki_errno.h"
26 #include "hitls_x509_local.h"
27 
28 #define BITS_OF_BYTE 8
29 #define HITLS_X509_EXT_NOT_FOUND 1
30 #define HITLS_X509_EXT_KEYUSAGE_UNUSED_BIT 0xFFFF7F00 // Only 9 bits are used.
31 
32 typedef enum {
33     HITLS_X509_EXT_OID_IDX,
34     HITLS_X509_EXT_CRITICAL_IDX,
35     HITLS_X509_EXT_VALUE_IDX,
36     HITLS_X509_EXT_MAX
37 } HITLS_X509_EXT_IDX;
38 
39 /**
40  * RFC 5280: section-4.2.1.9
41  * BasicConstraints ::= SEQUENCE {
42  *   cA                      BOOLEAN DEFAULT FALSE,
43  *   pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
44  */
45 static BSL_ASN1_TemplateItem g_bConsTempl[] = {
46     {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
47     {BSL_ASN1_TAG_BOOLEAN, BSL_ASN1_FLAG_DEFAULT, 1},
48     {BSL_ASN1_TAG_INTEGER, BSL_ASN1_FLAG_OPTIONAL, 1},
49 };
50 
51 typedef enum {
52     HITLS_X509_EXT_BC_CA_IDX,
53     HITLS_X509_EXT_BC_PATHLEN_IDX,
54     HITLS_X509_EXT_BC_MAX
55 } HITLS_X509_EXT_BASICCONSTRAINTS;
56 
57 /**
58  * RFC 5280: section-4.2.1.1
59  * AuthorityKeyIdentifier ::= SEQUENCE {
60  *   keyIdentifier             [0] KeyIdentifier           OPTIONAL,
61  *   authorityCertIssuer       [1] GeneralNames            OPTIONAL,
62  *   authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
63  */
64 #define HITLS_X509_CTX_SPECIFIC_TAG_AKID_KID    0
65 #define HITLS_X509_CTX_SPECIFIC_TAG_AKID_ISSUER 1
66 #define HITLS_X509_CTX_SPECIFIC_TAG_AKID_SERIAL 2
67 
68 static BSL_ASN1_TemplateItem g_akidTempl[] = {
69     {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
70         /* KeyIdentifier */
71         {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_KID, BSL_ASN1_FLAG_OPTIONAL, 1},
72         /* authorityCertIssuer */
73         {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_X509_CTX_SPECIFIC_TAG_AKID_ISSUER,
74             BSL_ASN1_FLAG_OPTIONAL | BSL_ASN1_FLAG_HEADERONLY, 1},
75         /* authorityCertSerialNumber */
76         {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_SERIAL, BSL_ASN1_FLAG_OPTIONAL, 1},
77 };
78 
79 typedef enum {
80     HITLS_X509_EXT_AKI_KID_IDX,
81     HITLS_X509_EXT_AKI_ISSUER_IDX,
82     HITLS_X509_EXT_AKI_SERIAL_IDX,
83     HITLS_X509_EXT_AKI_MAX,
84 } HITLS_X509_EXT_AKI;
85 
86 /**
87  * RFC 5280: section-4.2.1.2
88  * Two common methods for generating key identifiers from the public key are:
89  * (1) The kid is composed of 160-bit sha1 hash of the BIT STRING subjectPublicKey.
90  * (2) The kid is composed of a 4-bit type field with the value 0100 followed by the lease significant 60 bits of the
91  *     sha1 hash of the BIT STRING subjectPublicKey.
92  */
93 #define HITLS_X509_KID_MIN_LEN 8
94 #define HITLS_X509_KID_MAX_LEN 20
95 #define HITLS_X509_CRLNUMBER_MIN_LEN 1
96 #define HITLS_X509_CRLNUMBER_MAX_LEN 20
97 
98 /**
99  * RFC 5280: section-4.2.1.6
100  * SubjectAltName ::= GeneralNames
101  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
102  * GeneralName ::= CHOICE {
103  *   otherName                       [0]     OtherName,         -- not support
104  *   rfc822Name                      [1]     IA5String,
105  *   dNSName                         [2]     IA5String,
106  *   x400Address                     [3]     ORAddress,         -- not support
107  *   directoryName                   [4]     Name,
108  *   ediPartyName                    [5]     EDIPartyName,      -- not support
109  *   uniformResourceIdentifier       [6]     IA5String,
110  *   iPAddress                       [7]     OCTET STRING,
111  *   registeredID                    [8]     OBJECT IDENTIFIER  -- not support
112  * }
113  */
114 #define HITLS_X509_GENERALNAME_OTHER_TAG    (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 0)
115 #define HITLS_X509_GENERALNAME_RFC822_TAG   (BSL_ASN1_CLASS_CTX_SPECIFIC | 1)
116 #define HITLS_X509_GENERALNAME_DNS_TAG      (BSL_ASN1_CLASS_CTX_SPECIFIC | 2)
117 #define HITLS_X509_GENERALNAME_X400_TAG     (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 3)
118 #define HITLS_X509_GENERALNAME_DIR_TAG      (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 4)
119 #define HITLS_X509_GENERALNAME_EDI_TAG      (BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | 5)
120 #define HITLS_X509_GENERALNAME_URI_TAG      (BSL_ASN1_CLASS_CTX_SPECIFIC | 6)
121 #define HITLS_X509_GENERALNAME_IP_TAG       (BSL_ASN1_CLASS_CTX_SPECIFIC | 7)
122 #define HITLS_X509_GENERALNAME_RID_TAG      (BSL_ASN1_CLASS_CTX_SPECIFIC | 8)
123 
124 typedef struct {
125     uint8_t tag;
126     int32_t type;
127 } HITLS_X509_GeneralNameMap;
128 
129 static HITLS_X509_GeneralNameMap g_generalNameMap[] = {
130     {HITLS_X509_GENERALNAME_OTHER_TAG, HITLS_X509_GN_OTHER},
131     {HITLS_X509_GENERALNAME_RFC822_TAG, HITLS_X509_GN_EMAIL},
132     {HITLS_X509_GENERALNAME_DNS_TAG, HITLS_X509_GN_DNS},
133     {HITLS_X509_GENERALNAME_X400_TAG, HITLS_X509_GN_X400},
134     {HITLS_X509_GENERALNAME_DIR_TAG, HITLS_X509_GN_DNNAME},
135     {HITLS_X509_GENERALNAME_EDI_TAG, HITLS_X509_GN_EDI},
136     {HITLS_X509_GENERALNAME_URI_TAG, HITLS_X509_GN_URI},
137     {HITLS_X509_GENERALNAME_IP_TAG, HITLS_X509_GN_IP},
138     {HITLS_X509_GENERALNAME_RID_TAG, HITLS_X509_GN_RID},
139 };
140 
CmpExtByCid(const void * pExt,const void * pCid)141 static int32_t CmpExtByCid(const void *pExt, const void *pCid)
142 {
143     const HITLS_X509_ExtEntry *ext = pExt;
144     BslCid cid = *(const BslCid *)pCid;
145 
146     return cid == ext->cid ? 0 : HITLS_X509_EXT_NOT_FOUND;
147 }
148 
149 #if defined(HITLS_PKI_X509_CRT_PARSE) || defined(HITLS_PKI_X509_CRL_PARSE) || defined(HITLS_PKI_X509_CSR)
CmpExtByOid(const void * pExt,const void * pOid)150 static int32_t CmpExtByOid(const void *pExt, const void *pOid)
151 {
152     const HITLS_X509_ExtEntry *ext = pExt;
153     const BSL_ASN1_Buffer *oid = pOid;
154     if (ext->extnId.len != oid->len) {
155         return HITLS_X509_EXT_NOT_FOUND;
156     }
157     return memcmp(ext->extnId.buff, oid->buff, oid->len) == 0 ? 0 : HITLS_X509_EXT_NOT_FOUND;
158 }
159 
ParseExtKeyUsage(HITLS_X509_ExtEntry * extEntry,HITLS_X509_CertExt * ext)160 static int32_t ParseExtKeyUsage(HITLS_X509_ExtEntry *extEntry, HITLS_X509_CertExt *ext)
161 {
162     uint32_t len;
163     uint8_t *temp = extEntry->extnValue.buff;
164     uint32_t tempLen = extEntry->extnValue.len;
165     int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_BITSTRING, &temp, &tempLen, &len);
166     if (ret != BSL_SUCCESS) {
167         BSL_ERR_PUSH_ERROR(ret);
168         return ret;
169     }
170     BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BITSTRING, len, temp};
171     BSL_ASN1_BitString bitString = {0};
172     ret = BSL_ASN1_DecodePrimitiveItem(&asn, &bitString);
173     if (ret != BSL_SUCCESS) {
174         BSL_ERR_PUSH_ERROR(ret);
175         return ret;
176     }
177     if (bitString.len > sizeof(ext->keyUsage)) {
178         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXT_KU);
179         return HITLS_X509_ERR_PARSE_EXT_KU;
180     }
181     for (uint32_t i = 0; i < bitString.len; i++) {
182         ext->keyUsage |= (bitString.buff[i] << (BITS_OF_BYTE * i));
183     }
184     ext->extFlags |= HITLS_X509_EXT_FLAG_KUSAGE;
185     return HITLS_PKI_SUCCESS;
186 }
187 
ParseExtBasicConstraints(HITLS_X509_ExtEntry * extEntry,HITLS_X509_CertExt * ext)188 static int32_t ParseExtBasicConstraints(HITLS_X509_ExtEntry *extEntry, HITLS_X509_CertExt *ext)
189 {
190     uint8_t *temp = extEntry->extnValue.buff;
191     uint32_t tempLen = extEntry->extnValue.len;
192     BSL_ASN1_Buffer asnArr[HITLS_X509_EXT_BC_MAX] = {0};
193     BSL_ASN1_Template templ = {g_bConsTempl, sizeof(g_bConsTempl) / sizeof(g_bConsTempl[0])};
194     int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_EXT_BC_MAX);
195     if (tempLen != 0) {
196         ret = HITLS_X509_ERR_PARSE_EXT_BUF;
197     }
198     if (ret != BSL_SUCCESS) {
199         BSL_ERR_PUSH_ERROR(ret);
200         return ret;
201     }
202     if (asnArr[HITLS_X509_EXT_BC_CA_IDX].tag != 0) {
203         ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_EXT_BC_CA_IDX], &ext->isCa);
204         if (ret != BSL_SUCCESS) {
205             BSL_ERR_PUSH_ERROR(ret);
206             return ret;
207         }
208     }
209 
210     if (asnArr[HITLS_X509_EXT_BC_PATHLEN_IDX].tag != 0) {
211         ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_EXT_BC_PATHLEN_IDX], &ext->maxPathLen);
212         if (ret != BSL_SUCCESS) {
213             BSL_ERR_PUSH_ERROR(ret);
214             return ret;
215         }
216     }
217     ext->extFlags |= HITLS_X509_EXT_FLAG_BCONS;
218     return ret;
219 }
220 #endif
221 
ParseDirName(uint8_t ** encode,uint32_t * encLen,BslList ** list)222 static int32_t ParseDirName(uint8_t **encode, uint32_t *encLen, BslList **list)
223 {
224     uint32_t valueLen;
225     int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, encode, encLen, &valueLen);
226     if (ret != BSL_SUCCESS) {
227         BSL_ERR_PUSH_ERROR(ret);
228         return ret;
229     }
230 
231     *list = BSL_LIST_New(sizeof(HITLS_X509_NameNode));
232     if (*list == NULL) {
233         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
234         return BSL_MALLOC_FAIL;
235     }
236     BSL_ASN1_Buffer asn = {.buff = *encode, .len = valueLen};
237     ret = HITLS_X509_ParseNameList(&asn, *list);
238     if (ret == BSL_SUCCESS) {
239         *encode += valueLen;
240         *encLen -= valueLen;
241     } else {
242         BSL_LIST_FREE(*list, NULL);
243     }
244     return ret;
245 }
246 
ParseGeneralName(uint8_t tag,uint8_t ** encode,uint32_t * encLen,uint32_t nameLen,BslList * list)247 static int32_t ParseGeneralName(uint8_t tag, uint8_t **encode, uint32_t *encLen, uint32_t nameLen, BslList *list)
248 {
249     int32_t type = -1;
250     int32_t ret;
251     BslList *dirNames = NULL;
252     BSL_Buffer value = {0};
253     for (uint32_t i = 0; i < sizeof(g_generalNameMap) / sizeof(g_generalNameMap[0]); i++) {
254         if (g_generalNameMap[i].tag == tag) {
255             type = g_generalNameMap[i].type;
256             break;
257         }
258     }
259     if (type == -1) {
260         return HITLS_X509_ERR_PARSE_SAN_ITEM_UNKNOW;
261     }
262     if (tag == HITLS_X509_GENERALNAME_DIR_TAG) {
263         ret = ParseDirName(encode, encLen, &dirNames);
264         if (ret != HITLS_PKI_SUCCESS) {
265             return ret;
266         }
267         value.data = (uint8_t *)dirNames;
268         value.dataLen = sizeof(BslList *);
269     } else {
270         value.data = *encode;
271         value.dataLen = nameLen;
272     }
273     HITLS_X509_GeneralName *name = BSL_SAL_Calloc(1, sizeof(HITLS_X509_GeneralName));
274     if (name == NULL) {
275         if (dirNames != NULL) {
276             BSL_LIST_FREE(dirNames, NULL);
277         }
278         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
279         return BSL_MALLOC_FAIL;
280     }
281     name->type = type;
282     name->value = value;
283     ret = BSL_LIST_AddElement(list, name, BSL_LIST_POS_END);
284     if (ret != BSL_SUCCESS) {
285         BSL_LIST_FREE(dirNames, NULL);
286         BSL_SAL_Free(name);
287     }
288     return ret;
289 }
290 
FreeGeneralName(void * data)291 static void FreeGeneralName(void *data)
292 {
293     HITLS_X509_GeneralName *name = (HITLS_X509_GeneralName *)data;
294     if (name->type == HITLS_X509_GN_DNNAME) {
295         BSL_LIST_DeleteAll((BslList *)name->value.data, NULL);
296         BSL_SAL_Free(name->value.data);
297     }
298     BSL_SAL_Free(data);
299 }
300 
HITLS_X509_FreeGeneralName(HITLS_X509_GeneralName * data)301 void HITLS_X509_FreeGeneralName(HITLS_X509_GeneralName *data)
302 {
303     if (data == NULL) {
304         return;
305     }
306     if (data->type == HITLS_X509_GN_DNNAME) {
307         BSL_LIST_DeleteAll((BslList *)data->value.data, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode);
308     }
309     BSL_SAL_Free(data->value.data);
310     BSL_SAL_Free(data);
311 }
312 
HITLS_X509_ClearGeneralNames(BslList * names)313 void HITLS_X509_ClearGeneralNames(BslList *names)
314 {
315     if (names == NULL) {
316         return;
317     }
318     BSL_LIST_DeleteAll(names, (BSL_LIST_PFUNC_FREE)FreeGeneralName);
319 }
320 
X509_ExtNew(HITLS_X509_Ext * ext,int32_t type)321 HITLS_X509_Ext *X509_ExtNew(HITLS_X509_Ext *ext, int32_t type)
322 {
323     HITLS_X509_Ext *tmp = NULL;
324     if (ext == NULL) {
325         tmp = (HITLS_X509_Ext *)BSL_SAL_Calloc(1, sizeof(HITLS_X509_Ext));
326         if (tmp == NULL) {
327             return NULL;
328         }
329         ext = tmp;
330     }
331     ext->type = type;
332     ext->extList = BSL_LIST_New(sizeof(HITLS_X509_ExtEntry *));
333     if (ext->extList == NULL) {
334         BSL_SAL_Free(tmp);
335         return NULL;
336     }
337     if (type != HITLS_X509_EXT_TYPE_CRL) {
338         ext->extData = BSL_SAL_Calloc(1, sizeof(HITLS_X509_CertExt));
339         if (ext->extData == NULL) {
340             BSL_SAL_Free(ext->extList);
341             ext->extList = NULL;
342             BSL_SAL_Free(tmp);
343             return NULL;
344         }
345         ((HITLS_X509_CertExt *)(ext->extData))->maxPathLen = -1;
346     }
347     return ext;
348 }
349 
X509_ExtFree(HITLS_X509_Ext * ext,bool isFreeOut)350 void X509_ExtFree(HITLS_X509_Ext *ext, bool isFreeOut)
351 {
352     if (ext == NULL) {
353         return;
354     }
355     if ((ext->flag & HITLS_X509_EXT_FLAG_PARSE) != 0) {
356         BSL_LIST_FREE(ext->extList, NULL);
357     } else {
358         BSL_LIST_FREE(ext->extList, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree);
359     }
360     BSL_SAL_Free(ext->extData);
361     if (isFreeOut) {
362         BSL_SAL_Free(ext);
363     }
364 }
365 
HITLS_X509_ParseGeneralNames(uint8_t * encode,uint32_t encLen,BslList * list)366 int32_t HITLS_X509_ParseGeneralNames(uint8_t *encode, uint32_t encLen, BslList *list)
367 {
368     uint8_t *buff = encode;
369     uint32_t buffLen = encLen;
370     uint32_t nameValueLen;
371     uint8_t tag;
372     int32_t ret = HITLS_PKI_SUCCESS;
373 
374     while (buffLen != 0) {
375         // tag
376         tag = *buff;
377         buff++;
378         buffLen--;
379         // length
380         ret = BSL_ASN1_DecodeLen(&buff, &buffLen, false, &nameValueLen);
381         if (ret != BSL_SUCCESS) {
382             break;
383         }
384         if (nameValueLen == 0) {
385             continue;
386         }
387         // value
388         ret = ParseGeneralName(tag, &buff, &buffLen, nameValueLen, list);
389         if (ret != BSL_SUCCESS) {
390             break;
391         }
392         if (tag != HITLS_X509_GENERALNAME_DIR_TAG) {
393             buff += nameValueLen;
394             buffLen -= nameValueLen;
395         }
396     }
397     if (ret != BSL_SUCCESS) {
398         HITLS_X509_ClearGeneralNames(list);
399         BSL_ERR_PUSH_ERROR(ret);
400     }
401     return ret;
402 }
403 
HITLS_X509_ClearAuthorityKeyId(HITLS_X509_ExtAki * aki)404 void HITLS_X509_ClearAuthorityKeyId(HITLS_X509_ExtAki *aki)
405 {
406     if (aki == NULL) {
407         return;
408     }
409     if (aki->issuerName != NULL) {
410         HITLS_X509_ClearGeneralNames(aki->issuerName);
411         BSL_SAL_Free(aki->issuerName);
412         aki->issuerName = NULL;
413     }
414 }
415 
HITLS_X509_ParseAuthorityKeyId(HITLS_X509_ExtEntry * extEntry,HITLS_X509_ExtAki * aki)416 int32_t HITLS_X509_ParseAuthorityKeyId(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtAki *aki)
417 {
418     uint8_t *temp = extEntry->extnValue.buff;
419     uint32_t tempLen = extEntry->extnValue.len;
420     BslList *list = NULL;
421     BSL_ASN1_Buffer asnArr[HITLS_X509_EXT_AKI_MAX] = {0};
422     BSL_ASN1_Template templ = {g_akidTempl, sizeof(g_akidTempl) / sizeof(g_akidTempl[0])};
423 
424     int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_EXT_AKI_MAX);
425     if (ret != BSL_SUCCESS) {
426         BSL_ERR_PUSH_ERROR(ret);
427         return ret;
428     }
429 
430     if (asnArr[HITLS_X509_EXT_AKI_KID_IDX].tag != 0) {
431         aki->kid.data = asnArr[HITLS_X509_EXT_AKI_KID_IDX].buff;
432         aki->kid.dataLen = asnArr[HITLS_X509_EXT_AKI_KID_IDX].len;
433     }
434     /**
435      * ITU-T x509: 8.2.2.1 Authority key identifier extension
436      * authorityCertIssuer PRESENT, authorityCertSerialNumber PRESENT
437      * authorityCertIssuer ABSENT, authorityCertSerialNumber ABSENT
438      */
439     if ((asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].buff != NULL && asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].buff == NULL) ||
440         (asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].buff == NULL && asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].buff != NULL)) {
441         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_ILLEGAL_AKI);
442         return HITLS_X509_ERR_EXT_ILLEGAL_AKI;
443     }
444     if (asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].tag != 0) {
445         aki->serialNum.data = asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].buff;
446         aki->serialNum.dataLen = asnArr[HITLS_X509_EXT_AKI_SERIAL_IDX].len;
447     }
448     if (asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].tag != 0) {
449         list = BSL_LIST_New(sizeof(HITLS_X509_GeneralName));
450         if (list == NULL) {
451             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_AKI);
452             return HITLS_X509_ERR_PARSE_AKI;
453         }
454         ret = HITLS_X509_ParseGeneralNames(
455             asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].buff, asnArr[HITLS_X509_EXT_AKI_ISSUER_IDX].len, list);
456         if (ret != HITLS_PKI_SUCCESS) {
457             BSL_SAL_Free(list);
458             BSL_ERR_PUSH_ERROR(ret);
459             return ret;
460         }
461         aki->issuerName = list;
462     }
463     aki->critical = extEntry->critical;
464     return ret;
465 }
466 
HITLS_X509_ParseSubjectKeyId(HITLS_X509_ExtEntry * extEntry,HITLS_X509_ExtSki * ski)467 int32_t HITLS_X509_ParseSubjectKeyId(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtSki *ski)
468 {
469     uint8_t *temp = extEntry->extnValue.buff;
470     uint32_t tempLen = extEntry->extnValue.len;
471     uint32_t kidLen = 0;
472 
473     int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_OCTETSTRING, &temp, &tempLen, &kidLen);
474     if (ret != BSL_SUCCESS) {
475         BSL_ERR_PUSH_ERROR(ret);
476         return ret;
477     }
478 
479     ski->kid.data = temp;
480     ski->kid.dataLen = kidLen;
481     ski->critical = extEntry->critical;
482     return ret;
483 }
484 
X509_ParseCrlNumber(HITLS_X509_ExtEntry * extEntry,HITLS_X509_ExtCrlNumber * crlNumber)485 int32_t X509_ParseCrlNumber(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtCrlNumber *crlNumber)
486 {
487     uint8_t *temp = extEntry->extnValue.buff;
488     uint32_t tempLen = extEntry->extnValue.len;
489     uint32_t valueLen = 0;
490 
491     // CRL Number is encoded as an INTEGER
492     int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_INTEGER, &temp, &tempLen, &valueLen);
493     if (ret != BSL_SUCCESS) {
494         BSL_ERR_PUSH_ERROR(ret);
495         return ret;
496     }
497 
498     // Check CRL Number length
499     if (valueLen < HITLS_X509_CRLNUMBER_MIN_LEN || valueLen > HITLS_X509_CRLNUMBER_MAX_LEN) {
500         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_CRLNUMBER);
501         return HITLS_X509_ERR_EXT_CRLNUMBER;
502     }
503 
504     // Store CRL Number value
505     crlNumber->crlNumber.data = temp;
506     crlNumber->crlNumber.dataLen = valueLen;
507     crlNumber->critical = extEntry->critical;
508 
509     return HITLS_PKI_SUCCESS;
510 }
511 
512 #if defined(HITLS_PKI_X509_CRT_PARSE) || defined(HITLS_PKI_X509_CRL_PARSE) || defined(HITLS_PKI_X509_CSR_PARSE)
ParseExKeyUsageList(uint32_t layer,BSL_ASN1_Buffer * asn,void * param,BSL_ASN1_List * list)513 static int32_t ParseExKeyUsageList(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list)
514 {
515     (void)param;
516     if (layer == 1) {
517         return HITLS_PKI_SUCCESS;
518     }
519 
520     BSL_Buffer *buff = BSL_SAL_Malloc(sizeof(BSL_Buffer));
521     if (buff == NULL) {
522         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXKU_ITEM);
523         return HITLS_X509_ERR_PARSE_EXKU_ITEM;
524     }
525     buff->data = asn->buff;
526     buff->dataLen = asn->len;
527     int32_t ret = BSL_LIST_AddElement(list, buff, BSL_LIST_POS_AFTER);
528     if (ret != BSL_SUCCESS) {
529         BSL_ERR_PUSH_ERROR(ret);
530         BSL_SAL_Free(buff);
531     }
532     return ret;
533 }
534 
HITLS_X509_ParseExtendedKeyUsage(HITLS_X509_ExtEntry * extEntry,HITLS_X509_ExtExKeyUsage * exku)535 int32_t HITLS_X509_ParseExtendedKeyUsage(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtExKeyUsage *exku)
536 {
537     uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_TAG_OBJECT_ID};
538     BSL_ASN1_DecodeListParam listParam = {sizeof(expTag) / sizeof(uint8_t), expTag};
539 
540     BslList *list = BSL_LIST_New(sizeof(BSL_Buffer));
541     if (list == NULL) {
542         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXKU);
543         return HITLS_X509_ERR_PARSE_EXKU;
544     }
545 
546     int32_t ret = BSL_ASN1_DecodeListItem(&listParam, &extEntry->extnValue, ParseExKeyUsageList, NULL, list);
547     if (ret != HITLS_PKI_SUCCESS) {
548         BSL_LIST_DeleteAll(list, NULL);
549         BSL_SAL_Free(list);
550         return ret;
551     }
552 
553     exku->critical = extEntry->critical;
554     exku->oidList = list;
555     return ret;
556 }
557 
HITLS_X509_ClearSubjectAltName(HITLS_X509_ExtSan * san)558 void HITLS_X509_ClearSubjectAltName(HITLS_X509_ExtSan *san)
559 {
560     if (san == NULL) {
561         return;
562     }
563     if (san->names != NULL) {
564         HITLS_X509_ClearGeneralNames(san->names);
565         BSL_SAL_Free(san->names);
566         san->names = NULL;
567     }
568 }
569 
HITLS_X509_ParseSubjectAltName(HITLS_X509_ExtEntry * extEntry,HITLS_X509_ExtSan * san)570 int32_t HITLS_X509_ParseSubjectAltName(HITLS_X509_ExtEntry *extEntry, HITLS_X509_ExtSan *san)
571 {
572     uint32_t len;
573     uint8_t *buff = extEntry->extnValue.buff;
574     uint32_t buffLen = extEntry->extnValue.len;
575     // skip the sequence
576     int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, &buff, &buffLen, &len);
577     if (ret == BSL_SUCCESS && buffLen != len) {
578         ret = HITLS_X509_ERR_PARSE_NO_ENOUGH;
579     }
580     if (ret != BSL_SUCCESS) {
581         BSL_ERR_PUSH_ERROR(ret);
582         return ret;
583     }
584     BslList *list = BSL_LIST_New(sizeof(HITLS_X509_GeneralName));
585     if (list == NULL) {
586         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_SAN);
587         return HITLS_X509_ERR_PARSE_SAN;
588     }
589     ret = HITLS_X509_ParseGeneralNames(buff, len, list);
590     if (ret != HITLS_PKI_SUCCESS) {
591         BSL_SAL_FREE(list);
592         BSL_ERR_PUSH_ERROR(ret);
593         return ret;
594     }
595     san->names = list;
596     san->critical = extEntry->critical;
597     return ret;
598 }
599 
HITLS_X509_ClearExtendedKeyUsage(HITLS_X509_ExtExKeyUsage * exku)600 void HITLS_X509_ClearExtendedKeyUsage(HITLS_X509_ExtExKeyUsage *exku)
601 {
602     if (exku == NULL) {
603         return;
604     }
605     BSL_LIST_FREE(exku->oidList, NULL);
606 }
607 #endif
608 
609 #if defined(HITLS_PKI_X509_CRT_PARSE) || defined(HITLS_PKI_X509_CRL_PARSE) || defined(HITLS_PKI_X509_CSR)
610 static BSL_ASN1_TemplateItem g_x509ExtTempl[] = {
611     {BSL_ASN1_TAG_OBJECT_ID, 0, 0},
612     {BSL_ASN1_TAG_BOOLEAN, BSL_ASN1_FLAG_DEFAULT, 0},
613     {BSL_ASN1_TAG_OCTETSTRING, 0, 0},
614 };
615 
HITLS_X509_ParseExtItem(BSL_ASN1_Buffer * extItem,HITLS_X509_ExtEntry * extEntry)616 int32_t HITLS_X509_ParseExtItem(BSL_ASN1_Buffer *extItem, HITLS_X509_ExtEntry *extEntry)
617 {
618     uint8_t *temp = extItem->buff;
619     uint32_t tempLen = extItem->len;
620     BSL_ASN1_Buffer asnArr[HITLS_X509_EXT_MAX] = {0};
621     BSL_ASN1_Template templ = {g_x509ExtTempl, sizeof(g_x509ExtTempl) / sizeof(g_x509ExtTempl[0])};
622     int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asnArr, HITLS_X509_EXT_MAX);
623     if (tempLen != 0) {
624         ret = HITLS_X509_ERR_PARSE_EXT_BUF;
625     }
626     if (ret != BSL_SUCCESS) {
627         BSL_ERR_PUSH_ERROR(ret);
628         return ret;
629     }
630     // extnid
631     extEntry->extnId = asnArr[HITLS_X509_EXT_OID_IDX];
632     BslOidString oid = {extEntry->extnId.len, (char *)extEntry->extnId.buff, 0};
633     extEntry->cid = BSL_OBJ_GetCID(&oid);
634     // critical
635     if (asnArr[HITLS_X509_EXT_CRITICAL_IDX].tag == 0) {
636         extEntry->critical = false;
637     } else {
638         ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_EXT_CRITICAL_IDX], &extEntry->critical);
639         if (ret != BSL_SUCCESS) {
640             BSL_ERR_PUSH_ERROR(ret);
641             return ret;
642         }
643     }
644     extEntry->extnValue = asnArr[HITLS_X509_EXT_VALUE_IDX];
645     return ret;
646 }
647 #endif
648 
649 #if defined(HITLS_PKI_X509_CRT_GEN) || defined(HITLS_PKI_X509_CRL_GEN) || defined(HITLS_PKI_X509_CSR_GEN)
FreeExtEntryCont(HITLS_X509_ExtEntry * entry)650 static void FreeExtEntryCont(HITLS_X509_ExtEntry *entry)
651 {
652     BSL_SAL_FREE(entry->extnId.buff);
653     BSL_SAL_FREE(entry->extnValue.buff);
654     entry->extnId.len = 0;
655     entry->extnValue.len = 0;
656 }
657 
GetExtEntryByCid(BslList * extList,BslCid cid,HITLS_X509_ExtEntry ** entry,bool * isNew)658 static int32_t GetExtEntryByCid(BslList *extList, BslCid cid, HITLS_X509_ExtEntry **entry, bool *isNew)
659 {
660     BslOidString *oid = BSL_OBJ_GetOID(cid);
661     if (oid == NULL) {
662         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_OID);
663         return HITLS_X509_ERR_EXT_OID;
664     }
665     HITLS_X509_ExtEntry *extEntry = BSL_LIST_Search(extList, &cid, CmpExtByCid, NULL);
666     if (extEntry != NULL) {
667         *isNew = false;
668         FreeExtEntryCont(extEntry);
669         extEntry->critical = false;
670     } else {
671         extEntry = BSL_SAL_Calloc(1, sizeof(HITLS_X509_ExtEntry));
672         if (extEntry == NULL) {
673             BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
674             return BSL_MALLOC_FAIL;
675         }
676         *isNew = true;
677     }
678 
679     extEntry->cid = cid;
680     extEntry->extnId.tag = BSL_ASN1_TAG_OBJECT_ID;
681     extEntry->extnId.len = oid->octetLen;
682     if (extEntry->extnId.len != 0) {
683         extEntry->extnId.buff = BSL_SAL_Dump(oid->octs, oid->octetLen);
684         if (extEntry->extnId.buff == NULL) {
685             if (*isNew) {
686                 BSL_SAL_Free(extEntry);
687             }
688             BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
689             return BSL_DUMP_FAIL;
690         }
691     }
692     extEntry->extnValue.tag = BSL_ASN1_TAG_OCTETSTRING;
693     *entry = extEntry;
694     return HITLS_PKI_SUCCESS;
695 }
696 #endif
697 
698 #if defined(HITLS_PKI_X509_CRT_PARSE) || defined(HITLS_PKI_X509_CRL_PARSE) || defined(HITLS_PKI_X509_CSR)
ParseExtAsnItem(BSL_ASN1_Buffer * asn,void * param,BSL_ASN1_List * list)699 static int32_t ParseExtAsnItem(BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list)
700 {
701     HITLS_X509_Ext *ext = param;
702     HITLS_X509_ExtEntry extEntry = {0};
703     int32_t ret = HITLS_X509_ParseExtItem(asn, &extEntry);
704     if (ret != HITLS_PKI_SUCCESS) {
705         BSL_ERR_PUSH_ERROR(ret);
706         return ret;
707     }
708 
709     // Check if the extension already exists.
710     if (BSL_LIST_Search(list, &extEntry.extnId, CmpExtByOid, NULL) != NULL) {
711         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_PARSE_EXT_REPEAT);
712         return HITLS_X509_ERR_PARSE_EXT_REPEAT;
713     }
714 
715     // Add the extension to list.
716     ret =  HITLS_X509_AddListItemDefault(&extEntry, sizeof(HITLS_X509_ExtEntry), list);
717     if (ret != HITLS_PKI_SUCCESS) {
718         BSL_ERR_PUSH_ERROR(ret);
719         return ret;
720     }
721 
722     BslOidString oid = {extEntry.extnId.len, (char *)extEntry.extnId.buff, 0};
723     switch (BSL_OBJ_GetCID(&oid)) {
724         case BSL_CID_CE_KEYUSAGE:
725             return ParseExtKeyUsage(&extEntry, (HITLS_X509_CertExt *)ext->extData);
726         case BSL_CID_CE_BASICCONSTRAINTS:
727             return ParseExtBasicConstraints(&extEntry, (HITLS_X509_CertExt *)ext->extData);
728         default:
729             return HITLS_PKI_SUCCESS;
730     }
731 }
732 
ParseExtSeqof(uint32_t layer,BSL_ASN1_Buffer * asn,void * param,BSL_ASN1_List * list)733 static int32_t ParseExtSeqof(uint32_t layer, BSL_ASN1_Buffer *asn, void *param, BSL_ASN1_List *list)
734 {
735     return layer == 1 ? HITLS_PKI_SUCCESS : ParseExtAsnItem(asn, param, list);
736 }
737 
HITLS_X509_ParseExt(BSL_ASN1_Buffer * ext,HITLS_X509_Ext * certExt)738 int32_t HITLS_X509_ParseExt(BSL_ASN1_Buffer *ext, HITLS_X509_Ext *certExt)
739 {
740     if (certExt == NULL || certExt->extData == NULL) {
741         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_PARSE_AFTER_SET);
742         return HITLS_X509_ERR_EXT_PARSE_AFTER_SET;
743     }
744 
745     if ((certExt->flag & HITLS_X509_EXT_FLAG_GEN) != 0) {
746         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_PARSE_AFTER_SET);
747         return HITLS_X509_ERR_EXT_PARSE_AFTER_SET;
748     }
749     // x509 v1
750     if (ext->tag == 0) {
751         return HITLS_PKI_SUCCESS;
752     }
753 
754     uint8_t expTag[] = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE,
755                         BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE};
756     BSL_ASN1_DecodeListParam listParam = {2, expTag};
757     int ret = BSL_ASN1_DecodeListItem(&listParam, ext, &ParseExtSeqof, certExt, certExt->extList);
758     if (ret != BSL_SUCCESS) {
759         BSL_LIST_DeleteAll(certExt->extList, NULL);
760         BSL_ERR_PUSH_ERROR(ret);
761         return ret;
762     }
763     certExt->flag |= HITLS_X509_EXT_FLAG_PARSE;
764     return ret;
765 }
766 #endif
767 
768 #if defined(HITLS_PKI_X509_CRT_GEN) || defined(HITLS_PKI_X509_CRL_GEN) || defined(HITLS_PKI_X509_CSR_GEN)
SetExtBCons(HITLS_X509_Ext * ext,HITLS_X509_ExtEntry * entry,const void * val)769 static int32_t SetExtBCons(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val)
770 {
771     const HITLS_X509_ExtBCons *bCons = (const HITLS_X509_ExtBCons *)val;
772     BSL_ASN1_Template templ = {g_bConsTempl, sizeof(g_bConsTempl) / sizeof(g_bConsTempl[0])};
773     /**
774      * RFC 5280: section-4.2.1.9
775      * BasicConstraints ::= SEQUENCE {
776      *   cA                      BOOLEAN DEFAULT FALSE,
777      *   pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
778      */
779     BSL_ASN1_Buffer asns[] = {
780         {BSL_ASN1_TAG_BOOLEAN, bCons->isCa ? sizeof(bool) : 0, bCons->isCa ? (uint8_t *)(uintptr_t)&bCons->isCa : NULL},
781         {BSL_ASN1_TAG_INTEGER, 0, NULL},
782     };
783     int32_t ret;
784 
785     if (bCons->maxPathLen >= 0) {
786         ret = BSL_ASN1_EncodeLimb(BSL_ASN1_TAG_INTEGER, (uint64_t)bCons->maxPathLen, asns + 1);
787         if (ret != BSL_SUCCESS) {
788             BSL_ERR_PUSH_ERROR(ret);
789             return ret;
790         }
791     }
792 
793     ret = BSL_ASN1_EncodeTemplate(
794         &templ, asns, sizeof(asns) / sizeof(asns[0]), &entry->extnValue.buff, &entry->extnValue.len);
795     BSL_SAL_Free(asns[1].buff);
796     if (ret != BSL_SUCCESS) {
797         BSL_ERR_PUSH_ERROR(ret);
798         return ret;
799     }
800     entry->critical = bCons->critical;
801     HITLS_X509_CertExt *certExt = (HITLS_X509_CertExt *)ext->extData;
802     certExt->isCa = bCons->isCa;
803     certExt->maxPathLen = bCons->maxPathLen;
804     certExt->extFlags |= HITLS_X509_EXT_FLAG_BCONS;
805     return HITLS_PKI_SUCCESS;
806 }
807 
SetExtKeyUsage(HITLS_X509_Ext * ext,HITLS_X509_ExtEntry * entry,const void * val)808 static int32_t SetExtKeyUsage(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val)
809 {
810     const HITLS_X509_ExtKeyUsage *ku = (const HITLS_X509_ExtKeyUsage *)val;
811     if (ku->keyUsage == 0 || (ku->keyUsage & HITLS_X509_EXT_KEYUSAGE_UNUSED_BIT) != 0) {
812         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_KU);
813         return HITLS_X509_ERR_EXT_KU;
814     }
815 
816     // bit string
817     uint16_t keyUsage = (uint16_t)ku->keyUsage;
818     BSL_ASN1_BitString bs = {0};
819     bs.len = (keyUsage & HITLS_X509_EXT_KU_DECIPHER_ONLY) == 0 ? 1 : 2; // 2: decipher only is not 0
820     uint8_t buff[2] = {0}; // The max length of content(BitString, except unused bits) is 2 bytes.
821     buff[0] = (uint8_t)keyUsage;
822     buff[1] = (uint8_t)(keyUsage >> 8); // 8: 8 bits per byte
823     bs.buff = buff;
824     uint8_t tmp = bs.len == 1 ? (uint8_t)keyUsage : (uint8_t)(keyUsage >> BITS_OF_BYTE);
825     for (int32_t i = 1; i < BITS_OF_BYTE; i++) {
826         if ((uint8_t)(tmp << i) == 0) {
827             bs.unusedBits = BITS_OF_BYTE - i;
828             break;
829         }
830     }
831 
832     // encode bit string
833     BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_BITSTRING, sizeof(BSL_ASN1_BitString), (uint8_t *)&bs};
834     BSL_ASN1_TemplateItem item = {BSL_ASN1_TAG_BITSTRING, 0, 0};
835     BSL_ASN1_Template templ = {&item, 1};
836     int32_t ret = BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &entry->extnValue.buff, &entry->extnValue.len);
837     if (ret != BSL_SUCCESS) {
838         BSL_ERR_PUSH_ERROR(ret);
839         return ret;
840     }
841 
842     entry->critical = ku->critical;
843     HITLS_X509_CertExt *certExt = (HITLS_X509_CertExt *)ext->extData;
844     certExt->extFlags |= HITLS_X509_EXT_FLAG_KUSAGE;
845     return ret;
846 }
847 
SetExtAki(HITLS_X509_Ext * ext,HITLS_X509_ExtEntry * entry,const void * val)848 static int32_t SetExtAki(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val)
849 {
850     (void)ext;
851     const HITLS_X509_ExtAki *aki = (const HITLS_X509_ExtAki *)val;
852     entry->critical = aki->critical;
853 
854     if (aki->kid.dataLen < HITLS_X509_KID_MIN_LEN || aki->kid.dataLen > HITLS_X509_KID_MAX_LEN) {
855         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_KID);
856         return HITLS_X509_ERR_EXT_KID;
857     }
858 
859     BSL_ASN1_Buffer asns[] = {
860         {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_KID, aki->kid.dataLen, aki->kid.data},
861         {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_X509_CTX_SPECIFIC_TAG_AKID_ISSUER, 0, NULL},
862         {BSL_ASN1_CLASS_CTX_SPECIFIC | HITLS_X509_CTX_SPECIFIC_TAG_AKID_SERIAL, 0, NULL},
863     };
864     BSL_ASN1_Template templ = {g_akidTempl, sizeof(g_akidTempl) / sizeof(g_akidTempl[0])};
865     int32_t ret = BSL_ASN1_EncodeTemplate(
866         &templ, asns, sizeof(asns) / sizeof(asns[0]), &entry->extnValue.buff, &entry->extnValue.len);
867     if (ret != BSL_SUCCESS) {
868         BSL_ERR_PUSH_ERROR(ret);
869     }
870     return ret;
871 }
872 
SetExtSki(HITLS_X509_Ext * ext,HITLS_X509_ExtEntry * entry,const void * val)873 static int32_t SetExtSki(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val)
874 {
875     (void)ext;
876     const HITLS_X509_ExtSki *ski = (const HITLS_X509_ExtSki *)val;
877     entry->critical = ski->critical;
878 
879     if (ski->kid.dataLen < HITLS_X509_KID_MIN_LEN || ski->kid.dataLen > HITLS_X509_KID_MAX_LEN) {
880         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_KID);
881         return HITLS_X509_ERR_EXT_KID;
882     }
883 
884     BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_OCTETSTRING, ski->kid.dataLen, ski->kid.data};
885     BSL_ASN1_TemplateItem item = {BSL_ASN1_TAG_OCTETSTRING, 0, 0};
886     BSL_ASN1_Template templ = {&item, 1};
887     int32_t ret = BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &entry->extnValue.buff, &entry->extnValue.len);
888     if (ret != BSL_SUCCESS) {
889         BSL_ERR_PUSH_ERROR(ret);
890     }
891     return ret;
892 }
893 
SetAsn1Templ(BSL_Buffer * value,uint8_t tag,BSL_ASN1_TemplateItem * item,BSL_ASN1_Buffer * asn)894 static void SetAsn1Templ(BSL_Buffer *value, uint8_t tag, BSL_ASN1_TemplateItem *item, BSL_ASN1_Buffer *asn)
895 {
896     item->tag = tag;
897     asn->tag = tag;
898     asn->len = value->dataLen;
899     asn->buff = value->data;
900 }
901 
FreeGnAsns(BSL_ASN1_Buffer * asns,uint32_t number)902 static void FreeGnAsns(BSL_ASN1_Buffer *asns, uint32_t number)
903 {
904     for (uint32_t i = 0; i < number; i++) {
905         if (asns[i].tag == HITLS_X509_GENERALNAME_DIR_TAG) {
906             BSL_SAL_Free(asns[i].buff);
907         }
908     }
909     BSL_SAL_Free(asns);
910 }
911 
GetSanDirNameExtnValue(BslList * dirNames,BSL_ASN1_Buffer * extnValue)912 static int32_t GetSanDirNameExtnValue(BslList *dirNames, BSL_ASN1_Buffer *extnValue)
913 {
914     BSL_ASN1_Buffer tmp = {0};
915     int32_t ret = HITLS_X509_EncodeNameList((BSL_ASN1_List *)dirNames, &tmp);
916     if (ret != HITLS_PKI_SUCCESS) {
917         BSL_ERR_PUSH_ERROR(ret);
918         return ret;
919     }
920 
921     BSL_ASN1_TemplateItem item = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0};
922     BSL_ASN1_Template templ = {&item, 1};
923     ret = BSL_ASN1_EncodeTemplate(&templ, &tmp, 1, &extnValue->buff, &extnValue->len);
924     BSL_SAL_Free(tmp.buff);
925     if (ret != BSL_SUCCESS) {
926         BSL_ERR_PUSH_ERROR(ret);
927     }
928     extnValue->tag = HITLS_X509_GENERALNAME_DIR_TAG;
929     return ret;
930 }
931 
SetGnEncodeParam(BslList * names,BSL_ASN1_TemplateItem * items,BSL_ASN1_Buffer * asns)932 static int32_t SetGnEncodeParam(BslList *names, BSL_ASN1_TemplateItem *items, BSL_ASN1_Buffer *asns)
933 {
934     HITLS_X509_GeneralName **name = BSL_LIST_First(names);
935     BSL_ASN1_TemplateItem *item = items;
936     BSL_ASN1_Buffer *asn = asns;
937     int32_t ret;
938     while (name != NULL) {
939         if ((*name)->value.data == NULL || (*name)->value.dataLen == 0) {
940             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SAN_ELE);
941             return HITLS_X509_ERR_EXT_SAN_ELE;
942         }
943         switch ((*name)->type) {
944             case HITLS_X509_GN_EMAIL:
945                 SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_RFC822_TAG, item, asn);
946                 break;
947             case HITLS_X509_GN_DNS:
948                 SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_DNS_TAG, item, asn);
949                 break;
950             case HITLS_X509_GN_DNNAME:
951                 ret = GetSanDirNameExtnValue((BSL_ASN1_List *)(*name)->value.data, asn);
952                 if (ret != HITLS_PKI_SUCCESS) {
953                     return ret;
954                 }
955                 item->tag = HITLS_X509_GENERALNAME_DIR_TAG;
956                 break;
957             case HITLS_X509_GN_URI:
958                 SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_URI_TAG, item, asn);
959                 break;
960             case HITLS_X509_GN_IP:
961                 SetAsn1Templ(&(*name)->value, HITLS_X509_GENERALNAME_IP_TAG, item, asn);
962                 break;
963             default:
964                 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_GN_UNSUPPORT);
965                 return HITLS_X509_ERR_EXT_GN_UNSUPPORT;
966         }
967         item->depth = 1;
968         item++;
969         asn++;
970         name = BSL_LIST_Next(names);
971     }
972     return HITLS_PKI_SUCCESS;
973 }
974 
AllocEncodeParam(BSL_ASN1_TemplateItem ** items,uint32_t itemNum,BSL_ASN1_Buffer ** asns,uint32_t asnNum)975 static int32_t AllocEncodeParam(BSL_ASN1_TemplateItem **items, uint32_t itemNum, BSL_ASN1_Buffer **asns,
976     uint32_t asnNum)
977 {
978     *items = BSL_SAL_Calloc(itemNum, sizeof(BSL_ASN1_TemplateItem)); // sequence + names
979     if (*items == NULL) {
980         return BSL_MALLOC_FAIL;
981     }
982     *asns = BSL_SAL_Calloc(asnNum, sizeof(BSL_ASN1_Buffer));
983     if (*asns == NULL) {
984         BSL_SAL_Free(*items);
985         *items = NULL;
986         return BSL_MALLOC_FAIL;
987     }
988     return HITLS_PKI_SUCCESS;
989 }
990 
SetExtGeneralNames(HITLS_X509_Ext * ext,HITLS_X509_ExtEntry * entry,const void * val)991 static int32_t SetExtGeneralNames(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val)
992 {
993     (void)ext;
994     const HITLS_X509_ExtSan *san = (const HITLS_X509_ExtSan *)val;
995     if (san->names == NULL || BSL_LIST_COUNT(san->names) <= 0) {
996         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SAN);
997         return HITLS_X509_ERR_EXT_SAN;
998     }
999     entry->critical = san->critical;
1000 
1001     /* Encode extnValue */
1002     BSL_ASN1_TemplateItem *items = NULL;
1003     BSL_ASN1_Buffer *asns = NULL;
1004     uint32_t number = (uint32_t)BSL_LIST_COUNT(san->names);
1005     int32_t ret = AllocEncodeParam(&items, 1 + number, &asns, number);
1006     if (ret != HITLS_PKI_SUCCESS) {
1007         BSL_ERR_PUSH_ERROR(ret);
1008         return ret;
1009     }
1010     items[0].depth = 0;
1011     items[0].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE;
1012     ret = SetGnEncodeParam(san->names, items + 1, asns);
1013     if (ret != HITLS_PKI_SUCCESS) {
1014         BSL_SAL_Free(items);
1015         FreeGnAsns(asns, number);
1016         BSL_ERR_PUSH_ERROR(ret);
1017         return ret;
1018     }
1019 
1020     BSL_ASN1_Template templ = {items, number + 1};
1021     ret = BSL_ASN1_EncodeTemplate(&templ, asns, number, &entry->extnValue.buff, &entry->extnValue.len);
1022     BSL_SAL_Free(items);
1023     FreeGnAsns(asns, number);
1024     if (ret != BSL_SUCCESS) {
1025         BSL_ERR_PUSH_ERROR(ret);
1026     }
1027     return ret;
1028 }
1029 
SetExtExKeyUsage(HITLS_X509_Ext * ext,HITLS_X509_ExtEntry * entry,const void * val)1030 static int32_t SetExtExKeyUsage(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val)
1031 {
1032     (void)ext;
1033     const HITLS_X509_ExtExKeyUsage *exku = (const HITLS_X509_ExtExKeyUsage *)val;
1034     if (exku->oidList == NULL || BSL_LIST_COUNT(exku->oidList) <= 0) {
1035         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_EXTENDED_KU);
1036         return HITLS_X509_ERR_EXT_EXTENDED_KU;
1037     }
1038     entry->critical = exku->critical;
1039 
1040     BSL_ASN1_TemplateItem *items = NULL;
1041     BSL_ASN1_Buffer *asns = NULL;
1042     uint32_t number = (uint32_t)BSL_LIST_COUNT(exku->oidList);
1043     int32_t ret = AllocEncodeParam(&items, number + 1, &asns, number);
1044     if (ret != HITLS_PKI_SUCCESS) {
1045         BSL_ERR_PUSH_ERROR(ret);
1046         return ret;
1047     }
1048     items[0].depth = 0;
1049     items[0].tag = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE;
1050     BSL_Buffer **buffer = BSL_LIST_First(exku->oidList);
1051     for (uint32_t i = 0; i < number; i++) {
1052         if (buffer == NULL || *buffer == NULL || (*buffer)->dataLen == 0 || (*buffer)->data == NULL) {
1053             BSL_SAL_Free(items);
1054             BSL_SAL_Free(asns);
1055             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_EXTENDED_KU_ELE);
1056             return HITLS_X509_ERR_EXT_EXTENDED_KU_ELE;
1057         }
1058         items[i + 1].depth = 1;
1059         items[i + 1].tag = BSL_ASN1_TAG_OBJECT_ID;
1060         asns[i].tag = BSL_ASN1_TAG_OBJECT_ID;
1061         asns[i].len = (*buffer)->dataLen;
1062         asns[i].buff = (*buffer)->data;
1063         buffer = BSL_LIST_Next(exku->oidList);
1064     }
1065 
1066     BSL_ASN1_Template templ = {items, number + 1};
1067     ret = BSL_ASN1_EncodeTemplate(&templ, asns, number, &entry->extnValue.buff, &entry->extnValue.len);
1068     BSL_SAL_Free(items);
1069     BSL_SAL_Free(asns);
1070     if (ret != BSL_SUCCESS) {
1071         BSL_ERR_PUSH_ERROR(ret);
1072     }
1073     return ret;
1074 }
1075 
SetExtCrlNumber(HITLS_X509_Ext * ext,HITLS_X509_ExtEntry * entry,const void * val)1076 static int32_t SetExtCrlNumber(HITLS_X509_Ext *ext, HITLS_X509_ExtEntry *entry, const void *val)
1077 {
1078     if (ext->type != HITLS_X509_EXT_TYPE_CRL) {
1079         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SET);
1080         return HITLS_X509_ERR_EXT_SET;
1081     }
1082     const HITLS_X509_ExtCrlNumber *crlNumber = (const HITLS_X509_ExtCrlNumber *)val;
1083     entry->critical = crlNumber->critical;
1084 
1085     if (crlNumber->crlNumber.dataLen < HITLS_X509_CRLNUMBER_MIN_LEN ||
1086         crlNumber->crlNumber.dataLen > HITLS_X509_CRLNUMBER_MAX_LEN) {
1087         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_CRLNUMBER);
1088         return HITLS_X509_ERR_EXT_CRLNUMBER;
1089     }
1090 
1091     BSL_ASN1_Buffer asn = {BSL_ASN1_TAG_INTEGER, crlNumber->crlNumber.dataLen, crlNumber->crlNumber.data};
1092     BSL_ASN1_TemplateItem item = {BSL_ASN1_TAG_INTEGER, 0, 0};
1093     BSL_ASN1_Template templ = {&item, 1};
1094     int32_t ret = BSL_ASN1_EncodeTemplate(&templ, &asn, 1, &entry->extnValue.buff, &entry->extnValue.len);
1095     if (ret != BSL_SUCCESS) {
1096         BSL_ERR_PUSH_ERROR(ret);
1097     }
1098     return ret;
1099 }
1100 
HITLS_X509_SetExtList(void * param,BslList * extList,BslCid cid,BSL_Buffer * val,EncodeExtCb encodeExt)1101 int32_t HITLS_X509_SetExtList(void *param, BslList *extList, BslCid cid, BSL_Buffer *val, EncodeExtCb encodeExt)
1102 {
1103     HITLS_X509_ExtEntry *extEntry = NULL;
1104     bool isNew;
1105     int32_t ret = GetExtEntryByCid(extList, cid, &extEntry, &isNew);
1106     if (ret != HITLS_PKI_SUCCESS) {
1107         return ret;
1108     }
1109 
1110     ret = encodeExt(param, extEntry, val->data);
1111     if (ret != HITLS_PKI_SUCCESS) {
1112         FreeExtEntryCont(extEntry);
1113         if (isNew) {
1114             BSL_SAL_Free(extEntry);
1115         }
1116         return ret;
1117     }
1118     if (isNew) {
1119         ret = BSL_LIST_AddElement(extList, extEntry, BSL_LIST_POS_END);
1120         if (ret != BSL_SUCCESS) {
1121             BSL_ERR_PUSH_ERROR(ret);
1122             FreeExtEntryCont(extEntry);
1123             BSL_SAL_Free(extEntry);
1124             return ret;
1125         }
1126     }
1127     return HITLS_PKI_SUCCESS;
1128 }
1129 
SetExt(HITLS_X509_Ext * ext,BslCid cid,BSL_Buffer * val,uint32_t expectLen,EncodeExtCb encodeExt)1130 static int32_t SetExt(HITLS_X509_Ext *ext, BslCid cid, BSL_Buffer *val, uint32_t expectLen, EncodeExtCb encodeExt)
1131 {
1132     if ((ext->flag & HITLS_X509_EXT_FLAG_PARSE) != 0) {
1133         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SET_AFTER_PARSE);
1134         return HITLS_X509_ERR_EXT_SET_AFTER_PARSE;
1135     }
1136     if (val->dataLen != expectLen) {
1137         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1138         return HITLS_X509_ERR_INVALID_PARAM;
1139     }
1140 
1141     int32_t ret = HITLS_X509_SetExtList(ext, ext->extList, cid, val, encodeExt);
1142     if (ret != HITLS_PKI_SUCCESS) {
1143         BSL_ERR_PUSH_ERROR(ret);
1144         return ret;
1145     }
1146 
1147     ext->flag |= HITLS_X509_EXT_FLAG_GEN;
1148     return ret;
1149 }
1150 
SetExtCtrl(HITLS_X509_Ext * ext,int32_t cmd,void * val,uint32_t valLen)1151 static int32_t SetExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, uint32_t valLen)
1152 {
1153     BSL_Buffer buff = {val, valLen};
1154     switch (cmd) {
1155         case HITLS_X509_EXT_SET_BCONS:
1156             return SetExt(ext, BSL_CID_CE_BASICCONSTRAINTS, &buff, sizeof(HITLS_X509_ExtBCons),
1157                 (EncodeExtCb)SetExtBCons);
1158         case HITLS_X509_EXT_SET_KUSAGE:
1159             return SetExt(ext, BSL_CID_CE_KEYUSAGE, &buff, sizeof(HITLS_X509_ExtKeyUsage), (EncodeExtCb)SetExtKeyUsage);
1160         case HITLS_X509_EXT_SET_AKI:
1161             return SetExt(ext, BSL_CID_CE_AUTHORITYKEYIDENTIFIER, &buff, sizeof(HITLS_X509_ExtAki),
1162                 (EncodeExtCb)SetExtAki);
1163         case HITLS_X509_EXT_SET_SKI:
1164             return SetExt(ext, BSL_CID_CE_SUBJECTKEYIDENTIFIER, &buff, sizeof(HITLS_X509_ExtSki),
1165                 (EncodeExtCb)SetExtSki);
1166         case HITLS_X509_EXT_SET_SAN:
1167             return SetExt(ext, BSL_CID_CE_SUBJECTALTNAME, &buff, sizeof(HITLS_X509_ExtSan),
1168                 (EncodeExtCb)SetExtGeneralNames);
1169         case HITLS_X509_EXT_SET_EXKUSAGE:
1170             return SetExt(ext, BSL_CID_CE_EXTKEYUSAGE, &buff, sizeof(HITLS_X509_ExtExKeyUsage),
1171                 (EncodeExtCb)SetExtExKeyUsage);
1172         case HITLS_X509_EXT_SET_CRLNUMBER:
1173             return SetExt(ext, BSL_CID_CE_CRLNUMBER, &buff, sizeof(HITLS_X509_ExtCrlNumber),
1174                 (EncodeExtCb)SetExtCrlNumber);
1175         default:
1176             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1177             return HITLS_X509_ERR_INVALID_PARAM;
1178     }
1179 }
1180 #endif
1181 
HITLS_X509_GetExt(BslList * ext,BslCid cid,BSL_Buffer * val,uint32_t expectLen,DecodeExtCb decodeExt)1182 int32_t HITLS_X509_GetExt(BslList *ext, BslCid cid, BSL_Buffer *val, uint32_t expectLen, DecodeExtCb decodeExt)
1183 {
1184     if (ext == NULL) {
1185         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_NOT_FOUND);
1186         return HITLS_X509_ERR_EXT_NOT_FOUND;
1187     }
1188     if (val->dataLen != expectLen) {
1189         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1190         return HITLS_X509_ERR_INVALID_PARAM;
1191     }
1192     HITLS_X509_ExtEntry *extEntry = BSL_LIST_Search(ext, &cid, CmpExtByCid, NULL);
1193     if (extEntry == NULL) {
1194         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_NOT_FOUND);
1195         return HITLS_X509_ERR_EXT_NOT_FOUND;
1196     }
1197     return decodeExt(extEntry, val->data);
1198 }
1199 
GetExtKeyUsage(HITLS_X509_Ext * ext,uint32_t * val,uint32_t valLen)1200 static int32_t GetExtKeyUsage(HITLS_X509_Ext *ext, uint32_t *val, uint32_t valLen)
1201 {
1202     if (val == NULL || valLen != sizeof(uint32_t)) {
1203         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1204         return HITLS_X509_ERR_INVALID_PARAM;
1205     }
1206     HITLS_X509_CertExt *certExt = (HITLS_X509_CertExt *)ext->extData;
1207     *val = certExt->extFlags & HITLS_X509_EXT_FLAG_KUSAGE ? certExt->keyUsage : HITLS_X509_EXT_KU_NONE;
1208     return HITLS_PKI_SUCCESS;
1209 }
1210 
GetExtCtrl(HITLS_X509_Ext * ext,int32_t cmd,void * val,uint32_t valLen)1211 static int32_t GetExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, uint32_t valLen)
1212 {
1213     BSL_Buffer buff = {val, valLen};
1214     switch (cmd) {
1215         case HITLS_X509_EXT_GET_SKI:
1216             return HITLS_X509_GetExt(ext->extList, BSL_CID_CE_SUBJECTKEYIDENTIFIER, &buff, sizeof(HITLS_X509_ExtSki),
1217                 (DecodeExtCb)HITLS_X509_ParseSubjectKeyId);
1218         case HITLS_X509_EXT_GET_AKI:
1219             return HITLS_X509_GetExt(ext->extList, BSL_CID_CE_AUTHORITYKEYIDENTIFIER, &buff, sizeof(HITLS_X509_ExtAki),
1220                 (DecodeExtCb)HITLS_X509_ParseAuthorityKeyId);
1221         case HITLS_X509_EXT_GET_CRLNUMBER:
1222             return HITLS_X509_GetExt(ext->extList, BSL_CID_CE_CRLNUMBER, &buff, sizeof(HITLS_X509_ExtCrlNumber),
1223                 (DecodeExtCb)X509_ParseCrlNumber);
1224         case HITLS_X509_EXT_GET_KUSAGE:
1225             return GetExtKeyUsage(ext, val, valLen);
1226         default:
1227             BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1228             return HITLS_X509_ERR_INVALID_PARAM;
1229     }
1230 }
1231 
CheckExtByCid(HITLS_X509_Ext * ext,int32_t cid,bool * val,uint32_t valLen)1232 static int32_t CheckExtByCid(HITLS_X509_Ext *ext, int32_t cid, bool *val, uint32_t valLen)
1233 {
1234     if (valLen != sizeof(bool)) {
1235         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1236         return HITLS_X509_ERR_INVALID_PARAM;
1237     }
1238     *val = BSL_LIST_Search(ext->extList, &cid, CmpExtByCid, NULL) != NULL;
1239     return HITLS_PKI_SUCCESS;
1240 }
1241 
X509_CheckCmdValid(int32_t * cmdSet,uint32_t cmdSize,int32_t cmd)1242 bool X509_CheckCmdValid(int32_t *cmdSet, uint32_t cmdSize, int32_t cmd)
1243 {
1244     for (uint32_t i = 0; i < cmdSize; i++) {
1245         if (cmd == cmdSet[i]) {
1246             return true;
1247         }
1248     }
1249     return false;
1250 }
1251 
X509_ExtCtrl(HITLS_X509_Ext * ext,int32_t cmd,void * val,uint32_t valLen)1252 int32_t X509_ExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, uint32_t valLen)
1253 {
1254 #if defined(HITLS_PKI_X509_CRT_GEN) || defined(HITLS_PKI_X509_CRL_GEN) || defined(HITLS_PKI_X509_CSR_GEN)
1255     if (cmd >= HITLS_X509_EXT_SET_SKI && cmd < HITLS_X509_EXT_GET_SKI) {
1256         return SetExtCtrl(ext, cmd, val, valLen);
1257     }
1258 #endif
1259     if (cmd >= HITLS_X509_EXT_GET_SKI && cmd < HITLS_X509_EXT_CHECK_SKI) {
1260         return GetExtCtrl(ext, cmd, val, valLen);
1261     }
1262     if (cmd >= HITLS_X509_EXT_CHECK_SKI && cmd < HITLS_X509_CSR_GET_ATTRIBUTES) {
1263         return CheckExtByCid(ext, BSL_CID_CE_SUBJECTKEYIDENTIFIER, val, valLen);
1264     }
1265     BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1266     return HITLS_X509_ERR_INVALID_PARAM;
1267 }
1268 
HITLS_X509_ExtCtrl(HITLS_X509_Ext * ext,int32_t cmd,void * val,uint32_t valLen)1269 int32_t HITLS_X509_ExtCtrl(HITLS_X509_Ext *ext, int32_t cmd, void *val, uint32_t valLen)
1270 {
1271     if (ext == NULL || val == NULL) {
1272         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1273         return HITLS_X509_ERR_INVALID_PARAM;
1274     }
1275     if (ext->type == HITLS_X509_EXT_TYPE_CERT || ext->type == HITLS_X509_EXT_TYPE_CRL) {
1276         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_UNSUPPORT);
1277         return HITLS_X509_ERR_EXT_UNSUPPORT;
1278     }
1279     static int32_t cmdSet[] = {HITLS_X509_EXT_SET_SKI, HITLS_X509_EXT_SET_AKI, HITLS_X509_EXT_SET_KUSAGE,
1280         HITLS_X509_EXT_SET_SAN, HITLS_X509_EXT_SET_BCONS, HITLS_X509_EXT_SET_EXKUSAGE, HITLS_X509_EXT_GET_SKI,
1281         HITLS_X509_EXT_GET_AKI, HITLS_X509_EXT_CHECK_SKI, HITLS_X509_EXT_GET_KUSAGE};
1282     if (!X509_CheckCmdValid(cmdSet, sizeof(cmdSet) / sizeof(int32_t), cmd)) {
1283         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_UNSUPPORT);
1284         return HITLS_X509_ERR_EXT_UNSUPPORT;
1285     }
1286 
1287     return X509_ExtCtrl(ext, cmd, val, valLen);
1288 }
1289 
HITLS_X509_SetGeneralNames(HITLS_X509_ExtEntry * extEntry,void * val)1290 int32_t HITLS_X509_SetGeneralNames(HITLS_X509_ExtEntry *extEntry, void *val)
1291 {
1292     if (extEntry == NULL || val == NULL) {
1293         return BSL_NULL_INPUT;
1294     }
1295 
1296     return SetExtGeneralNames(NULL, extEntry, val);
1297 }
1298 
HITLS_X509_ExtEntryFree(HITLS_X509_ExtEntry * entry)1299 void HITLS_X509_ExtEntryFree(HITLS_X509_ExtEntry *entry)
1300 {
1301     if (entry == NULL) {
1302         return;
1303     }
1304     BSL_SAL_FREE(entry->extnId.buff);
1305     BSL_SAL_FREE(entry->extnValue.buff);
1306     BSL_SAL_Free(entry);
1307 }
1308 
1309 #if defined(HITLS_PKI_X509_CRT_GEN) || defined(HITLS_PKI_X509_CRL_GEN) || defined(HITLS_PKI_X509_CSR_GEN)
1310 /**
1311  * RFC 5280: section-4.1
1312  * Extension  ::=  SEQUENCE  {
1313         extnID      OBJECT IDENTIFIER,
1314         critical    BOOLEAN DEFAULT FALSE,
1315         extnValue   OCTET STRING
1316                     -- contains the DER encoding of an ASN.1 value
1317                     -- corresponding to the extension type identified
1318                     -- by extnID
1319         }
1320  */
1321 static BSL_ASN1_TemplateItem g_extSeqTempl[] = {
1322     {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
1323         {BSL_ASN1_TAG_OBJECT_ID, 0, 1},
1324         {BSL_ASN1_TAG_BOOLEAN, BSL_ASN1_FLAG_DEFAULT, 1},
1325         {BSL_ASN1_TAG_OCTETSTRING, 1, 1},
1326 };
1327 
1328 #define X509_CRLEXT_ELEM_NUMBER 3
HITLS_X509_EncodeExtEntry(BSL_ASN1_List * list,BSL_ASN1_Buffer * ext)1329 int32_t HITLS_X509_EncodeExtEntry(BSL_ASN1_List *list, BSL_ASN1_Buffer *ext)
1330 {
1331     uint32_t count = (uint32_t)BSL_LIST_COUNT(list);
1332     BSL_ASN1_Buffer *asnBuf = BSL_SAL_Malloc(count * X509_CRLEXT_ELEM_NUMBER * sizeof(BSL_ASN1_Buffer));
1333     if (asnBuf == NULL) {
1334         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
1335         return BSL_MALLOC_FAIL;
1336     }
1337     uint32_t iter = 0;
1338     HITLS_X509_ExtEntry *node = NULL;
1339     for (node = BSL_LIST_GET_FIRST(list); node != NULL; node = BSL_LIST_GET_NEXT(list)) {
1340         asnBuf[iter].tag = node->extnId.tag;
1341         asnBuf[iter].buff = node->extnId.buff;
1342         asnBuf[iter++].len = node->extnId.len;
1343         asnBuf[iter].tag = BSL_ASN1_TAG_BOOLEAN;
1344         asnBuf[iter].len = node->critical ? 1 : 0;
1345         asnBuf[iter++].buff = node->critical ? (uint8_t *)&(node->critical) : NULL;
1346         asnBuf[iter].tag = node->extnValue.tag;
1347         asnBuf[iter].buff = node->extnValue.buff;
1348         asnBuf[iter++].len = node->extnValue.len;
1349     }
1350 
1351     BSL_ASN1_Template templ = {g_extSeqTempl, sizeof(g_extSeqTempl) / sizeof(g_extSeqTempl[0])};
1352     int32_t ret = BSL_ASN1_EncodeListItem(BSL_ASN1_TAG_SEQUENCE, count, &templ, asnBuf, iter, ext);
1353     BSL_SAL_Free(asnBuf);
1354     return ret;
1355 }
1356 
HITLS_X509_EncodeExt(uint8_t tag,BSL_ASN1_List * list,BSL_ASN1_Buffer * ext)1357 int32_t HITLS_X509_EncodeExt(uint8_t tag, BSL_ASN1_List *list, BSL_ASN1_Buffer *ext)
1358 {
1359     if (BSL_LIST_COUNT(list) <= 0) {
1360         ext->tag = tag;
1361         ext->len = 0;
1362         ext->buff = NULL;
1363         return HITLS_PKI_SUCCESS;
1364     }
1365     BSL_ASN1_Buffer extbuff = {0};
1366     int32_t ret = HITLS_X509_EncodeExtEntry(list, &extbuff);
1367     if (ret != HITLS_PKI_SUCCESS) {
1368         return ret;
1369     }
1370     BSL_ASN1_TemplateItem extTempl[] = {
1371         {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
1372     };
1373     BSL_ASN1_Template templ = {extTempl, 1};
1374     ret = BSL_ASN1_EncodeTemplate(&templ, &extbuff, 1, &(ext->buff), &(ext->len));
1375     BSL_SAL_Free(extbuff.buff);
1376     if (ret != HITLS_PKI_SUCCESS) {
1377         BSL_ERR_PUSH_ERROR(ret);
1378         return ret;
1379     }
1380     ext->tag = tag;
1381     return HITLS_PKI_SUCCESS;
1382 }
1383 #endif // HITLS_PKI_X509_CRT_GEN || HITLS_PKI_X509_CRL_GEN || HITLS_PKI_X509_CSR_GEN
1384 
1385 #if defined(HITLS_PKI_X509_CRT_GEN) || defined(HITLS_PKI_X509_CRL_GEN)
X509_DupExtEntry(const HITLS_X509_ExtEntry * src)1386 HITLS_X509_ExtEntry *X509_DupExtEntry(const HITLS_X509_ExtEntry *src)
1387 {
1388     /* Src is not null. */
1389     HITLS_X509_ExtEntry *dest = BSL_SAL_Malloc(sizeof(HITLS_X509_ExtEntry));
1390     if (dest == NULL) {
1391         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
1392         return NULL;
1393     }
1394     dest->cid = src->cid;
1395     dest->critical = src->critical;
1396 
1397     // extId
1398     dest->extnId.tag = src->extnId.tag;
1399     dest->extnId.len = src->extnId.len;
1400     if (src->extnId.len != 0) {
1401         dest->extnId.buff = BSL_SAL_Dump(src->extnId.buff, src->extnId.len);
1402         if (dest->extnId.buff == NULL) {
1403             BSL_SAL_Free(dest);
1404             BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
1405             return NULL;
1406         }
1407     }
1408     // extnValue
1409     dest->extnValue.tag = src->extnValue.tag;
1410     dest->extnValue.len = src->extnValue.len;
1411     if (src->extnValue.len != 0) {
1412         dest->extnValue.buff = BSL_SAL_Dump(src->extnValue.buff, src->extnValue.len);
1413         if (dest->extnValue.buff == NULL) {
1414             BSL_SAL_Free(dest->extnId.buff);
1415             BSL_SAL_Free(dest);
1416             BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
1417             return NULL;
1418         }
1419     }
1420     return dest;
1421 }
1422 #endif
1423 
1424 #ifdef HITLS_PKI_X509_CRT_GEN
HITLS_X509_ExtReplace(HITLS_X509_Ext * dest,HITLS_X509_Ext * src)1425 int32_t HITLS_X509_ExtReplace(HITLS_X509_Ext *dest, HITLS_X509_Ext *src)
1426 {
1427     if (dest == NULL || dest->extData == NULL || src == NULL || src->extData == NULL) {
1428         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1429         return HITLS_X509_ERR_INVALID_PARAM;
1430     }
1431     if ((dest->flag & HITLS_X509_EXT_FLAG_PARSE) != 0) {
1432         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SET_AFTER_PARSE);
1433         return HITLS_X509_ERR_EXT_SET_AFTER_PARSE;
1434     }
1435     HITLS_X509_CertExt *certExt = (HITLS_X509_CertExt *)dest->extData;
1436     HITLS_X509_CertExt *srcExt = (HITLS_X509_CertExt *)src->extData;
1437     certExt->isCa = srcExt->isCa;
1438     certExt->maxPathLen = srcExt->maxPathLen;
1439     certExt->keyUsage = srcExt->keyUsage;
1440     certExt->extFlags = srcExt->extFlags;
1441 
1442     if (BSL_LIST_COUNT(src->extList) <= 0) {
1443         BSL_LIST_DeleteAll(dest->extList, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree);
1444         return HITLS_PKI_SUCCESS;
1445     }
1446     BslList *list =
1447         BSL_LIST_Copy(src->extList, (BSL_LIST_PFUNC_DUP)X509_DupExtEntry, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree);
1448     if (list == NULL) {
1449         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_EXT_SET);
1450         return HITLS_X509_ERR_EXT_SET;
1451     }
1452     BSL_LIST_FREE(dest->extList, (BSL_LIST_PFUNC_FREE)HITLS_X509_ExtEntryFree);
1453     dest->extList = list;
1454     dest->flag |= HITLS_X509_EXT_FLAG_GEN;
1455     return HITLS_PKI_SUCCESS;
1456 }
1457 #endif
1458 
HITLS_X509_ExtNew(int32_t type)1459 HITLS_X509_Ext *HITLS_X509_ExtNew(int32_t type)
1460 {
1461     if (type == HITLS_X509_EXT_TYPE_CERT || type == HITLS_X509_EXT_TYPE_CRL) {
1462         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
1463         return NULL;
1464     }
1465     return X509_ExtNew(NULL, type);
1466 }
1467 
HITLS_X509_ExtFree(HITLS_X509_Ext * ext)1468 void HITLS_X509_ExtFree(HITLS_X509_Ext *ext)
1469 {
1470     X509_ExtFree(ext, true);
1471 }
1472 #endif // HITLS_PKI_X509
1473