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