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_CSR
18 #include "securec.h"
19 #include "bsl_sal.h"
20 #include "bsl_asn1.h"
21 #include "bsl_obj_internal.h"
22 #include "bsl_err_internal.h"
23 #ifdef HITLS_BSL_PEM
24 #include "bsl_pem_internal.h"
25 #endif // HITLS_BSL_PEM
26 #include "bsl_log_internal.h"
27 #include "hitls_pki_errno.h"
28 #include "crypt_encode_decode_key.h"
29 #include "crypt_errno.h"
30 #ifdef HITLS_BSL_SAL_FILE
31 #include "sal_file.h"
32 #endif
33 #include "crypt_eal_codecs.h"
34 #include "hitls_csr_local.h"
35 #include "hitls_pki_utils.h"
36 #include "hitls_pki_csr.h"
37
38 #define HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE 0
39
40 #define HITLS_X509_CSR_PARSE_FLAG 0x01
41 #define HITLS_X509_CSR_GEN_FLAG 0x02
42
43 #ifdef HITLS_PKI_X509_CSR_PARSE
44 /**
45 * RFC2986: section 4
46 * CertificationRequest ::= SEQUENCE {
47 * certificationRequestInfo CertificationRequestInfo,
48 * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
49 * signature BIT STRING
50 * }
51 */
52 BSL_ASN1_TemplateItem g_csrTempl[] = {
53 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* PKCS10 csr */
54 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* req info */
55 /* 2: version */
56 {BSL_ASN1_TAG_INTEGER, 0, 2},
57 /* 2: subject name */
58 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2},
59 /* 2: public key info */
60 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 2},
61 /* 2: attributes */
62 {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE,
63 BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 2},
64 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */
65 {BSL_ASN1_TAG_OBJECT_ID, 0, 2},
66 {BSL_ASN1_TAG_ANY, BSL_ASN1_FLAG_OPTIONAL, 2},
67 {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */
68 };
69
70 typedef enum {
71 HITLS_X509_CSR_REQINFO_VERSION_IDX = 0,
72 HITLS_X509_CSR_REQINFO_SUBJECT_NAME_IDX = 1,
73 HITLS_X509_CSR_REQINFO_PUBKEY_INFO_IDX = 2,
74 HITLS_X509_CSR_REQINFO_ATTRS_IDX = 3,
75 HITLS_X509_CSR_SIGNALG_OID_IDX = 4,
76 HITLS_X509_CSR_SIGNALG_ANY_IDX = 5,
77 HITLS_X509_CSR_SIGN_IDX = 6,
78 HITLS_X509_CSR_MAX_IDX = 7,
79 } HITLS_X509_CSR_IDX;
80 #endif // HITLS_PKI_X509_CSR_PARSE
81
HITLS_X509_CsrNew(void)82 HITLS_X509_Csr *HITLS_X509_CsrNew(void)
83 {
84 HITLS_X509_Csr *csr = NULL;
85 BSL_ASN1_List *subjectName = NULL;
86 HITLS_X509_Attrs *attributes = NULL;
87 csr = (HITLS_X509_Csr *)BSL_SAL_Calloc(1, sizeof(HITLS_X509_Csr));
88 if (csr == NULL) {
89 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
90 return NULL;
91 }
92
93 subjectName = BSL_LIST_New(sizeof(HITLS_X509_NameNode));
94 if (subjectName == NULL) {
95 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
96 goto ERR;
97 }
98 attributes = HITLS_X509_AttrsNew();
99 if (attributes == NULL) {
100 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
101 goto ERR;
102 }
103 BSL_SAL_ReferencesInit(&(csr->references));
104 csr->reqInfo.subjectName = subjectName;
105 csr->reqInfo.attributes = attributes;
106 csr->state = HITLS_X509_CSR_STATE_NEW;
107 return csr;
108 ERR:
109 BSL_SAL_FREE(subjectName);
110 HITLS_X509_AttrsFree(attributes, NULL);
111 BSL_SAL_FREE(csr);
112 return NULL;
113 }
114
HITLS_X509_ProviderCsrNew(HITLS_PKI_LibCtx * libCtx,const char * attrName)115 HITLS_X509_Csr *HITLS_X509_ProviderCsrNew(HITLS_PKI_LibCtx *libCtx, const char *attrName)
116 {
117 HITLS_X509_Csr *csr = HITLS_X509_CsrNew();
118 if (csr == NULL) {
119 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
120 return NULL;
121 }
122 csr->libCtx = libCtx;
123 csr->attrName = attrName;
124 return csr;
125 }
126
HITLS_X509_CsrFree(HITLS_X509_Csr * csr)127 void HITLS_X509_CsrFree(HITLS_X509_Csr *csr)
128 {
129 if (csr == NULL) {
130 return;
131 }
132 int ret = 0;
133 BSL_SAL_AtomicDownReferences(&(csr->references), &ret);
134 if (ret > 0) {
135 return;
136 }
137 BSL_SAL_ReferencesFree(&(csr->references));
138 if (csr->flag == HITLS_X509_CSR_GEN_FLAG) {
139 BSL_LIST_FREE(csr->reqInfo.subjectName, (BSL_LIST_PFUNC_FREE)HITLS_X509_FreeNameNode);
140 BSL_SAL_FREE(csr->reqInfo.reqInfoRawData);
141 BSL_SAL_FREE(csr->signature.buff);
142 } else {
143 BSL_LIST_FREE(csr->reqInfo.subjectName, NULL);
144 }
145 #ifdef HITLS_CRYPTO_SM2
146 if (csr->signAlgId.algId == BSL_CID_SM2DSAWITHSM3) {
147 BSL_SAL_FREE(csr->signAlgId.sm2UserId.data);
148 csr->signAlgId.sm2UserId.dataLen = 0;
149 }
150 #endif
151 HITLS_X509_AttrsFree(csr->reqInfo.attributes, NULL);
152 csr->reqInfo.attributes = NULL;
153 BSL_SAL_FREE(csr->rawData);
154 CRYPT_EAL_PkeyFreeCtx(csr->reqInfo.ealPubKey);
155 csr->reqInfo.ealPubKey = NULL;
156
157 BSL_SAL_FREE(csr);
158 }
159
160 #ifdef HITLS_PKI_X509_CSR_PARSE
HITLS_X509_CsrTagGetOrCheck(int32_t type,uint32_t idx,void * data,void * expVal)161 int32_t HITLS_X509_CsrTagGetOrCheck(int32_t type, uint32_t idx, void *data, void *expVal)
162 {
163 (void)idx;
164 if (type == BSL_ASN1_TYPE_GET_ANY_TAG) {
165 BSL_ASN1_Buffer *param = (BSL_ASN1_Buffer *)data;
166 BslOidString oidStr = {param->len, (char *)param->buff, 0};
167 BslCid cid = BSL_OBJ_GetCID(&oidStr);
168 if (cid == BSL_CID_UNKNOWN) {
169 return HITLS_X509_ERR_GET_ANY_TAG;
170 }
171 if (cid == BSL_CID_RSASSAPSS) {
172 /* note: any It can be encoded empty or it can be null */
173 *(uint8_t *)expVal = BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE;
174 return BSL_SUCCESS;
175 } else {
176 *(uint8_t *)expVal = BSL_ASN1_TAG_NULL; // is null
177 return BSL_SUCCESS;
178 }
179 }
180
181 return HITLS_X509_ERR_INVALID_PARAM;
182 }
183
ParseCertRequestInfo(BSL_ASN1_Buffer * asnArr,HITLS_X509_Csr * csr)184 static int32_t ParseCertRequestInfo(BSL_ASN1_Buffer *asnArr, HITLS_X509_Csr *csr)
185 {
186 int32_t ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CSR_REQINFO_VERSION_IDX], &csr->reqInfo.version);
187 if (ret != BSL_SUCCESS) {
188 BSL_ERR_PUSH_ERROR(ret);
189 return ret;
190 }
191 /* subject name */
192 ret = HITLS_X509_ParseNameList(&asnArr[HITLS_X509_CSR_REQINFO_SUBJECT_NAME_IDX], csr->reqInfo.subjectName);
193 if (ret != BSL_SUCCESS) {
194 BSL_ERR_PUSH_ERROR(ret);
195 return ret;
196 }
197 /* public key info */
198 BSL_Buffer subPubKeyBuff = {asnArr[HITLS_X509_CSR_REQINFO_PUBKEY_INFO_IDX].buff,
199 asnArr[HITLS_X509_CSR_REQINFO_PUBKEY_INFO_IDX].len};
200 ret = CRYPT_EAL_ProviderDecodeBuffKey(csr->libCtx, csr->attrName, BSL_CID_UNKNOWN, "ASN1",
201 "PUBKEY_SUBKEY_WITHOUT_SEQ", &subPubKeyBuff, NULL, (CRYPT_EAL_PkeyCtx **)&csr->reqInfo.ealPubKey);
202 if (ret != BSL_SUCCESS) {
203 BSL_ERR_PUSH_ERROR(ret);
204 goto ERR;
205 }
206 /* attributes */
207 ret = HITLS_X509_ParseAttrList(&asnArr[HITLS_X509_CSR_REQINFO_ATTRS_IDX], csr->reqInfo.attributes, NULL, NULL);
208 if (ret != BSL_SUCCESS) {
209 BSL_ERR_PUSH_ERROR(ret);
210 goto ERR;
211 }
212 return ret;
213
214 ERR:
215 if (csr->reqInfo.ealPubKey != NULL) {
216 CRYPT_EAL_PkeyFreeCtx(csr->reqInfo.ealPubKey);
217 csr->reqInfo.ealPubKey = NULL;
218 }
219 BSL_LIST_FREE(csr->reqInfo.subjectName, NULL);
220 return ret;
221 }
222
X509CsrBuffAsn1Parse(uint8_t * encode,uint32_t encodeLen,HITLS_X509_Csr * csr)223 static int32_t X509CsrBuffAsn1Parse(uint8_t *encode, uint32_t encodeLen, HITLS_X509_Csr *csr)
224 {
225 uint8_t *temp = encode;
226 uint32_t tempLen = encodeLen;
227 // template parse
228 BSL_ASN1_Buffer asnArr[HITLS_X509_CSR_MAX_IDX] = {0};
229 BSL_ASN1_Template templ = {g_csrTempl, sizeof(g_csrTempl) / sizeof(g_csrTempl[0])};
230 int32_t ret = BSL_ASN1_DecodeTemplate(&templ, HITLS_X509_CsrTagGetOrCheck,
231 &temp, &tempLen, asnArr, HITLS_X509_CSR_MAX_IDX);
232 if (ret != BSL_SUCCESS) {
233 BSL_ERR_PUSH_ERROR(ret);
234 return ret;
235 }
236 // parse reqInfo raw data
237 ret = HITLS_X509_ParseTbsRawData(encode, encodeLen, &csr->reqInfo.reqInfoRawData,
238 &csr->reqInfo.reqInfoRawDataLen);
239 if (ret != HITLS_PKI_SUCCESS) {
240 BSL_ERR_PUSH_ERROR(ret);
241 goto ERR;
242 }
243 // parse reqInfo
244 ret = ParseCertRequestInfo(asnArr, csr);
245 if (ret != HITLS_PKI_SUCCESS) {
246 goto ERR;
247 }
248 // parse sign alg
249 ret = HITLS_X509_ParseSignAlgInfo(&asnArr[HITLS_X509_CSR_SIGNALG_OID_IDX],
250 &asnArr[HITLS_X509_CSR_SIGNALG_ANY_IDX], &csr->signAlgId);
251 if (ret != HITLS_PKI_SUCCESS) {
252 BSL_ERR_PUSH_ERROR(ret);
253 goto ERR;
254 }
255 // parse signature
256 ret = BSL_ASN1_DecodePrimitiveItem(&asnArr[HITLS_X509_CSR_SIGN_IDX], &csr->signature);
257 if (ret != BSL_SUCCESS) {
258 BSL_ERR_PUSH_ERROR(ret);
259 goto ERR;
260 }
261 csr->rawData = encode;
262 csr->rawDataLen = encodeLen - tempLen;
263 return HITLS_PKI_SUCCESS;
264 ERR:
265 HITLS_X509_AttrsFree(csr->reqInfo.attributes, NULL);
266 csr->reqInfo.attributes = NULL;
267 BSL_LIST_FREE(csr->reqInfo.subjectName, NULL);
268 if (csr->reqInfo.ealPubKey != NULL) {
269 CRYPT_EAL_PkeyFreeCtx(csr->reqInfo.ealPubKey);
270 csr->reqInfo.ealPubKey = NULL;
271 }
272 return ret;
273 }
274
X509CsrAsn1Parse(bool isCopy,const BSL_Buffer * encode,HITLS_X509_Csr * csr)275 static int32_t X509CsrAsn1Parse(bool isCopy, const BSL_Buffer *encode, HITLS_X509_Csr *csr)
276 {
277 uint8_t *data = encode->data;
278 uint32_t dataLen = encode->dataLen;
279 if ((csr->flag & HITLS_X509_CSR_GEN_FLAG) != 0) {
280 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
281 return HITLS_X509_ERR_INVALID_PARAM;
282 }
283 uint8_t *tmp = NULL;
284 if (isCopy) {
285 tmp = (uint8_t *)BSL_SAL_Dump(data, dataLen);
286 if (tmp == NULL) {
287 BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
288 return BSL_DUMP_FAIL;
289 }
290 data = tmp;
291 }
292 int32_t ret = X509CsrBuffAsn1Parse(data, dataLen, csr);
293 if (ret != HITLS_PKI_SUCCESS) {
294 BSL_SAL_FREE(tmp);
295 return ret;
296 }
297 csr->flag |= HITLS_X509_CSR_PARSE_FLAG;
298 return HITLS_PKI_SUCCESS;
299 }
300
301 #ifdef HITLS_BSL_PEM
X509CsrPemParse(const BSL_Buffer * encode,HITLS_X509_Csr * csr)302 static int32_t X509CsrPemParse(const BSL_Buffer *encode, HITLS_X509_Csr *csr)
303 {
304 uint8_t *tmpBuf = encode->data;
305 uint32_t tmpBufLen = encode->dataLen;
306 BSL_Buffer asn1Buf = {NULL, 0};
307 BSL_PEM_Symbol symbol = {BSL_PEM_CERT_REQ_BEGIN_STR, BSL_PEM_CERT_REQ_END_STR};
308 int32_t ret = BSL_PEM_DecodePemToAsn1((char **)&tmpBuf, &tmpBufLen, &symbol, &asn1Buf.data,
309 &asn1Buf.dataLen);
310 if (ret != HITLS_PKI_SUCCESS) {
311 BSL_ERR_PUSH_ERROR(ret);
312 return ret;
313 }
314 ret = X509CsrAsn1Parse(false, &asn1Buf, csr);
315 if (ret != HITLS_PKI_SUCCESS) {
316 BSL_SAL_FREE(asn1Buf.data);
317 BSL_ERR_PUSH_ERROR(ret);
318 }
319
320 return ret;
321 }
322 #endif // HITLS_BSL_PEM
323
HITLS_X509_CsrParseBuff(int32_t format,const BSL_Buffer * encode,HITLS_X509_Csr ** csr)324 int32_t HITLS_X509_CsrParseBuff(int32_t format, const BSL_Buffer *encode, HITLS_X509_Csr **csr)
325 {
326 if (encode == NULL || csr == NULL || *csr != NULL || encode->data == NULL || encode->dataLen == 0) {
327 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
328 return HITLS_X509_ERR_INVALID_PARAM;
329 }
330 int32_t ret;
331 HITLS_X509_Csr *tempCsr = HITLS_X509_CsrNew();
332 if (tempCsr == NULL) {
333 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
334 return BSL_MALLOC_FAIL;
335 }
336 switch (format) {
337 case BSL_FORMAT_ASN1:
338 ret = X509CsrAsn1Parse(true, encode, tempCsr);
339 break;
340 #ifdef HITLS_BSL_PEM
341 case BSL_FORMAT_PEM:
342 ret = X509CsrPemParse(encode, tempCsr);
343 break;
344 #endif // HITLS_BSL_PEM
345 default:
346 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_FORMAT_UNSUPPORT);
347 ret = HITLS_X509_ERR_FORMAT_UNSUPPORT;
348 break;
349 }
350 if (ret != HITLS_PKI_SUCCESS) {
351 BSL_ERR_PUSH_ERROR(ret);
352 HITLS_X509_CsrFree(tempCsr);
353 return ret;
354 }
355
356 *csr = tempCsr;
357 return ret;
358 }
359
360 #ifdef HITLS_BSL_SAL_FILE
HITLS_X509_CsrParseFile(int32_t format,const char * path,HITLS_X509_Csr ** csr)361 int32_t HITLS_X509_CsrParseFile(int32_t format, const char *path, HITLS_X509_Csr **csr)
362 {
363 if (path == NULL || csr == NULL) {
364 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
365 return HITLS_X509_ERR_INVALID_PARAM;
366 }
367 uint8_t *data = NULL;
368 uint32_t dataLen = 0;
369 int32_t ret = BSL_SAL_ReadFile(path, &data, &dataLen);
370 if (ret != BSL_SUCCESS) {
371 BSL_ERR_PUSH_ERROR(ret);
372 return ret;
373 }
374
375 BSL_Buffer encode = {data, dataLen};
376 ret = HITLS_X509_CsrParseBuff(format, &encode, csr);
377 BSL_SAL_Free(data);
378 return ret;
379 }
380 #endif // HITLS_BSL_SAL_FILE
381
382 #endif // HITLS_PKI_X509_CSR_PARSE
383
384 #ifdef HITLS_PKI_X509_CSR_GEN
CheckCsrValid(HITLS_X509_Csr * csr)385 static int32_t CheckCsrValid(HITLS_X509_Csr *csr)
386 {
387 if (csr->reqInfo.ealPubKey == NULL) {
388 return HITLS_X509_ERR_CSR_INVALID_PUBKEY;
389 }
390 if (csr->reqInfo.subjectName == NULL || BSL_LIST_COUNT(csr->reqInfo.subjectName) <= 0) {
391 return HITLS_X509_ERR_CSR_INVALID_SUBJECT_DN;
392 }
393
394 return HITLS_PKI_SUCCESS;
395 }
396
EncodeCsrReqInfoItem(HITLS_X509_ReqInfo * reqInfo,BSL_ASN1_Buffer * subject,BSL_ASN1_Buffer * publicKey,BSL_ASN1_Buffer * attributes)397 static int32_t EncodeCsrReqInfoItem(HITLS_X509_ReqInfo *reqInfo, BSL_ASN1_Buffer *subject,
398 BSL_ASN1_Buffer *publicKey, BSL_ASN1_Buffer *attributes)
399 {
400 /* encode subject name */
401 int32_t ret = HITLS_X509_EncodeNameList(reqInfo->subjectName, subject);
402 if (ret != HITLS_PKI_SUCCESS) {
403 BSL_ERR_PUSH_ERROR(ret);
404 return ret;
405 }
406 /* encode public key */
407 BSL_Buffer pub = {0};
408 ret = CRYPT_EAL_EncodePubKeyBuffInternal(reqInfo->ealPubKey, BSL_FORMAT_ASN1, CRYPT_PUBKEY_SUBKEY,
409 false, &pub);
410 if (ret != CRYPT_SUCCESS) {
411 BSL_ERR_PUSH_ERROR(ret);
412 goto ERR;
413 }
414
415 /* encode attribute */
416 ret = HITLS_X509_EncodeAttrList(
417 BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE,
418 reqInfo->attributes, NULL, attributes);
419 if (ret != HITLS_PKI_SUCCESS) {
420 BSL_ERR_PUSH_ERROR(ret);
421 goto ERR;
422 }
423
424 publicKey->buff = pub.data;
425 publicKey->len = pub.dataLen;
426 return ret;
427 ERR:
428 BSL_SAL_FREE(subject->buff);
429 BSL_SAL_FREE(pub.data);
430 BSL_SAL_FREE(attributes->buff);
431 return ret;
432 }
433
434 static BSL_ASN1_TemplateItem g_reqInfoTempl[] = {
435 /* version */
436 {BSL_ASN1_TAG_INTEGER, 0, 0},
437 /* subject name */
438 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0},
439 /* public key */
440 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, BSL_ASN1_FLAG_HEADERONLY, 0},
441 /* attributes */
442 {BSL_ASN1_CLASS_CTX_SPECIFIC | BSL_ASN1_TAG_CONSTRUCTED | HITLS_CSR_CTX_SPECIFIC_TAG_ATTRIBUTE,
443 BSL_ASN1_FLAG_HEADERONLY | BSL_ASN1_FLAG_SAME, 0},
444 };
445
446 #define HITLS_X509_CSR_REQINFO_SIZE 4
447
EncodeCsrReqInfo(HITLS_X509_ReqInfo * reqInfo,BSL_ASN1_Buffer * reqInfoBuff)448 static int32_t EncodeCsrReqInfo(HITLS_X509_ReqInfo *reqInfo, BSL_ASN1_Buffer *reqInfoBuff)
449 {
450 BSL_ASN1_Buffer subject = {0, 0, NULL};
451 BSL_ASN1_Buffer publicKey = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL};
452 BSL_ASN1_Buffer attributes = {0, 0, NULL};
453 int ret = EncodeCsrReqInfoItem(reqInfo, &subject, &publicKey, &attributes);
454 if (ret != HITLS_PKI_SUCCESS) {
455 return ret;
456 }
457 uint8_t version = (uint8_t)reqInfo->version;
458 BSL_ASN1_Template templ = { g_reqInfoTempl, sizeof(g_reqInfoTempl) / sizeof(g_reqInfoTempl[0]) };
459 BSL_ASN1_Buffer reqInfoAsn[HITLS_X509_CSR_REQINFO_SIZE] = {
460 {BSL_ASN1_TAG_INTEGER, 1, &version},
461 subject,
462 publicKey,
463 attributes
464 };
465 ret = BSL_ASN1_EncodeTemplate(&templ, reqInfoAsn, HITLS_X509_CSR_REQINFO_SIZE, &reqInfoBuff->buff,
466 &reqInfoBuff->len);
467 BSL_SAL_FREE(subject.buff);
468 BSL_SAL_FREE(publicKey.buff);
469 BSL_SAL_FREE(attributes.buff);
470 if (ret != BSL_SUCCESS) {
471 BSL_ERR_PUSH_ERROR(ret);
472 }
473
474 return ret;
475 }
476
477 BSL_ASN1_TemplateItem g_briefCsrTempl[] = {
478 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0}, /* pkcs10 csr */
479 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* reqInfo */
480 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 1}, /* signAlg */
481 {BSL_ASN1_TAG_BITSTRING, 0, 1} /* sig */
482 };
483
484 #define HITLS_X509_CSR_BRIEF_SIZE 3
485
X509EncodeAsn1CsrCore(HITLS_X509_Csr * csr)486 static int32_t X509EncodeAsn1CsrCore(HITLS_X509_Csr *csr)
487 {
488 if (csr->signature.buff == NULL || csr->signature.len == 0 ||
489 csr->reqInfo.reqInfoRawData == NULL || csr->reqInfo.reqInfoRawDataLen == 0 ||
490 csr->signAlgId.algId == BSL_CID_UNKNOWN) {
491 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CSR_NOT_SIGNED);
492 return HITLS_X509_ERR_CSR_NOT_SIGNED;
493 }
494
495 BSL_ASN1_Buffer asnArr[HITLS_X509_CSR_BRIEF_SIZE] = {
496 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, csr->reqInfo.reqInfoRawDataLen, csr->reqInfo.reqInfoRawData},
497 {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL},
498 {BSL_ASN1_TAG_BITSTRING, sizeof(BSL_ASN1_BitString), (uint8_t *)&csr->signature}
499 };
500 uint32_t valLen = 0;
501 int32_t ret = BSL_ASN1_DecodeTagLen(asnArr[0].tag, &asnArr[0].buff, &asnArr[0].len, &valLen); // 0 is reqInfo
502 if (ret != HITLS_PKI_SUCCESS) {
503 BSL_ERR_PUSH_ERROR(ret);
504 return ret;
505 }
506
507 ret = HITLS_X509_EncodeSignAlgInfo(&csr->signAlgId, &asnArr[1]); // 1 is signAlg
508 if (ret != HITLS_PKI_SUCCESS) {
509 BSL_ERR_PUSH_ERROR(ret);
510 return ret;
511 }
512
513 BSL_ASN1_Template csrTempl = { g_briefCsrTempl, sizeof(g_briefCsrTempl) / sizeof(g_briefCsrTempl[0]) };
514 ret = BSL_ASN1_EncodeTemplate(&csrTempl, asnArr, HITLS_X509_CSR_BRIEF_SIZE, &csr->rawData, &csr->rawDataLen);
515 BSL_SAL_FREE(asnArr[1].buff);
516 if (ret != HITLS_PKI_SUCCESS) {
517 BSL_ERR_PUSH_ERROR(ret);
518 }
519 return ret;
520 }
521
522 /**
523 * @brief Encode ASN.1 csr
524 *
525 * @param csr [IN] Pointer to the csr structure
526 * @param buff [OUT] Pointer to the buffer.
527 * If NULL, only the ASN.1 csr is encoded.
528 * If non-NULL, the DER encoding content of the csr is stored in buff
529 * @return int32_t Return value, 0 means success, other values mean failure
530 */
X509EncodeAsn1Csr(HITLS_X509_Csr * csr,BSL_Buffer * buff)531 static int32_t X509EncodeAsn1Csr(HITLS_X509_Csr *csr, BSL_Buffer *buff)
532 {
533 int32_t ret;
534 if ((csr->flag & HITLS_X509_CSR_GEN_FLAG) != 0) {
535 if (csr->state != HITLS_X509_CSR_STATE_SIGN && csr->state != HITLS_X509_CSR_STATE_GEN) {
536 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CSR_NOT_SIGNED);
537 return HITLS_X509_ERR_CSR_NOT_SIGNED;
538 }
539 if (csr->state == HITLS_X509_CSR_STATE_SIGN) {
540 ret = X509EncodeAsn1CsrCore(csr);
541 if (ret != HITLS_PKI_SUCCESS) {
542 BSL_ERR_PUSH_ERROR(ret);
543 return ret;
544 }
545 csr->state = HITLS_X509_CSR_STATE_GEN;
546 }
547 }
548 if (csr->rawData == NULL || csr->rawDataLen == 0) {
549 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_CSR_NOT_SIGNED);
550 return HITLS_X509_ERR_CSR_NOT_SIGNED;
551 }
552 if (buff == NULL) {
553 return HITLS_PKI_SUCCESS;
554 }
555 buff->data = BSL_SAL_Dump(csr->rawData, csr->rawDataLen);
556 if (buff->data == NULL) {
557 BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
558 return BSL_DUMP_FAIL;
559 }
560 buff->dataLen = csr->rawDataLen;
561 return HITLS_PKI_SUCCESS;
562 }
563
564 #ifdef HITLS_BSL_PEM
X509EncodePemCsr(HITLS_X509_Csr * csr,BSL_Buffer * buff)565 static int32_t X509EncodePemCsr(HITLS_X509_Csr *csr, BSL_Buffer *buff)
566 {
567 BSL_Buffer asn1 = {0};
568 int32_t ret = X509EncodeAsn1Csr(csr, &asn1);
569 if (ret != HITLS_PKI_SUCCESS) {
570 BSL_ERR_PUSH_ERROR(ret);
571 return ret;
572 }
573
574 BSL_Buffer base64 = {0};
575 BSL_PEM_Symbol symbol = {BSL_PEM_CERT_REQ_BEGIN_STR, BSL_PEM_CERT_REQ_END_STR};
576 ret = BSL_PEM_EncodeAsn1ToPem(asn1.data, asn1.dataLen, &symbol, (char **)&base64.data, &base64.dataLen);
577 BSL_SAL_FREE(asn1.data);
578 if (ret != BSL_SUCCESS) {
579 BSL_ERR_PUSH_ERROR(ret);
580 return ret;
581 }
582 buff->data = base64.data;
583 buff->dataLen = base64.dataLen;
584 return HITLS_PKI_SUCCESS;
585 }
586 #endif // HITLS_BSL_PEM
587
HITLS_X509_CsrGenBuff(int32_t format,HITLS_X509_Csr * csr,BSL_Buffer * buff)588 int32_t HITLS_X509_CsrGenBuff(int32_t format, HITLS_X509_Csr *csr, BSL_Buffer *buff)
589 {
590 if (csr == NULL || buff == NULL || buff->data != NULL) {
591 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
592 return HITLS_X509_ERR_INVALID_PARAM;
593 }
594
595 switch (format) {
596 case BSL_FORMAT_ASN1:
597 return X509EncodeAsn1Csr(csr, buff);
598 #ifdef HITLS_BSL_PEM
599 case BSL_FORMAT_PEM:
600 return X509EncodePemCsr(csr, buff);
601 #endif // HITLS_BSL_PEM
602 default:
603 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_FORMAT_UNSUPPORT);
604 return HITLS_X509_ERR_FORMAT_UNSUPPORT;
605 }
606 }
607
608 #ifdef HITLS_BSL_SAL_FILE
HITLS_X509_CsrGenFile(int32_t format,HITLS_X509_Csr * csr,const char * path)609 int32_t HITLS_X509_CsrGenFile(int32_t format, HITLS_X509_Csr *csr, const char *path)
610 {
611 if (path == NULL) {
612 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
613 return HITLS_X509_ERR_INVALID_PARAM;
614 }
615
616 BSL_Buffer encode = { NULL, 0};
617 int32_t ret = HITLS_X509_CsrGenBuff(format, csr, &encode);
618 if (ret != HITLS_PKI_SUCCESS) {
619 BSL_ERR_PUSH_ERROR(ret);
620 return ret;
621 }
622
623 ret = BSL_SAL_WriteFile(path, encode.data, encode.dataLen);
624 BSL_SAL_Free(encode.data);
625 if (ret != HITLS_PKI_SUCCESS) {
626 BSL_ERR_PUSH_ERROR(ret);
627 }
628
629 return ret;
630 }
631 #endif // HITLS_BSL_SAL_FILE
632
633 #endif // HITLS_PKI_X509_CSR_GEN
634
X509GetAttr(HITLS_X509_Attrs * attrs,HITLS_X509_Attrs ** val,uint32_t valLen)635 static int32_t X509GetAttr(HITLS_X509_Attrs *attrs, HITLS_X509_Attrs **val, uint32_t valLen)
636 {
637 if (val == NULL || valLen != sizeof(HITLS_X509_Attrs *)) {
638 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
639 return HITLS_X509_ERR_INVALID_PARAM;
640 }
641 *val = attrs;
642 return HITLS_PKI_SUCCESS;
643 }
644
HITLS_X509_CsrCtrl(HITLS_X509_Csr * csr,int32_t cmd,void * val,uint32_t valLen)645 int32_t HITLS_X509_CsrCtrl(HITLS_X509_Csr *csr, int32_t cmd, void *val, uint32_t valLen)
646 {
647 if (csr == NULL) {
648 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
649 return HITLS_X509_ERR_INVALID_PARAM;
650 }
651
652 if (((csr->flag & HITLS_X509_CSR_PARSE_FLAG) != 0) && cmd >= HITLS_X509_SET_VERSION &&
653 cmd < HITLS_X509_EXT_SET_SKI) {
654 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SET_AFTER_PARSE);
655 return HITLS_X509_ERR_SET_AFTER_PARSE;
656 }
657
658 switch (cmd) {
659 case HITLS_X509_REF_UP:
660 return HITLS_X509_RefUp(&csr->references, val, valLen);
661 #ifdef HITLS_PKI_X509_CSR_GEN
662 case HITLS_X509_SET_PUBKEY:
663 csr->flag |= HITLS_X509_CSR_GEN_FLAG;
664 csr->state = HITLS_X509_CSR_STATE_SET;
665 return HITLS_X509_SetPkey(&csr->reqInfo.ealPubKey, val);
666 case HITLS_X509_ADD_SUBJECT_NAME:
667 csr->flag |= HITLS_X509_CSR_GEN_FLAG;
668 csr->state = HITLS_X509_CSR_STATE_SET;
669 return HITLS_X509_AddDnName(csr->reqInfo.subjectName, (HITLS_X509_DN *)val, valLen);
670 #ifdef HITLS_CRYPTO_SM2
671 case HITLS_X509_SET_VFY_SM2_USER_ID:
672 if (csr->signAlgId.algId != BSL_CID_SM2DSA && csr->signAlgId.algId != BSL_CID_SM2DSAWITHSM3) {
673 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_VFY_SIGNALG_NOT_MATCH);
674 return HITLS_X509_ERR_VFY_SIGNALG_NOT_MATCH;
675 }
676 return HITLS_X509_SetSm2UserId(&csr->signAlgId.sm2UserId, val, valLen);
677 #endif
678 #endif
679 case HITLS_X509_GET_ENCODELEN:
680 return HITLS_X509_GetEncodeLen(csr->rawDataLen, val, valLen);
681 case HITLS_X509_GET_ENCODE:
682 return HITLS_X509_GetEncodeData(csr->rawData, val);
683 case HITLS_X509_GET_PUBKEY:
684 return HITLS_X509_GetPubKey(csr->reqInfo.ealPubKey, val);
685 case HITLS_X509_GET_SIGNALG:
686 return HITLS_X509_GetSignAlg(csr->signAlgId.algId, (int32_t *)val, valLen);
687 case HITLS_X509_GET_SUBJECT_DN:
688 return HITLS_X509_GetList(csr->reqInfo.subjectName, val, valLen);
689 case HITLS_X509_CSR_GET_ATTRIBUTES:
690 return X509GetAttr(csr->reqInfo.attributes, val, valLen);
691 default:
692 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
693 return HITLS_X509_ERR_INVALID_PARAM;
694 }
695 }
696
HITLS_X509_CsrVerify(HITLS_X509_Csr * csr)697 int32_t HITLS_X509_CsrVerify(HITLS_X509_Csr *csr)
698 {
699 if (csr == NULL || csr->reqInfo.ealPubKey == NULL || csr->reqInfo.reqInfoRawData == NULL ||
700 csr->signature.buff == NULL) {
701 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
702 return HITLS_X509_ERR_INVALID_PARAM;
703 }
704
705 int32_t ret = HITLS_X509_CheckSignature((const CRYPT_EAL_PkeyCtx *)csr->reqInfo.ealPubKey,
706 csr->reqInfo.reqInfoRawData, csr->reqInfo.reqInfoRawDataLen, &csr->signAlgId, &csr->signature);
707 if (ret != HITLS_PKI_SUCCESS) {
708 BSL_ERR_PUSH_ERROR(ret);
709 }
710
711 return ret;
712 }
713
714 #ifdef HITLS_PKI_X509_CSR_GEN
CsrSignCb(int32_t mdId,CRYPT_EAL_PkeyCtx * prvKey,HITLS_X509_Asn1AlgId * signAlgId,HITLS_X509_Csr * csr)715 int32_t CsrSignCb(int32_t mdId, CRYPT_EAL_PkeyCtx *prvKey, HITLS_X509_Asn1AlgId *signAlgId,
716 HITLS_X509_Csr *csr)
717 {
718 BSL_ASN1_Buffer reqInfoAsn1 = {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, NULL};
719 BSL_Buffer signBuff = {NULL, 0};
720
721 csr->signAlgId = *signAlgId;
722 int32_t ret = CRYPT_EAL_PkeyPairCheck((CRYPT_EAL_PkeyCtx *)csr->reqInfo.ealPubKey, prvKey);
723 if (ret != CRYPT_SUCCESS) {
724 BSL_ERR_PUSH_ERROR(ret);
725 return ret;
726 }
727 ret = EncodeCsrReqInfo(&csr->reqInfo, &reqInfoAsn1);
728 if (ret != HITLS_PKI_SUCCESS) {
729 BSL_ERR_PUSH_ERROR(ret);
730 return ret;
731 }
732 ret = HITLS_X509_SignAsn1Data(prvKey, mdId, &reqInfoAsn1, &signBuff, &csr->signature);
733 BSL_SAL_Free(reqInfoAsn1.buff);
734 if (ret != HITLS_PKI_SUCCESS) {
735 BSL_ERR_PUSH_ERROR(ret);
736 return ret;
737 }
738
739 csr->reqInfo.reqInfoRawData = signBuff.data;
740 csr->reqInfo.reqInfoRawDataLen = signBuff.dataLen;
741 csr->state = HITLS_X509_CSR_STATE_SIGN;
742 return ret;
743 }
744
HITLS_X509_CsrSign(int32_t mdId,const CRYPT_EAL_PkeyCtx * prvKey,const HITLS_X509_SignAlgParam * algParam,HITLS_X509_Csr * csr)745 int32_t HITLS_X509_CsrSign(int32_t mdId, const CRYPT_EAL_PkeyCtx *prvKey, const HITLS_X509_SignAlgParam *algParam,
746 HITLS_X509_Csr *csr)
747 {
748 if (csr == NULL || prvKey == NULL) {
749 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
750 return HITLS_X509_ERR_INVALID_PARAM;
751 }
752 if ((csr->flag & HITLS_X509_CSR_PARSE_FLAG) != 0) {
753 BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_SIGN_AFTER_PARSE);
754 return HITLS_X509_ERR_SIGN_AFTER_PARSE;
755 }
756 if (csr->state == HITLS_X509_CSR_STATE_SIGN || csr->state == HITLS_X509_CSR_STATE_GEN) {
757 return HITLS_PKI_SUCCESS;
758 }
759
760 int32_t ret = CheckCsrValid(csr);
761 if (ret != HITLS_PKI_SUCCESS) {
762 BSL_ERR_PUSH_ERROR(ret);
763 return ret;
764 }
765
766 BSL_SAL_FREE(csr->signature.buff);
767 csr->signature.len = 0;
768 BSL_SAL_FREE(csr->reqInfo.reqInfoRawData);
769 csr->reqInfo.reqInfoRawDataLen = 0;
770 BSL_SAL_FREE(csr->rawData);
771 csr->rawDataLen = 0;
772 #ifdef HITLS_CRYPTO_SM2
773 if (csr->signAlgId.algId == BSL_CID_SM2DSAWITHSM3) {
774 BSL_SAL_FREE(csr->signAlgId.sm2UserId.data);
775 csr->signAlgId.sm2UserId.dataLen = 0;
776 }
777 #endif
778 return HITLS_X509_Sign(mdId, prvKey, algParam, csr, (HITLS_X509_SignCb)CsrSignCb);
779 }
780 #endif // HITLS_PKI_X509_CSR_GEN
781
782 #endif // HITLS_PKI_X509_CSR
783