• 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 
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_CODECSKEY) && defined(HITLS_CRYPTO_PROVIDER)
18 #include "crypt_eal_implprovider.h"
19 #include "crypt_eal_pkey.h"
20 #include "crypt_provider.h"
21 #include "crypt_params_key.h"
22 #include "crypt_types.h"
23 #include "crypt_errno.h"
24 #include "crypt_utils.h"
25 #include "eal_pkey.h"
26 #include "crypt_decode_key_impl.h"
27 #include "bsl_err_internal.h"
28 
29 typedef struct {
30     CRYPT_EAL_LibCtx *libCtx;
31     const char *targetAttrName;
32     const char *outFormat;
33     const char *outType;
34 } DECODER_Lowkey2PkeyCtx;
35 
DECODER_LowKeyObject2PkeyObjectNewCtx(void * provCtx)36 void *DECODER_LowKeyObject2PkeyObjectNewCtx(void *provCtx)
37 {
38     (void)provCtx;
39     DECODER_Lowkey2PkeyCtx *ctx = (DECODER_Lowkey2PkeyCtx *)BSL_SAL_Calloc(1, sizeof(DECODER_Lowkey2PkeyCtx));
40     if (ctx == NULL) {
41         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
42         return NULL;
43     }
44 
45     ctx->outFormat = "OBJECT";
46     ctx->outType = "HIGH_KEY";
47     return (void *)ctx;
48 }
49 
DECODER_LowKeyObject2PkeyObjectSetParam(void * ctx,const BSL_Param * param)50 int32_t DECODER_LowKeyObject2PkeyObjectSetParam(void *ctx, const BSL_Param *param)
51 {
52     DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
53     if (decoderCtx == NULL || param == NULL) {
54         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
55         return CRYPT_NULL_INPUT;
56     }
57     const BSL_Param *libCtxParam = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_DECODE_LIB_CTX);
58     if (libCtxParam != NULL) {
59         if (libCtxParam->valueType != BSL_PARAM_TYPE_CTX_PTR) {
60             BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
61             return CRYPT_INVALID_ARG;
62         }
63         decoderCtx->libCtx = (CRYPT_EAL_LibCtx *)(uintptr_t)libCtxParam->value;
64     }
65     const BSL_Param *targetAttrNameParam = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_DECODE_TARGET_ATTR_NAME);
66     if (targetAttrNameParam != NULL) {
67         if (targetAttrNameParam->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
68             BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
69             return CRYPT_INVALID_ARG;
70         }
71         decoderCtx->targetAttrName = (const char *)(uintptr_t)targetAttrNameParam->value;
72     }
73 
74     return CRYPT_SUCCESS;
75 }
76 
DECODER_LowKeyObject2PkeyObjectGetParam(void * ctx,BSL_Param * param)77 int32_t DECODER_LowKeyObject2PkeyObjectGetParam(void *ctx, BSL_Param *param)
78 {
79     DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
80     if (decoderCtx == NULL) {
81         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
82         return CRYPT_NULL_INPUT;
83     }
84     DECODER_CommonCtx commonCtx = {
85         .outFormat = decoderCtx->outFormat,
86         .outType = decoderCtx->outType
87     };
88     return DECODER_CommonGetParam(&commonCtx, param);
89 }
90 typedef struct LowKeyObjectMethodInfo {
91     CRYPT_EAL_ImplPkeyMgmtExport export;
92     CRYPT_EAL_ImplPkeyMgmtDupCtx dupCtx;
93     CRYPT_EAL_ImplPkeyMgmtFreeCtx freeCtx;
94 } LowKeyObjectMethodInfo;
95 
GetLowKeyObjectInfo(const BSL_Param * inParam,void ** object,int32_t * objectType,LowKeyObjectMethodInfo * method)96 static int32_t GetLowKeyObjectInfo(const BSL_Param *inParam, void **object, int32_t *objectType,
97     LowKeyObjectMethodInfo *method)
98 {
99     const BSL_Param *lowObjectRef = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_OBJECT_DATA);
100     if (lowObjectRef == NULL || lowObjectRef->valueType != BSL_PARAM_TYPE_CTX_PTR) {
101         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
102         return CRYPT_INVALID_ARG;
103     }
104     const BSL_Param *lowObjectRefType = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_OBJECT_TYPE);
105     if (lowObjectRefType == NULL || lowObjectRefType->valueType != BSL_PARAM_TYPE_INT32) {
106         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
107         return CRYPT_INVALID_ARG;
108     }
109     const BSL_Param *exportFunc = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PKEY_EXPORT_METHOD_FUNC);
110     if (exportFunc == NULL || exportFunc->valueType != BSL_PARAM_TYPE_FUNC_PTR) {
111         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
112         return CRYPT_INVALID_ARG;
113     }
114     const BSL_Param *dupFunc = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PKEY_DUP_METHOD_FUNC);
115     if (dupFunc == NULL || dupFunc->valueType != BSL_PARAM_TYPE_FUNC_PTR) {
116         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
117         return CRYPT_INVALID_ARG;
118     }
119     const BSL_Param *freeFunc = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PKEY_FREE_METHOD_FUNC);
120     if (freeFunc == NULL || freeFunc->valueType != BSL_PARAM_TYPE_FUNC_PTR) {
121         BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
122         return CRYPT_INVALID_ARG;
123     }
124     if (lowObjectRef->value == NULL || lowObjectRefType->value == NULL) {
125         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
126         return CRYPT_NULL_INPUT;
127     }
128     *object = (void *)(uintptr_t)lowObjectRef->value;
129     *objectType = *((int32_t *)(uintptr_t)lowObjectRefType->value);
130     method->export = (CRYPT_EAL_ImplPkeyMgmtExport)(uintptr_t)exportFunc->value;
131     method->dupCtx = (CRYPT_EAL_ImplPkeyMgmtDupCtx)(uintptr_t)dupFunc->value;
132     method->freeCtx = (CRYPT_EAL_ImplPkeyMgmtFreeCtx)(uintptr_t)freeFunc->value;
133     return CRYPT_SUCCESS;
134 }
135 
GetProviderInfo(const BSL_Param * inParam,CRYPT_EAL_ProvMgrCtx ** lastDecoderProviderCtx)136 static int32_t GetProviderInfo(const BSL_Param *inParam, CRYPT_EAL_ProvMgrCtx **lastDecoderProviderCtx)
137 {
138     const BSL_Param *lastDecoderProvCtxParam = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PROVIDER_CTX);
139     if (lastDecoderProvCtxParam != NULL) {
140         if (lastDecoderProvCtxParam->valueType != BSL_PARAM_TYPE_CTX_PTR) {
141             BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
142             return CRYPT_INVALID_ARG;
143         }
144         *lastDecoderProviderCtx = (CRYPT_EAL_ProvMgrCtx *)(uintptr_t)lastDecoderProvCtxParam->value;
145     }
146     return CRYPT_SUCCESS;
147 }
148 
149 typedef struct {
150     CRYPT_EAL_PkeyMgmtInfo *pkeyAlgInfo;
151     void *targetKeyRef;
152 } ImportTargetPkeyArgs;
153 
ImportTargetPkey(const BSL_Param * param,void * args)154 static int32_t ImportTargetPkey(const BSL_Param *param, void *args)
155 {
156     if (param == NULL || args == NULL) {
157         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
158         return CRYPT_NULL_INPUT;
159     }
160 
161     ImportTargetPkeyArgs *importTargetPkeyArgs = (ImportTargetPkeyArgs *)args;
162     void *provCtx = NULL;
163     CRYPT_EAL_PkeyMgmtInfo *pkeyAlgInfo = importTargetPkeyArgs->pkeyAlgInfo;
164     if (pkeyAlgInfo == NULL || pkeyAlgInfo->keyMgmtMethod->provNewCtx == NULL ||
165         pkeyAlgInfo->keyMgmtMethod->import == NULL || pkeyAlgInfo->keyMgmtMethod->freeCtx == NULL) {
166         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
167         return CRYPT_NULL_INPUT;
168     }
169     int32_t ret = CRYPT_EAL_ProviderCtrl(pkeyAlgInfo->mgrCtx, CRYPT_PROVIDER_GET_USER_CTX, &provCtx, sizeof(provCtx));
170     if (ret != CRYPT_SUCCESS) {
171         BSL_ERR_PUSH_ERROR(ret);
172         return ret;
173     }
174     void *keyRef = pkeyAlgInfo->keyMgmtMethod->provNewCtx(provCtx, pkeyAlgInfo->algId);
175     if (keyRef == NULL) {
176         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
177         return CRYPT_MEM_ALLOC_FAIL;
178     }
179     ret = pkeyAlgInfo->keyMgmtMethod->import(keyRef, param);
180     if (ret != CRYPT_SUCCESS) {
181         BSL_ERR_PUSH_ERROR(ret);
182         pkeyAlgInfo->keyMgmtMethod->freeCtx(keyRef);
183         return ret;
184     }
185     importTargetPkeyArgs->targetKeyRef = keyRef;
186     return CRYPT_SUCCESS;
187 }
188 
TransLowKeyToTargetLowKey(CRYPT_EAL_PkeyMgmtInfo * pkeyAlgInfo,const LowKeyObjectMethodInfo * method,void * lowObjectRef,void ** targetKeyRef)189 static int32_t TransLowKeyToTargetLowKey(CRYPT_EAL_PkeyMgmtInfo *pkeyAlgInfo, const LowKeyObjectMethodInfo *method,
190     void *lowObjectRef, void **targetKeyRef)
191 {
192     ImportTargetPkeyArgs importTargetPkeyArgs = {0};
193     importTargetPkeyArgs.pkeyAlgInfo = pkeyAlgInfo;
194 
195     if (method->export == NULL) {
196         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
197         return CRYPT_NULL_INPUT;
198     }
199     BSL_Param param[3] = {
200         {CRYPT_PARAM_PKEY_PROCESS_FUNC, BSL_PARAM_TYPE_FUNC_PTR, ImportTargetPkey, 0, 0},
201         {CRYPT_PARAM_PKEY_PROCESS_ARGS, BSL_PARAM_TYPE_CTX_PTR, &importTargetPkeyArgs, 0, 0},
202         BSL_PARAM_END
203     };
204     int32_t ret = method->export(lowObjectRef, param);
205     if (ret != CRYPT_SUCCESS) {
206         BSL_ERR_PUSH_ERROR(ret);
207         return ret;
208     }
209 
210     *targetKeyRef = importTargetPkeyArgs.targetKeyRef;
211     return CRYPT_SUCCESS;
212 }
213 
DupLowKey(const LowKeyObjectMethodInfo * method,void * lowObjectRef,void ** targetKeyRef)214 static int32_t DupLowKey(const LowKeyObjectMethodInfo *method, void *lowObjectRef, void **targetKeyRef)
215 {
216     if (method->dupCtx == NULL) {
217         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
218         return CRYPT_NULL_INPUT;
219     }
220 
221     *targetKeyRef = method->dupCtx(lowObjectRef);
222     if (*targetKeyRef == NULL) {
223         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
224         return CRYPT_MEM_ALLOC_FAIL;
225     }
226 
227     return CRYPT_SUCCESS;
228 }
229 
ConstructOutObjectParam(BSL_Param ** outParam,void * object)230 static int32_t ConstructOutObjectParam(BSL_Param **outParam, void *object)
231 {
232     BSL_Param *result = BSL_SAL_Calloc(2, sizeof(BSL_Param));
233     if (result == NULL) {
234         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
235         return CRYPT_MEM_ALLOC_FAIL;
236     }
237     int32_t ret = BSL_PARAM_InitValue(&result[0], CRYPT_PARAM_DECODE_OBJECT_DATA, BSL_PARAM_TYPE_CTX_PTR,
238         object, 0);
239     if (ret != CRYPT_SUCCESS) {
240         BSL_SAL_Free(result);
241         BSL_ERR_PUSH_ERROR(ret);
242     }
243     *outParam = result;
244     return ret;
245 }
246 
247 /* input is pem format buffer, output is der format buffer */
DECODER_LowKeyObject2PkeyObjectDecode(void * ctx,const BSL_Param * inParam,BSL_Param ** outParam)248 int32_t DECODER_LowKeyObject2PkeyObjectDecode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam)
249 {
250     if (ctx == NULL || inParam == NULL || outParam == NULL) {
251         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
252         return CRYPT_NULL_INPUT;
253     }
254     DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
255     void *lowObjectRef = NULL;
256     int32_t lowObjectRefType = 0;
257     CRYPT_EAL_ProvMgrCtx *lastDecoderProviderCtx = NULL;
258     LowKeyObjectMethodInfo method = {0};
259     void *targetKeyRef = NULL;
260     CRYPT_EAL_PkeyMgmtInfo pkeyAlgInfo = {0};
261     int32_t ret = 0;
262     RETURN_RET_IF_ERR(GetLowKeyObjectInfo(inParam, &lowObjectRef, &lowObjectRefType, &method), ret);
263     if (method.freeCtx == NULL) {
264         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
265         return CRYPT_NULL_INPUT;
266     }
267     RETURN_RET_IF_ERR(GetProviderInfo(inParam, &lastDecoderProviderCtx), ret);
268     RETURN_RET_IF_ERR(CRYPT_EAL_GetPkeyAlgInfo(decoderCtx->libCtx, lowObjectRefType, decoderCtx->targetAttrName,
269         &pkeyAlgInfo), ret);
270     if (pkeyAlgInfo.mgrCtx != lastDecoderProviderCtx) {
271         ret = TransLowKeyToTargetLowKey(&pkeyAlgInfo, &method, lowObjectRef, &targetKeyRef);
272     } else {
273         ret = DupLowKey(&method, lowObjectRef, &targetKeyRef);
274     }
275     if (ret != CRYPT_SUCCESS) {
276         goto EXIT;
277     }
278     CRYPT_EAL_PkeyCtx *ealPKey = CRYPT_EAL_MakeKeyByPkeyAlgInfo(&pkeyAlgInfo, targetKeyRef, sizeof(void *));
279     if (ealPKey == NULL) {
280         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
281         goto EXIT;
282     }
283     ret = ConstructOutObjectParam(outParam, ealPKey);
284     if (ret != CRYPT_SUCCESS) {
285         CRYPT_EAL_PkeyFreeCtx(ealPKey);
286         BSL_ERR_PUSH_ERROR(ret);
287     }
288     return ret;
289 
290 EXIT:
291     BSL_SAL_Free(pkeyAlgInfo.keyMgmtMethod);
292     if (targetKeyRef != NULL) {
293         method.freeCtx(targetKeyRef);
294     }
295     return ret;
296 }
297 
DECODER_LowKeyObject2PkeyObjectFreeOutData(void * ctx,BSL_Param * outParam)298 void DECODER_LowKeyObject2PkeyObjectFreeOutData(void *ctx, BSL_Param *outParam)
299 {
300     DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
301     if (outParam == NULL || decoderCtx == NULL) {
302         return;
303     }
304     BSL_Param *objectDataParam = BSL_PARAM_FindParam(outParam, CRYPT_PARAM_DECODE_OBJECT_DATA);
305     if (objectDataParam == NULL || objectDataParam->valueType != BSL_PARAM_TYPE_CTX_PTR ||
306         objectDataParam->value == NULL) {
307         return;
308     }
309     CRYPT_EAL_PkeyCtx *ealPKey = (CRYPT_EAL_PkeyCtx *)objectDataParam->value;
310     CRYPT_EAL_PkeyFreeCtx(ealPKey);
311     BSL_SAL_Free(outParam);
312 }
313 
DECODER_LowKeyObject2PkeyObjectFreeCtx(void * ctx)314 void DECODER_LowKeyObject2PkeyObjectFreeCtx(void *ctx)
315 {
316     if (ctx == NULL) {
317         return;
318     }
319     BSL_SAL_Free(ctx);
320 }
321 
322 #endif