• 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_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