1 /*
2 * Copyright (C) 2021 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
16 #include "util/hap_cert_verify_openssl_utils.h"
17
18 #include <cmath>
19 #include <fstream>
20
21 #include "openssl/pem.h"
22 #include "openssl/sha.h"
23
24 #include "common/hap_verify_log.h"
25 #include "init/hap_crl_manager.h"
26 #include "init/trusted_root_ca.h"
27 #include "securec.h"
28 #include "util/hap_verify_openssl_utils.h"
29
30 namespace OHOS {
31 namespace Security {
32 namespace Verify {
33 const uint32_t HapCertVerifyOpensslUtils::MIN_CERT_CHAIN_LEN_NEED_VERIFY_CRL = 2;
34 const int32_t HapCertVerifyOpensslUtils::OPENSSL_READ_CRL_MAX_TIME = 1048576; // 1024 * 1024
35 const int32_t HapCertVerifyOpensslUtils::OPENSSL_READ_CRL_LEN_EACH_TIME = 1024;
36 const int32_t HapCertVerifyOpensslUtils::BASE64_ENCODE_LEN_OF_EACH_GROUP_DATA = 4;
37 const int32_t HapCertVerifyOpensslUtils::BASE64_ENCODE_PACKET_LEN = 3;
38 constexpr int32_t BUFF_SIZE = 3;
39
GetX509CertFromPemString(const std::string & pemString)40 X509* HapCertVerifyOpensslUtils::GetX509CertFromPemString(const std::string& pemString)
41 {
42 BIO* pemBio = BIO_new(BIO_s_mem());
43 if (pemBio == nullptr) {
44 HapVerifyOpensslUtils::GetOpensslErrorMessage();
45 HAPVERIFY_LOG_ERROR(LABEL, "BIO_new failed");
46 return nullptr;
47 }
48 int32_t strLen = static_cast<int>(pemString.size());
49 if (BIO_write(pemBio, pemString.c_str(), strLen) != strLen) {
50 HapVerifyOpensslUtils::GetOpensslErrorMessage();
51 HAPVERIFY_LOG_ERROR(LABEL, "BIO_write failed");
52 BIO_free_all(pemBio);
53 return nullptr;
54 }
55 X509* cert = PEM_read_bio_X509(pemBio, nullptr, nullptr, nullptr);
56 BIO_free_all(pemBio);
57 return cert;
58 }
59
GetX509CertFromBase64String(const std::string & base64String)60 X509* HapCertVerifyOpensslUtils::GetX509CertFromBase64String(const std::string& base64String)
61 {
62 std::unique_ptr<unsigned char[]> decodeBuffer = std::make_unique<unsigned char[]>(base64String.size());
63
64 const unsigned char* input = reinterpret_cast<const unsigned char *>(base64String.c_str());
65 int32_t len = EVP_DecodeBlock(decodeBuffer.get(), input, base64String.size());
66 if (len <= 0) {
67 HapVerifyOpensslUtils::GetOpensslErrorMessage();
68 HAPVERIFY_LOG_ERROR(LABEL, "base64Decode failed, len: %{public}d", len);
69 return nullptr;
70 }
71
72 const unsigned char* derBits = decodeBuffer.get();
73 X509* cert = d2i_X509(nullptr, &derBits, len);
74 return cert;
75 }
76
GetPublickeyBase64FromPemCert(const std::string & certStr,std::string & publicKey)77 bool HapCertVerifyOpensslUtils::GetPublickeyBase64FromPemCert(const std::string& certStr, std::string& publicKey)
78 {
79 X509* cert = GetX509CertFromPemString(certStr);
80 if (cert == nullptr) {
81 HAPVERIFY_LOG_ERROR(LABEL, "GetX509CertFromPemString failed");
82 return false;
83 }
84
85 if (!GetPublickeyBase64(cert, publicKey)) {
86 HAPVERIFY_LOG_ERROR(LABEL, "X509_get_pubkey failed");
87 HapVerifyOpensslUtils::GetOpensslErrorMessage();
88 X509_free(cert);
89 return false;
90 }
91 X509_free(cert);
92 return true;
93 }
94
GetFingerprintBase64FromPemCert(const std::string & certStr,std::string & fingerprint)95 bool HapCertVerifyOpensslUtils::GetFingerprintBase64FromPemCert(const std::string& certStr, std::string& fingerprint)
96 {
97 HAPVERIFY_LOG_DEBUG(LABEL, "GetFingerprintBase64FromPemCert begin");
98 X509* cert = GetX509CertFromPemString(certStr);
99 if (cert == nullptr) {
100 HAPVERIFY_LOG_ERROR(LABEL, "GetX509CertFromPemString failed");
101 return false;
102 }
103 int32_t certLen = i2d_X509(cert, nullptr);
104 if (certLen <= 0) {
105 HAPVERIFY_LOG_ERROR(LABEL, "certLen %{public}d, i2d_X509 failed", certLen);
106 HapVerifyOpensslUtils::GetOpensslErrorMessage();
107 X509_free(cert);
108 return false;
109 }
110
111 std::unique_ptr<unsigned char[]> derCertificate = std::make_unique<unsigned char[]>(certLen);
112
113 unsigned char* derCertificateBackup = derCertificate.get();
114 if (i2d_X509(cert, &derCertificateBackup) <= 0) {
115 HAPVERIFY_LOG_ERROR(LABEL, "i2d_X509 failed");
116 HapVerifyOpensslUtils::GetOpensslErrorMessage();
117 X509_free(cert);
118 return false;
119 }
120 SHA256_CTX sha256;
121 SHA256_Init(&sha256);
122 SHA256_Update(&sha256, derCertificate.get(), certLen);
123 unsigned char hash[SHA256_DIGEST_LENGTH];
124 SHA256_Final(hash, &sha256);
125 char buff[BUFF_SIZE] = {0};
126 for (int32_t index = 0; index < SHA256_DIGEST_LENGTH; ++index) {
127 if (sprintf_s(buff, sizeof(buff), "%02X", hash[index]) < 0) {
128 fingerprint.clear();
129 HAPVERIFY_LOG_ERROR(LABEL, "transforms hash string to hexadecimal string failed");
130 X509_free(cert);
131 return false;
132 }
133 fingerprint += buff;
134 }
135 X509_free(cert);
136 HAPVERIFY_LOG_DEBUG(LABEL, "GetFingerprintBase64FromPemCert end %{public}s", fingerprint.c_str());
137 return true;
138 }
139
GetPublickeyBase64(const X509 * cert,std::string & publicKey)140 bool HapCertVerifyOpensslUtils::GetPublickeyBase64(const X509* cert, std::string& publicKey)
141 {
142 EVP_PKEY *pkey = X509_get0_pubkey(cert);
143 if (pkey == nullptr) {
144 HAPVERIFY_LOG_ERROR(LABEL, "X509_get0_pubkey failed");
145 HapVerifyOpensslUtils::GetOpensslErrorMessage();
146 return false;
147 }
148
149 int32_t keyLen = i2d_PublicKey(pkey, nullptr);
150 if (keyLen <= 0) {
151 HAPVERIFY_LOG_ERROR(LABEL, "keyLen %{public}d, i2d_PublicKey failed", keyLen);
152 HapVerifyOpensslUtils::GetOpensslErrorMessage();
153 return false;
154 }
155 std::unique_ptr<unsigned char[]> derPublicKey = std::make_unique<unsigned char[]>(keyLen);
156 int32_t base64KeyLen = CalculateLenAfterBase64Encode(keyLen);
157 std::unique_ptr<unsigned char[]> base64PublicKey = std::make_unique<unsigned char[]>(base64KeyLen);
158 unsigned char* derCertificateBackup = derPublicKey.get();
159 if (i2d_PublicKey(pkey, &derCertificateBackup) <= 0) {
160 HAPVERIFY_LOG_ERROR(LABEL, "i2d_PublicKey failed");
161 HapVerifyOpensslUtils::GetOpensslErrorMessage();
162 return false;
163 }
164
165 int32_t outLen = EVP_EncodeBlock(base64PublicKey.get(), derPublicKey.get(), keyLen);
166 publicKey = std::string(reinterpret_cast<char*>(base64PublicKey.get()), outLen);
167 return true;
168 }
169
170 /*
171 * The length after Base64 encoding is 4/3 of the length before encoding,
172 * and openssl function will add '\0' to the encoded string.
173 * So len_after_encode = len_before_encode * 4/3 + 1
174 */
CalculateLenAfterBase64Encode(int32_t len)175 int32_t HapCertVerifyOpensslUtils::CalculateLenAfterBase64Encode(int32_t len)
176 {
177 return static_cast<int>(ceil(static_cast<long double>(len) / BASE64_ENCODE_PACKET_LEN) *
178 BASE64_ENCODE_LEN_OF_EACH_GROUP_DATA + 1);
179 }
180
CompareX509Cert(const X509 * certA,const std::string & base64Cert)181 bool HapCertVerifyOpensslUtils::CompareX509Cert(const X509* certA, const std::string& base64Cert)
182 {
183 if (certA == nullptr) {
184 HAPVERIFY_LOG_ERROR(LABEL, "certA is nullptr");
185 return false;
186 }
187
188 X509* certB = GetX509CertFromPemString(base64Cert);
189 if (certB == nullptr) {
190 HAPVERIFY_LOG_ERROR(LABEL, "generate certB failed");
191 return false;
192 }
193 bool ret = (X509_cmp(certA, certB) == 0);
194 X509_free(certB);
195 return ret;
196 }
197
GetX509CrlFromDerBuffer(const HapByteBuffer & crlBuffer,int32_t offset,int32_t len)198 X509_CRL* HapCertVerifyOpensslUtils::GetX509CrlFromDerBuffer(
199 const HapByteBuffer& crlBuffer, int32_t offset, int32_t len)
200 {
201 if (crlBuffer.GetBufferPtr() == nullptr) {
202 HAPVERIFY_LOG_ERROR(LABEL, "invalid input, crlbuffer is null");
203 return nullptr;
204 }
205 if ((len <= 0) || (offset < 0) || (crlBuffer.GetCapacity() - len < offset)) {
206 HAPVERIFY_LOG_ERROR(LABEL, "invalid input, offset: %{public}d, len: %{public}d", offset, len);
207 return nullptr;
208 }
209
210 BIO* derBio = BIO_new(BIO_s_mem());
211 if (derBio == nullptr) {
212 HapVerifyOpensslUtils::GetOpensslErrorMessage();
213 HAPVERIFY_LOG_ERROR(LABEL, "BIO_new failed");
214 return nullptr;
215 }
216 if (BIO_write(derBio, crlBuffer.GetBufferPtr() + offset, len) != len) {
217 HapVerifyOpensslUtils::GetOpensslErrorMessage();
218 HAPVERIFY_LOG_ERROR(LABEL, "BIO_write failed");
219 BIO_free_all(derBio);
220 return nullptr;
221 }
222 X509_CRL* crl = d2i_X509_CRL_bio(derBio, nullptr);
223 BIO_free_all(derBio);
224 return crl;
225 }
226
WriteX509CrlToStream(std::ofstream & crlFile,X509_CRL * crl)227 void HapCertVerifyOpensslUtils::WriteX509CrlToStream(std::ofstream& crlFile, X509_CRL* crl)
228 {
229 if (!crlFile.is_open()) {
230 HAPVERIFY_LOG_ERROR(LABEL, "fill is not open");
231 return;
232 }
233
234 BIO* derBio = BIO_new(BIO_s_mem());
235 if (derBio == nullptr) {
236 HAPVERIFY_LOG_ERROR(LABEL, "BIO_new failed");
237 return;
238 }
239 if (crl == nullptr || i2d_X509_CRL_bio(derBio, crl) == 0) {
240 BIO_free_all(derBio);
241 HAPVERIFY_LOG_ERROR(LABEL, "i2d_X509_CRL_bio failed");
242 return;
243 }
244
245 int32_t totalLen = 0;
246 long long posStart = crlFile.tellp();
247 crlFile.seekp(posStart + sizeof(totalLen));
248 char buf[OPENSSL_READ_CRL_LEN_EACH_TIME];
249 int32_t readLen = BIO_read(derBio, buf, sizeof(buf));
250 int32_t readTime = 0;
251 while (readLen > 0 && (++readTime < OPENSSL_READ_CRL_MAX_TIME)) {
252 crlFile.write(buf, readLen);
253 totalLen += readLen;
254 readLen = BIO_read(derBio, buf, sizeof(buf));
255 }
256 BIO_free_all(derBio);
257 long long posEnd = crlFile.tellp();
258 crlFile.seekp(posStart);
259 /* write crl data len */
260 crlFile.write(reinterpret_cast<char*>(&totalLen), sizeof(totalLen));
261 crlFile.seekp(posEnd);
262 }
263
GenerateCertSignFromCertStack(STACK_OF (X509)* certs,CertSign & certVisitSign)264 void HapCertVerifyOpensslUtils::GenerateCertSignFromCertStack(STACK_OF(X509)* certs, CertSign& certVisitSign)
265 {
266 if (certs == nullptr) {
267 return;
268 }
269
270 for (int32_t i = 0; i < sk_X509_num(certs); i++) {
271 X509* cert = sk_X509_value(certs, i);
272 if (cert == nullptr) {
273 continue;
274 }
275 certVisitSign[cert] = false;
276 }
277 }
278
ClearCertVisitSign(CertSign & certVisitSign)279 void HapCertVerifyOpensslUtils::ClearCertVisitSign(CertSign& certVisitSign)
280 {
281 for (auto& certPair : certVisitSign) {
282 certPair.second = false;
283 }
284 }
285
GetCertsChain(CertChain & certsChain,CertSign & certVisitSign)286 bool HapCertVerifyOpensslUtils::GetCertsChain(CertChain& certsChain, CertSign& certVisitSign)
287 {
288 if (certsChain.empty() || certVisitSign.empty()) {
289 HAPVERIFY_LOG_ERROR(LABEL, "input is invalid");
290 return false;
291 }
292
293 X509* issuerCert;
294 X509* cert = certsChain[0];
295 while ((issuerCert = FindCertOfIssuer(cert, certVisitSign)) != nullptr) {
296 certsChain.push_back(X509_dup(issuerCert));
297 certVisitSign[issuerCert] = true;
298 cert = issuerCert;
299 }
300
301 TrustedRootCa& rootCertsObj = TrustedRootCa::GetInstance();
302 issuerCert = rootCertsObj.FindMatchedRoot(certsChain[certsChain.size() - 1]);
303 if (issuerCert == nullptr) {
304 std::string caIssuer;
305 GetIssuerFromX509(certsChain[certsChain.size() - 1], caIssuer);
306 HAPVERIFY_LOG_ERROR(LABEL, "it do not come from trusted root, issuer: %{public}s", caIssuer.c_str());
307 return false;
308 }
309 if (X509_cmp(issuerCert, certsChain[certsChain.size() - 1]) == 0) {
310 X509_free(issuerCert);
311 } else {
312 certsChain.push_back(issuerCert);
313 }
314 return true;
315 }
316
FindCertOfIssuer(X509 * cert,CertSign & certVisitSign)317 X509* HapCertVerifyOpensslUtils::FindCertOfIssuer(X509* cert, CertSign& certVisitSign)
318 {
319 if (cert == nullptr) {
320 HAPVERIFY_LOG_ERROR(LABEL, "input is invalid");
321 return nullptr;
322 }
323
324 X509_NAME* signCertIssuer = X509_get_issuer_name(cert);
325 for (auto certPair : certVisitSign) {
326 if (certPair.second) {
327 continue;
328 }
329
330 X509* issuerCert = certPair.first;
331 X509_NAME* issuerCertSubject = X509_get_subject_name(issuerCert);
332 /* verify sign and issuer */
333 if (X509NameCompare(issuerCertSubject, signCertIssuer) &&
334 CertVerify(cert, issuerCert)) {
335 return issuerCert;
336 }
337 }
338 return nullptr;
339 }
340
CertVerify(X509 * cert,const X509 * issuerCert)341 bool HapCertVerifyOpensslUtils::CertVerify(X509* cert, const X509* issuerCert)
342 {
343 if (cert == nullptr) {
344 HAPVERIFY_LOG_ERROR(LABEL, "input is invalid");
345 return false;
346 }
347
348 EVP_PKEY* caPublicKey = X509_get0_pubkey(issuerCert);
349 if (caPublicKey == nullptr) {
350 HapVerifyOpensslUtils::GetOpensslErrorMessage();
351 HAPVERIFY_LOG_ERROR(LABEL, "get pubkey from caCert failed");
352 return false;
353 }
354 return X509_verify(cert, caPublicKey) > 0;
355 }
356
VerifyCertChainPeriodOfValidity(CertChain & certsChain,const ASN1_TYPE * signTime)357 bool HapCertVerifyOpensslUtils::VerifyCertChainPeriodOfValidity(CertChain& certsChain, const ASN1_TYPE* signTime)
358 {
359 if (certsChain.empty()) {
360 return false;
361 }
362
363 for (uint32_t i = 0; i < certsChain.size() - 1; i++) {
364 if (certsChain[i] == nullptr) {
365 HAPVERIFY_LOG_ERROR(LABEL, "%{public}dst cert is nullptr", i);
366 return false;
367 }
368 const ASN1_TIME* notBefore = X509_get0_notBefore(certsChain[i]);
369 const ASN1_TIME* notAfter = X509_get0_notAfter(certsChain[i]);
370 if (!CheckSignTimeInValidPeriod(signTime, notBefore, notAfter)) {
371 HAPVERIFY_LOG_ERROR(LABEL, "%{public}dst cert is not in period of validity", i);
372 return false;
373 }
374 }
375 return true;
376 }
377
CheckAsn1TimeIsValid(const ASN1_TIME * asn1Time)378 bool HapCertVerifyOpensslUtils::CheckAsn1TimeIsValid(const ASN1_TIME* asn1Time)
379 {
380 if (asn1Time == nullptr || asn1Time->data == nullptr) {
381 return false;
382 }
383 return true;
384 }
385
CheckAsn1TypeIsValid(const ASN1_TYPE * asn1Type)386 bool HapCertVerifyOpensslUtils::CheckAsn1TypeIsValid(const ASN1_TYPE* asn1Type)
387 {
388 if (asn1Type == nullptr || asn1Type->value.asn1_string == nullptr ||
389 asn1Type->value.asn1_string->data == nullptr) {
390 return false;
391 }
392 return true;
393 }
394
CheckSignTimeInValidPeriod(const ASN1_TYPE * signTime,const ASN1_TIME * notBefore,const ASN1_TIME * notAfter)395 bool HapCertVerifyOpensslUtils::CheckSignTimeInValidPeriod(const ASN1_TYPE* signTime,
396 const ASN1_TIME* notBefore, const ASN1_TIME* notAfter)
397 {
398 if (!CheckAsn1TimeIsValid(notBefore) || !CheckAsn1TimeIsValid(notAfter)) {
399 HAPVERIFY_LOG_ERROR(LABEL, "no valid period");
400 return false;
401 }
402 if (!CheckAsn1TypeIsValid(signTime)) {
403 HAPVERIFY_LOG_ERROR(LABEL, "signTime is invalid");
404 return false;
405 }
406
407 if (ASN1_TIME_compare(notBefore, signTime->value.asn1_string) > 0 ||
408 ASN1_TIME_compare(notAfter, signTime->value.asn1_string) < 0) {
409 HAPVERIFY_LOG_ERROR(LABEL, "Out of valid period, signTime: %{public}s, notBefore: %{public}s, "
410 "notAfter: %{public}s", signTime->value.asn1_string->data, notBefore->data, notAfter->data);
411 return false;
412 }
413 HAPVERIFY_LOG_DEBUG(LABEL, "signTime type: %{public}d, data: %{public}s, notBefore: %{public}s, "
414 "notAfter: %{public}s", signTime->type, signTime->value.asn1_string->data, notBefore->data, notAfter->data);
415 return true;
416 }
417
VerifyCrl(CertChain & certsChain,STACK_OF (X509_CRL)* crls,Pkcs7Context & pkcs7Context)418 bool HapCertVerifyOpensslUtils::VerifyCrl(CertChain& certsChain, STACK_OF(X509_CRL)* crls, Pkcs7Context& pkcs7Context)
419 {
420 if (certsChain.empty()) {
421 HAPVERIFY_LOG_ERROR(LABEL, "cert chain is null");
422 return false;
423 }
424
425 /* get signed cert's issuer and then it will be used to find local crl */
426 if (!GetIssuerFromX509(certsChain[0], pkcs7Context.certIssuer)) {
427 HAPVERIFY_LOG_ERROR(LABEL, "get issuer of signed cert failed");
428 return false;
429 }
430 X509_CRL* targetCrl = GetCrlBySignedCertIssuer(crls, certsChain[0]);
431 /* crl is optional */
432 if (targetCrl != nullptr && certsChain.size() >= MIN_CERT_CHAIN_LEN_NEED_VERIFY_CRL) {
433 /* if it include crl, it must be verified by ca cert */
434 if (X509_CRL_verify(targetCrl, X509_get0_pubkey(certsChain[1])) <= 0) {
435 HapVerifyOpensslUtils::GetOpensslErrorMessage();
436 HAPVERIFY_LOG_ERROR(LABEL, "verify crlInPackage failed");
437 return false;
438 }
439 }
440 HapCrlManager& hapCrlManager = HapCrlManager::GetInstance();
441 return hapCrlManager.CrlCheck(certsChain[0], targetCrl, pkcs7Context);
442 }
443
GetCrlBySignedCertIssuer(STACK_OF (X509_CRL)* crls,const X509 * cert)444 X509_CRL* HapCertVerifyOpensslUtils::GetCrlBySignedCertIssuer(STACK_OF(X509_CRL)* crls, const X509* cert)
445 {
446 if (crls == nullptr || cert == nullptr) {
447 return nullptr;
448 }
449
450 X509_NAME* certIssuer = X509_get_issuer_name(cert);
451 for (int32_t i = 0; i < sk_X509_CRL_num(crls); i++) {
452 X509_CRL* crl = sk_X509_CRL_value(crls, i);
453 if (crl == nullptr) {
454 continue;
455 }
456
457 X509_NAME* crlIssuer = X509_CRL_get_issuer(crl);
458 if (X509NameCompare(crlIssuer, certIssuer)) {
459 return crl;
460 }
461 }
462 return nullptr;
463 }
464
X509NameCompare(const X509_NAME * a,const X509_NAME * b)465 bool HapCertVerifyOpensslUtils::X509NameCompare(const X509_NAME* a, const X509_NAME* b)
466 {
467 if (a == nullptr || b == nullptr) {
468 return false;
469 }
470
471 return X509_NAME_cmp(a, b) == 0;
472 }
473
GetSubjectFromX509(const X509 * cert,std::string & subject)474 bool HapCertVerifyOpensslUtils::GetSubjectFromX509(const X509* cert, std::string& subject)
475 {
476 if (cert == nullptr) {
477 HAPVERIFY_LOG_ERROR(LABEL, "cert is nullptr");
478 return false;
479 }
480
481 X509_NAME* name = X509_get_subject_name(cert);
482 subject = GetDnToString(name);
483 HAPVERIFY_LOG_DEBUG(LABEL, "subject = %{public}s", subject.c_str());
484 return true;
485 }
486
GetIssuerFromX509(const X509 * cert,std::string & issuer)487 bool HapCertVerifyOpensslUtils::GetIssuerFromX509(const X509* cert, std::string& issuer)
488 {
489 if (cert == nullptr) {
490 HAPVERIFY_LOG_ERROR(LABEL, "cert is nullptr");
491 return false;
492 }
493
494 X509_NAME* name = X509_get_issuer_name(cert);
495 issuer = GetDnToString(name);
496 HAPVERIFY_LOG_DEBUG(LABEL, "cert issuer = %{public}s", issuer.c_str());
497 return true;
498 }
499
GetSerialNumberFromX509(const X509 * cert,long long & certNumber)500 bool HapCertVerifyOpensslUtils::GetSerialNumberFromX509(const X509* cert, long long& certNumber)
501 {
502 if (cert == nullptr) {
503 HAPVERIFY_LOG_ERROR(LABEL, "cert is nullptr");
504 return false;
505 }
506
507 const ASN1_INTEGER* certSN = X509_get0_serialNumber(cert);
508 certNumber = ASN1_INTEGER_get(certSN);
509 HAPVERIFY_LOG_DEBUG(LABEL, "cert number = %{public}lld", certNumber);
510 return true;
511 }
512
GetIssuerFromX509Crl(const X509_CRL * crl,std::string & issuer)513 bool HapCertVerifyOpensslUtils::GetIssuerFromX509Crl(const X509_CRL* crl, std::string& issuer)
514 {
515 if (crl == nullptr) {
516 HAPVERIFY_LOG_ERROR(LABEL, "clr is nullptr");
517 return false;
518 }
519
520 X509_NAME* name = X509_CRL_get_issuer(crl);
521 if (name == nullptr) {
522 HAPVERIFY_LOG_ERROR(LABEL, "crl issuer nullptr");
523 return false;
524 }
525 issuer = GetDnToString(name);
526 return true;
527 }
528
GetDnToString(X509_NAME * name)529 std::string HapCertVerifyOpensslUtils::GetDnToString(X509_NAME* name)
530 {
531 if (name == nullptr) {
532 return "";
533 }
534
535 std::string countryName;
536 GetTextFromX509Name(name, NID_countryName, countryName);
537 std::string organizationName;
538 GetTextFromX509Name(name, NID_organizationName, organizationName);
539 std::string organizationalUnitName;
540 GetTextFromX509Name(name, NID_organizationalUnitName, organizationalUnitName);
541 std::string commonName;
542 GetTextFromX509Name(name, NID_commonName, commonName);
543 return "C=" + countryName + ", O=" + organizationName + ", OU=" + organizationalUnitName +
544 ", CN=" + commonName;
545 }
546
GetTextFromX509Name(X509_NAME * name,int32_t nId,std::string & text)547 void HapCertVerifyOpensslUtils::GetTextFromX509Name(X509_NAME* name, int32_t nId, std::string& text)
548 {
549 int32_t textLen = X509_NAME_get_text_by_NID(name, nId, nullptr, 0);
550 if (textLen <= 0) {
551 return;
552 }
553
554 std::unique_ptr<char[]> buffer = std::make_unique<char[]>(textLen + 1);
555 if (X509_NAME_get_text_by_NID(name, nId, buffer.get(), textLen + 1) != textLen) {
556 return;
557 }
558 text = std::string(buffer.get());
559 }
560 } // namespace Verify
561 } // namespace Security
562 } // namespace OHOS
563