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 #include "hitls_build.h"
16 #if defined(HITLS_TLS_CALLBACK_CERT) || defined(HITLS_TLS_FEATURE_PROVIDER)
17 #include <stdint.h>
18 #include "securec.h"
19 #include "crypt_eal_pkey.h"
20 #include "hitls_error.h"
21 #include "hitls_cert_type.h"
22 #include "hitls_type.h"
23 #include "hitls_pki_cert.h"
24 #include "hitls_error.h"
25 #include "bsl_err_internal.h"
26 #include "tls_config.h"
27 #include "cert_mgr_ctx.h"
28 #include "config_type.h"
29
HITLS_X509_Adapt_CertEncode(HITLS_Ctx * ctx,HITLS_CERT_X509 * cert,uint8_t * buf,uint32_t len,uint32_t * usedLen)30 int32_t HITLS_X509_Adapt_CertEncode(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert, uint8_t *buf, uint32_t len,
31 uint32_t *usedLen)
32 {
33 (void)ctx;
34 *usedLen = 0;
35 uint32_t encodeLen = 0;
36 int32_t ret = HITLS_X509_CertCtrl((HITLS_X509_Cert *)cert, HITLS_X509_GET_ENCODELEN, &encodeLen,
37 (int32_t)sizeof(uint32_t));
38 if (ret != HITLS_SUCCESS) {
39 BSL_ERR_PUSH_ERROR(ret);
40 return ret;
41 }
42 if (len < encodeLen) {
43 BSL_ERR_PUSH_ERROR(HITLS_INVALID_INPUT);
44 return HITLS_INVALID_INPUT;
45 }
46 uint8_t *encodedBuff = NULL;
47 ret = HITLS_X509_CertCtrl((HITLS_X509_Cert *)cert, HITLS_X509_GET_ENCODE, (void *)&encodedBuff, 0);
48 if (ret != HITLS_SUCCESS) {
49 return ret;
50 }
51
52 (void)memcpy_s(buf, len, encodedBuff, encodeLen);
53 *usedLen = encodeLen;
54 return ret;
55 }
56
57 #ifdef HITLS_TLS_FEATURE_PROVIDER
HITLS_CERT_ProviderCertParse(HITLS_Lib_Ctx * libCtx,const char * attrName,const uint8_t * buf,uint32_t len,HITLS_ParseType type,const char * format)58 HITLS_CERT_X509 *HITLS_CERT_ProviderCertParse(HITLS_Lib_Ctx *libCtx, const char *attrName, const uint8_t *buf,
59 uint32_t len, HITLS_ParseType type, const char *format)
60 {
61 BSL_Buffer encodedCert = { NULL, 0 };
62 int ret;
63 HITLS_X509_Cert *cert = NULL;
64 switch (type) {
65 case TLS_PARSE_TYPE_FILE:
66 ret = HITLS_X509_ProviderCertParseFile(libCtx, attrName, format, (const char *)buf, &cert);
67 break;
68 case TLS_PARSE_TYPE_BUFF:
69 encodedCert.data = (uint8_t *)(uintptr_t)buf;
70 encodedCert.dataLen = len;
71 ret = HITLS_X509_ProviderCertParseBuff(libCtx, attrName, format, &encodedCert, &cert);
72 break;
73 default:
74 BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_UNSUPPORT_FORMAT);
75 ret = HITLS_CERT_SELF_ADAPT_UNSUPPORT_FORMAT;
76 break;
77 }
78 if (ret != HITLS_SUCCESS) {
79 BSL_ERR_PUSH_ERROR(ret);
80 return NULL;
81 }
82
83 return cert;
84 }
85 #else
HITLS_X509_Adapt_CertParse(HITLS_Config * config,const uint8_t * buf,uint32_t len,HITLS_ParseType type,HITLS_ParseFormat format)86 HITLS_CERT_X509 *HITLS_X509_Adapt_CertParse(HITLS_Config *config, const uint8_t *buf, uint32_t len,
87 HITLS_ParseType type, HITLS_ParseFormat format)
88 {
89 (void)config;
90 BSL_Buffer encodedCert = { NULL, 0 };
91 int ret;
92 HITLS_X509_Cert *cert = NULL;
93 switch (type) {
94 case TLS_PARSE_TYPE_FILE:
95 ret = HITLS_X509_CertParseFile(format, (const char *)buf, &cert);
96 break;
97 case TLS_PARSE_TYPE_BUFF:
98 encodedCert.data = (uint8_t *)(uintptr_t)buf;
99 encodedCert.dataLen = len;
100 ret = HITLS_X509_CertParseBuff(format, &encodedCert, &cert);
101 break;
102 default:
103 BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_UNSUPPORT_FORMAT);
104 ret = HITLS_CERT_SELF_ADAPT_UNSUPPORT_FORMAT;
105 break;
106 }
107 if (ret != HITLS_SUCCESS) {
108 BSL_ERR_PUSH_ERROR(ret);
109 return NULL;
110 }
111
112 return cert;
113 }
114 #endif
115
HITLS_X509_Adapt_CertDup(HITLS_CERT_X509 * cert)116 HITLS_CERT_X509 *HITLS_X509_Adapt_CertDup(HITLS_CERT_X509 *cert)
117 {
118 return HITLS_X509_CertDup(cert);
119 }
120
HITLS_X509_Adapt_CertFree(HITLS_CERT_X509 * cert)121 void HITLS_X509_Adapt_CertFree(HITLS_CERT_X509 *cert)
122 {
123 HITLS_X509_CertFree(cert);
124 }
125
HITLS_X509_Adapt_CertRef(HITLS_CERT_X509 * cert)126 HITLS_CERT_X509 *HITLS_X509_Adapt_CertRef(HITLS_CERT_X509 *cert)
127 {
128 int ref = 0;
129 int ret = HITLS_X509_CertCtrl(cert, HITLS_X509_REF_UP, (void *)&ref, (int32_t)sizeof(int));
130 if (ret != HITLS_SUCCESS) {
131 BSL_ERR_PUSH_ERROR(ret);
132 return NULL;
133 }
134 return cert;
135 }
136
BslCid2SignHashAlgo(HITLS_Config * config,BslCid signAlgId,BslCid hashAlgId)137 static HITLS_SignHashAlgo BslCid2SignHashAlgo(HITLS_Config *config, BslCid signAlgId, BslCid hashAlgId)
138 {
139 uint32_t size = 0;
140 const TLS_SigSchemeInfo *sigSchemeInfoList = ConfigGetSignatureSchemeInfoList(config, &size);
141 for (size_t i = 0; i < size; i++) {
142 if (sigSchemeInfoList[i].signHashAlgId == (int32_t)signAlgId &&
143 sigSchemeInfoList[i].hashAlgId == (int32_t)hashAlgId) {
144 return sigSchemeInfoList[i].signatureScheme;
145 }
146 }
147
148 return CERT_SIG_SCHEME_UNKNOWN;
149 }
150
CertCtrlGetSignAlgo(HITLS_Config * config,HITLS_CERT_X509 * cert,HITLS_SignHashAlgo * algSign)151 static int32_t CertCtrlGetSignAlgo(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_SignHashAlgo *algSign)
152 {
153 BslCid signAlgCid = 0;
154 BslCid hashCid = 0;
155 *algSign = CERT_SIG_SCHEME_UNKNOWN;
156 int32_t ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SIGNALG, &signAlgCid, sizeof(BslCid));
157 if (ret != HITLS_SUCCESS) {
158 BSL_ERR_PUSH_ERROR(ret);
159 return ret;
160 }
161 ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SIGN_MDALG, &hashCid, sizeof(BslCid));
162 if (ret != HITLS_SUCCESS) {
163 BSL_ERR_PUSH_ERROR(ret);
164 return ret;
165 }
166 *algSign = BslCid2SignHashAlgo(config, signAlgCid, hashCid);
167 return HITLS_SUCCESS;
168 }
169
CertCheckKeyUsage(HITLS_Config * config,HITLS_CERT_X509 * cert,uint32_t inKeyUsage,bool * res)170 static int32_t CertCheckKeyUsage(HITLS_Config *config, HITLS_CERT_X509 *cert, uint32_t inKeyUsage, bool *res)
171 {
172 uint32_t keyUsage = 0;
173 int32_t ret = HITLS_X509_CertCtrl(cert, HITLS_X509_EXT_GET_KUSAGE, &keyUsage, sizeof(uint32_t));
174 if (ret != HITLS_SUCCESS) {
175 BSL_ERR_PUSH_ERROR(ret);
176 return ret;
177 }
178 if (keyUsage == HITLS_X509_EXT_KU_NONE) {
179 #ifdef HITLS_TLS_PROTO_TLCP11
180 // Key usage must be present, otherwise the chain is broken.
181 if (config == NULL) {
182 return HITLS_INVALID_INPUT;
183 }
184 if (config->maxVersion == HITLS_VERSION_TLCP_DTLCP11) {
185 BSL_ERR_PUSH_ERROR(HITLS_CERT_ERR_NO_KEYUSAGE);
186 return HITLS_CERT_ERR_NO_KEYUSAGE;
187 }
188 #endif
189 *res = true;
190 return HITLS_SUCCESS;
191 }
192 *res = (keyUsage & inKeyUsage) != 0;
193 return HITLS_SUCCESS;
194 }
195
HITLS_X509_Adapt_CertCtrl(HITLS_Config * config,HITLS_CERT_X509 * cert,HITLS_CERT_CtrlCmd cmd,void * input,void * output)196 int32_t HITLS_X509_Adapt_CertCtrl(HITLS_Config *config, HITLS_CERT_X509 *cert, HITLS_CERT_CtrlCmd cmd,
197 void *input, void *output)
198 {
199 (void)input;
200 int32_t ret = HITLS_SUCCESS;
201 switch (cmd) {
202 case CERT_CTRL_GET_ENCODE_LEN:
203 ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ENCODELEN, output, (uint32_t)sizeof(int32_t));
204 break;
205 case CERT_CTRL_GET_PUB_KEY:
206 ret = HITLS_X509_CertCtrl(cert, HITLS_X509_GET_PUBKEY, output, (uint32_t)sizeof(CRYPT_EAL_PkeyPub *));
207 break;
208 case CERT_CTRL_GET_SIGN_ALGO:
209 return CertCtrlGetSignAlgo(config, cert, (HITLS_SignHashAlgo *)output);
210 #ifdef HITLS_TLS_CONFIG_KEY_USAGE
211 case CERT_KEY_CTRL_IS_KEYENC_USAGE:
212 return CertCheckKeyUsage(config, cert, HITLS_X509_EXT_KU_KEY_ENCIPHERMENT, (bool *)output);
213 case CERT_KEY_CTRL_IS_DIGITAL_SIGN_USAGE:
214 return CertCheckKeyUsage(config, cert, HITLS_X509_EXT_KU_DIGITAL_SIGN, (bool *)output);
215 case CERT_KEY_CTRL_IS_KEY_CERT_SIGN_USAGE:
216 return CertCheckKeyUsage(config, cert, HITLS_X509_EXT_KU_KEY_CERT_SIGN, (bool *)output);
217 case CERT_KEY_CTRL_IS_KEY_AGREEMENT_USAGE:
218 return CertCheckKeyUsage(config, cert, HITLS_X509_EXT_KU_KEY_AGREEMENT, (bool *)output);
219 case CERT_KEY_CTRL_IS_DATA_ENC_USAGE:
220 return CertCheckKeyUsage(config, cert, HITLS_X509_EXT_KU_DATA_ENCIPHERMENT, (bool *)output);
221 case CERT_KEY_CTRL_IS_NON_REPUDIATION_USAGE:
222 return CertCheckKeyUsage(config, cert, HITLS_X509_EXT_KU_NON_REPUDIATION, (bool *)output);
223 #endif
224 default:
225 BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_ERR);
226 return HITLS_CERT_SELF_ADAPT_ERR;
227 }
228 if (ret != HITLS_SUCCESS) {
229 BSL_ERR_PUSH_ERROR(ret);
230 }
231
232 return ret;
233 }
234 #endif /* defined(HITLS_TLS_CALLBACK_CERT) || defined(HITLS_TLS_FEATURE_PROVIDER) */
235