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("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("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("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("GetX509CertFromPemString failed");
82         return false;
83     }
84 
85     if (!GetPublickeyBase64(cert, publicKey)) {
86         HAPVERIFY_LOG_ERROR("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("GetFingerprintBase64FromPemCert begin");
98     X509* cert = GetX509CertFromPemString(certStr);
99     if (cert == nullptr) {
100         HAPVERIFY_LOG_ERROR("GetX509CertFromPemString failed");
101         return false;
102     }
103     int32_t certLen = i2d_X509(cert, nullptr);
104     if (certLen <= 0) {
105         HAPVERIFY_LOG_ERROR("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("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("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("GetFingerprintBase64FromPemCert end %{private}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("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("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("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 
GetOrganizationFromPemCert(const std::string & certStr,std::string & organization)170 bool HapCertVerifyOpensslUtils::GetOrganizationFromPemCert(const std::string& certStr, std::string& organization)
171 {
172     HAPVERIFY_LOG_DEBUG("GetFingerprintBase64FromPemCert begin");
173     X509* cert = GetX509CertFromPemString(certStr);
174     if (cert == nullptr) {
175         HAPVERIFY_LOG_ERROR("GetX509CertFromPemString failed");
176         return false;
177     }
178     X509_NAME* name = X509_get_subject_name(cert);
179     GetTextFromX509Name(name, NID_organizationName, organization);
180     X509_free(cert);
181     return true;
182 }
183 
184 /*
185  * The length after Base64 encoding is 4/3 of the length before encoding,
186  * and openssl function will add '\0' to the encoded string.
187  * So len_after_encode = len_before_encode * 4/3 + 1
188  */
CalculateLenAfterBase64Encode(int32_t len)189 int32_t HapCertVerifyOpensslUtils::CalculateLenAfterBase64Encode(int32_t len)
190 {
191     return (len + BASE64_ENCODE_PACKET_LEN - 1) / BASE64_ENCODE_PACKET_LEN * BASE64_ENCODE_LEN_OF_EACH_GROUP_DATA + 1;
192 }
193 
CompareX509Cert(const X509 * certA,const std::string & base64Cert)194 bool HapCertVerifyOpensslUtils::CompareX509Cert(const X509* certA, const std::string& base64Cert)
195 {
196     if (certA == nullptr) {
197         HAPVERIFY_LOG_ERROR("certA is nullptr");
198         return false;
199     }
200 
201     X509* certB = GetX509CertFromPemString(base64Cert);
202     if (certB == nullptr) {
203         HAPVERIFY_LOG_ERROR("generate certB failed");
204         return false;
205     }
206     bool ret = (X509_cmp(certA, certB) == 0);
207     X509_free(certB);
208     return ret;
209 }
210 
GetX509CrlFromDerBuffer(const HapByteBuffer & crlBuffer,int32_t offset,int32_t len)211 X509_CRL* HapCertVerifyOpensslUtils::GetX509CrlFromDerBuffer(
212     const HapByteBuffer& crlBuffer, int32_t offset, int32_t len)
213 {
214     if (crlBuffer.GetBufferPtr() == nullptr) {
215         HAPVERIFY_LOG_ERROR("invalid input, crlbuffer is null");
216         return nullptr;
217     }
218     if ((len <= 0) || (offset < 0) || (crlBuffer.GetCapacity() - len < offset)) {
219         HAPVERIFY_LOG_ERROR("invalid input, offset: %{public}d, len: %{public}d", offset, len);
220         return nullptr;
221     }
222 
223     BIO* derBio = BIO_new(BIO_s_mem());
224     if (derBio == nullptr) {
225         HapVerifyOpensslUtils::GetOpensslErrorMessage();
226         HAPVERIFY_LOG_ERROR("BIO_new failed");
227         return nullptr;
228     }
229     if (BIO_write(derBio, crlBuffer.GetBufferPtr() + offset, len) != len) {
230         HapVerifyOpensslUtils::GetOpensslErrorMessage();
231         HAPVERIFY_LOG_ERROR("BIO_write failed");
232         BIO_free_all(derBio);
233         return nullptr;
234     }
235     X509_CRL* crl = d2i_X509_CRL_bio(derBio, nullptr);
236     BIO_free_all(derBio);
237     return crl;
238 }
239 
WriteX509CrlToStream(std::ofstream & crlFile,X509_CRL * crl)240 void HapCertVerifyOpensslUtils::WriteX509CrlToStream(std::ofstream& crlFile, X509_CRL* crl)
241 {
242     if (!crlFile.is_open()) {
243         HAPVERIFY_LOG_ERROR("fill is not open");
244         return;
245     }
246 
247     BIO* derBio = BIO_new(BIO_s_mem());
248     if (derBio == nullptr) {
249         HAPVERIFY_LOG_ERROR("BIO_new failed");
250         return;
251     }
252     if (crl == nullptr || i2d_X509_CRL_bio(derBio, crl) == 0) {
253         BIO_free_all(derBio);
254         HAPVERIFY_LOG_ERROR("i2d_X509_CRL_bio failed");
255         return;
256     }
257 
258     int32_t totalLen = 0;
259     long long posStart = crlFile.tellp();
260     crlFile.seekp(posStart + sizeof(totalLen));
261     char buf[OPENSSL_READ_CRL_LEN_EACH_TIME];
262     int32_t readLen = BIO_read(derBio, buf, sizeof(buf));
263     int32_t readTime = 1;
264     while (readLen > 0 && (readTime < OPENSSL_READ_CRL_MAX_TIME)) {
265         readTime++;
266         crlFile.write(buf, readLen);
267         totalLen += readLen;
268         readLen = BIO_read(derBio, buf, sizeof(buf));
269     }
270     BIO_free_all(derBio);
271     long long posEnd = crlFile.tellp();
272     crlFile.seekp(posStart);
273     /* write crl data len */
274     crlFile.write(reinterpret_cast<char*>(&totalLen), sizeof(totalLen));
275     crlFile.seekp(posEnd);
276 }
277 
GenerateCertSignFromCertStack(STACK_OF (X509)* certs,CertSign & certVisitSign)278 void HapCertVerifyOpensslUtils::GenerateCertSignFromCertStack(STACK_OF(X509)* certs, CertSign& certVisitSign)
279 {
280     if (certs == nullptr) {
281         return;
282     }
283 
284     for (int32_t i = 0; i < sk_X509_num(certs); i++) {
285         X509* cert = sk_X509_value(certs, i);
286         if (cert == nullptr) {
287             continue;
288         }
289         certVisitSign[cert] = false;
290     }
291 }
292 
ClearCertVisitSign(CertSign & certVisitSign)293 void HapCertVerifyOpensslUtils::ClearCertVisitSign(CertSign& certVisitSign)
294 {
295     for (auto& certPair : certVisitSign) {
296         certPair.second = false;
297     }
298 }
299 
GetCertsChain(CertChain & certsChain,CertSign & certVisitSign,Pkcs7Context & pkcs7Context)300 bool HapCertVerifyOpensslUtils::GetCertsChain(CertChain& certsChain, CertSign& certVisitSign,
301     Pkcs7Context& pkcs7Context)
302 {
303     if (certsChain.empty() || certVisitSign.empty()) {
304         HAPVERIFY_LOG_ERROR("input is invalid");
305         return false;
306     }
307 
308     X509* issuerCert;
309     X509* cert = certsChain[0];
310     while ((issuerCert = FindCertOfIssuer(cert, certVisitSign)) != nullptr) {
311         certsChain.push_back(X509_dup(issuerCert));
312         certVisitSign[issuerCert] = true;
313         cert = issuerCert;
314     }
315 
316     TrustedRootCa& rootCertsObj = TrustedRootCa::GetInstance();
317     issuerCert = rootCertsObj.FindMatchedRoot(certsChain[certsChain.size() - 1]);
318     std::string caIssuer;
319     GetIssuerFromX509(certsChain[certsChain.size() - 1], caIssuer);
320     pkcs7Context.rootCa = caIssuer;
321     if (issuerCert == nullptr) {
322         HAPVERIFY_LOG_ERROR("it do not come from trusted root, issuer: %{public}s", caIssuer.c_str());
323         return false;
324     }
325     if (X509_cmp(issuerCert, certsChain[certsChain.size() - 1]) == 0) {
326         X509_free(issuerCert);
327     } else {
328         certsChain.push_back(issuerCert);
329     }
330     return true;
331 }
332 
FindCertOfIssuer(X509 * cert,CertSign & certVisitSign)333 X509* HapCertVerifyOpensslUtils::FindCertOfIssuer(X509* cert, CertSign& certVisitSign)
334 {
335     if (cert == nullptr) {
336         HAPVERIFY_LOG_ERROR("input is invalid");
337         return nullptr;
338     }
339 
340     X509_NAME* signCertIssuer = X509_get_issuer_name(cert);
341     for (auto certPair : certVisitSign) {
342         if (certPair.second) {
343             continue;
344         }
345 
346         X509* issuerCert = certPair.first;
347         X509_NAME* issuerCertSubject = X509_get_subject_name(issuerCert);
348         /* verify sign and issuer */
349         if (X509NameCompare(issuerCertSubject, signCertIssuer) &&
350             CertVerify(cert, issuerCert)) {
351             return issuerCert;
352         }
353     }
354     return nullptr;
355 }
356 
CertVerify(X509 * cert,const X509 * issuerCert)357 bool HapCertVerifyOpensslUtils::CertVerify(X509* cert, const X509* issuerCert)
358 {
359     if (cert == nullptr) {
360         HAPVERIFY_LOG_ERROR("input is invalid");
361         return false;
362     }
363 
364     EVP_PKEY* caPublicKey = X509_get0_pubkey(issuerCert);
365     if (caPublicKey == nullptr) {
366         HapVerifyOpensslUtils::GetOpensslErrorMessage();
367         HAPVERIFY_LOG_ERROR("get pubkey from caCert failed");
368         return false;
369     }
370     return X509_verify(cert, caPublicKey) > 0;
371 }
372 
VerifyCertChainPeriodOfValidity(CertChain & certsChain,const ASN1_TYPE * signTime)373 bool HapCertVerifyOpensslUtils::VerifyCertChainPeriodOfValidity(CertChain& certsChain, const ASN1_TYPE* signTime)
374 {
375     if (certsChain.empty()) {
376         return false;
377     }
378 
379     for (uint32_t i = 0; i < certsChain.size() - 1; i++) {
380         if (certsChain[i] == nullptr) {
381             HAPVERIFY_LOG_ERROR("%{public}dst cert is nullptr", i);
382             return false;
383         }
384         const ASN1_TIME* notBefore = X509_get0_notBefore(certsChain[i]);
385         const ASN1_TIME* notAfter = X509_get0_notAfter(certsChain[i]);
386         if (!CheckSignTimeInValidPeriod(signTime, notBefore, notAfter)) {
387             HAPVERIFY_LOG_ERROR("%{public}dst cert is not in period of validity", i);
388             return false;
389         }
390     }
391     return true;
392 }
393 
CheckAsn1TimeIsValid(const ASN1_TIME * asn1Time)394 bool HapCertVerifyOpensslUtils::CheckAsn1TimeIsValid(const ASN1_TIME* asn1Time)
395 {
396     if (asn1Time == nullptr || asn1Time->data == nullptr) {
397         return false;
398     }
399     return true;
400 }
401 
CheckAsn1TypeIsValid(const ASN1_TYPE * asn1Type)402 bool HapCertVerifyOpensslUtils::CheckAsn1TypeIsValid(const ASN1_TYPE* asn1Type)
403 {
404     if (asn1Type == nullptr || asn1Type->value.asn1_string == nullptr ||
405         asn1Type->value.asn1_string->data == nullptr) {
406         return false;
407     }
408     return true;
409 }
410 
CheckSignTimeInValidPeriod(const ASN1_TYPE * signTime,const ASN1_TIME * notBefore,const ASN1_TIME * notAfter)411 bool HapCertVerifyOpensslUtils::CheckSignTimeInValidPeriod(const ASN1_TYPE* signTime,
412     const ASN1_TIME* notBefore, const ASN1_TIME* notAfter)
413 {
414     if (!CheckAsn1TimeIsValid(notBefore) || !CheckAsn1TimeIsValid(notAfter)) {
415         HAPVERIFY_LOG_ERROR("no valid period");
416         return false;
417     }
418     if (!CheckAsn1TypeIsValid(signTime)) {
419         HAPVERIFY_LOG_ERROR("signTime is invalid");
420         return false;
421     }
422 
423     if (ASN1_TIME_compare(notBefore, signTime->value.asn1_string) > 0 ||
424         ASN1_TIME_compare(notAfter, signTime->value.asn1_string) < 0) {
425         HAPVERIFY_LOG_ERROR("Out of valid period, signTime: %{public}s, notBefore: %{public}s, "
426             "notAfter: %{public}s", signTime->value.asn1_string->data, notBefore->data, notAfter->data);
427         return false;
428     }
429     HAPVERIFY_LOG_DEBUG("signTime type: %{public}d, data: %{public}s, notBefore: %{public}s, "
430         "notAfter: %{public}s", signTime->type, signTime->value.asn1_string->data, notBefore->data, notAfter->data);
431     return true;
432 }
433 
VerifyCrl(CertChain & certsChain,STACK_OF (X509_CRL)* crls,Pkcs7Context & pkcs7Context)434 bool HapCertVerifyOpensslUtils::VerifyCrl(CertChain& certsChain, STACK_OF(X509_CRL)* crls, Pkcs7Context& pkcs7Context)
435 {
436     if (certsChain.empty()) {
437         HAPVERIFY_LOG_ERROR("cert chain is null");
438         return false;
439     }
440 
441     /* get signed cert's issuer and then it will be used to find local crl */
442     if (!GetIssuerFromX509(certsChain[0], pkcs7Context.certIssuer)) {
443         HAPVERIFY_LOG_ERROR("get issuer of signed cert failed");
444         return false;
445     }
446     X509_CRL* targetCrl = GetCrlBySignedCertIssuer(crls, certsChain[0]);
447     /* crl is optional */
448     if (targetCrl != nullptr && certsChain.size() >= MIN_CERT_CHAIN_LEN_NEED_VERIFY_CRL) {
449         /* if it include crl, it must be verified by ca cert */
450         if (X509_CRL_verify(targetCrl, X509_get0_pubkey(certsChain[1])) <= 0) {
451             HapVerifyOpensslUtils::GetOpensslErrorMessage();
452             HAPVERIFY_LOG_ERROR("verify crlInPackage failed");
453             return false;
454         }
455     }
456     HapCrlManager& hapCrlManager = HapCrlManager::GetInstance();
457     return hapCrlManager.CrlCheck(certsChain[0], targetCrl, pkcs7Context);
458 }
459 
GetCrlBySignedCertIssuer(STACK_OF (X509_CRL)* crls,const X509 * cert)460 X509_CRL* HapCertVerifyOpensslUtils::GetCrlBySignedCertIssuer(STACK_OF(X509_CRL)* crls, const X509* cert)
461 {
462     if (crls == nullptr || cert == nullptr) {
463         return nullptr;
464     }
465 
466     X509_NAME* certIssuer = X509_get_issuer_name(cert);
467     for (int32_t i = 0; i < sk_X509_CRL_num(crls); i++) {
468         X509_CRL* crl = sk_X509_CRL_value(crls, i);
469         if (crl == nullptr) {
470             continue;
471         }
472 
473         X509_NAME* crlIssuer = X509_CRL_get_issuer(crl);
474         if (X509NameCompare(crlIssuer, certIssuer)) {
475             return crl;
476         }
477     }
478     return nullptr;
479 }
480 
X509NameCompare(const X509_NAME * a,const X509_NAME * b)481 bool HapCertVerifyOpensslUtils::X509NameCompare(const X509_NAME* a, const X509_NAME* b)
482 {
483     if (a == nullptr || b == nullptr) {
484         return false;
485     }
486 
487     return X509_NAME_cmp(a, b) == 0;
488 }
489 
GetSubjectFromX509(const X509 * cert,std::string & subject)490 bool HapCertVerifyOpensslUtils::GetSubjectFromX509(const X509* cert, std::string& subject)
491 {
492     if (cert == nullptr) {
493         HAPVERIFY_LOG_ERROR("cert is nullptr");
494         return false;
495     }
496 
497     X509_NAME* name = X509_get_subject_name(cert);
498     subject = GetDnToString(name);
499     HAPVERIFY_LOG_DEBUG("subject = %{public}s", subject.c_str());
500     return true;
501 }
502 
GetIssuerFromX509(const X509 * cert,std::string & issuer)503 bool HapCertVerifyOpensslUtils::GetIssuerFromX509(const X509* cert, std::string& issuer)
504 {
505     if (cert == nullptr) {
506         HAPVERIFY_LOG_ERROR("cert is nullptr");
507         return false;
508     }
509 
510     X509_NAME* name = X509_get_issuer_name(cert);
511     issuer = GetDnToString(name);
512     HAPVERIFY_LOG_DEBUG("cert issuer = %{public}s", issuer.c_str());
513     return true;
514 }
515 
GetSerialNumberFromX509(const X509 * cert,long long & certNumber)516 bool HapCertVerifyOpensslUtils::GetSerialNumberFromX509(const X509* cert, long long& certNumber)
517 {
518     if (cert == nullptr) {
519         HAPVERIFY_LOG_ERROR("cert is nullptr");
520         return false;
521     }
522 
523     const ASN1_INTEGER* certSN = X509_get0_serialNumber(cert);
524     certNumber = ASN1_INTEGER_get(certSN);
525     HAPVERIFY_LOG_DEBUG("cert number = %{public}lld", certNumber);
526     return true;
527 }
528 
GetIssuerFromX509Crl(const X509_CRL * crl,std::string & issuer)529 bool HapCertVerifyOpensslUtils::GetIssuerFromX509Crl(const X509_CRL* crl, std::string& issuer)
530 {
531     if (crl == nullptr) {
532         HAPVERIFY_LOG_ERROR("clr is nullptr");
533         return false;
534     }
535 
536     X509_NAME* name = X509_CRL_get_issuer(crl);
537     if (name == nullptr) {
538         HAPVERIFY_LOG_ERROR("crl issuer nullptr");
539         return false;
540     }
541     issuer = GetDnToString(name);
542     return true;
543 }
544 
GetDnToString(X509_NAME * name)545 std::string HapCertVerifyOpensslUtils::GetDnToString(X509_NAME* name)
546 {
547     if (name == nullptr) {
548         return "";
549     }
550 
551     std::string countryName;
552     GetTextFromX509Name(name, NID_countryName, countryName);
553     std::string organizationName;
554     GetTextFromX509Name(name, NID_organizationName, organizationName);
555     std::string organizationalUnitName;
556     GetTextFromX509Name(name, NID_organizationalUnitName, organizationalUnitName);
557     std::string commonName;
558     GetTextFromX509Name(name, NID_commonName, commonName);
559     return "C=" + countryName + ", O=" + organizationName + ", OU=" + organizationalUnitName +
560         ", CN=" + commonName;
561 }
562 
GetTextFromX509Name(X509_NAME * name,int32_t nId,std::string & text)563 void HapCertVerifyOpensslUtils::GetTextFromX509Name(X509_NAME* name, int32_t nId, std::string& text)
564 {
565     int32_t textLen = X509_NAME_get_text_by_NID(name, nId, nullptr, 0);
566     if (textLen <= 0) {
567         return;
568     }
569 
570     std::unique_ptr<char[]> buffer = std::make_unique<char[]>(textLen + 1);
571     if (X509_NAME_get_text_by_NID(name, nId, buffer.get(), textLen + 1) != textLen) {
572         return;
573     }
574     text = std::string(buffer.get());
575 }
576 } // namespace Verify
577 } // namespace Security
578 } // namespace OHOS
579