1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "crypto_asym_key.h"
17 #include <string.h>
18 #include <stdlib.h>
19 #include "key_pair.h"
20 #include "memory.h"
21 #include "pub_key.h"
22 #include "result.h"
23 #include "blob.h"
24 #include "object_base.h"
25 #include "native_common.h"
26 #include "big_integer.h"
27 #include "asy_key_generator.h"
28 
29 
30 typedef struct OH_CryptoAsymKeyGenerator {
31     HcfObjectBase base;
32 
33     HcfResult (*generateKeyPair)(HcfAsyKeyGenerator *self, HcfParamsSpec *params,
34         HcfKeyPair **returnKeyPair);
35 
36     HcfResult (*convertKey)(HcfAsyKeyGenerator *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob,
37         HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair);
38 
39     HcfResult (*convertPemKey)(HcfAsyKeyGenerator *self, HcfParamsSpec *params, const char *pubKeyStr,
40         const char *priKeyStr, HcfKeyPair **returnKeyPair);
41 
42     const char *(*getAlgoName)(HcfAsyKeyGenerator *self);
43 } OH_CryptoAsymKeyGenerator;
44 
45 typedef struct OH_CryptoKeyPair {
46     HcfObjectBase base;
47 
48     HcfPriKey *priKey;
49 
50     HcfPubKey *pubKey;
51 } OH_CryptoKeyPair;
52 
53 typedef struct OH_CryptoPubKey {
54     HcfKey base;
55 
56     HcfResult (*getAsyKeySpecBigInteger)(const HcfPubKey *self, const AsyKeySpecItem item,
57         HcfBigInteger *returnBigInteger);
58 
59     HcfResult (*getAsyKeySpecString)(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString);
60 
61     HcfResult (*getAsyKeySpecInt)(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt);
62 
63     HcfResult (*getEncodedDer)(const HcfPubKey *self, const char *format, HcfBlob *returnBlob);
64 } OH_CryptoPubKey;
65 
OH_CryptoAsymKeyGenerator_Create(const char * algoName,OH_CryptoAsymKeyGenerator ** ctx)66 OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Create(const char *algoName, OH_CryptoAsymKeyGenerator **ctx)
67 {
68     if (ctx == NULL) {
69         return CRYPTO_INVALID_PARAMS;
70     }
71     HcfResult ret = HcfAsyKeyGeneratorCreate(algoName, (HcfAsyKeyGenerator **)ctx);
72     return GetOhCryptoErrCode(ret);
73 }
74 
OH_CryptoAsymKeyGenerator_Generate(OH_CryptoAsymKeyGenerator * ctx,OH_CryptoKeyPair ** keyCtx)75 OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Generate(OH_CryptoAsymKeyGenerator *ctx, OH_CryptoKeyPair **keyCtx)
76 {
77     if ((ctx == NULL) || (ctx->generateKeyPair == NULL) || (keyCtx == NULL)) {
78         return CRYPTO_INVALID_PARAMS;
79     }
80     HcfResult ret = ctx->generateKeyPair((HcfAsyKeyGenerator *)ctx, NULL, (HcfKeyPair **)keyCtx);
81     return GetOhCryptoErrCode(ret);
82 }
83 
OH_CryptoAsymKeyGenerator_Convert(OH_CryptoAsymKeyGenerator * ctx,Crypto_EncodingType type,Crypto_DataBlob * pubKeyData,Crypto_DataBlob * priKeyData,OH_CryptoKeyPair ** keyCtx)84 OH_Crypto_ErrCode OH_CryptoAsymKeyGenerator_Convert(OH_CryptoAsymKeyGenerator *ctx, Crypto_EncodingType type,
85     Crypto_DataBlob *pubKeyData, Crypto_DataBlob *priKeyData, OH_CryptoKeyPair **keyCtx)
86 {
87     if ((ctx == NULL) || (pubKeyData == NULL && priKeyData == NULL) || (keyCtx == NULL)) {
88         return CRYPTO_INVALID_PARAMS;
89     }
90     HcfResult ret = HCF_SUCCESS;
91     const char *priKeyStr = (priKeyData == NULL)? NULL : (const char *)priKeyData->data;
92     const char *pubKeyStr = (pubKeyData == NULL)? NULL : (const char *)pubKeyData->data;
93     switch (type) {
94         case CRYPTO_PEM:
95             ret = ctx->convertPemKey == NULL ? HCF_INVALID_PARAMS :
96                 ctx->convertPemKey((HcfAsyKeyGenerator *)ctx, NULL, pubKeyStr, priKeyStr, (HcfKeyPair **)keyCtx);
97             break;
98         case CRYPTO_DER:
99             ret = ctx->convertKey == NULL ? HCF_INVALID_PARAMS :
100                 ctx->convertKey((HcfAsyKeyGenerator *)ctx, NULL, (HcfBlob *)pubKeyData,
101                                 (HcfBlob *)priKeyData, (HcfKeyPair **)keyCtx);
102             break;
103         default:
104             return CRYPTO_INVALID_PARAMS;
105     }
106     return GetOhCryptoErrCode(ret);
107 }
108 
OH_CryptoAsymKeyGenerator_GetAlgoName(OH_CryptoAsymKeyGenerator * ctx)109 const char *OH_CryptoAsymKeyGenerator_GetAlgoName(OH_CryptoAsymKeyGenerator *ctx)
110 {
111     if ((ctx == NULL) || (ctx->getAlgoName == NULL)) {
112         return NULL;
113     }
114     return ctx->getAlgoName((HcfAsyKeyGenerator *)ctx);
115 }
116 
OH_CryptoAsymKeyGenerator_Destroy(OH_CryptoAsymKeyGenerator * ctx)117 void OH_CryptoAsymKeyGenerator_Destroy(OH_CryptoAsymKeyGenerator *ctx)
118 {
119     if ((ctx == NULL) || (ctx->base.destroy == NULL)) {
120         return;
121     }
122     ctx->base.destroy((HcfObjectBase *)ctx);
123 }
124 
OH_CryptoKeyPair_Destroy(OH_CryptoKeyPair * keyCtx)125 void OH_CryptoKeyPair_Destroy(OH_CryptoKeyPair *keyCtx)
126 {
127     if ((keyCtx == NULL) || (keyCtx->base.destroy == NULL)) {
128         return;
129     }
130     keyCtx->base.destroy((HcfObjectBase *)keyCtx);
131 }
132 
OH_CryptoKeyPair_GetPubKey(OH_CryptoKeyPair * keyCtx)133 OH_CryptoPubKey *OH_CryptoKeyPair_GetPubKey(OH_CryptoKeyPair *keyCtx)
134 {
135     if (keyCtx == NULL) {
136         return NULL;
137     }
138     return (OH_CryptoPubKey *)keyCtx->pubKey;
139 }
140 
OH_CryptoPubKey_Encode(OH_CryptoPubKey * key,Crypto_EncodingType type,const char * encodingStandard,Crypto_DataBlob * out)141 OH_Crypto_ErrCode OH_CryptoPubKey_Encode(OH_CryptoPubKey *key, Crypto_EncodingType type,
142     const char *encodingStandard, Crypto_DataBlob *out)
143 {
144     if ((key == NULL) || (out == NULL)) {
145         return CRYPTO_INVALID_PARAMS;
146     }
147     HcfResult ret = HCF_SUCCESS;
148     char *pemStr = NULL;
149     switch (type) {
150         case CRYPTO_PEM:
151             if (key->base.getEncodedPem == NULL) {
152                 return CRYPTO_INVALID_PARAMS;
153             }
154             ret = key->base.getEncodedPem((HcfKey *)key, encodingStandard, &pemStr);
155             if (ret != HCF_SUCCESS) {
156                 break;
157             }
158             out->data = (uint8_t *)pemStr;
159             out->len = strlen(pemStr);
160             break;
161         case CRYPTO_DER:
162             if (encodingStandard != NULL) {
163                 ret = key->getEncodedDer == NULL ? HCF_INVALID_PARAMS :
164                     key->getEncodedDer((HcfPubKey *)key, encodingStandard, (HcfBlob *)out);
165                 break;
166             } else {
167                 ret = key->base.getEncoded == NULL ? HCF_INVALID_PARAMS
168                                                    : key->base.getEncoded((HcfKey *)key, (HcfBlob *)out);
169                 break;
170             }
171         default:
172             return CRYPTO_INVALID_PARAMS;
173     }
174 
175     return GetOhCryptoErrCode(ret);
176 }
177 
OH_CryptoPubKey_GetParam(OH_CryptoPubKey * key,CryptoAsymKey_ParamType item,Crypto_DataBlob * value)178 OH_Crypto_ErrCode OH_CryptoPubKey_GetParam(OH_CryptoPubKey *key, CryptoAsymKey_ParamType item, Crypto_DataBlob *value)
179 {
180     if ((key == NULL) || (value == NULL)) {
181         return CRYPTO_INVALID_PARAMS;
182     }
183     HcfResult ret = HCF_SUCCESS;
184     int32_t *returnInt = NULL;
185     char *returnStr = NULL;
186     HcfBigInteger bigIntValue = {0};
187     switch (item) {
188         case CRYPTO_DH_L_INT:
189         case CRYPTO_ECC_H_INT:
190         case CRYPTO_ECC_FIELD_SIZE_INT:
191             returnInt = (int32_t *)HcfMalloc(sizeof(int32_t), 0);
192             if (returnInt == NULL) {
193                 ret = HCF_ERR_MALLOC;
194                 break;
195             }
196             ret = key->getAsyKeySpecInt == NULL ? HCF_INVALID_PARAMS :
197                 key->getAsyKeySpecInt((HcfPubKey *)key, (AsyKeySpecItem)item, returnInt);
198             if (ret != HCF_SUCCESS) {
199                 HcfFree(returnInt);
200                 break;
201             }
202             value->data = (uint8_t *)returnInt;
203             value->len = sizeof(int32_t);
204             break;
205         case CRYPTO_ECC_FIELD_TYPE_STR:
206         case CRYPTO_ECC_CURVE_NAME_STR:
207             ret = key->getAsyKeySpecString == NULL ? HCF_INVALID_PARAMS :
208                 key->getAsyKeySpecString((HcfPubKey *)key, (AsyKeySpecItem)item, &returnStr);
209             if (ret != HCF_SUCCESS) {
210                 break;
211             }
212             value->data = (uint8_t *)returnStr;
213             value->len = strlen(returnStr);
214             break;
215         default:
216             ret = key->getAsyKeySpecBigInteger == NULL ? HCF_INVALID_PARAMS :
217                 key->getAsyKeySpecBigInteger((HcfPubKey *)key, (AsyKeySpecItem)item, &bigIntValue);
218             if (ret != HCF_SUCCESS) {
219                 break;
220             }
221             value->data = (uint8_t *)bigIntValue.data;
222             value->len = (size_t)bigIntValue.len;
223             break;
224     }
225     return GetOhCryptoErrCode(ret);
226 }
227