• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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_verify_openssl_utils.h"
17 
18 #include "common/hap_verify_log.h"
19 #include "openssl/asn1.h"
20 #include "openssl/bio.h"
21 #include "openssl/crypto.h"
22 #include "openssl/err.h"
23 #include "openssl/obj_mac.h"
24 #include "openssl/objects.h"
25 #include "openssl/rsa.h"
26 #include "openssl/x509.h"
27 
28 namespace OHOS {
29 namespace Security {
30 namespace Verify {
31 using Pkcs7SignerInfoStack = STACK_OF(PKCS7_SIGNER_INFO);
32 using X509AttributeStack = STACK_OF(X509_ATTRIBUTE);
33 
34 const int HapVerifyOpensslUtils::OPENSSL_PKCS7_VERIFY_SUCCESS = 1;
35 const int HapVerifyOpensslUtils::OPENSSL_ERR_MESSAGE_MAX_LEN = 1024;
36 
37 /*
38  * OPENSSL_READ_DATA_MAX_TIME * OPENSSL_READ_DATA_LEN_EACH_TIME < 2GBytes.
39  * make the maximum size of data that can be read each time be 1 KBytes,
40  * so the maximum times of read data is 1024 * 1024 * 2 = 2097152;
41  */
42 const int HapVerifyOpensslUtils::OPENSSL_READ_DATA_MAX_TIME = 2097152;
43 const int HapVerifyOpensslUtils::OPENSSL_READ_DATA_LEN_EACH_TIME = 1024;
44 
45 /* Signature algorithm OID for extended PKCS7 */
46 const std::string HapVerifyOpensslUtils::PKCS7_EXT_SHAWITHRSA_PSS = "1.2.840.113549.1.1.10";
47 const int HapVerifyOpensslUtils::MAX_OID_LENGTH = 128;
48 
ParsePkcs7Package(const unsigned char packageData[],unsigned int packageLen,Pkcs7Context & pkcs7Context)49 bool HapVerifyOpensslUtils::ParsePkcs7Package(const unsigned char packageData[],
50     unsigned int packageLen, Pkcs7Context& pkcs7Context)
51 {
52     if (packageData == nullptr || packageLen == 0) {
53         HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
54         return false;
55     }
56 
57     pkcs7Context.p7 = d2i_PKCS7(nullptr, &packageData, packageLen);
58     if (!CheckPkcs7SignedDataIsValid(pkcs7Context.p7)) {
59         GetOpensslErrorMessage();
60         HAPVERIFY_LOG_ERROR(LABEL, "p7 is invalid");
61         return false;
62     }
63     if (!GetContentInfo(pkcs7Context.p7->d.sign->contents, pkcs7Context.content)) {
64         HAPVERIFY_LOG_ERROR(LABEL, "Get content from pkcs7 failed");
65         return false;
66     }
67     return true;
68 }
69 
GetCertChains(PKCS7 * p7,Pkcs7Context & pkcs7Context)70 bool HapVerifyOpensslUtils::GetCertChains(PKCS7* p7, Pkcs7Context& pkcs7Context)
71 {
72     if (!CheckPkcs7SignedDataIsValid(p7)) {
73         HAPVERIFY_LOG_ERROR(LABEL, "p7 is invalid");
74         return false;
75     }
76 
77     CertSign certVisitSign;
78     HapCertVerifyOpensslUtils::GenerateCertSignFromCertStack(p7->d.sign->cert, certVisitSign);
79 
80     Pkcs7SignerInfoStack* signerInfoStack = PKCS7_get_signer_info(p7);
81     if (signerInfoStack == nullptr) {
82         HAPVERIFY_LOG_ERROR(LABEL, "get signerInfoStack error");
83         GetOpensslErrorMessage();
84         return false;
85     }
86     int signCount = sk_PKCS7_SIGNER_INFO_num(signerInfoStack);
87     if (signCount <= 0) {
88         HAPVERIFY_LOG_ERROR(LABEL, "can not find signinfo");
89         return false;
90     }
91 
92     for (int i = 0; i < signCount; i++) {
93         /* get ith signInfo */
94         PKCS7_SIGNER_INFO* signInfo = sk_PKCS7_SIGNER_INFO_value(signerInfoStack, i);
95         if (signInfo == nullptr) {
96             HAPVERIFY_LOG_ERROR(LABEL, "signInfo %{public}dst is nullptr", i);
97             return false;
98         }
99         /* GET X509 certificate */
100         X509* cert = PKCS7_cert_from_signer_info(p7, signInfo);
101         if (cert == nullptr) {
102             HAPVERIFY_LOG_ERROR(LABEL, "get cert for %{public}dst signInfo failed", i);
103             return false;
104         }
105         CertChain certChain;
106         pkcs7Context.certChains.push_back(certChain);
107         pkcs7Context.certChains[i].push_back(X509_dup(cert));
108         HapCertVerifyOpensslUtils::ClearCertVisitSign(certVisitSign);
109         certVisitSign[cert] = true;
110         if (!VerifyCertChain(pkcs7Context.certChains[i], p7, signInfo, pkcs7Context, certVisitSign)) {
111             HAPVERIFY_LOG_ERROR(LABEL, "verify %{public}dst certchain failed", i);
112             return false;
113         }
114     }
115     return true;
116 }
117 
VerifyCertChain(CertChain & certsChain,PKCS7 * p7,PKCS7_SIGNER_INFO * signInfo,Pkcs7Context & pkcs7Context,CertSign & certVisitSign)118 bool HapVerifyOpensslUtils::VerifyCertChain(CertChain& certsChain, PKCS7* p7,
119     PKCS7_SIGNER_INFO* signInfo, Pkcs7Context& pkcs7Context, CertSign& certVisitSign)
120 {
121     if (!HapCertVerifyOpensslUtils::GetCertsChain(certsChain, certVisitSign)) {
122         HAPVERIFY_LOG_ERROR(LABEL, "get cert chain for signInfo failed");
123         return false;
124     }
125     ASN1_TYPE* signTime = PKCS7_get_signed_attribute(signInfo, NID_pkcs9_signingTime);
126     if (!HapCertVerifyOpensslUtils::VerifyCertChainPeriodOfValidity(certsChain, signTime)) {
127         HAPVERIFY_LOG_ERROR(LABEL, "VerifyCertChainPeriodOfValidity for signInfo failed");
128         return false;
129     }
130     if (!HapCertVerifyOpensslUtils::VerifyCrl(certsChain, p7->d.sign->crl, pkcs7Context)) {
131         HAPVERIFY_LOG_ERROR(LABEL, "VerifyCrl for signInfo failed");
132         return false;
133     }
134     return true;
135 }
136 
CheckPkcs7SignedDataIsValid(const PKCS7 * p7)137 bool HapVerifyOpensslUtils::CheckPkcs7SignedDataIsValid(const PKCS7* p7)
138 {
139     if (p7 == nullptr || !PKCS7_type_is_signed(p7) || p7->d.sign == nullptr) {
140         return false;
141     }
142     return true;
143 }
144 
VerifyPkcs7(Pkcs7Context & pkcs7Context)145 bool HapVerifyOpensslUtils::VerifyPkcs7(Pkcs7Context& pkcs7Context)
146 {
147     if (!CheckPkcs7SignedDataIsValid(pkcs7Context.p7)) {
148         HAPVERIFY_LOG_ERROR(LABEL, "p7 type is invalid signed_data_pkcs7");
149         return false;
150     }
151 
152     if (!VerifyPkcs7SignedData(pkcs7Context)) {
153         HAPVERIFY_LOG_ERROR(LABEL, "verify p7 error");
154         return false;
155     }
156     return true;
157 }
158 
VerifyPkcs7SignedData(Pkcs7Context & pkcs7Context)159 bool HapVerifyOpensslUtils::VerifyPkcs7SignedData(Pkcs7Context& pkcs7Context)
160 {
161     /* get signed data which was used to be signed */
162     BIO* p7Bio = PKCS7_dataDecode(pkcs7Context.p7, nullptr, nullptr, nullptr);
163     if (p7Bio == nullptr) {
164         HAPVERIFY_LOG_ERROR(LABEL, "get p7bio error");
165         GetOpensslErrorMessage();
166         return false;
167     }
168     char buf[OPENSSL_READ_DATA_LEN_EACH_TIME] = {0};
169     int readLen = BIO_read(p7Bio, buf, sizeof(buf));
170     int readTime = 0;
171     while ((readLen > 0) && (++readTime < OPENSSL_READ_DATA_MAX_TIME)) {
172         readLen = BIO_read(p7Bio, buf, sizeof(buf));
173     }
174     Pkcs7SignerInfoStack* signerInfoStack = PKCS7_get_signer_info(pkcs7Context.p7);
175     if (signerInfoStack == nullptr) {
176         HAPVERIFY_LOG_ERROR(LABEL, "get signerInfoStack error");
177         BIO_free_all(p7Bio);
178         GetOpensslErrorMessage();
179         return false;
180     }
181     /* get the num of signInfo */
182     int signCount = sk_PKCS7_SIGNER_INFO_num(signerInfoStack);
183     if (signCount <= 0) {
184         HAPVERIFY_LOG_ERROR(LABEL, "can not find signinfo");
185         BIO_free_all(p7Bio);
186         return false;
187     }
188     for (int i = 0; i < signCount; i++) {
189         if (!VerifySignInfo(signerInfoStack, p7Bio, i, pkcs7Context)) {
190             HAPVERIFY_LOG_ERROR(LABEL, "Verify %{public}dst signInfo failed", i);
191             BIO_free_all(p7Bio);
192             return false;
193         }
194     }
195     BIO_free_all(p7Bio);
196     return true;
197 }
198 
VerifySignInfo(STACK_OF (PKCS7_SIGNER_INFO)* signerInfoStack,BIO * p7Bio,int signInfoNum,Pkcs7Context & pkcs7Context)199 bool HapVerifyOpensslUtils::VerifySignInfo(STACK_OF(PKCS7_SIGNER_INFO)* signerInfoStack,
200     BIO* p7Bio, int signInfoNum, Pkcs7Context& pkcs7Context) {
201     if (signerInfoStack == nullptr || p7Bio == nullptr) {
202         HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
203         return false;
204     }
205     /* get signInfo */
206     PKCS7_SIGNER_INFO* signInfo = sk_PKCS7_SIGNER_INFO_value(signerInfoStack, signInfoNum);
207     if (signInfo == nullptr) {
208         HAPVERIFY_LOG_ERROR(LABEL, "signInfo %{public}dst is nullptr", signInfoNum);
209         return false;
210     }
211     /* GET X509 certificate */
212     X509* cert = pkcs7Context.certChains[signInfoNum][0];
213     bool isShaWithRsaPss = IsEnablePss(signInfo);
214     if (isShaWithRsaPss) {
215         EVP_PKEY* pkey = X509_get0_pubkey(cert);
216         if (pkey == nullptr) {
217             HAPVERIFY_LOG_ERROR(LABEL, "signInfo %{public}dst X509_get_pubkey failed", signInfoNum);
218             return false;
219         }
220         HAPVERIFY_LOG_DEBUG(LABEL, "use RSA/pss");
221         if (!VerifyShaWithRsaPss(signInfo, p7Bio, pkey, isShaWithRsaPss)) {
222             HAPVERIFY_LOG_ERROR(LABEL, "VerifyShaWithRsaPss %{public}dst signInfo failed", signInfoNum);
223             return false;
224         }
225     } else {
226         if (PKCS7_signatureVerify(p7Bio, pkcs7Context.p7, signInfo, cert) <= 0) {
227             HAPVERIFY_LOG_ERROR(LABEL, "PKCS7_signatureVerify %{public}dst signInfo failed", signInfoNum);
228             GetOpensslErrorMessage();
229             return false;
230         }
231     }
232     return true;
233 }
234 
IsEnablePss(const PKCS7_SIGNER_INFO * signInfo)235 bool HapVerifyOpensslUtils::IsEnablePss(const PKCS7_SIGNER_INFO* signInfo)
236 {
237     char oId[MAX_OID_LENGTH];
238     if (signInfo->digest_enc_alg == nullptr) {
239         HAPVERIFY_LOG_ERROR(LABEL, "signInfo->digest_enc_alg is nullptr");
240         return false;
241     }
242     int len = OBJ_obj2txt(oId, sizeof(oId), signInfo->digest_enc_alg->algorithm, 1);
243     if (len < 0 || len >= MAX_OID_LENGTH) {
244         HAPVERIFY_LOG_ERROR(LABEL, "Get length of oId failed");
245         return false;
246     }
247     return PKCS7_EXT_SHAWITHRSA_PSS.compare(0, PKCS7_EXT_SHAWITHRSA_PSS.size(), oId, len) == 0;
248 }
249 
VerifyShaWithRsaPss(const PKCS7_SIGNER_INFO * signInfo,BIO * p7Bio,EVP_PKEY * pkey,bool isPss)250 bool HapVerifyOpensslUtils::VerifyShaWithRsaPss(const PKCS7_SIGNER_INFO* signInfo,
251     BIO* p7Bio, EVP_PKEY* pkey, bool isPss)
252 {
253     if (signInfo->digest_alg == nullptr) {
254         HAPVERIFY_LOG_ERROR(LABEL, "signInfo->digest_alg is nullptr");
255         return false;
256     }
257     int mdType = OBJ_obj2nid(signInfo->digest_alg->algorithm);
258     const EVP_MD_CTX* mdCtx = FindMdCtxInBio(p7Bio, mdType);
259     EVP_MD_CTX* mdCtxTmp = EVP_MD_CTX_new();
260     if (mdCtxTmp == nullptr) {
261         HAPVERIFY_LOG_ERROR(LABEL, "EVP_MD_CTX_new failed");
262         return false;
263     }
264     if (!EVP_MD_CTX_copy_ex(mdCtxTmp, mdCtx)) {
265         HAPVERIFY_LOG_ERROR(LABEL, "EVP_MD_CTX_copy_ex failed");
266         EVP_MD_CTX_free(mdCtxTmp);
267         return false;
268     }
269     if (!VerifyPkcs7AuthAttributes(signInfo, mdCtxTmp, mdType)) {
270         HAPVERIFY_LOG_ERROR(LABEL, "VerifyPkcs7AuthAttributes failed");
271         EVP_MD_CTX_free(mdCtxTmp);
272         return false;
273     }
274 
275     unsigned char digest[EVP_MAX_MD_SIZE];
276     unsigned int digestLen;
277     if (EVP_DigestFinal_ex(mdCtxTmp, digest, &digestLen) <= 0) {
278         HAPVERIFY_LOG_ERROR(LABEL, "Digest content failed");
279         GetOpensslErrorMessage();
280         EVP_MD_CTX_free(mdCtxTmp);
281         return false;
282     }
283     EVP_MD_CTX_free(mdCtxTmp);
284 
285     if (!VerifyShaWithRsaPss(signInfo, pkey, isPss, digest, digestLen)) {
286         HAPVERIFY_LOG_ERROR(LABEL, "VerifyShaWithRsaPss failed");
287         GetOpensslErrorMessage();
288         return false;
289     }
290     return true;
291 }
292 
FindMdCtxInBio(BIO * p7Bio,int mdType)293 const EVP_MD_CTX* HapVerifyOpensslUtils::FindMdCtxInBio(BIO* p7Bio, int mdType)
294 {
295     EVP_MD_CTX* mdCtx = nullptr;
296     while (p7Bio) {
297         BIO_get_md_ctx(p7Bio, &mdCtx);
298         if (mdCtx == nullptr) {
299             HAPVERIFY_LOG_ERROR(LABEL, "Get null from bio");
300             return nullptr;
301         }
302         if ((EVP_MD_CTX_type(mdCtx) == mdType) || (EVP_MD_pkey_type(EVP_MD_CTX_md(mdCtx)) == mdType)) {
303             break;
304         }
305         p7Bio = BIO_next(p7Bio);
306     }
307     return mdCtx;
308 }
309 
VerifyPkcs7AuthAttributes(const PKCS7_SIGNER_INFO * signInfo,EVP_MD_CTX * mdCtx,int mdType)310 bool HapVerifyOpensslUtils::VerifyPkcs7AuthAttributes(const PKCS7_SIGNER_INFO* signInfo, EVP_MD_CTX* mdCtx, int mdType)
311 {
312     X509AttributeStack* authAttributes = signInfo->auth_attr;
313     if ((authAttributes != nullptr) && (sk_X509_ATTRIBUTE_num(authAttributes) != 0)) {
314         unsigned char digest[EVP_MAX_MD_SIZE];
315         unsigned int digestLen;
316         if (EVP_DigestFinal_ex(mdCtx, digest, &digestLen) <= 0) {
317             HAPVERIFY_LOG_ERROR(LABEL, "Digest content failed");
318             GetOpensslErrorMessage();
319             return false;
320         }
321         ASN1_OCTET_STRING* digestInAttribute = PKCS7_digest_from_attributes(authAttributes);
322         if (!AsnStringCmp(digestInAttribute, digest, static_cast<int>(digestLen))) {
323             HAPVERIFY_LOG_ERROR(LABEL, "AsnStringCmp failed");
324             return false;
325         }
326 
327         if (!EVP_VerifyInit_ex(mdCtx, EVP_get_digestbynid(mdType), nullptr)) {
328             HAPVERIFY_LOG_ERROR(LABEL, "EVP_VerifyInit_ex failed");
329             GetOpensslErrorMessage();
330             return false;
331         }
332 
333         unsigned char* attributesData = nullptr;
334         int attributesLen = ASN1_item_i2d(reinterpret_cast<ASN1_VALUE*>(authAttributes), &attributesData,
335             ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
336         if (attributesLen <= 0 || attributesData == nullptr) {
337             HAPVERIFY_LOG_ERROR(LABEL, "ASN1_item_i2d failed");
338             GetOpensslErrorMessage();
339             return false;
340         }
341         if (!EVP_VerifyUpdate(mdCtx, attributesData, attributesLen)) {
342             HAPVERIFY_LOG_ERROR(LABEL, "EVP_VerifyUpdate failed");
343             GetOpensslErrorMessage();
344             OPENSSL_free(attributesData);
345             return false;
346         }
347         OPENSSL_free(attributesData);
348     }
349     return true;
350 }
351 
AsnStringCmp(const ASN1_OCTET_STRING * asnStr,const unsigned char data[],int len)352 bool HapVerifyOpensslUtils::AsnStringCmp(const ASN1_OCTET_STRING* asnStr, const unsigned char data[], int len)
353 {
354     if (asnStr == nullptr) {
355         HAPVERIFY_LOG_ERROR(LABEL, "asnStr is nullptr");
356         return false;
357     }
358     if (asnStr->data == nullptr) {
359         HAPVERIFY_LOG_ERROR(LABEL, "asnStr->data is nullptr");
360         return false;
361     }
362     if (data == nullptr) {
363         HAPVERIFY_LOG_ERROR(LABEL, "data is nullptr");
364         return false;
365     }
366     if (asnStr->length != len) {
367         HAPVERIFY_LOG_ERROR(LABEL, "asnStr->length: %{public}d is not equal to len: %{public}d", asnStr->length, len);
368         return false;
369     }
370     for (int i = 0; i < len; i++) {
371         if (asnStr->data[i] != data[i]) {
372             HAPVERIFY_LOG_ERROR(LABEL, "%{public}dst data is not equal", i);
373             return false;
374         }
375     }
376     return true;
377 }
378 
VerifyShaWithRsaPss(const PKCS7_SIGNER_INFO * signInfo,EVP_PKEY * pkey,bool isPss,const unsigned char digest[],unsigned int digestLen)379 bool HapVerifyOpensslUtils::VerifyShaWithRsaPss(const PKCS7_SIGNER_INFO* signInfo, EVP_PKEY* pkey, bool isPss,
380     const unsigned char digest[], unsigned int digestLen)
381 {
382     EVP_PKEY_CTX* pkeyCtx = EVP_PKEY_CTX_new(pkey, nullptr);
383     if (pkeyCtx == nullptr) {
384         HAPVERIFY_LOG_ERROR(LABEL, "EVP_PKEY_CTX_new failed");
385         GetOpensslErrorMessage();
386         return false;
387     }
388     if (EVP_PKEY_verify_init(pkeyCtx) <= 0) {
389         HAPVERIFY_LOG_ERROR(LABEL, "EVP_PKEY_verify_init failed");
390         GetOpensslErrorMessage();
391         EVP_PKEY_CTX_free(pkeyCtx);
392         return false;
393     }
394     if (signInfo->digest_alg == nullptr || signInfo->enc_digest == nullptr) {
395         HAPVERIFY_LOG_ERROR(LABEL, "no digest_alg or enc_digest in signInfo");
396         EVP_PKEY_CTX_free(pkeyCtx);
397         return false;
398     }
399     int mdType = OBJ_obj2nid(signInfo->digest_alg->algorithm);
400     if ((isPss && EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, RSA_PKCS1_PSS_PADDING) <= 0) ||
401         (EVP_PKEY_CTX_set_signature_md(pkeyCtx, EVP_get_digestbynid(mdType)) <= 0)) {
402         HAPVERIFY_LOG_ERROR(LABEL, "set rsa_padding or signature_md failed");
403         GetOpensslErrorMessage();
404         EVP_PKEY_CTX_free(pkeyCtx);
405         return false;
406     }
407     if (EVP_PKEY_verify(pkeyCtx, signInfo->enc_digest->data, signInfo->enc_digest->length, digest, digestLen) <= 0) {
408         HAPVERIFY_LOG_ERROR(LABEL, "EVP_PKEY_verify failed");
409         GetOpensslErrorMessage();
410         EVP_PKEY_CTX_free(pkeyCtx);
411         return false;
412     }
413     EVP_PKEY_CTX_free(pkeyCtx);
414     return true;
415 }
416 
GetPublickeys(const CertChain & signCertChain,std::vector<std::string> & SignatureVec)417 bool HapVerifyOpensslUtils::GetPublickeys(const CertChain& signCertChain,
418     std::vector<std::string>& SignatureVec)
419 {
420     for (unsigned int i = 0; i < signCertChain.size(); i++) {
421         if (!GetPublickeyFromCertificate(signCertChain[i], SignatureVec)) {
422             HAPVERIFY_LOG_ERROR(LABEL, "%{public}ust Get Publickey failed", i);
423             return false;
424         }
425     }
426     return !SignatureVec.empty();
427 }
428 
GetSignatures(const CertChain & signCertChain,std::vector<std::string> & SignatureVec)429 bool HapVerifyOpensslUtils::GetSignatures(const CertChain& signCertChain,
430     std::vector<std::string>& SignatureVec)
431 {
432     for (unsigned int i = 0; i < signCertChain.size(); i++) {
433         if (!GetDerCert(signCertChain[i], SignatureVec)) {
434             HAPVERIFY_LOG_ERROR(LABEL, "%{public}ust GetDerCert failed", i);
435             return false;
436         }
437     }
438     return !SignatureVec.empty();
439 }
440 
GetDerCert(X509 * ptrX509,std::vector<std::string> & SignatureVec)441 bool HapVerifyOpensslUtils::GetDerCert(X509* ptrX509, std::vector<std::string>& SignatureVec)
442 {
443     if (ptrX509 == nullptr) {
444         return false;
445     }
446 
447     int certLen = i2d_X509(ptrX509, nullptr);
448     if (certLen <= 0) {
449         HAPVERIFY_LOG_ERROR(LABEL, "certLen %{public}d, i2d_X509 failed", certLen);
450         GetOpensslErrorMessage();
451         return false;
452     }
453     std::unique_ptr<unsigned char[]> derCertificate = std::make_unique<unsigned char[]>(certLen);
454     int base64CertLen = HapCertVerifyOpensslUtils::CalculateLenAfterBase64Encode(certLen);
455     std::unique_ptr<unsigned char[]> base64Certificate = std::make_unique<unsigned char[]>(base64CertLen);
456     unsigned char* derCertificateBackup = derCertificate.get();
457     if (i2d_X509(ptrX509, &derCertificateBackup) <= 0) {
458         HAPVERIFY_LOG_ERROR(LABEL, "i2d_X509 failed");
459         GetOpensslErrorMessage();
460         return false;
461     }
462 
463     /* base64 encode */
464     int len = EVP_EncodeBlock(base64Certificate.get(), derCertificate.get(), certLen);
465     SignatureVec.emplace_back(std::string(reinterpret_cast<char*>(base64Certificate.get()), len));
466     return true;
467 }
468 
GetPublickeyFromCertificate(const X509 * ptrX509,std::vector<std::string> & publicKeyVec)469 bool HapVerifyOpensslUtils::GetPublickeyFromCertificate(const X509* ptrX509, std::vector<std::string>& publicKeyVec)
470 {
471     if (ptrX509 == nullptr) {
472         return false;
473     }
474 
475     std::string publicKey;
476     if (!HapCertVerifyOpensslUtils::GetPublickeyBase64(ptrX509, publicKey)) {
477         HAPVERIFY_LOG_ERROR(LABEL, "GetPublickeyBase64 Failed");
478         return false;
479     }
480     publicKeyVec.emplace_back(publicKey);
481     return true;
482 }
483 
GetContentInfo(const PKCS7 * p7ContentInfo,HapByteBuffer & content)484 bool HapVerifyOpensslUtils::GetContentInfo(const PKCS7* p7ContentInfo, HapByteBuffer& content)
485 {
486     if ((p7ContentInfo == nullptr) || !PKCS7_type_is_data(p7ContentInfo)) {
487         HAPVERIFY_LOG_ERROR(LABEL, "p7ContentInfo is invalid");
488         return false;
489     }
490 
491     ASN1_OCTET_STRING* strContentInfo = p7ContentInfo->d.data;
492     if (strContentInfo == nullptr) {
493         HAPVERIFY_LOG_ERROR(LABEL, "strContentInfo is invalid");
494         return false;
495     }
496 
497     int strContentInfoLen = strContentInfo->length;
498     unsigned char* strContentInfoData = strContentInfo->data;
499     if (strContentInfoData == nullptr || strContentInfoLen <= 0) {
500         HAPVERIFY_LOG_ERROR(LABEL, "ASN1_OCTET_STRING is invalid");
501         return false;
502     }
503 
504     content.SetCapacity(strContentInfoLen);
505     content.PutData(0, reinterpret_cast<char*>(strContentInfoData), strContentInfoLen);
506     HAPVERIFY_LOG_DEBUG(LABEL, "strContentInfoLen: %{public}d", strContentInfoLen);
507     return true;
508 }
509 
GetDigestAlgorithmOutputSizeBytes(int nId)510 int HapVerifyOpensslUtils::GetDigestAlgorithmOutputSizeBytes(int nId)
511 {
512     return EVP_MD_size(EVP_get_digestbynid(nId));
513 }
514 
CheckDigestParameter(const DigestParameter & digestParameter)515 bool HapVerifyOpensslUtils::CheckDigestParameter(const DigestParameter& digestParameter)
516 {
517     if (digestParameter.md == nullptr) {
518         HAPVERIFY_LOG_ERROR(LABEL, "md is nullptr");
519         return false;
520     }
521     if (digestParameter.ptrCtx == nullptr) {
522         HAPVERIFY_LOG_ERROR(LABEL, "ptrCtx is nullptr");
523         return false;
524     }
525     return true;
526 }
527 
DigestInit(const DigestParameter & digestParameter)528 bool HapVerifyOpensslUtils::DigestInit(const DigestParameter& digestParameter)
529 {
530     if (!CheckDigestParameter(digestParameter)) {
531         return false;
532     }
533     if (EVP_DigestInit(digestParameter.ptrCtx, digestParameter.md) <= 0) {
534         GetOpensslErrorMessage();
535         HAPVERIFY_LOG_ERROR(LABEL, "EVP_DigestInit failed");
536         return false;
537     }
538     return true;
539 }
540 
541 /* the caller must ensure that EVP_DigestInit was called before calling this function */
DigestUpdate(const DigestParameter & digestParameter,const unsigned char content[],int len)542 bool HapVerifyOpensslUtils::DigestUpdate(const DigestParameter& digestParameter,
543     const unsigned char content[], int len)
544 {
545     if (content == nullptr) {
546         HAPVERIFY_LOG_ERROR(LABEL, "content is nullptr");
547         return false;
548     }
549     if (!CheckDigestParameter(digestParameter)) {
550         return false;
551     }
552     if (EVP_DigestUpdate(digestParameter.ptrCtx, content, len) <= 0) {
553         GetOpensslErrorMessage();
554         HAPVERIFY_LOG_ERROR(LABEL, "EVP_DigestUpdate chunk failed");
555         return false;
556     }
557     return true;
558 }
559 
GetDigest(const DigestParameter & digestParameter,unsigned char (& out)[EVP_MAX_MD_SIZE])560 int HapVerifyOpensslUtils::GetDigest(const DigestParameter& digestParameter, unsigned char (&out)[EVP_MAX_MD_SIZE])
561 {
562     unsigned int outLen = 0;
563     if (!CheckDigestParameter(digestParameter)) {
564         return outLen;
565     }
566     if (EVP_DigestFinal(digestParameter.ptrCtx, out, &outLen) <= 0) {
567         GetOpensslErrorMessage();
568         HAPVERIFY_LOG_ERROR(LABEL, "EVP_DigestFinal failed");
569         outLen = 0;
570     }
571     return outLen;
572 }
573 
GetDigest(const HapByteBuffer & chunk,const std::vector<OptionalBlock> & optionalBlocks,const DigestParameter & digestParameter,unsigned char (& out)[EVP_MAX_MD_SIZE])574 int HapVerifyOpensslUtils::GetDigest(const HapByteBuffer& chunk, const std::vector<OptionalBlock>& optionalBlocks,
575     const DigestParameter& digestParameter, unsigned char (&out)[EVP_MAX_MD_SIZE])
576 {
577     int chunkLen = chunk.Remaining();
578     unsigned int outLen = 0;
579     if (digestParameter.md == nullptr) {
580         HAPVERIFY_LOG_ERROR(LABEL, "md is nullprt");
581         return outLen;
582     }
583     if (digestParameter.ptrCtx == nullptr) {
584         HAPVERIFY_LOG_ERROR(LABEL, "ptrCtx is nullprt");
585         return outLen;
586     }
587 
588     if (EVP_DigestInit(digestParameter.ptrCtx, digestParameter.md) <= 0) {
589         GetOpensslErrorMessage();
590         HAPVERIFY_LOG_ERROR(LABEL, "EVP_DigestInit failed");
591         return outLen;
592     }
593 
594     if (EVP_DigestUpdate(digestParameter.ptrCtx, chunk.GetBufferPtr(), chunkLen) <= 0) {
595         GetOpensslErrorMessage();
596         HAPVERIFY_LOG_ERROR(LABEL, "EVP_DigestUpdate chunk failed");
597         return outLen;
598     }
599     for (int i = 0; i < static_cast<int>(optionalBlocks.size()); i++) {
600         chunkLen = optionalBlocks[i].optionalBlockValue.GetCapacity();
601         if (EVP_DigestUpdate(digestParameter.ptrCtx, optionalBlocks[i].optionalBlockValue.GetBufferPtr(),
602             chunkLen) <= 0) {
603             GetOpensslErrorMessage();
604             HAPVERIFY_LOG_ERROR(LABEL, "EVP_DigestUpdate %{public}dst optional block failed", i);
605             return outLen;
606         }
607     }
608 
609     if (EVP_DigestFinal(digestParameter.ptrCtx, out, &outLen) <= 0) {
610         GetOpensslErrorMessage();
611         HAPVERIFY_LOG_ERROR(LABEL, "EVP_DigestFinal failed");
612         outLen = 0;
613     }
614     return outLen;
615 }
616 
GetOpensslErrorMessage()617 void HapVerifyOpensslUtils::GetOpensslErrorMessage()
618 {
619     unsigned long retOpenssl;
620     char errOpenssl[OPENSSL_ERR_MESSAGE_MAX_LEN];
621     while ((retOpenssl = ERR_get_error()) != 0) {
622         ERR_error_string(retOpenssl, errOpenssl);
623         HAPVERIFY_LOG_ERROR(LABEL, "openssl err: %{public}lu, message: %{public}s", retOpenssl, errOpenssl);
624     }
625 }
626 
GetDigestAlgorithmId(int signAlgorithm)627 int HapVerifyOpensslUtils::GetDigestAlgorithmId(int signAlgorithm)
628 {
629     switch (signAlgorithm) {
630         case ALGORITHM_SHA256_WITH_RSA_PSS:
631         case ALGORITHM_SHA256_WITH_RSA_PKCS1_V1_5:
632         case ALGORITHM_SHA256_WITH_ECDSA:
633         case ALGORITHM_SHA256_WITH_DSA:
634             return NID_sha256;
635         case ALGORITHM_SHA384_WITH_RSA_PSS:
636         case ALGORITHM_SHA384_WITH_RSA_PKCS1_V1_5:
637         case ALGORITHM_SHA384_WITH_ECDSA:
638         case ALGORITHM_SHA384_WITH_DSA:
639             return NID_sha384;
640         case ALGORITHM_SHA512_WITH_RSA_PSS:
641         case ALGORITHM_SHA512_WITH_RSA_PKCS1_V1_5:
642         case ALGORITHM_SHA512_WITH_ECDSA:
643         case ALGORITHM_SHA512_WITH_DSA:
644             return NID_sha512;
645         default:
646             HAPVERIFY_LOG_ERROR(LABEL, "signAlgorithm: %{public}d error", signAlgorithm);
647             return NID_undef;
648     }
649 }
650 } // namespace Verify
651 } // namespace Security
652 } // namespace OHOS
653