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 <cassert>
16 #include <string>
17 #include <unordered_map>
18 #include <openssl/x509.h>
19 #include <openssl/x509v3.h>
20 #include <openssl/conf.h>
21 
22 #include "cert_tools.h"
23 #include "openssl/ec.h"
24 #include "openssl/obj_mac.h"
25 #include "openssl/asn1.h"
26 #include "signature_tools_log.h"
27 #include "constant.h"
28 
29 namespace OHOS {
30 namespace SignatureTools {
31 
32 static std::unordered_map<std::string, long> externDic{
33     {"digitalSignature", X509v3_KU_DIGITAL_SIGNATURE},
34     {"nonRepudiation", X509v3_KU_NON_REPUDIATION},
35     {"keyEncipherment", X509v3_KU_KEY_ENCIPHERMENT},
36     {"dataEncipherment", X509v3_KU_DATA_ENCIPHERMENT},
37     {"keyAgreement", X509v3_KU_KEY_AGREEMENT},
38     {"certificateSignature", X509v3_KU_KEY_CERT_SIGN},
39     {"crlSignature", X509v3_KU_CRL_SIGN},
40     {"encipherOnly", X509v3_KU_ENCIPHER_ONLY},
41     {"decipherOnly", X509v3_KU_DECIPHER_ONLY},
42 
43 };
44 
45 static std::unordered_map<std::string, std::string> externKey{
46     {"serverAuthentication", "1.3.6.1.5.5.7.3.1"},
47     {"clientAuthentication",  "1.3.6.1.5.5.7.3.2"},
48     {"codeSignature",  "1.3.6.1.5.5.7.3.3"},
49     {"emailProtection",  "1.3.6.1.5.5.7.3.4"},
50     {"smartCardLogin",  "1.3.6.1.5.5.7.3.5"},
51     {"timestamp",  "1.3.6.1.5.5.7.3.8"},
52     {"ocspSignature",  "1.3.6.1.5.5.7.3.9"},
53 
54 };
55 
SaveCertTofile(const std::string& filename, X509* cert)56 bool CertTools::SaveCertTofile(const std::string& filename, X509* cert)
57 {
58     BIO* certBio = BIO_new_file(filename.data(), "w");
59     if (!certBio) {
60         VerifyHapOpensslUtils::GetOpensslErrorMessage();
61         SIGNATURE_TOOLS_LOGE("BIO_new failed");
62         return false;
63     }
64 
65     if (PEM_write_bio_X509(certBio, cert) < 0) {
66         VerifyHapOpensslUtils::GetOpensslErrorMessage();
67         SIGNATURE_TOOLS_LOGE("PEM_write_bio_X509 failed");
68         BIO_free(certBio);
69         return false;
70     }
71     BIO_free(certBio);
72     return true;
73 }
74 
UpdateConstraint(Options* options)75 static bool UpdateConstraint(Options* options)
76 {
77     if (options->count(Options::BASIC_CONSTRAINTS)) {
78         if (!CertTools::String2Bool(options, Options::BASIC_CONSTRAINTS)) {
79             return false;
80         }
81     } else {
82         (*options)[Options::BASIC_CONSTRAINTS] = DEFAULT_BASIC_CONSTRAINTS;
83     }
84 
85     if (options->count(Options::BASIC_CONSTRAINTS_CRITICAL)) {
86         if (!CertTools::String2Bool(options, Options::BASIC_CONSTRAINTS_CRITICAL)) {
87             return false;
88         }
89     } else {
90         (*options)[Options::BASIC_CONSTRAINTS_CRITICAL] = DEFAULT_BASIC_CONSTRAINTS_CRITICAL;
91     }
92 
93     if (options->count(Options::BASIC_CONSTRAINTS_CA)) {
94         if (!CertTools::String2Bool(options, Options::BASIC_CONSTRAINTS_CA)) {
95             return false;
96         }
97     } else {
98         (*options)[Options::BASIC_CONSTRAINTS_CA] = DEFAULT_BASIC_CONSTRAINTS_CA;
99     }
100     return true;
101 }
102 
SetBisicConstraints(Options* options, X509* cert)103 bool CertTools::SetBisicConstraints(Options* options, X509* cert)
104 {
105     if (!UpdateConstraint(options)) {
106         return false;
107     }
108 
109     bool basicCon = options->GetBool(Options::BASIC_CONSTRAINTS);
110     if (basicCon) {
111         bool basicConstraintsCritical = options->GetBool(Options::BASIC_CONSTRAINTS_CRITICAL);
112         int critial = basicConstraintsCritical ? 1 : 0;
113         bool basicConstraintsCa = options->GetBool(Options::BASIC_CONSTRAINTS_CA);
114         std::string  ContainCa = basicConstraintsCa ? "CA:TRUE" : "CA:FALSE";
115         std::string constraints = ContainCa + "," + "pathlen:" +
116             std::to_string(options->GetInt(Options::BASIC_CONSTRAINTS_PATH_LEN));
117         X509V3_CTX ctx;
118         X509V3_set_ctx_nodb(&ctx);
119 
120         X509_EXTENSION* ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, constraints.c_str());
121         if (!X509_EXTENSION_set_critical(ext, critial)) {
122             SIGNATURE_TOOLS_LOGE("failed to set  critical for extKeyUsage ");
123             X509_EXTENSION_free(ext);
124             VerifyHapOpensslUtils::GetOpensslErrorMessage();
125             return false;
126         }
127         if (!X509_add_ext(cert, ext, -1)) {
128             SIGNATURE_TOOLS_LOGE("X509_add_ext failed");
129             X509_EXTENSION_free(ext);
130             VerifyHapOpensslUtils::GetOpensslErrorMessage();
131             return false;
132         }
133         X509_EXTENSION_free(ext);
134     }
135 
136     return true;
137 }
138 
SetBisicConstraintsPathLen(Options* options, X509* cert)139 bool CertTools::SetBisicConstraintsPathLen(Options* options, X509* cert)
140 {
141     std::string setOptions = "CA:TRUE, pathlen:" +
142         std::to_string(options->GetInt(Options::BASIC_CONSTRAINTS_PATH_LEN));
143     X509V3_CTX ctx;
144     X509V3_set_ctx_nodb(&ctx);
145     X509_EXTENSION* ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, setOptions.c_str());
146     if (!X509_EXTENSION_set_critical(ext, 1)) {
147         SIGNATURE_TOOLS_LOGE("failed to set  critical for extKeyUsage ");
148         X509_EXTENSION_free(ext);
149         VerifyHapOpensslUtils::GetOpensslErrorMessage();
150         return false;
151     }
152     if (!X509_add_ext(cert, ext, -1)) {
153         SIGNATURE_TOOLS_LOGE("X509_add_ext failed\n");
154         X509_EXTENSION_free(ext);
155         VerifyHapOpensslUtils::GetOpensslErrorMessage();
156         return false;
157     }
158     X509_EXTENSION_free(ext);
159     return true;
160 }
161 
SignForSubCert(X509* cert, X509_REQ* subcsr, X509_REQ* rootcsr, EVP_PKEY* caPrikey, Options* options)162 bool CertTools::SignForSubCert(X509* cert, X509_REQ* subcsr, X509_REQ* rootcsr, EVP_PKEY* caPrikey, Options* options)
163 {
164     bool result = false;
165     std::string signAlg = options->GetString(Options::SIGN_ALG);
166     EVP_PKEY* pubKey = X509_REQ_get_pubkey(subcsr);
167     X509_NAME* issuerName = X509_REQ_get_subject_name(rootcsr);
168     X509_NAME* subjectName = X509_REQ_get_subject_name(subcsr);
169     if (pubKey == NULL) {
170         SIGNATURE_TOOLS_LOGE("X509_REQ_get_pubkey failed");
171         goto err;
172     }
173     if (caPrikey == nullptr || rootcsr == nullptr || subcsr == nullptr) {
174         SIGNATURE_TOOLS_LOGE("Sign failed because of caPrikey, roocsr or subcsr is nullptr");
175         goto err;
176     }
177     result = (!X509_set_pubkey(cert, pubKey));
178     if (result) {
179         SIGNATURE_TOOLS_LOGE("X509_set_pubkey failed");
180         goto err;
181     }
182     result = (!X509_set_issuer_name(cert, issuerName));
183     if (result) {
184         SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed");
185         goto err;
186     }
187     result = (!X509_set_subject_name(cert, subjectName));
188     if (result) {
189         SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed");
190         goto err;
191     }
192     result = (!SignCert(cert, caPrikey, signAlg));
193     if (result) {
194         goto err;
195     }
196     EVP_PKEY_free(pubKey);
197     return true;
198 err:
199     EVP_PKEY_free(pubKey);
200     X509_NAME_free(issuerName);
201     X509_NAME_free(subjectName);
202     VerifyHapOpensslUtils::GetOpensslErrorMessage();
203     return false;
204 }
205 
SignCsrGenerateCert(X509_REQ* rootcsr, X509_REQ* subcsr, EVP_PKEY* keyPair, Options* options)206 X509* CertTools::SignCsrGenerateCert(X509_REQ* rootcsr, X509_REQ* subcsr,
207                                      EVP_PKEY* keyPair, Options* options)
208 {
209     bool result = false;
210     X509* cert = X509_new();
211     int validity = options->GetInt(Options::VALIDITY);
212     result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
213               !SetCertSerialNum(cert));
214     if (result) {
215         goto err;
216     }
217     result = SetCertValidity(cert, validity);
218     if (!result) {
219         goto err;
220     }
221     result = (!SetBisicConstraintsPathLen(options, cert) ||
222               !SetKeyIdentifierExt(cert) ||
223               !SetAuthorizeKeyIdentifierExt(cert)||
224               !SetKeyUsage(cert, options) ||
225               !SignForSubCert(cert, subcsr, rootcsr, keyPair, options));
226     if (result) {
227         goto err;
228     }
229     return  cert;
230 err:
231     X509_free(cert);
232     return nullptr;
233 }
234 
SetSubjectForCert(X509_REQ* certReq, X509* cert)235 bool CertTools::SetSubjectForCert(X509_REQ* certReq, X509* cert)
236 {
237     if (certReq == nullptr) {
238         SIGNATURE_TOOLS_LOGE("set subjcet failed because of certReq is nullptr");
239         goto err;
240     }
241 
242     if (X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq)) != 1) {
243         SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed");
244         goto err;
245     }
246 
247     if (X509_set_issuer_name(cert, X509_REQ_get_subject_name(certReq)) != 1) {
248         SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed");
249         goto err;
250     }
251     return true;
252 err:
253     VerifyHapOpensslUtils::GetOpensslErrorMessage();
254     return false;
255 }
256 
GenerateRootCertificate(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)257 X509* CertTools::GenerateRootCertificate(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)
258 {
259     bool result = false;
260     X509* cert = X509_new();
261     int validity = options->GetInt(Options::VALIDITY);
262     std::string signAlg = options->GetString(Options::SIGN_ALG);
263     result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
264               !SetCertSerialNum(cert));
265     if (result) {
266         goto err;
267     }
268     if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
269         goto err;
270     }
271     result = (!SetBisicConstraintsPathLen(options, cert) ||
272               !SetSubjectForCert(certReq, cert) ||
273               !SetCertPublickKey(cert, certReq) ||
274               !SetKeyIdentifierExt(cert) ||
275               !SetKeyUsage(cert, options));
276     if (result) {
277         goto err;
278     }
279     result = (!SignCert(cert, keyPair, signAlg));
280     if (result) {
281         goto err;
282     }
283     return cert;
284 err:
285     X509_free(cert);
286     return nullptr;
287 }
288 
GenerateSubCert(EVP_PKEY* keyPair, X509_REQ* rootcsr, Options* options)289 X509* CertTools::GenerateSubCert(EVP_PKEY* keyPair, X509_REQ* rootcsr, Options* options)
290 {
291     std::unique_ptr<LocalizationAdapter> adapter = std::make_unique< LocalizationAdapter>(options);
292     EVP_PKEY* subKey = nullptr;
293     X509_REQ* subcsr = nullptr;
294     X509* subCert = nullptr;
295     subKey = adapter->GetAliasKey(false);
296     if (subKey == nullptr) {
297         SIGNATURE_TOOLS_LOGE("failed to get the keypair");
298         goto err;
299     }
300     subcsr = CertTools::GenerateCsr(subKey, options->GetString(Options::SIGN_ALG),
301                                     options->GetString(Options::SUBJECT));
302     if (subcsr == nullptr) {
303         SIGNATURE_TOOLS_LOGE("failed to generate csr");
304         goto err;
305     }
306     subCert = SignCsrGenerateCert(rootcsr, subcsr, keyPair, options);
307     if (subCert == nullptr) {
308         SIGNATURE_TOOLS_LOGE("failed to generate the subCert");
309         goto err;
310     }
311     EVP_PKEY_free(subKey);
312     X509_REQ_free(subcsr);
313     return subCert;
314 err:
315     EVP_PKEY_free(subKey);
316     X509_REQ_free(subcsr);
317     return nullptr;
318 }
319 
SetKeyUsage(X509* cert, Options* options)320 bool CertTools::SetKeyUsage(X509* cert, Options* options)
321 {
322     std::string keyUsage = options->GetString(Options::KEY_USAGE);
323     ASN1_INTEGER* keyUsageInt = ASN1_INTEGER_new();
324     long key = 0;
325     if (keyUsage.empty()) {
326         key = X509v3_KU_KEY_CERT_SIGN | X509v3_KU_CRL_SIGN;
327         if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key)) {
328             SIGNATURE_TOOLS_LOGE("failed to set asn1_integer");
329             ASN1_INTEGER_free(keyUsageInt);
330             return false;
331         }
332         if (!X509_add1_ext_i2d(cert, NID_key_usage, keyUsageInt, 0, X509V3_ADD_DEFAULT)) {
333             SIGNATURE_TOOLS_LOGE("failed to add ext");
334             ASN1_INTEGER_free(keyUsageInt);
335             return false;
336         }
337     } else {
338         bool keyUsageCritical = options->GetBool(Options::KEY_USAGE_CRITICAL);
339         int crit = keyUsageCritical > 0 ? 1 : 0;
340         std::vector<std::string> vecs = StringUtils::SplitString(keyUsage.c_str(), ',');
341         for (auto &vec : vecs) {
342             key |= externDic[vec];
343         }
344         if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key)) {
345             SIGNATURE_TOOLS_LOGE("failed to set asn1_integer");
346             ASN1_INTEGER_free(keyUsageInt);
347             return false;
348         }
349         if (!X509_add1_ext_i2d(cert, NID_key_usage, keyUsageInt, crit, X509V3_ADD_DEFAULT)) {
350             SIGNATURE_TOOLS_LOGE("failed to add ext");
351             ASN1_INTEGER_free(keyUsageInt);
352             return false;
353         }
354     }
355     ASN1_INTEGER_free(keyUsageInt);
356     return true;
357 }
358 
SetkeyUsageExt(X509* cert, Options* options)359 bool CertTools::SetkeyUsageExt(X509* cert, Options* options)
360 {
361     X509_EXTENSION* ext = nullptr;
362     bool keyUsageCritical = options->GetBool(Options::KEY_USAGE_CRITICAL);
363     int crit = keyUsageCritical  ? 1 : 0;
364     if (!options->GetString(Options::EXT_KEY_USAGE).empty()) {
365         ext = X509V3_EXT_conf(NULL, NULL, NID_EXT_KEYUSAGE_CONST.c_str(),
366                               externKey[options->GetString(Options::EXT_KEY_USAGE)].c_str());
367         if (!X509_EXTENSION_set_critical(ext, crit)) {
368             SIGNATURE_TOOLS_LOGE("failed to set  critical for extKeyUsage ");
369             X509_EXTENSION_free(ext);
370             return false;
371         }
372         if (!X509_add_ext(cert, ext, -1)) {
373             SIGNATURE_TOOLS_LOGE("failed to add extension");
374             X509_EXTENSION_free(ext);
375             return false;
376         }
377     }
378     X509_EXTENSION_free(ext);
379     return true;
380 }
381 
SetExpandedInformation(X509* cert, Options* options)382 bool CertTools::SetExpandedInformation(X509* cert, Options* options)
383 {
384     bool result = false;
385     result = (!SetKeyUsage(cert, options) ||
386               !SetkeyUsageExt(cert, options));
387     if (result) {
388         SIGNATURE_TOOLS_LOGE("Failed to set expanded information ");
389         return false;
390     }
391     return true;
392 }
393 
SetPubkeyAndSignCert(X509* cert, X509_REQ* issuercsr, X509_REQ* certReq, EVP_PKEY* keyPair, Options* options)394 bool CertTools::SetPubkeyAndSignCert(X509* cert, X509_REQ* issuercsr,
395                                      X509_REQ* certReq, EVP_PKEY* keyPair, Options* options)
396 {
397     if (!X509_set_issuer_name(cert, X509_REQ_get_subject_name(issuercsr))) {
398         SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed");
399         goto err;
400     }
401 
402     if (!X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq))) {
403         SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed");
404         goto err;
405     }
406     if ((options->GetString(Options::SIGN_ALG)) == SIGN_ALG_SHA256) {
407         if (!X509_sign(cert, keyPair, EVP_sha256())) {
408             SIGNATURE_TOOLS_LOGE("X509_sign failed");
409             goto err;
410         }
411     } else {
412         if (!X509_sign(cert, keyPair, EVP_sha384())) {
413             SIGNATURE_TOOLS_LOGE("X509_sign failed");
414             goto err;
415         }
416     }
417     return true;
418 err:
419     VerifyHapOpensslUtils::GetOpensslErrorMessage();
420     return false;
421 }
422 
GenerateCert(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)423 X509* CertTools::GenerateCert(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)
424 {
425     int validity = 0;
426     bool result = false;
427     X509_REQ* issuercsr = CertTools::GenerateCsr(keyPair, options->GetString(Options::SIGN_ALG),
428                                                  options->GetString(Options::ISSUER));
429     if (issuercsr == nullptr) {
430         SIGNATURE_TOOLS_LOGE("failed to generate the issuercsr");
431         return nullptr;
432     }
433 
434     X509* cert = X509_new();
435     result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
436               !SetCertSerialNum(cert) ||
437               !SetKeyIdentifierExt(cert));
438     if (result) {
439         goto err;
440     }
441     validity = options->GetInt(Options::VALIDITY);
442     if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
443         goto err;
444     }
445 
446     result = (!SetBisicConstraints(options, cert) ||
447               !SetCertPublickKey(cert, certReq) ||
448               !SetExpandedInformation(cert, options) ||
449               !SetPubkeyAndSignCert(cert, issuercsr, certReq, keyPair, options));
450     if (result) {
451         goto err;
452     }
453     X509_REQ_free(issuercsr);
454     return cert;
455 err:
456     X509_free(cert);
457     X509_REQ_free(issuercsr);
458     return nullptr;
459 }
460 
GenerateCsr(EVP_PKEY* evpPkey, std::string signAlgorithm, std::string subject)461 X509_REQ* CertTools::GenerateCsr(EVP_PKEY* evpPkey, std::string signAlgorithm, std::string subject)
462 {
463     X509_NAME* name = nullptr;
464     X509_REQ* req = X509_REQ_new();
465 
466     if (!X509_REQ_set_pubkey(req, evpPkey)) {
467         SIGNATURE_TOOLS_LOGE("X509_REQ_set_pubkey failed");
468         goto err;
469     }
470 
471     name = BuildDN(subject, req);
472     if (!name) {
473         SIGNATURE_TOOLS_LOGE("failed to add subject into cert");
474         goto err;
475     }
476 
477     if (signAlgorithm == SIGN_ALG_SHA256) {
478         if (!X509_REQ_sign(req, evpPkey, EVP_sha256())) {
479             SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed");
480             goto err;
481         }
482     } else if (signAlgorithm == SIGN_ALG_SHA384) {
483         if (!X509_REQ_sign(req, evpPkey, EVP_sha384())) {
484             SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed");
485             goto err;
486         }
487     } else {
488         PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
489                             "Sign algorithm format error! Please check again.");
490         goto err;
491     }
492     return req;
493 err:
494     VerifyHapOpensslUtils::GetOpensslErrorMessage();
495     X509_REQ_free(req);
496     return nullptr;
497 }
498 
CsrToString(X509_REQ* csr)499 std::string CertTools::CsrToString(X509_REQ* csr)
500 {
501     BIO* csrBio = BIO_new(BIO_s_mem());
502     if (!csrBio) {
503         return "";
504     }
505     if (!PEM_write_bio_X509_REQ(csrBio, csr)) {
506         VerifyHapOpensslUtils::GetOpensslErrorMessage();
507         SIGNATURE_TOOLS_LOGE("PEM_write_bio_X509_REQ error");
508         BIO_free(csrBio);
509         return "";
510     }
511     BUF_MEM* data = nullptr;
512     BIO_get_mem_ptr(csrBio, &data);
513     if (!data) {
514         BIO_free(csrBio);
515         return "";
516     }
517     if (!data->data) {
518         BIO_free(csrBio);
519         return "";
520     }
521     std::string csrStr(data->data, data->length);
522     BIO_free(csrBio);
523     return csrStr;
524 }
525 
ReadfileToX509(const std::string& filename)526 X509* CertTools::ReadfileToX509(const std::string& filename)
527 {
528     BIO* certBio = BIO_new_file(filename.c_str(), "rb");
529     if (!certBio) {
530         VerifyHapOpensslUtils::GetOpensslErrorMessage();
531         SIGNATURE_TOOLS_LOGE("BIO_new_file failed");
532         BIO_free(certBio);
533         return nullptr;
534     }
535 
536     X509* cert = X509_new();
537     if (!PEM_read_bio_X509(certBio, &cert, NULL, NULL)) {
538         VerifyHapOpensslUtils::GetOpensslErrorMessage();
539         SIGNATURE_TOOLS_LOGE("PEM_read_bio_X509 failed");
540         X509_free(cert);
541         BIO_free(certBio);
542         return nullptr;
543     }
544     BIO_free(certBio);
545 
546     return cert;
547 }
548 
SetCertVersion(X509* cert, int versionNum)549 bool CertTools::SetCertVersion(X509* cert, int versionNum)
550 {
551     if (!X509_set_version(cert, versionNum)) {
552         VerifyHapOpensslUtils::GetOpensslErrorMessage();
553         SIGNATURE_TOOLS_LOGE("set x509 cert version failed");
554         return false;
555     }
556     return true;
557 }
558 
SetCertSerialNum(X509* cert)559 bool CertTools::SetCertSerialNum(X509* cert)
560 {
561     BN_CTX* ctx = BN_CTX_new();
562     BIGNUM* bignum = BN_new();
563     uint8_t serialNumberValue[RANDOM_SERIAL_NUMBER_LENGTH] = {0};
564     if (!SerialNumberBuilder(serialNumberValue, sizeof(serialNumberValue))) {
565         goto err;
566     }
567     if (!BN_bin2bn(serialNumberValue, sizeof(serialNumberValue), bignum)) {
568         VerifyHapOpensslUtils::GetOpensslErrorMessage();
569         goto err;
570     }
571     if (BN_is_negative(bignum)) {
572         BN_set_negative(bignum, 0); // Replace negative numbers with positive ones
573     }
574     if (!BN_to_ASN1_INTEGER(bignum, X509_get_serialNumber(cert))) {
575         VerifyHapOpensslUtils::GetOpensslErrorMessage();
576         goto err;
577     }
578     BN_CTX_free(ctx);
579     BN_free(bignum);
580     return true;
581 err:
582     SIGNATURE_TOOLS_LOGE("set x509 cert serial number failed");
583     BN_CTX_free(ctx);
584     BN_free(bignum);
585     return false;
586 }
587 
SetCertIssuerName(X509* cert, X509_NAME* issuer)588 bool CertTools::SetCertIssuerName(X509* cert, X509_NAME* issuer)
589 {
590     if (!X509_set_issuer_name(cert, issuer)) {
591         VerifyHapOpensslUtils::GetOpensslErrorMessage();
592         SIGNATURE_TOOLS_LOGE("set x509 cert issuer name failed");
593         return false;
594     }
595     return true;
596 }
597 
SetCertSubjectName(X509* cert, X509_REQ* subjectCsr)598 bool CertTools::SetCertSubjectName(X509* cert, X509_REQ* subjectCsr)
599 {
600     X509_NAME* subject = nullptr;
601     if (!(subject = X509_REQ_get_subject_name(subjectCsr))) {
602         VerifyHapOpensslUtils::GetOpensslErrorMessage();
603         SIGNATURE_TOOLS_LOGE("get X509 cert subject name failed");
604         return false;
605     }
606     if (!X509_set_subject_name(cert, subject)) {
607         VerifyHapOpensslUtils::GetOpensslErrorMessage();
608         SIGNATURE_TOOLS_LOGE("set X509 cert subject name failed");
609         return false;
610     }
611     return true;
612 }
613 
SetCertValidityStartAndEnd(X509* cert, long vilidityStart, long vilidityEnd)614 bool CertTools::SetCertValidityStartAndEnd(X509* cert, long vilidityStart, long vilidityEnd)
615 {
616     if (!X509_gmtime_adj(X509_getm_notBefore(cert), vilidityStart)) {
617         VerifyHapOpensslUtils::GetOpensslErrorMessage();
618         SIGNATURE_TOOLS_LOGE("set cert vilidity start time failed");
619         return false;
620     }
621     if (!X509_gmtime_adj(X509_getm_notAfter(cert), vilidityEnd)) {
622         VerifyHapOpensslUtils::GetOpensslErrorMessage();
623         SIGNATURE_TOOLS_LOGE("set cert vilidity end time failed");
624         return false;
625     }
626     return true;
627 }
628 
SetCertPublickKey(X509* cert, X509_REQ* subjectCsr)629 bool CertTools::SetCertPublickKey(X509* cert, X509_REQ* subjectCsr)
630 {
631     EVP_PKEY* publicKey = X509_REQ_get_pubkey(subjectCsr);
632     if (!publicKey) {
633         VerifyHapOpensslUtils::GetOpensslErrorMessage();
634         SIGNATURE_TOOLS_LOGE("get the pubkey from csr failed");
635         return false;
636     }
637     if (!X509_set_pubkey(cert, publicKey)) {
638         VerifyHapOpensslUtils::GetOpensslErrorMessage();
639         EVP_PKEY_free(publicKey);
640         SIGNATURE_TOOLS_LOGE("set public key to cert failed");
641         return false;
642     }
643     EVP_PKEY_free(publicKey);
644     return true;
645 }
646 
SetBasicExt(X509* cert)647 bool CertTools::SetBasicExt(X509* cert)
648 {
649     X509_EXTENSION* basicExtension = X509V3_EXT_conf(NULL, NULL, NID_BASIC_CONST.c_str(),
650                                                      DEFAULT_BASIC_EXTENSION.c_str());
651     if (!X509_add_ext(cert, basicExtension, -1)) {
652         VerifyHapOpensslUtils::GetOpensslErrorMessage();
653         SIGNATURE_TOOLS_LOGE("set basicExtension information failed");
654         X509_EXTENSION_free(basicExtension);
655         return false;
656     }
657     X509_EXTENSION_free(basicExtension);
658     return true;
659 }
660 
SetkeyUsageExt(X509* cert)661 bool CertTools::SetkeyUsageExt(X509* cert)
662 {
663     X509_EXTENSION* keyUsageExtension = X509V3_EXT_conf(NULL, NULL, NID_KEYUSAGE_CONST.c_str(),
664                                                         DEFAULT_KEYUSAGE_EXTENSION.c_str());
665     if (!X509_add_ext(cert, keyUsageExtension, -1)) {
666         VerifyHapOpensslUtils::GetOpensslErrorMessage();
667         SIGNATURE_TOOLS_LOGE("set keyUsageExtension information failed");
668         X509_EXTENSION_free(keyUsageExtension);
669         return false;
670     }
671     X509_EXTENSION_free(keyUsageExtension);
672     return true;
673 }
674 
SetKeyUsageEndExt(X509* cert)675 bool CertTools::SetKeyUsageEndExt(X509* cert)
676 {
677     X509_EXTENSION* keyUsageEndExtension = X509V3_EXT_conf(NULL, NULL, NID_EXT_KEYUSAGE_CONST.c_str(),
678                                                            DEFAULT_EXTEND_KEYUSAGE.c_str());
679     if (!X509_add_ext(cert, keyUsageEndExtension, -1)) {
680         VerifyHapOpensslUtils::GetOpensslErrorMessage();
681         SIGNATURE_TOOLS_LOGE("set keyUsageEndExtension information failed");
682         X509_EXTENSION_free(keyUsageEndExtension);
683         return false;
684     }
685     X509_EXTENSION_free(keyUsageEndExtension);
686     return true;
687 }
688 
SetKeyIdentifierExt(X509* cert)689 bool CertTools::SetKeyIdentifierExt(X509* cert)
690 {
691     unsigned char digest[SHA256_DIGEST_LENGTH] = {0};
692     unsigned int digestLen = 0;
693     if (X509_pubkey_digest(cert, EVP_sha256(), digest, &digestLen) != 1) {
694         VerifyHapOpensslUtils::GetOpensslErrorMessage();
695         SIGNATURE_TOOLS_LOGE("digest x509 cert public key failed");
696         return false;
697     }
698     ASN1_OCTET_STRING* pubKeyDigestData = ASN1_OCTET_STRING_new();
699     if (!ASN1_OCTET_STRING_set(pubKeyDigestData, digest, digestLen)) {
700         VerifyHapOpensslUtils::GetOpensslErrorMessage();
701         SIGNATURE_TOOLS_LOGE("set ANS1 pubKeyDigestData failed");
702         ASN1_OCTET_STRING_free(pubKeyDigestData);
703         return false;
704     }
705 
706     X509_EXTENSION* subKeyIdentifierExtension = nullptr;
707     /* function OBJ_nid2obj(NID_subject_key_identifier) return value is a global variable, so should not free it */
708     subKeyIdentifierExtension = X509_EXTENSION_create_by_OBJ(NULL, OBJ_nid2obj(NID_subject_key_identifier),
709                                                              0, pubKeyDigestData);
710     if (!X509_add_ext(cert, subKeyIdentifierExtension, -1)) {
711         VerifyHapOpensslUtils::GetOpensslErrorMessage();
712         SIGNATURE_TOOLS_LOGE("set subKeyIdentifierExtension information failed");
713         ASN1_OCTET_STRING_free(pubKeyDigestData);
714         X509_EXTENSION_free(subKeyIdentifierExtension);
715         return false;
716     }
717     ASN1_OCTET_STRING_free(pubKeyDigestData);
718     X509_EXTENSION_free(subKeyIdentifierExtension);
719     return true;
720 }
721 
SetAuthorizeKeyIdentifierExt(X509* cert)722 bool CertTools::SetAuthorizeKeyIdentifierExt(X509* cert)
723 {
724     unsigned char key_id[] = { 0x73, 0x3a, 0x81, 0x87, 0x8f, 0x95, 0xc1, 0x94,
725                                0xcf, 0xef, 0xab, 0x6f, 0x7f, 0x01, 0x52, 0x86,
726                                0xa3, 0xc2, 0x01, 0xc2 };
727     unsigned int key_id_len = sizeof(key_id);
728     X509_EXTENSION* ext = nullptr;
729     AUTHORITY_KEYID* akid = AUTHORITY_KEYID_new();
730     akid->keyid = ASN1_OCTET_STRING_new();
731     if (!ASN1_OCTET_STRING_set(akid->keyid, key_id, key_id_len)) {
732         VerifyHapOpensslUtils::GetOpensslErrorMessage();
733         SIGNATURE_TOOLS_LOGE("set ANS1 pubKeyDigestData failed");
734         AUTHORITY_KEYID_free(akid);
735         return false;
736     }
737     ext = X509V3_EXT_i2d(NID_authority_key_identifier, 1, akid);
738     if (!X509_add_ext(cert, ext, -1)) {
739         SIGNATURE_TOOLS_LOGE("Failed to add AKI extension to certificate");
740         X509_EXTENSION_free(ext);
741         AUTHORITY_KEYID_free(akid);
742         return false;
743     }
744 
745     X509_EXTENSION_free(ext);
746     AUTHORITY_KEYID_free(akid);
747     return true;
748 }
749 
SetSignCapacityExt(X509* cert, const char signCapacity[], int capacityLen)750 bool CertTools::SetSignCapacityExt(X509* cert, const char signCapacity[], int capacityLen)
751 {
752     ASN1_OCTET_STRING* certSignCapacityData = ASN1_OCTET_STRING_new();
753     if (!ASN1_OCTET_STRING_set(certSignCapacityData, (const unsigned char*)signCapacity, capacityLen)) {
754         VerifyHapOpensslUtils::GetOpensslErrorMessage();
755         SIGNATURE_TOOLS_LOGE("failed to set pubkey digst into ASN1 object");
756         ASN1_OCTET_STRING_free(certSignCapacityData);
757         return false;
758     }
759     // generate user-define Nid
760     ASN1_OBJECT* nid = OBJ_txt2obj(X509_EXT_OID.c_str(), 1);
761     X509_EXTENSION* certSignCapacityExt = X509_EXTENSION_create_by_OBJ(NULL, nid, 0, certSignCapacityData);
762 
763     if (!X509_add_ext(cert, certSignCapacityExt, -1)) {
764         VerifyHapOpensslUtils::GetOpensslErrorMessage();
765         SIGNATURE_TOOLS_LOGE("set certSignCapacityExt information failed");
766         ASN1_OBJECT_free(nid);
767         X509_EXTENSION_free(certSignCapacityExt);
768         ASN1_OCTET_STRING_free(certSignCapacityData);
769         return false;
770     }
771     ASN1_OBJECT_free(nid);
772     X509_EXTENSION_free(certSignCapacityExt);
773     ASN1_OCTET_STRING_free(certSignCapacityData);
774     return true;
775 }
776 
SignCert(X509* cert, EVP_PKEY* privateKey, std::string signAlg)777 bool CertTools::SignCert(X509* cert, EVP_PKEY* privateKey, std::string signAlg)
778 {
779     const EVP_MD* alg = nullptr;
780     if (signAlg == SIGN_ALG_SHA256) {
781         /* in openssl this func return value is stack variable, so we not need to release it */
782         alg = EVP_sha256();
783     }
784     if (signAlg == SIGN_ALG_SHA384) {
785         alg = EVP_sha384();
786     }
787     if (!X509_sign(cert, privateKey, alg)) {
788         VerifyHapOpensslUtils::GetOpensslErrorMessage();
789         SIGNATURE_TOOLS_LOGE("sign X509 cert failed");
790         return false;
791     }
792     return true;
793 }
794 
SetCertValidity(X509* cert, int validity)795 bool CertTools::SetCertValidity(X509* cert, int validity)
796 {
797     if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
798         return false;
799     }
800     return true;
801 }
802 
SerialNumberBuilder(uint8_t* serialNum, int length)803 bool CertTools::SerialNumberBuilder(uint8_t* serialNum, int length)
804 {
805     if (RAND_bytes(serialNum, length) != 1) { // this function is thread safity
806         SIGNATURE_TOOLS_LOGE("serial number build failed");
807         return false;
808     }
809     return true;
810 }
811 
GenerateEndCert(X509_REQ* csr, EVP_PKEY* issuerKeyPair, LocalizationAdapter& adapter, const char signCapacity[], int capacityLen)812 X509* CertTools::GenerateEndCert(X509_REQ* csr, EVP_PKEY* issuerKeyPair,
813                                  LocalizationAdapter& adapter,
814                                  const char signCapacity[], int capacityLen)
815 {
816     X509* cert = X509_new(); // in this function, should not release X509cert memory
817     X509_REQ* issuerReq = nullptr;
818     bool result = false;
819     issuerReq = X509_REQ_new();
820     std::string issuerStr = adapter.options->GetString(adapter.options->ISSUER);
821     int validity = adapter.options->GetInt(adapter.options->VALIDITY);
822     std::string signAlg = adapter.options->GetString(adapter.options->SIGN_ALG);
823 
824     result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) || !SetCertSerialNum(cert));
825     if (result) {
826         goto err;
827     }
828     result = (!SetCertIssuerName(cert, BuildDN(issuerStr, issuerReq)) || !SetCertSubjectName(cert, csr));
829     if (result) {
830         goto err;
831     }
832     result = (!SetCertValidity(cert, validity) || !SetCertPublickKey(cert, csr));
833     if (result) {
834         goto err;
835     }
836     result = (!SetBasicExt(cert) || !SetkeyUsageExt(cert) || !SetKeyUsageEndExt(cert));
837     if (result) {
838         goto err;
839     }
840     result = (!SetKeyIdentifierExt(cert) || !SetSignCapacityExt(cert, signCapacity, capacityLen));
841     if (result) {
842         goto err;
843     }
844     if (!SignCert(cert, issuerKeyPair, signAlg)) {
845         goto err;
846     }
847 
848     adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {});
849     return cert; // return x509 assets
850 err:
851     adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {cert});
852     return nullptr;
853 }
854 
String2Bool(Options* options, const std::string& option)855 bool CertTools::String2Bool(Options* options, const std::string& option)
856 {
857     std::string val = options->GetString(option);
858     if (val == "1" || val == "true" || val == "TRUE") {
859         (*options)[option] = true;
860     } else if (val == "0" || val == "false" || val == "FALSE") {
861         (*options)[option] = false;
862     } else {
863         PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
864                             val + "is not valid value for " + "-" + option);
865         return false;
866     }
867     return true;
868 }
869 } // namespace SignatureTools
870 } // namespace OHOS
871 
872