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