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