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