• 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_PKCS12
18 #include "securec.h"
19 #include "bsl_err_internal.h"
20 #include "bsl_asn1.h"
21 #include "bsl_obj_internal.h"
22 #include "crypt_eal_codecs.h"
23 #include "crypt_eal_md.h"
24 #include "crypt_encode_decode_key.h"
25 #include "hitls_pki_errno.h"
26 
27 #ifdef HITLS_PKI_PKCS12_PARSE
28 /**
29  * Data Content Type
30  * Data ::= OCTET STRING
31  *
32  * https://datatracker.ietf.org/doc/html/rfc5652#section-4
33  */
HITLS_CMS_ParseAsn1Data(BSL_Buffer * encode,BSL_Buffer * dataValue)34 int32_t HITLS_CMS_ParseAsn1Data(BSL_Buffer *encode, BSL_Buffer *dataValue)
35 {
36     if (encode == NULL || dataValue == NULL) {
37         BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_NULL_POINTER);
38         return HITLS_CMS_ERR_NULL_POINTER;
39     }
40     uint8_t *temp = encode->data;
41     uint32_t tempLen = encode->dataLen;
42     uint32_t decodeLen = 0;
43     uint8_t *data = NULL;
44     int32_t ret = BSL_ASN1_DecodeTagLen(BSL_ASN1_TAG_OCTETSTRING, &temp, &tempLen, &decodeLen);
45     if (ret != BSL_SUCCESS) {
46         BSL_ERR_PUSH_ERROR(ret);
47         return ret;
48     }
49     if (decodeLen == 0) {
50         BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_INVALID_DATA);
51         return HITLS_CMS_ERR_INVALID_DATA;
52     }
53     data = BSL_SAL_Dump(temp, decodeLen);
54     if (data == NULL) {
55         BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
56         return BSL_DUMP_FAIL;
57     }
58     dataValue->data = data;
59     dataValue->dataLen = decodeLen;
60     return HITLS_PKI_SUCCESS;
61 }
62 #endif
63 
64 /**
65  * DigestInfo ::= SEQUENCE {
66  *      digestAlgorithm DigestAlgorithmIdentifier,
67  *      digest Digest
68  * }
69  *
70  * https://datatracker.ietf.org/doc/html/rfc2315#section-9.4
71  */
72 
73 static BSL_ASN1_TemplateItem g_digestInfoTempl[] = {
74     /* digestAlgorithm */
75     {BSL_ASN1_TAG_CONSTRUCTED | BSL_ASN1_TAG_SEQUENCE, 0, 0},
76         {BSL_ASN1_TAG_OBJECT_ID, 0, 1},
77         {BSL_ASN1_TAG_NULL, 0, 1},
78     /* digest */
79     {BSL_ASN1_TAG_OCTETSTRING, 0, 0},
80 };
81 
82 typedef enum {
83     HITLS_P7_DIGESTINFO_OID_IDX,
84     HITLS_P7_DIGESTINFO_ALGPARAM_IDX,
85     HITLS_P7_DIGESTINFO_OCTSTRING_IDX,
86     HITLS_P7_DIGESTINFO_MAX_IDX,
87 } HITLS_P7_DIGESTINFO_IDX;
88 
HITLS_CMS_ParseDigestInfo(BSL_Buffer * encode,BslCid * cid,BSL_Buffer * digest)89 int32_t HITLS_CMS_ParseDigestInfo(BSL_Buffer *encode, BslCid *cid, BSL_Buffer *digest)
90 {
91     if (encode == NULL || encode->data == NULL || digest == NULL || cid == NULL) {
92         BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_NULL_POINTER);
93         return HITLS_CMS_ERR_NULL_POINTER;
94     }
95     if (encode->dataLen == 0 || digest->data != NULL) {
96         BSL_ERR_PUSH_ERROR(HITLS_X509_ERR_INVALID_PARAM);
97         return HITLS_X509_ERR_INVALID_PARAM;
98     }
99     uint8_t *temp = encode->data;
100     uint32_t  tempLen = encode->dataLen;
101     BSL_ASN1_Buffer asn1[HITLS_P7_DIGESTINFO_MAX_IDX] = {0};
102     BSL_ASN1_Template templ = {g_digestInfoTempl, sizeof(g_digestInfoTempl) / sizeof(g_digestInfoTempl[0])};
103     int32_t ret = BSL_ASN1_DecodeTemplate(&templ, NULL, &temp, &tempLen, asn1, HITLS_P7_DIGESTINFO_MAX_IDX);
104     if (ret != BSL_SUCCESS) {
105         BSL_ERR_PUSH_ERROR(ret);
106         return ret;
107     }
108     BslOidString oidStr = {asn1[HITLS_P7_DIGESTINFO_OID_IDX].len, (char *)asn1[HITLS_P7_DIGESTINFO_OID_IDX].buff, 0};
109     BslCid parseCid = BSL_OBJ_GetCID(&oidStr);
110     if (parseCid == BSL_CID_UNKNOWN) {
111         BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_PARSE_TYPE);
112         return HITLS_CMS_ERR_PARSE_TYPE;
113     }
114     if (asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].len == 0) {
115         BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_INVALID_DATA);
116         return HITLS_CMS_ERR_INVALID_DATA;
117     }
118     uint8_t *output = BSL_SAL_Dump(asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].buff,
119         asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].len);
120     if (output == NULL) {
121         BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
122         return BSL_DUMP_FAIL;
123     }
124     digest->data = output;
125     digest->dataLen = asn1[HITLS_P7_DIGESTINFO_OCTSTRING_IDX].len;
126     *cid = parseCid;
127     return HITLS_PKI_SUCCESS;
128 }
129 
130 #ifdef HITLS_PKI_PKCS12_GEN
HITLS_CMS_EncodeDigestInfoBuff(BslCid cid,BSL_Buffer * in,BSL_Buffer * encode)131 int32_t HITLS_CMS_EncodeDigestInfoBuff(BslCid cid, BSL_Buffer *in, BSL_Buffer *encode)
132 {
133     if (in == NULL || encode == NULL || encode->data != NULL || (in->data == NULL && in->dataLen != 0)) {
134         BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_NULL_POINTER);
135         return HITLS_CMS_ERR_NULL_POINTER;
136     }
137 
138     BslOidString *oidstr = BSL_OBJ_GetOID(cid);
139     if (oidstr == NULL) {
140         BSL_ERR_PUSH_ERROR(HITLS_CMS_ERR_INVALID_ALGO);
141         return HITLS_CMS_ERR_INVALID_ALGO;
142     }
143     BSL_ASN1_Buffer asn1[HITLS_P7_DIGESTINFO_MAX_IDX] = {
144         {BSL_ASN1_TAG_OBJECT_ID, oidstr->octetLen, (uint8_t *)oidstr->octs},
145         {BSL_ASN1_TAG_NULL, 0, NULL},
146         {BSL_ASN1_TAG_OCTETSTRING, in->dataLen, in->data},
147     };
148     BSL_Buffer tmp = {0};
149     BSL_ASN1_Template templ = {g_digestInfoTempl, sizeof(g_digestInfoTempl) / sizeof(g_digestInfoTempl[0])};
150     int32_t ret = BSL_ASN1_EncodeTemplate(&templ, asn1, HITLS_P7_DIGESTINFO_MAX_IDX, &tmp.data, &tmp.dataLen);
151     if (ret != BSL_SUCCESS) {
152         BSL_ERR_PUSH_ERROR(ret);
153         return ret;
154     }
155     encode->data = tmp.data;
156     encode->dataLen = tmp.dataLen;
157     return HITLS_PKI_SUCCESS;
158 }
159 #endif
160 #endif // HITLS_PKI_PKCS12
161