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