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