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