• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 #include "key_store_helper.h"
16 #include <cstring>
17 #include "openssl/err.h"
18 #include "constant.h"
19 #include "signature_tools_errno.h"
20 
21 namespace OHOS {
22 namespace SignatureTools {
KeyStoreHelper()23 KeyStoreHelper::KeyStoreHelper()
24 {
25     passWordStatus = true;
26     keyPairPwdLen = 0;
27     keyStorePwdLen = 0;
28     publicKeyStatus = RET_FAILED;
29     privateKeyStatus = RET_FAILED;
30 }
31 
SetPassWordStatus(bool status)32 void KeyStoreHelper::SetPassWordStatus(bool status)
33 {
34     passWordStatus = status;
35 }
36 
SetIsRegen(bool autoCreate)37 void KeyStoreHelper::SetIsRegen(bool autoCreate)
38 {
39     isRegen = autoCreate;
40 }
41 
GetPassWordStatus()42 bool KeyStoreHelper::GetPassWordStatus()
43 {
44     return passWordStatus;
45 }
46 
ResetKeyStatusvariable()47 void KeyStoreHelper::ResetKeyStatusvariable()
48 {
49     publicKeyStatus = RET_FAILED;
50     privateKeyStatus = RET_FAILED;
51 }
52 
ResePwdLenvariable()53 void KeyStoreHelper::ResePwdLenvariable()
54 {
55     keyPairPwdLen = 0;
56     keyStorePwdLen = 0;
57 }
58 
PrintAliasExistErrorMsg(const std::string & alias,const std::string & keyStorePath)59 void KeyStoreHelper::PrintAliasExistErrorMsg(const std::string& alias, const std::string& keyStorePath)
60 {
61     if (!isRegen) {
62         PrintErrorNumberMsg("KEY_ALIAS_ERROR", KEY_ALIAS_ERROR, "keyAlias: '"
63                             + alias + "' is not exist in" + keyStorePath);
64     }
65 }
66 
KeyPairFree(EC_GROUP * group,EC_KEY * pkey,const std::string & Message)67 void KeyStoreHelper::KeyPairFree(EC_GROUP* group, EC_KEY* pkey, const std::string& Message)
68 {
69     if (!Message.empty()) {
70         SIGNATURE_TOOLS_LOGE("%s", Message.c_str());
71     }
72 
73     EC_GROUP_free(group);
74     group = nullptr;
75 
76     EC_KEY_free(pkey);
77     pkey = nullptr;
78 }
79 
KeyPairFree(BIGNUM * bnSerial,X509_NAME * issuerName,X509_NAME * subjectName,ASN1_INTEGER * ai,const std::string & Message)80 void KeyStoreHelper::KeyPairFree(BIGNUM* bnSerial, X509_NAME* issuerName, X509_NAME* subjectName,
81                                  ASN1_INTEGER* ai, const std::string& Message)
82 {
83     if (!Message.empty()) {
84         SIGNATURE_TOOLS_LOGE("%s", Message.c_str());
85     }
86 
87     BN_free(bnSerial);
88     bnSerial = nullptr;
89 
90     ASN1_INTEGER_free(ai);
91     ai = nullptr;
92 
93     X509_NAME_free(issuerName);
94     issuerName = nullptr;
95 
96     X509_NAME_free(subjectName);
97     subjectName = nullptr;
98 }
99 
KeyPairFree(X509 * cert,PKCS12 * p12,BIO * bioOut,const std::string & Message)100 void KeyStoreHelper::KeyPairFree(X509* cert, PKCS12* p12, BIO* bioOut, const std::string& Message)
101 {
102     if (!Message.empty()) {
103         SIGNATURE_TOOLS_LOGE("%s", Message.c_str());
104     }
105 
106     X509_free(cert);
107     cert = nullptr;
108 
109     PKCS12_free(p12);
110     p12 = nullptr;
111 
112     BIO_free_all(bioOut);
113     bioOut = nullptr;
114 }
115 
KeyPairFree(STACK_OF (X509)* ocerts,STACK_OF (PKCS12_SAFEBAG)* bags,char * name)116 void KeyStoreHelper::KeyPairFree(STACK_OF(X509)* ocerts, STACK_OF(PKCS12_SAFEBAG)* bags, char* name)
117 {
118     sk_X509_pop_free(ocerts, X509_free);
119     ocerts = nullptr;
120 
121     sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
122     bags = nullptr;
123 
124     free(name);
125     name = nullptr;
126 }
127 
KeyPairFree(STACK_OF (PKCS7)* safes,EVP_PKEY * publickey)128 void KeyStoreHelper::KeyPairFree(STACK_OF(PKCS7)* safes, EVP_PKEY* publickey)
129 {
130     sk_PKCS7_pop_free(safes, PKCS7_free);
131     safes = nullptr;
132 
133     EVP_PKEY_free(publickey);
134     publickey = nullptr;
135 }
136 
KeyPairFree(STACK_OF (PKCS12_SAFEBAG)* bags,PKCS8_PRIV_KEY_INFO * p8,char * name)137 void KeyStoreHelper::KeyPairFree(STACK_OF(PKCS12_SAFEBAG)* bags, PKCS8_PRIV_KEY_INFO* p8, char* name)
138 {
139     sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
140     bags = nullptr;
141 
142     PKCS8_PRIV_KEY_INFO_free(p8);
143     p8 = nullptr;
144 
145     free(name);
146     name = nullptr;
147 }
148 
InitX509(X509 & cert,EVP_PKEY & evpPkey)149 bool KeyStoreHelper::InitX509(X509& cert, EVP_PKEY& evpPkey)
150 {
151     BIGNUM* bnSerial = BN_new();
152     X509_NAME* issuerName = X509_NAME_new();
153     const EVP_MD* md = EVP_sha256();
154     X509_NAME* subjectName = nullptr;
155     if (!bnSerial || !issuerName || !md) {
156         KeyPairFree(bnSerial, issuerName, subjectName, nullptr, "Failed to initialize the x509 info.");
157         return false;
158     }
159     ASN1_INTEGER* ai = BN_to_ASN1_INTEGER(bnSerial, NULL);
160     if (ai == NULL || issuerName == NULL) {
161         KeyPairFree(bnSerial, issuerName, subjectName, ai, "Failed to initialize the x509 structure.");
162         return false;
163     }
164     X509_set_serialNumber(&cert, ai);
165     X509_gmtime_adj(X509_get_notBefore(&cert), 0);
166     X509_gmtime_adj(X509_get_notAfter(&cert), (long)DEFAULT_VALIDITY_DAYS * ONE_DAY_TIME);
167     if (!X509_NAME_add_entry_by_txt(issuerName, "C",
168         MBSTRING_ASC, reinterpret_cast<const unsigned char*>("US"), -1, -1, 0)
169         || !X509_NAME_add_entry_by_txt(issuerName, "O",
170         MBSTRING_ASC, reinterpret_cast<const unsigned char*>("My Company"), -1, -1, 0)
171         || !X509_NAME_add_entry_by_txt(issuerName, "CN",
172         MBSTRING_ASC, reinterpret_cast<const unsigned char*>("My Issuer"), -1, -1, 0)) {
173         KeyPairFree(bnSerial, issuerName, subjectName, ai,
174                     "Failed to initialize the x509 structure.X509_NAME type");
175         return false;
176     }
177     X509_set_issuer_name(&cert, issuerName);
178     subjectName = X509_NAME_dup(issuerName);
179     if (subjectName == NULL) {
180         KeyPairFree(bnSerial, issuerName, subjectName, ai,
181                     "Failed to initialize the x509 structure.X509_NAME type");
182         return false;
183     }
184     X509_set_subject_name(&cert, subjectName);
185     if (!X509_set_pubkey(&cert, &evpPkey)) {
186         KeyPairFree(bnSerial, issuerName, subjectName, ai,
187                     "Failed to initialize the x509 structure.X509_NAME type");
188         return false;
189     }
190     X509_set_version(&cert, DEFAULT_CERT_VERSION);
191     if (!X509_sign(&cert, &evpPkey, md)) {
192         KeyPairFree(bnSerial, issuerName, subjectName, ai,
193                     "Failed to initialize the x509 structure.X509_NAME type");
194         return false;
195     }
196     KeyPairFree(bnSerial, issuerName, subjectName, ai, "");
197     return true;
198 }
199 
SetPwdLenKeyStatus(char * pass,char * keyPass)200 void KeyStoreHelper::SetPwdLenKeyStatus(char* pass, char* keyPass)
201 {
202     ResePwdLenvariable();
203     ResetKeyStatusvariable();
204 
205     if (pass != nullptr) {
206         keyStorePwdLen = strlen(pass);
207     }
208 
209     if (keyPass != nullptr) {
210         keyPairPwdLen = strlen(keyPass);
211     }
212 }
213 
214 /*
215 * Function: Find the key pair in the PKCS12 structure by alias.
216 * Annotation: This function is to modify the openSSL interface "PKCS12_parse" and "find_friendly_name" functions,
217 *             To fit java generated p12 files.
218 * find_friendly_name interface: Look for aliases in PKCS12 structures, one key pair for each PKCS12 structure.
219 * PKCS12_parse interface: Parse the PKCS12 structure, and obtain the key pair,
220 *                         one PKCS12 structure corresponds to one key pair.
221 * FindKeyPair interface: Get the stack structure "STACK_OF(PKCS7)" of PKCS7 in PKCS12 structure, and then traverse
222 *                        the "STACK_OF(PKCS7)" structure to get the public key and the private key by alias.
223 **/
FindKeyPair(PKCS12 * p12,const std::string & alias,char * keyPwd,char * keyStorePwd,EVP_PKEY ** keyPiar,const std::string & keyStorePath)224 int KeyStoreHelper::FindKeyPair(PKCS12* p12, const std::string& alias, char* keyPwd,
225                                 char* keyStorePwd, EVP_PKEY** keyPiar, const std::string& keyStorePath)
226 {
227     EVP_PKEY* publickey = nullptr;
228     STACK_OF(PKCS7)* safes = nullptr;
229     PKCS7* safe = nullptr;
230 
231     SetPwdLenKeyStatus(keyStorePwd, keyPwd);
232 
233     if ((safes = PKCS12_unpack_authsafes(p12)) == NULL) {
234         sk_PKCS7_pop_free(safes, PKCS7_free);
235         return RET_FAILED;
236     }
237 
238     for (int n = 0; n < sk_PKCS7_num(safes); n++) {
239         if ((publicKeyStatus == RET_OK) && (privateKeyStatus == RET_OK)) {
240             break;
241         }
242 
243         safe = sk_PKCS7_value(safes, n);
244         if (OBJ_obj2nid(safe->type) == NID_pkcs7_encrypted) {
245             if (publicKeyStatus != RET_OK) {
246                 publicKeyStatus = GetPublicKey(safe, alias, keyStorePwd, keyStorePwdLen, &publickey);
247             }
248 
249             if (!GetPassWordStatus()) {
250                 KeyPairFree(safes, publickey);
251                 return RET_FAILED;
252             }
253         } else if (OBJ_obj2nid(safe->type) == NID_pkcs7_data && privateKeyStatus != RET_OK) {
254             privateKeyStatus = GetPrivateKey(safe, alias, keyPwd, keyPairPwdLen, keyPiar);
255             if (!GetPassWordStatus()) {
256                 KeyPairFree(safes, publickey);
257                 return RET_FAILED;
258             }
259         }
260     }
261 
262     if (((publicKeyStatus == RET_OK) && (privateKeyStatus == RET_OK))
263         && (publickey != nullptr) && (*keyPiar != nullptr)) {
264         if (EVP_PKEY_copy_parameters(*keyPiar, publickey) != 1) {
265             KeyPairFree(safes, publickey);
266             SIGNATURE_TOOLS_LOGE("publickey and privatekey set EVP_PKEY struct failed");
267             return RET_FAILED;
268         }
269 
270         KeyPairFree(safes, publickey);
271         return RET_OK;
272     }
273     PrintAliasExistErrorMsg(alias, keyStorePath);
274     KeyPairFree(safes, publickey);
275     return RET_FAILED;
276 }
277 
GetPublicKey(PKCS7 * safe,const std::string & alias,char * pass,int passlen,EVP_PKEY ** publickey)278 int KeyStoreHelper::GetPublicKey(PKCS7* safe, const std::string& alias, char* pass, int passlen, EVP_PKEY** publickey)
279 {
280     char* name = NULL;
281     PKCS12_SAFEBAG* bag = nullptr;
282     STACK_OF(PKCS12_SAFEBAG)* bags = nullptr;
283     STACK_OF(X509)* ocerts = sk_X509_new_null();
284 
285     bags = PKCS12_unpack_p7encdata(safe, pass, passlen);
286     if (bags == nullptr) {
287         PrintErrorNumberMsg("KEY_PASSWORD_ERROR", KEY_PASSWORD_ERROR, "'" + alias + "' keypair password error");
288         KeyPairFree(ocerts, bags, name);
289         SetPassWordStatus(false);
290         return RET_FAILED;
291     }
292 
293     if (ParsePkcs12Safebags(bags, pass, passlen, ocerts) == RET_FAILED) {
294         PrintErrorNumberMsg("KEY_PASSWORD_ERROR", KEY_PASSWORD_ERROR, "'" + alias + "' keypair password error");
295         KeyPairFree(ocerts, bags, name);
296         SetPassWordStatus(false);
297         return RET_FAILED;
298     }
299     for (int i = 0; i < sk_X509_num(ocerts); i++) {
300         bag = sk_PKCS12_SAFEBAG_value(bags, i);
301         name = PKCS12_get_friendlyname(bag);
302         if (strcmp(name, alias.c_str()) != 0) {
303             continue;
304         }
305         X509* cert = sk_X509_value(ocerts, i);
306         if (cert == nullptr) {
307             KeyPairFree(ocerts, bags, name);
308             return RET_FAILED;
309         }
310         *publickey = X509_get_pubkey(cert);
311         if (*publickey != nullptr) {
312             KeyPairFree(ocerts, bags, name);
313             return RET_OK;
314         }
315     }
316 
317     KeyPairFree(ocerts, bags, name);
318     return RET_FAILED;
319 }
320 
GetPrivateKey(PKCS7 * safe,const std::string & alias,char * pass,int passlen,EVP_PKEY ** keyPiar)321 int KeyStoreHelper::GetPrivateKey(PKCS7* safe, const std::string& alias, char* pass, int passlen, EVP_PKEY** keyPiar)
322 {
323     STACK_OF(PKCS12_SAFEBAG)* bags = nullptr;
324     PKCS12_SAFEBAG* bag = nullptr;
325     PKCS8_PRIV_KEY_INFO* p8 = nullptr;
326     char* name = NULL;
327 
328     bags = PKCS12_unpack_p7data(safe);
329     for (int m = 0; m < sk_PKCS12_SAFEBAG_num(bags); m++) {
330         bag = sk_PKCS12_SAFEBAG_value(bags, m);
331         if (PKCS12_SAFEBAG_get_nid(bag) != NID_pkcs8ShroudedKeyBag) {
332             continue;
333         }
334         name = PKCS12_get_friendlyname(bag);
335         if (strcmp(name, alias.c_str()) != 0) {
336             continue;
337         }
338         if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL) {
339             PrintErrorNumberMsg("KEY_PASSWORD_ERROR", KEY_PASSWORD_ERROR, "'" + alias
340                                 + "' keypair password error");
341             KeyPairFree(bags, p8, name);
342             SetPassWordStatus(false);
343             return RET_FAILED;
344         }
345         *keyPiar = EVP_PKCS82PKEY(p8);
346         if (*keyPiar == NULL) {
347             KeyPairFree(bags, p8, name);
348             return RET_FAILED;
349         }
350 
351         KeyPairFree(bags, p8, name);
352         return RET_OK;
353     }
354 
355     KeyPairFree(bags, p8, name);
356     return RET_FAILED;
357 }
358 
WriteKeyStore(EVP_PKEY * evpPkey,std::string & keyStorePath,char * keyStorePwd,std::string alias,char * keyPwd)359 int KeyStoreHelper::WriteKeyStore(EVP_PKEY* evpPkey, std::string& keyStorePath,
360                                   char* keyStorePwd, std::string alias, char* keyPwd)
361 {
362     X509* cert = X509_new();
363     PKCS12* p12 = nullptr;
364     BIO* bioOut = nullptr;
365 
366     if (evpPkey == nullptr) {
367         KeyPairFree(cert, p12, bioOut, "The key pair pointer is null");
368         return RET_FAILED;
369     }
370 
371     if (!InitX509(*cert, *evpPkey)) {
372         KeyPairFree(cert, p12, bioOut, "initialize x509 structure failed");
373         return RET_FAILED;
374     }
375 
376     if (CreatePKCS12(&p12, keyStorePath, keyStorePwd, keyPwd, alias.c_str(), evpPkey, cert) == RET_FAILED) {
377         KeyPairFree(cert, p12, bioOut, "Create PKCS12 Structure Failed");
378         return RET_FAILED;
379     }
380 
381     bioOut = BIO_new_file(keyStorePath.c_str(), "wb");
382     if (bioOut == nullptr) {
383         KeyPairFree(cert, p12, bioOut, "Open file: '" + keyStorePath + "' failed");
384         return RET_FAILED;
385     }
386 
387     if (i2d_PKCS12_bio(bioOut, p12) != 1) {
388         KeyPairFree(cert, p12, bioOut, "PKCS12 structure write File failure");
389         return RET_FAILED;
390     }
391 
392     KeyPairFree(cert, p12, bioOut, "");
393     return RET_OK;
394 }
395 
396 /*
397 * Function: Create a PKCS12 structured keystore, If the key stock is available, the key pair is appended.
398 * Annotation: This function is a modification of the OpenSSL "PKCS12_create" function, To fit java generated p12 files.
399 * PKCS12_create interface: A p12 file holds multiple PKCS12 structures, and a structure holds a key pair.
400 * CreatePKCS12 interface: A p12 file stores a PKCS12 structure,a PKCS12 structure stores multiplePKCS7 structures,
401 *                         and a PKCS7 structure corresponds to a key pair.
402 **/
CreatePKCS12(PKCS12 ** p12,const std::string & charsStorePath,char * keyStorePwd,char * keyPwd,const std::string & charsAlias,EVP_PKEY * evpPkey,X509 * cert)403 int KeyStoreHelper::CreatePKCS12(PKCS12** p12, const std::string& charsStorePath, char* keyStorePwd,
404                                  char* keyPwd, const std::string& charsAlias, EVP_PKEY* evpPkey, X509* cert)
405 {
406     STACK_OF(PKCS7)* safes = nullptr;
407     PKCS12* acceptP12 = nullptr;
408     BIO* bioOut = BIO_new_file(charsStorePath.c_str(), "rb");
409     if (bioOut != nullptr) {
410         acceptP12 = d2i_PKCS12_bio(bioOut, NULL);
411         if (acceptP12 == nullptr) {
412             return RET_FAILED;
413         }
414         if (Pkcs12PasswordParse(acceptP12, keyStorePwd, charsStorePath) == RET_FAILED) {
415             BIO_free_all(bioOut);
416             return RET_FAILED;
417         }
418         safes = PKCS12_unpack_authsafes(acceptP12);
419     }
420 
421     BIO_free_all(bioOut);
422     if (keyStorePwd == nullptr) {
423         *p12 = CreatePKCS12(keyStorePwd, keyPwd, charsAlias.c_str(), evpPkey, cert, 0, 0, 0, -1, 0, &safes);
424     } else {
425         *p12 = CreatePKCS12(keyStorePwd, keyPwd, charsAlias.c_str(), evpPkey, cert, 0, 0, 0, 0, 0, &safes);
426     }
427 
428     sk_PKCS7_pop_free(safes, PKCS7_free);
429     safes = nullptr;
430     PKCS12_free(acceptP12);
431 
432     if (*p12 == nullptr) {
433         return RET_FAILED;
434     }
435     return RET_OK;
436 }
437 
ReadKeyStore(std::string & keyStorePath,char * keyStorePwd,const std::string & alias,char * keyPwd,EVP_PKEY ** evpPkey)438 int KeyStoreHelper::ReadKeyStore(std::string& keyStorePath, char* keyStorePwd, const std::string& alias,
439                                  char* keyPwd, EVP_PKEY** evpPkey)
440 {
441     X509* cert = nullptr;
442     PKCS12* p12 = nullptr;
443     BIO* bioOut = nullptr;
444 
445     bioOut = BIO_new_file(keyStorePath.c_str(), "rb");
446     if (bioOut == nullptr) {
447         VerifyHapOpensslUtils::GetOpensslErrorMessage();
448         KeyPairFree(cert, p12, bioOut, "Open file: '" + keyStorePath + "' failed");
449         return RET_FAILED;
450     }
451 
452     p12 = d2i_PKCS12_bio(bioOut, NULL);
453     if (Pkcs12PasswordParse(p12, keyStorePwd, keyStorePath) == RET_FAILED) {
454         KeyPairFree(cert, p12, bioOut, "");
455         SetPassWordStatus(false);
456         return RET_FAILED;
457     }
458     int status = FindKeyPair(p12, alias, keyPwd, keyStorePwd, evpPkey, keyStorePath);
459     if (status == RET_FAILED) {
460         KeyPairFree(cert, p12, bioOut, "");
461         return RET_FAILED;
462     }
463 
464     KeyPairFree(cert, p12, bioOut, "");
465     return RET_OK;
466 }
467 
Pkcs12PasswordParse(PKCS12 * p12,const char * keyStorePwd,const std::string & keyStoreFile)468 int KeyStoreHelper::Pkcs12PasswordParse(PKCS12* p12, const char* keyStorePwd, const std::string& keyStoreFile)
469 {
470     if (p12 == NULL) {
471         PrintErrorNumberMsg("KEYSTORE_STRUCTURE_ERROR", KEYSTORE_STRUCTURE_ERROR, "'" + keyStoreFile
472                             + "' keystore is not a PKCS12 structure");
473         return RET_FAILED;
474     }
475 
476     if (keyStorePwd == NULL || *keyStorePwd == '\0') {
477         if (!PKCS12_mac_present(p12) || PKCS12_verify_mac(p12, NULL, 0)) {
478             keyStorePwd = NULL;
479         } else if (PKCS12_verify_mac(p12, "", 0)) {
480             keyStorePwd = "";
481         } else {
482             goto err;
483         }
484     } else if (!PKCS12_verify_mac(p12, keyStorePwd, -1)) {
485         goto err;
486     }
487 
488     return RET_OK;
489 err:
490     PrintErrorNumberMsg("KEYSTORE_PASSWORD_ERROR", KEYSTORE_PASSWORD_ERROR, "keyStore password error");
491     return RET_FAILED;
492 }
493 
IsKeyStoreFileExist(std::string & keyStorePath)494 bool KeyStoreHelper::IsKeyStoreFileExist(std::string& keyStorePath)
495 {
496     if (keyStorePath.empty()) {
497         return false;
498     }
499     BIO* bioOut = nullptr;
500     bioOut = BIO_new_file(keyStorePath.c_str(), "rb");
501     if (bioOut == nullptr) {
502         return false;
503     }
504     BIO_free(bioOut);
505     return true;
506 }
507 
GenerateKeyPair(const std::string & algorithm,int keySize)508 EVP_PKEY* KeyStoreHelper::GenerateKeyPair(const std::string& algorithm, int keySize)
509 {
510     if (algorithm.empty() || (0 == keySize)) {
511         SIGNATURE_TOOLS_LOGI("keyAlg and keySize is nullptr!");
512         return nullptr;
513     }
514     EC_GROUP* group = nullptr;
515     EC_KEY* keyPair = EC_KEY_new();
516 
517     if (keySize == static_cast<int>(NIST_P_256)) {
518         group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
519     } else if (keySize == static_cast<int>(NIST_P_384)) {
520         group = EC_GROUP_new_by_curve_name(NID_secp384r1);
521     } else {
522         VerifyHapOpensslUtils::GetOpensslErrorMessage();
523         KeyPairFree(group, keyPair, "Algorithm length error");
524         return nullptr;
525     }
526     if (!group) {
527         VerifyHapOpensslUtils::GetOpensslErrorMessage();
528         KeyPairFree(group, keyPair, "Elliptic curve encryption using P256 or P384 failed");
529         return nullptr;
530     }
531 
532     EC_KEY_set_group(keyPair, group);
533     if (EC_KEY_generate_key(keyPair) != 1) {
534         VerifyHapOpensslUtils::GetOpensslErrorMessage();
535         KeyPairFree(group, keyPair, "Description Failed to generate an elliptic curve key pair");
536         return nullptr;
537     }
538     if (EC_KEY_check_key(keyPair) != 1) {
539         VerifyHapOpensslUtils::GetOpensslErrorMessage();
540         KeyPairFree(group, keyPair, "Description Failed to generate an elliptic curve key pair");
541         return nullptr;
542     }
543     EVP_PKEY* pkey = EVP_PKEY_new();
544     EVP_PKEY_set1_EC_KEY(pkey, keyPair);
545     KeyPairFree(group, keyPair, "");
546     return pkey;
547 }
548 
CreatePKCS12(const char * keyStorePwd,const char * keyPwd,const char * name,EVP_PKEY * pkey,X509 * cert,int keyNid,int certNid,int iter,int macStatus,int keyType,STACK_OF (PKCS7)** safes)549 PKCS12* KeyStoreHelper::CreatePKCS12(const char* keyStorePwd, const char* keyPwd, const char* name, EVP_PKEY* pkey,
550                                      X509* cert, int keyNid, int certNid, int iter,
551                                      int macStatus, int keyType, STACK_OF(PKCS7)** safes)
552 {
553     PKCS12* p12 = NULL;
554     STACK_OF(PKCS12_SAFEBAG)* bags = NULL;
555     unsigned char keyId[EVP_MAX_MD_SIZE];
556     unsigned int keyIdLen = 0;
557     PKCS12_SAFEBAG* bag = NULL;
558 
559     if (!certNid) {
560         certNid = NID_PBE_CBC;
561     }
562     SetNidMac(keyNid, iter, macStatus);
563     if (!pkey && !cert) {
564         PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT);
565         return NULL;
566     }
567 
568     if (!X509_check_private_key(cert, pkey)) {
569         return NULL;
570     }
571     X509_digest(cert, EVP_sha384(), keyId, &keyIdLen);
572 
573     if (SetCertPkcs12(cert, bag, bags, keyId, keyIdLen, name, safes, certNid, iter, keyStorePwd) == RET_FAILED) {
574         goto err;
575     }
576 
577     if (SetPkeyPkcs12(pkey, bag, bags, name, safes, iter, keyPwd, keyType, keyNid, keyId, keyIdLen) == RET_FAILED) {
578         goto err;
579     }
580 
581     p12 = PKCS12_add_safes(*safes, 0);
582 
583     if (!p12) {
584         goto err;
585     }
586     safes = NULL;
587     if ((macStatus != -1) && !PKCS12_set_mac(p12, keyStorePwd, -1, NULL, 0, macStatus, NULL)) {
588         goto err;
589     }
590     return p12;
591 
592 err:
593     sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
594     return NULL;
595 }
596 
SetNidMac(int & nidKey,int & iter,int & macStatus)597 void KeyStoreHelper::SetNidMac(int& nidKey, int& iter, int& macStatus)
598 {
599     if (!nidKey) {
600         nidKey = NID_TRIPLEDES_CBC;
601     }
602 
603     if (!iter) {
604         iter = PKCS12_DEFAULT_ITER;
605     }
606 
607     if (!macStatus) {
608         macStatus = 1;
609     }
610 }
611 
SetCertPkcs12(X509 * cert,PKCS12_SAFEBAG * bag,STACK_OF (PKCS12_SAFEBAG)* certBags,unsigned char * keyId,unsigned int keyIdLen,const char * name,STACK_OF (PKCS7)** safes,int certNid,int iter,const char * keyStorePwd)612 int KeyStoreHelper::SetCertPkcs12(X509* cert, PKCS12_SAFEBAG* bag, STACK_OF(PKCS12_SAFEBAG)* certBags,
613                                   unsigned char* keyId, unsigned int keyIdLen,
614                                   const char* name, STACK_OF(PKCS7)** safes,
615                                   int certNid, int iter, const char* keyStorePwd)
616 {
617     if (cert) {
618         bag = PKCS12_add_cert(&certBags, cert);
619         if (name && !PKCS12_add_friendlyname(bag, name, -1)) {
620             goto err;
621         }
622 
623         if (keyIdLen && !PKCS12_add_localkeyid(bag, keyId, keyIdLen)) {
624             goto err;
625         }
626     }
627 
628     if (certBags && !PKCS12_add_safe(safes, certBags, certNid, iter, keyStorePwd)) {
629         goto err;
630     }
631 
632     sk_PKCS12_SAFEBAG_pop_free(certBags, PKCS12_SAFEBAG_free);
633     certBags = nullptr;
634     return RET_OK;
635 err:
636     sk_PKCS12_SAFEBAG_pop_free(certBags, PKCS12_SAFEBAG_free);
637     certBags = nullptr;
638     return RET_FAILED;
639 }
640 
SetPkeyPkcs12(EVP_PKEY * pkey,PKCS12_SAFEBAG * bag,STACK_OF (PKCS12_SAFEBAG)* keyBags,const char * name,STACK_OF (PKCS7)** safes,int iter,const char * keyPwd,int keyType,int keyNid,unsigned char * keyId,unsigned int keyIdLen)641 int KeyStoreHelper::SetPkeyPkcs12(EVP_PKEY* pkey, PKCS12_SAFEBAG* bag, STACK_OF(PKCS12_SAFEBAG)* keyBags,
642                                   const char* name, STACK_OF(PKCS7)** safes, int iter, const char* keyPwd,
643                                   int keyType, int keyNid, unsigned char* keyId, unsigned int keyIdLen)
644 {
645     if (pkey) {
646         bag = PKCS12_add_key(&keyBags, pkey, keyType, iter, keyNid, keyPwd);
647         if (!bag) {
648             return RET_FAILED;
649         }
650 
651         if (GetAttrNid(bag, pkey, NID_ms_csp_name) == RET_FAILED) {
652             goto err;
653         }
654 
655         if (GetAttrNid(bag, pkey, NID_LocalKeySet) == RET_FAILED) {
656             goto err;
657         }
658 
659         if (name && !PKCS12_add_friendlyname(bag, name, -1)) {
660             goto err;
661         }
662 
663         if (keyIdLen && !PKCS12_add_localkeyid(bag, keyId, keyIdLen)) {
664             goto err;
665         }
666     }
667     if (keyBags && !PKCS12_add_safe(safes, keyBags, -1, 0, NULL)) {
668         goto err;
669     }
670 
671     sk_PKCS12_SAFEBAG_pop_free(keyBags, PKCS12_SAFEBAG_free);
672     keyBags = nullptr;
673     return RET_OK;
674 err:
675     sk_PKCS12_SAFEBAG_pop_free(keyBags, PKCS12_SAFEBAG_free);
676     keyBags = nullptr;
677     return RET_FAILED;
678 }
679 
GetAttrNid(PKCS12_SAFEBAG * bag,EVP_PKEY * pkey,int nid)680 int KeyStoreHelper::GetAttrNid(PKCS12_SAFEBAG* bag, EVP_PKEY* pkey, int nid)
681 {
682     int idx;
683     X509_ATTRIBUTE* attr;
684     idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
685     if (idx < 0) {
686         return RET_OK;
687     }
688     attr = EVP_PKEY_get_attr(pkey, idx);
689     STACK_OF(X509_ATTRIBUTE)* attrlib = const_cast<STACK_OF(X509_ATTRIBUTE)*>(PKCS12_SAFEBAG_get0_attrs(bag));
690     if (!X509at_add1_attr(&attrlib, attr)) {
691         return RET_FAILED;
692     }
693     return RET_OK;
694 }
695 
ParsePkcs12Safebag(PKCS12_SAFEBAG * bag,const char * pass,int passlen,STACK_OF (X509)* ocerts)696 int KeyStoreHelper::ParsePkcs12Safebag(PKCS12_SAFEBAG* bag, const char* pass, int passlen, STACK_OF(X509)* ocerts)
697 {
698     X509* x509Cert = nullptr;
699     const ASN1_TYPE* attr;
700     ASN1_BMPSTRING* name = NULL;
701     ASN1_OCTET_STRING* kid = NULL;
702     if ((attr = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName))) {
703         name = attr->value.bmpstring;
704     }
705 
706     if ((attr = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID))) {
707         kid = attr->value.octet_string;
708     }
709 
710     if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag && PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) {
711         return RET_OK;
712     }
713 
714     if ((x509Cert = PKCS12_SAFEBAG_get1_cert(bag)) == NULL) {
715         return RET_FAILED;
716     }
717 
718     if (kid && !X509_keyid_set1(x509Cert, kid->data, kid->length)) {
719         goto err;
720     }
721 
722     if (name) {
723         int len;
724         unsigned char* data;
725         len = ASN1_STRING_to_UTF8(&data, name);
726         if (!SetX509Alias(len, x509Cert, data)) {
727             goto err;
728         }
729     }
730     if (!sk_X509_push(ocerts, x509Cert)) {
731         goto err;
732     }
733 
734     return RET_OK;
735 err:
736     X509_free(x509Cert);
737     return RET_FAILED;
738 }
739 
SetX509Alias(int len,X509 * x509,unsigned char * data)740 bool KeyStoreHelper::SetX509Alias(int len, X509* x509, unsigned char* data)
741 {
742     if (len >= 0) {
743         int r = X509_alias_set1(x509, data, len);
744         OPENSSL_free(data);
745         if (!r) {
746             X509_free(x509);
747             return false;
748         }
749     }
750     return true;
751 }
752 
ParsePkcs12Safebags(const STACK_OF (PKCS12_SAFEBAG)* bags,const char * pass,int passlen,STACK_OF (X509)* ocerts)753 int KeyStoreHelper::ParsePkcs12Safebags(const STACK_OF(PKCS12_SAFEBAG)* bags, const char* pass,
754                                         int passlen, STACK_OF(X509)* ocerts)
755 {
756     int i;
757     for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
758         if (ParsePkcs12Safebag(sk_PKCS12_SAFEBAG_value(bags, i), pass, passlen, ocerts) == RET_FAILED)
759             return RET_FAILED;
760     }
761     return RET_OK;
762 }
763 } // namespace SignatureTools
764 } // namespace OHOS