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_HOST_SERVER) || defined(HITLS_TLS_PROTO_TLS13)
17 #include "tls_binlog_id.h"
18 #include "bsl_log.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_err_internal.h"
21 #include "bsl_sal.h"
22 #include "bsl_bytes.h"
23 #include "crypt_algid.h"
24 #include "hitls_error.h"
25 #include "cert_method.h"
26 #include "hs_msg.h"
27 #include "hs_ctx.h"
28 #include "hs_verify.h"
29 #include "parse_msg.h"
30 #include "parse_common.h"
31 #include "config_type.h"
32
CheckSignHashAlg(TLS_Ctx * ctx,uint16_t signHashAlg)33 static int32_t CheckSignHashAlg(TLS_Ctx *ctx, uint16_t signHashAlg)
34 {
35 int32_t ret = CheckPeerSignScheme(ctx, ctx->hsCtx->peerCert, signHashAlg);
36 if (ret != HITLS_SUCCESS) {
37 return ParseErrorProcess(ctx, ret, 0, NULL, ALERT_ILLEGAL_PARAMETER);
38 }
39
40 TLS_Config *config = &ctx->config.tlsConfig;
41 #ifdef HITLS_TLS_PROTO_TLS13
42 if (ctx->negotiatedInfo.version == HITLS_VERSION_TLS13) {
43 const TLS_SigSchemeInfo *schemeInfo = ConfigGetSignatureSchemeInfo(config, signHashAlg);
44 if (schemeInfo == NULL || ((schemeInfo->certVersionBits & TLS13_VERSION_BIT) == 0)) {
45 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16195, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
46 "not allowed to use 0x%X signAlg tls1.3.", signHashAlg, 0, 0, 0);
47 return ParseErrorProcess(ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_HANDSHAKE_FAILURE);
48 }
49 }
50 #endif /* HITLS_TLS_PROTO_TLS13 */
51 uint32_t i = 0;
52 for (i = 0; i < config->signAlgorithmsSize; i++) {
53 if (signHashAlg == config->signAlgorithms[i]) {
54 break;
55 }
56 }
57
58 if (i == config->signAlgorithmsSize) {
59 return ParseErrorProcess(ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, BINLOG_ID15865,
60 BINGLOG_STR("the signHashAlg match failed"), ALERT_HANDSHAKE_FAILURE);
61 }
62
63 #ifdef HITLS_TLS_FEATURE_SECURITY
64 if (SECURITY_SslCheck(ctx, HITLS_SECURITY_SECOP_SIGALG_CHECK, 0, signHashAlg, NULL) != SECURITY_SUCCESS) {
65 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17159, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
66 "signHashAlg 0x%x SslCheck fail", signHashAlg, 0, 0, 0);
67 return ParseErrorProcess(ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_HANDSHAKE_FAILURE);
68 }
69 #endif
70
71 return HITLS_SUCCESS;
72 }
73
ParseCertificateVerifyPre(ParsePacket * pkt,uint16_t * signHashAlg)74 static int32_t ParseCertificateVerifyPre(ParsePacket *pkt, uint16_t *signHashAlg)
75 {
76 const char *logStr = BINGLOG_STR("parse cert verifypre fail");
77 /* 2-byte signature hash algorithm + 2-byte signature data length.
78 If the message length is less than 4 bytes, a failure message is returned. */
79 if (pkt->bufLen < 4u) {
80 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16964, logStr, ALERT_DECODE_ERROR);
81 }
82 if (pkt->ctx->negotiatedInfo.version >= HITLS_VERSION_TLS12) {
83 int32_t ret = ParseBytesToUint16(pkt, signHashAlg);
84 if (ret != HITLS_SUCCESS) {
85 return ParseErrorProcess(pkt->ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16965, logStr, ALERT_DECODE_ERROR);
86 }
87
88 if (CheckSignHashAlg(pkt->ctx, *signHashAlg) != HITLS_SUCCESS) {
89 BSL_ERR_PUSH_ERROR(HITLS_PARSE_UNSUPPORT_SIGN_ALG);
90 return HITLS_PARSE_UNSUPPORT_SIGN_ALG;
91 }
92 }
93 return HITLS_SUCCESS;
94 }
95
KeyMatchSignAlg(TLS_Ctx * ctx,HITLS_SignHashAlgo signScheme,HITLS_CERT_KeyType keyType,HITLS_CERT_Key * key)96 static int32_t KeyMatchSignAlg(TLS_Ctx *ctx, HITLS_SignHashAlgo signScheme, HITLS_CERT_KeyType keyType,
97 HITLS_CERT_Key *key)
98 {
99 (void)key;
100 HITLS_CERT_KeyType certKeyType = SAL_CERT_SignScheme2CertKeyType(ctx, signScheme);
101 if (certKeyType != keyType) {
102 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16197, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
103 "signScheme not matche key, signScheme is 0x%X, certKeyType is %u, keyType is %u", signScheme, certKeyType,
104 keyType, 0);
105 return ParseErrorProcess(ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_ILLEGAL_PARAMETER);
106 }
107
108 /* check curve matches signature algorithm, only check ec key for tls1.3 */
109 if (ctx->negotiatedInfo.version != HITLS_VERSION_TLS13) {
110 return HITLS_SUCCESS;
111 }
112 #ifdef HITLS_TLS_PROTO_TLS13
113 HITLS_Config *config = &ctx->config.tlsConfig;
114 const TLS_SigSchemeInfo *schemeInfo = ConfigGetSignatureSchemeInfo(config, signScheme);
115 if (schemeInfo == NULL) {
116 return ParseErrorProcess(ctx, HITLS_PARSE_UNSUPPORT_SIGN_ALG, 0, NULL, ALERT_ILLEGAL_PARAMETER);
117 }
118 if (schemeInfo->paraId == CRYPT_PKEY_PARAID_MAX) {
119 return HITLS_SUCCESS;
120 }
121 int32_t paramId = CRYPT_PKEY_PARAID_MAX;
122 int32_t ret = SAL_CERT_KeyCtrl(config, key, CERT_KEY_CTRL_GET_PARAM_ID, NULL, (void *)¶mId);
123 if (ret != HITLS_SUCCESS || paramId != schemeInfo->paraId) {
124 return ParseErrorProcess(ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16198,
125 BINGLOG_STR("paramId mismatch sigScheme"), ALERT_INTERNAL_ERROR);
126 }
127 #endif /* HITLS_TLS_PROTO_TLS13 */
128 return HITLS_SUCCESS;
129 }
130
VerifySignData(TLS_Ctx * ctx,uint16_t signHashAlg,const uint8_t * sign,uint16_t signSize)131 static int VerifySignData(TLS_Ctx *ctx, uint16_t signHashAlg, const uint8_t *sign, uint16_t signSize)
132 {
133 CERT_MgrCtx *mgrCtx = ctx->config.tlsConfig.certMgrCtx;
134 if (ctx->hsCtx == NULL || ctx->hsCtx->peerCert == NULL) {
135 return ParseErrorProcess(ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, BINLOG_ID15866,
136 BINGLOG_STR("no peer certificate"), ALERT_CERTIFICATE_REQUIRED);
137 }
138
139 HITLS_CERT_X509 *cert = SAL_CERT_PairGetX509(ctx->hsCtx->peerCert);
140 HITLS_CERT_Key *pubkey = NULL;
141 int32_t ret = SAL_CERT_X509Ctrl(&ctx->config.tlsConfig, cert, CERT_CTRL_GET_PUB_KEY, NULL, (void *)&pubkey);
142 if (ret != HITLS_SUCCESS) {
143 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16966, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
144 "GET_PUB_KEY fail", 0, 0, 0, 0);
145 ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
146 return ret;
147 }
148
149 HITLS_SignHashAlgo signScheme = signHashAlg;
150 HITLS_CERT_KeyType keyType = TLS_CERT_KEY_TYPE_UNKNOWN;
151 ret = SAL_CERT_KeyCtrl(&ctx->config.tlsConfig, pubkey, CERT_KEY_CTRL_GET_TYPE, NULL, (void *)&keyType);
152 if (ret != HITLS_SUCCESS) {
153 SAL_CERT_KeyFree(mgrCtx, pubkey);
154 return ParseErrorProcess(ctx, ret, BINLOG_ID16072,
155 BINGLOG_STR("SAL_CERT_KeyCtrl fails"), ALERT_INTERNAL_ERROR);
156 }
157
158 if (signScheme == 0) {
159 /** If the value of the signature hash algorithm is 0, the peer does not send the signature algorithm.
160 In this case, we need to obtain the default signature algorithm through the certificate. */
161 signScheme = SAL_CERT_GetDefaultSignHashAlgo(keyType);
162 if (signScheme == CERT_SIG_SCHEME_UNKNOWN) {
163 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16073, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
164 "no available signature scheme, key type = %u.", keyType, 0, 0, 0);
165 SAL_CERT_KeyFree(mgrCtx, pubkey);
166 return ParseErrorProcess(ctx, HITLS_PARSE_VERIFY_SIGN_FAIL, 0, NULL, ALERT_INTERNAL_ERROR);
167 }
168 }
169
170 /* check whether the signature scheme matches the certificate key */
171 if (KeyMatchSignAlg(ctx, signScheme, keyType, pubkey) != HITLS_SUCCESS) {
172 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16967, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
173 "KeyMatchSignAlg fail", 0, 0, 0, 0);
174 SAL_CERT_KeyFree(mgrCtx, pubkey);
175 return HITLS_PARSE_VERIFY_SIGN_FAIL;
176 }
177
178 /** verifying certificate data */
179 ret = VERIFY_VerifySignData(ctx, pubkey, signScheme, sign, signSize);
180 SAL_CERT_KeyFree(mgrCtx, pubkey);
181 return ret;
182 }
183
ParseCertificateVerify(TLS_Ctx * ctx,const uint8_t * buf,uint32_t bufLen,HS_Msg * hsMsg)184 int32_t ParseCertificateVerify(TLS_Ctx *ctx, const uint8_t *buf, uint32_t bufLen, HS_Msg *hsMsg)
185 {
186 uint16_t signHashAlg = 0;
187 uint32_t offset = 0;
188 ParsePacket pkt = {.ctx = ctx, .buf = buf, .bufLen = bufLen, .bufOffset = &offset};
189
190 int32_t ret = ParseCertificateVerifyPre(&pkt, &signHashAlg);
191 if (ret != HITLS_SUCCESS) {
192 return ret;
193 }
194 const char *logStr = BINGLOG_STR("parse cert verify fail");
195 uint16_t signSize = 0;
196 ret = ParseBytesToUint16(&pkt, &signSize);
197 if (ret != HITLS_SUCCESS) {
198 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16968, logStr, ALERT_DECODE_ERROR);
199 }
200
201 if ((signSize != (pkt.bufLen - *pkt.bufOffset)) || (signSize == 0)) {
202 return ParseErrorProcess(pkt.ctx, HITLS_PARSE_INVALID_MSG_LEN, BINLOG_ID16969, logStr, ALERT_DECODE_ERROR);
203 }
204
205 const uint8_t *sign = &pkt.buf[*pkt.bufOffset];
206
207 ret = VerifySignData(pkt.ctx, signHashAlg, sign, signSize);
208 if (ret != HITLS_SUCCESS) {
209 return ret;
210 }
211
212 CertificateVerifyMsg *msg = &hsMsg->body.certificateVerify;
213 msg->signHashAlg = signHashAlg;
214 msg->signSize = signSize;
215 BSL_SAL_FREE(msg->sign);
216 msg->sign = BSL_SAL_Dump(sign, signSize);
217 if (msg->sign == NULL) {
218 return ParseErrorProcess(pkt.ctx, HITLS_MEMALLOC_FAIL, BINLOG_ID16970,
219 BINGLOG_STR("Dump fail"), ALERT_INTERNAL_ERROR);
220 }
221 pkt.ctx->peerInfo.peerSignHashAlg = signHashAlg;
222 return HITLS_SUCCESS;
223 }
224
CleanCertificateVerify(CertificateVerifyMsg * msg)225 void CleanCertificateVerify(CertificateVerifyMsg *msg)
226 {
227 if (msg == NULL) {
228 return;
229 }
230
231 BSL_SAL_FREE(msg->sign);
232
233 return;
234 }
235 #endif /* HITLS_TLS_HOST_CLIENT || HITLS_TLS_PROTO_TLS13 */