• 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 "bsl_sal.h"
20 #include "bsl_types.h"
21 #include "bsl_err_internal.h"
22 #include "hitls_x509_adapt.h"
23 #include "crypt_eal_codecs.h"
24 #include "crypt_errno.h"
25 #include "hitls_cert.h"
26 #include "hitls_cert_type.h"
27 #include "hitls_error.h"
28 #include "hitls_type.h"
29 #include "crypt_eal_pkey.h"
30 #include "hitls_crypt_type.h"
31 #include "config_type.h"
32 #include "tls_config.h"
33 #include "cert_mgr_ctx.h"
34 
GetPassByCb(HITLS_PasswordCb passWordCb,void * passWordCbUserData,char * pass,int32_t * passLen)35 static int32_t GetPassByCb(HITLS_PasswordCb passWordCb, void *passWordCbUserData, char *pass, int32_t *passLen)
36 {
37     if (pass == NULL || passLen == NULL) {
38         BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
39         return HITLS_NULL_INPUT;
40     }
41     int32_t len = 0;
42     if (passWordCb != NULL) {
43         len = passWordCb(pass, *passLen, 0, passWordCbUserData);
44         if (len < 0) {
45             BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_ERR);
46             return HITLS_CERT_SELF_ADAPT_ERR;
47         }
48     } else {
49         if (passWordCbUserData != NULL) {
50             uint32_t userDataLen = BSL_SAL_Strnlen((const char *)passWordCbUserData, *passLen);
51             if (userDataLen == 0 || userDataLen == (uint32_t)*passLen) {
52                 BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_ERR);
53                 return HITLS_CERT_SELF_ADAPT_ERR;
54             }
55             (void)memcpy_s(pass, *passLen, (char *)passWordCbUserData, userDataLen + 1);
56             len = userDataLen;
57         }
58     }
59 
60     *passLen = len;
61     return HITLS_SUCCESS;
62 }
63 
GetPrivKeyPassword(HITLS_Config * config,uint8_t * pwd,int32_t * pwdLen)64 static int32_t GetPrivKeyPassword(HITLS_Config *config, uint8_t *pwd, int32_t *pwdLen)
65 {
66     HITLS_PasswordCb pwCb = HITLS_CFG_GetDefaultPasswordCb(config);
67     void *userData = HITLS_CFG_GetDefaultPasswordCbUserdata(config);
68     int32_t len = *pwdLen;
69     int32_t ret = GetPassByCb(pwCb, userData, (char *)pwd, pwdLen);
70     if (ret != HITLS_SUCCESS) {
71         BSL_ERR_PUSH_ERROR(ret);
72         (void)memset_s(pwd, len, 0, len);
73     }
74     return ret;
75 }
76 
77 #ifdef HITLS_TLS_FEATURE_PROVIDER
HITLS_X509_Adapt_ProviderKeyParse(HITLS_Config * config,const uint8_t * buf,uint32_t len,HITLS_ParseType type,const char * format,const char * encodeType)78 HITLS_CERT_Key *HITLS_X509_Adapt_ProviderKeyParse(HITLS_Config *config, const uint8_t *buf, uint32_t len,
79     HITLS_ParseType type, const char *format, const char *encodeType)
80 {
81     HITLS_Lib_Ctx *libCtx = LIBCTX_FROM_CONFIG(config);
82     const char *attrName = ATTRIBUTE_FROM_CONFIG(config);
83     int32_t ret;
84     BSL_Buffer encode = {0};
85     HITLS_CERT_Key *ealPriKey = NULL;
86     uint8_t pwd[MAX_PASS_LEN] = { 0 };
87     BSL_Buffer pwdBuff = {pwd, sizeof(pwd)};
88     (void)GetPrivKeyPassword(config, pwdBuff.data, (int32_t *)&pwdBuff.dataLen);
89     switch (type) {
90         case TLS_PARSE_TYPE_FILE:
91             ret = CRYPT_EAL_ProviderDecodeFileKey(libCtx, attrName, BSL_CID_UNKNOWN, format, encodeType,
92                 (const char *)buf, &pwdBuff, (CRYPT_EAL_PkeyCtx **)&ealPriKey);
93             break;
94         case TLS_PARSE_TYPE_BUFF:
95             encode.data = (uint8_t *)(uintptr_t)buf;
96             encode.dataLen = len;
97             ret = CRYPT_EAL_ProviderDecodeBuffKey(libCtx, attrName, BSL_CID_UNKNOWN, format, encodeType,
98                 &encode, &pwdBuff, (CRYPT_EAL_PkeyCtx **)&ealPriKey);
99             break;
100         default:
101             BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_UNSUPPORT_FORMAT);
102             (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN);
103             return NULL;
104     }
105     if (ret != HITLS_SUCCESS) {
106         BSL_ERR_PUSH_ERROR(ret);
107     }
108     (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN);
109     return ealPriKey;
110 }
111 
112 #else
HITLS_X509_Adapt_KeyParse(HITLS_Config * config,const uint8_t * buf,uint32_t len,HITLS_ParseType type,HITLS_ParseFormat format)113 HITLS_CERT_Key *HITLS_X509_Adapt_KeyParse(HITLS_Config *config, const uint8_t *buf, uint32_t len,
114     HITLS_ParseType type, HITLS_ParseFormat format)
115 {
116     (void)config;
117     int32_t ret;
118     BSL_Buffer encode = {0};
119     HITLS_CERT_Key *ealPriKey = NULL;
120     uint8_t pwd[MAX_PASS_LEN] = { 0 };
121     int32_t pwdLen = (int32_t)sizeof(pwd);
122     (void)GetPrivKeyPassword(config, pwd, &pwdLen);
123     switch (type) {
124         case TLS_PARSE_TYPE_FILE:
125             ret = CRYPT_EAL_DecodeFileKey(format, CRYPT_ENCDEC_UNKNOW, (const char *)buf, pwd, pwdLen,
126                 (CRYPT_EAL_PkeyCtx **)&ealPriKey);
127             break;
128         case TLS_PARSE_TYPE_BUFF:
129             encode.data = (uint8_t *)(uintptr_t)buf;
130             encode.dataLen = len;
131             ret = CRYPT_EAL_DecodeBuffKey(format, CRYPT_ENCDEC_UNKNOW, &encode, pwd, pwdLen,
132                 (CRYPT_EAL_PkeyCtx **)&ealPriKey);
133             break;
134         default:
135             BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_UNSUPPORT_FORMAT);
136             (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN);
137             return NULL;
138     }
139     if (ret != HITLS_SUCCESS) {
140         BSL_ERR_PUSH_ERROR(ret);
141     }
142     (void)memset_s(pwd, MAX_PASS_LEN, 0, MAX_PASS_LEN);
143     return ealPriKey;
144 }
145 #endif
146 
HITLS_X509_Adapt_KeyDup(HITLS_CERT_Key * key)147 HITLS_CERT_Key *HITLS_X509_Adapt_KeyDup(HITLS_CERT_Key *key)
148 {
149     return (HITLS_CERT_Key *)CRYPT_EAL_PkeyDupCtx(key);
150 }
151 
HITLS_X509_Adapt_KeyFree(HITLS_CERT_Key * key)152 void HITLS_X509_Adapt_KeyFree(HITLS_CERT_Key *key)
153 {
154     CRYPT_EAL_PkeyFreeCtx(key);
155 }
156 
GetCurveNameByKey(HITLS_Config * config,const CRYPT_EAL_PkeyCtx * key)157 static HITLS_NamedGroup GetCurveNameByKey(HITLS_Config *config, const CRYPT_EAL_PkeyCtx *key)
158 {
159     CRYPT_PKEY_ParaId paraId = CRYPT_EAL_PkeyGetParaId(key);
160     if (paraId == CRYPT_PKEY_PARAID_MAX) {
161         return HITLS_NAMED_GROUP_BUTT;
162     }
163     uint32_t size = 0;
164     const TLS_GroupInfo *groupInfoList = ConfigGetGroupInfoList(config, &size);
165     for (size_t i = 0; i < size; i++) {
166         if (groupInfoList[i].paraId == (int32_t)paraId) {
167             return groupInfoList[i].groupId;
168         }
169     }
170     return HITLS_NAMED_GROUP_BUTT;
171 }
172 
CertKeyAlgId2KeyType(CRYPT_EAL_PkeyCtx * pkey)173 static HITLS_CERT_KeyType CertKeyAlgId2KeyType(CRYPT_EAL_PkeyCtx *pkey)
174 {
175     CRYPT_PKEY_AlgId cid = CRYPT_EAL_PkeyGetId(pkey);
176     if (cid == CRYPT_PKEY_RSA) {
177         CRYPT_RsaPadType padType = 0;
178         if (CRYPT_EAL_PkeyCtrl(pkey, CRYPT_CTRL_GET_RSA_PADDING, &padType, sizeof(CRYPT_RsaPadType)) != CRYPT_SUCCESS) {
179             return TLS_CERT_KEY_TYPE_UNKNOWN;
180         }
181         if (padType == CRYPT_EMSA_PSS) {
182             return TLS_CERT_KEY_TYPE_RSA_PSS;
183         }
184     }
185     return (HITLS_CERT_KeyType)cid;
186 }
187 
HITLS_X509_Adapt_KeyCtrl(HITLS_Config * config,HITLS_CERT_Key * key,HITLS_CERT_CtrlCmd cmd,void * input,void * output)188 int32_t HITLS_X509_Adapt_KeyCtrl(HITLS_Config *config, HITLS_CERT_Key *key, HITLS_CERT_CtrlCmd cmd,
189     void *input, void *output)
190 {
191     (void)input;
192     int32_t ret = HITLS_SUCCESS;
193     switch (cmd) {
194         case CERT_KEY_CTRL_GET_SIGN_LEN:
195             *(uint32_t *)output = CRYPT_EAL_PkeyGetSignLen((const CRYPT_EAL_PkeyCtx *)key);
196             break;
197         case CERT_KEY_CTRL_GET_TYPE:
198             *(HITLS_CERT_KeyType *)output = CertKeyAlgId2KeyType(key);
199             break;
200         case CERT_KEY_CTRL_GET_CURVE_NAME:
201             *(HITLS_NamedGroup *)output = GetCurveNameByKey(config, key);
202             break;
203         case CERT_KEY_CTRL_GET_POINT_FORMAT:
204             /* Currently only uncompressed is used */
205             *(HITLS_ECPointFormat *)output = HITLS_POINT_FORMAT_UNCOMPRESSED;
206             break;
207         case CERT_KEY_CTRL_GET_SECBITS:
208             *(int32_t *)output = CRYPT_EAL_PkeyGetSecurityBits(key);
209             break;
210         case CERT_KEY_CTRL_GET_PARAM_ID:
211             *(int32_t *)output = CRYPT_EAL_PkeyGetParaId(key);
212             break;
213         default:
214             BSL_ERR_PUSH_ERROR(HITLS_CERT_SELF_ADAPT_ERR);
215             ret = HITLS_CERT_SELF_ADAPT_ERR;
216             break;
217     }
218 
219     return ret;
220 }
221 
222 #endif /* defined(HITLS_TLS_CALLBACK_CERT) || defined(HITLS_TLS_FEATURE_PROVIDER) */
223