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
18 #if defined(HITLS_CRYPTO_CODECSKEY) && defined(HITLS_BSL_PEM) && defined(HITLS_CRYPTO_PROVIDER)
19 #include <stdint.h>
20 #include <string.h>
21 #include "crypt_eal_implprovider.h"
22 #include "crypt_errno.h"
23 #include "crypt_params_key.h"
24 #include "bsl_sal.h"
25 #include "bsl_err_internal.h"
26 #include "bsl_pem_internal.h"
27 #include "crypt_encode_decode_local.h"
28 #include "crypt_decode_key_impl.h"
29
30 typedef struct {
31 void *provCtx;
32 const char *outFormat;
33 const char *outType;
34 } DECODER_Pem2DerCtx;
35
DECODER_Pem2DerNewCtx(void * provCtx)36 void *DECODER_Pem2DerNewCtx(void *provCtx)
37 {
38 (void)provCtx;
39 DECODER_Pem2DerCtx *ctx = (DECODER_Pem2DerCtx *)BSL_SAL_Calloc(1, sizeof(DECODER_Pem2DerCtx));
40 if (ctx == NULL) {
41 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
42 return NULL;
43 }
44 ctx->provCtx = provCtx;
45 ctx->outFormat = "ASN1";
46 ctx->outType = NULL;
47 return ctx;
48 }
49
DECODER_Pem2DerGetParam(void * ctx,BSL_Param * param)50 int32_t DECODER_Pem2DerGetParam(void *ctx, BSL_Param *param)
51 {
52 DECODER_Pem2DerCtx *decoderCtx = (DECODER_Pem2DerCtx *)ctx;
53 if (decoderCtx == NULL) {
54 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
55 return CRYPT_NULL_INPUT;
56 }
57 DECODER_CommonCtx commonCtx = {
58 .outFormat = decoderCtx->outFormat,
59 .outType = decoderCtx->outType
60 };
61 return DECODER_CommonGetParam(&commonCtx, param);
62 }
63
DECODER_Pem2DerSetParam(void * ctx,const BSL_Param * param)64 int32_t DECODER_Pem2DerSetParam(void *ctx, const BSL_Param *param)
65 {
66 (void)ctx;
67 (void)param;
68 return CRYPT_SUCCESS;
69 }
70
71 /* input is pem format buffer, output is der format buffer */
DECODER_Pem2DerDecode(void * ctx,const BSL_Param * inParam,BSL_Param ** outParam)72 int32_t DECODER_Pem2DerDecode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam)
73 {
74 if (ctx == NULL || inParam == NULL || outParam == NULL) {
75 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
76 return CRYPT_NULL_INPUT;
77 }
78 BSL_PEM_Symbol symbol = {0};
79 char *dataType = NULL;
80 DECODER_Pem2DerCtx *decoderCtx = (DECODER_Pem2DerCtx *)ctx;
81 const BSL_Param *input = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_BUFFER_DATA);
82 if (input == NULL) {
83 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
84 return CRYPT_NULL_INPUT;
85 }
86 if (input->value == NULL || input->valueLen == 0 || input->valueType != BSL_PARAM_TYPE_OCTETS) {
87 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
88 return CRYPT_INVALID_ARG;
89 }
90 BSL_Buffer encode = {(uint8_t *)(uintptr_t)input->value, input->valueLen};
91 uint8_t *asn1Encode = NULL;
92 uint32_t asn1Len = 0;
93 int32_t ret = BSL_PEM_GetSymbolAndType((char *)encode.data, encode.dataLen, &symbol, &dataType);
94 if (ret != CRYPT_SUCCESS) {
95 BSL_ERR_PUSH_ERROR(ret);
96 return ret;
97 }
98
99 ret = BSL_PEM_DecodePemToAsn1((char **)&encode.data, &encode.dataLen, &symbol, &asn1Encode, &asn1Len);
100 if (ret != CRYPT_SUCCESS) {
101 BSL_SAL_Free(asn1Encode);
102 BSL_ERR_PUSH_ERROR(ret);
103 return ret;
104 }
105 decoderCtx->outType = dataType;
106 return CRYPT_DECODE_ConstructBufferOutParam(outParam, asn1Encode, asn1Len);
107 }
108
DECODER_Pem2DerFreeOutData(void * ctx,BSL_Param * outParam)109 void DECODER_Pem2DerFreeOutData(void *ctx, BSL_Param *outParam)
110 {
111 (void)ctx;
112 if (outParam == NULL) {
113 return;
114 }
115 BSL_Param *asn1DataParam = BSL_PARAM_FindParam(outParam, CRYPT_PARAM_DECODE_BUFFER_DATA);
116 if (asn1DataParam == NULL) {
117 return;
118 }
119 BSL_SAL_Free(asn1DataParam->value);
120 asn1DataParam->value = NULL;
121 asn1DataParam->valueLen = 0;
122 BSL_SAL_Free(outParam);
123 }
124
DECODER_Pem2DerFreeCtx(void * ctx)125 void DECODER_Pem2DerFreeCtx(void *ctx)
126 {
127 if (ctx == NULL) {
128 return;
129 }
130 BSL_SAL_Free(ctx);
131 }
132 #endif /* HITLS_CRYPTO_CODECSKEY && HITLS_BSL_PEM && HITLS_CRYPTO_PROVIDER */
133