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