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 int32_t HapVerifyOpensslUtils::OPENSSL_PKCS7_VERIFY_SUCCESS = 1;
35 const int32_t 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 int32_t HapVerifyOpensslUtils::OPENSSL_READ_DATA_MAX_TIME = 2097152;
43 const int32_t 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 int32_t HapVerifyOpensslUtils::MAX_OID_LENGTH = 128;
48
ParsePkcs7Package(const unsigned char packageData[],uint32_t packageLen,Pkcs7Context & pkcs7Context)49 bool HapVerifyOpensslUtils::ParsePkcs7Package(const unsigned char packageData[],
50 uint32_t packageLen, Pkcs7Context& pkcs7Context)
51 {
52 if (packageData == nullptr || packageLen == 0) {
53 HAPVERIFY_LOG_ERROR("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("p7 is invalid");
61 return false;
62 }
63 if (!GetContentInfo(pkcs7Context.p7->d.sign->contents, pkcs7Context.content)) {
64 HAPVERIFY_LOG_ERROR("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("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("get signerInfoStack error");
83 GetOpensslErrorMessage();
84 return false;
85 }
86 int32_t signCount = sk_PKCS7_SIGNER_INFO_num(signerInfoStack);
87 if (signCount <= 0) {
88 HAPVERIFY_LOG_ERROR("can not find signinfo");
89 return false;
90 }
91
92 for (int32_t 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("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("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("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, pkcs7Context)) {
122 HAPVERIFY_LOG_ERROR("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("VerifyCertChainPeriodOfValidity for signInfo failed");
128 return false;
129 }
130 if (!HapCertVerifyOpensslUtils::VerifyCrl(certsChain, p7->d.sign->crl, pkcs7Context)) {
131 HAPVERIFY_LOG_ERROR("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("p7 type is invalid signed_data_pkcs7");
149 return false;
150 }
151
152 if (!VerifyPkcs7SignedData(pkcs7Context)) {
153 HAPVERIFY_LOG_ERROR("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("get p7bio error");
165 GetOpensslErrorMessage();
166 return false;
167 }
168 char buf[OPENSSL_READ_DATA_LEN_EACH_TIME] = {0};
169 int32_t readLen = BIO_read(p7Bio, buf, sizeof(buf));
170 int32_t 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("get signerInfoStack error");
177 BIO_free_all(p7Bio);
178 GetOpensslErrorMessage();
179 return false;
180 }
181 /* get the num of signInfo */
182 int32_t signCount = sk_PKCS7_SIGNER_INFO_num(signerInfoStack);
183 if (signCount <= 0) {
184 HAPVERIFY_LOG_ERROR("can not find signinfo");
185 BIO_free_all(p7Bio);
186 return false;
187 }
188 for (int32_t i = 0; i < signCount; i++) {
189 if (!VerifySignInfo(signerInfoStack, p7Bio, i, pkcs7Context)) {
190 HAPVERIFY_LOG_ERROR("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,int32_t signInfoNum,Pkcs7Context & pkcs7Context)199 bool HapVerifyOpensslUtils::VerifySignInfo(STACK_OF(PKCS7_SIGNER_INFO)* signerInfoStack,
200 BIO* p7Bio, int32_t signInfoNum, Pkcs7Context& pkcs7Context) {
201 if (signerInfoStack == nullptr || p7Bio == nullptr) {
202 HAPVERIFY_LOG_ERROR("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("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("signInfo %{public}dst X509_get_pubkey failed", signInfoNum);
218 return false;
219 }
220 HAPVERIFY_LOG_DEBUG("use RSA/pss");
221 if (!VerifyShaWithRsaPss(signInfo, p7Bio, pkey, isShaWithRsaPss)) {
222 HAPVERIFY_LOG_ERROR("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("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("signInfo->digest_enc_alg is nullptr");
240 return false;
241 }
242 int32_t len = OBJ_obj2txt(oId, sizeof(oId), signInfo->digest_enc_alg->algorithm, 1);
243 if (len < 0 || len >= MAX_OID_LENGTH) {
244 HAPVERIFY_LOG_ERROR("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("signInfo->digest_alg is nullptr");
255 return false;
256 }
257 int32_t 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("EVP_MD_CTX_new failed");
262 return false;
263 }
264 if (!EVP_MD_CTX_copy_ex(mdCtxTmp, mdCtx)) {
265 HAPVERIFY_LOG_ERROR("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("VerifyPkcs7AuthAttributes failed");
271 EVP_MD_CTX_free(mdCtxTmp);
272 return false;
273 }
274
275 unsigned char digest[EVP_MAX_MD_SIZE];
276 uint32_t digestLen;
277 if (EVP_DigestFinal_ex(mdCtxTmp, digest, &digestLen) <= 0) {
278 HAPVERIFY_LOG_ERROR("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("VerifyShaWithRsaPss failed");
287 GetOpensslErrorMessage();
288 return false;
289 }
290 return true;
291 }
292
FindMdCtxInBio(BIO * p7Bio,int32_t mdType)293 const EVP_MD_CTX* HapVerifyOpensslUtils::FindMdCtxInBio(BIO* p7Bio, int32_t 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("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,int32_t mdType)310 bool HapVerifyOpensslUtils::VerifyPkcs7AuthAttributes(
311 const PKCS7_SIGNER_INFO* signInfo, EVP_MD_CTX* mdCtx, int32_t mdType)
312 {
313 X509AttributeStack* authAttributes = signInfo->auth_attr;
314 if ((authAttributes != nullptr) && (sk_X509_ATTRIBUTE_num(authAttributes) != 0)) {
315 unsigned char digest[EVP_MAX_MD_SIZE];
316 uint32_t digestLen;
317 if (EVP_DigestFinal_ex(mdCtx, digest, &digestLen) <= 0) {
318 HAPVERIFY_LOG_ERROR("Digest content failed");
319 GetOpensslErrorMessage();
320 return false;
321 }
322 ASN1_OCTET_STRING* digestInAttribute = PKCS7_digest_from_attributes(authAttributes);
323 if (!AsnStringCmp(digestInAttribute, digest, static_cast<int>(digestLen))) {
324 HAPVERIFY_LOG_ERROR("AsnStringCmp failed");
325 return false;
326 }
327
328 if (!EVP_VerifyInit_ex(mdCtx, EVP_get_digestbynid(mdType), nullptr)) {
329 HAPVERIFY_LOG_ERROR("EVP_VerifyInit_ex failed");
330 GetOpensslErrorMessage();
331 return false;
332 }
333
334 unsigned char* attributesData = nullptr;
335 int32_t attributesLen = ASN1_item_i2d(reinterpret_cast<ASN1_VALUE*>(authAttributes), &attributesData,
336 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
337 if (attributesLen <= 0 || attributesData == nullptr) {
338 HAPVERIFY_LOG_ERROR("ASN1_item_i2d failed");
339 GetOpensslErrorMessage();
340 return false;
341 }
342 if (!EVP_VerifyUpdate(mdCtx, attributesData, attributesLen)) {
343 HAPVERIFY_LOG_ERROR("EVP_VerifyUpdate failed");
344 GetOpensslErrorMessage();
345 OPENSSL_free(attributesData);
346 return false;
347 }
348 OPENSSL_free(attributesData);
349 }
350 return true;
351 }
352
AsnStringCmp(const ASN1_OCTET_STRING * asnStr,const unsigned char data[],int32_t len)353 bool HapVerifyOpensslUtils::AsnStringCmp(const ASN1_OCTET_STRING* asnStr, const unsigned char data[], int32_t len)
354 {
355 if (asnStr == nullptr) {
356 HAPVERIFY_LOG_ERROR("asnStr is nullptr");
357 return false;
358 }
359 if (asnStr->data == nullptr) {
360 HAPVERIFY_LOG_ERROR("asnStr->data is nullptr");
361 return false;
362 }
363 if (data == nullptr) {
364 HAPVERIFY_LOG_ERROR("data is nullptr");
365 return false;
366 }
367 if (asnStr->length != len) {
368 HAPVERIFY_LOG_ERROR("asnStr->length: %{public}d is not equal to len: %{public}d", asnStr->length, len);
369 return false;
370 }
371 for (int32_t i = 0; i < len; i++) {
372 if (asnStr->data[i] != data[i]) {
373 HAPVERIFY_LOG_ERROR("%{public}dst data is not equal", i);
374 return false;
375 }
376 }
377 return true;
378 }
379
VerifyShaWithRsaPss(const PKCS7_SIGNER_INFO * signInfo,EVP_PKEY * pkey,bool isPss,const unsigned char digest[],uint32_t digestLen)380 bool HapVerifyOpensslUtils::VerifyShaWithRsaPss(const PKCS7_SIGNER_INFO* signInfo, EVP_PKEY* pkey, bool isPss,
381 const unsigned char digest[], uint32_t digestLen)
382 {
383 EVP_PKEY_CTX* pkeyCtx = EVP_PKEY_CTX_new(pkey, nullptr);
384 if (pkeyCtx == nullptr) {
385 HAPVERIFY_LOG_ERROR("EVP_PKEY_CTX_new failed");
386 GetOpensslErrorMessage();
387 return false;
388 }
389 if (EVP_PKEY_verify_init(pkeyCtx) <= 0) {
390 HAPVERIFY_LOG_ERROR("EVP_PKEY_verify_init failed");
391 GetOpensslErrorMessage();
392 EVP_PKEY_CTX_free(pkeyCtx);
393 return false;
394 }
395 if (signInfo->digest_alg == nullptr || signInfo->enc_digest == nullptr) {
396 HAPVERIFY_LOG_ERROR("no digest_alg or enc_digest in signInfo");
397 EVP_PKEY_CTX_free(pkeyCtx);
398 return false;
399 }
400 int32_t mdType = OBJ_obj2nid(signInfo->digest_alg->algorithm);
401 if ((isPss && EVP_PKEY_CTX_set_rsa_padding(pkeyCtx, RSA_PKCS1_PSS_PADDING) <= 0) ||
402 (EVP_PKEY_CTX_set_signature_md(pkeyCtx, EVP_get_digestbynid(mdType)) <= 0)) {
403 HAPVERIFY_LOG_ERROR("set rsa_padding or signature_md failed");
404 GetOpensslErrorMessage();
405 EVP_PKEY_CTX_free(pkeyCtx);
406 return false;
407 }
408 if (EVP_PKEY_verify(pkeyCtx, signInfo->enc_digest->data, signInfo->enc_digest->length, digest, digestLen) <= 0) {
409 HAPVERIFY_LOG_ERROR("EVP_PKEY_verify failed");
410 GetOpensslErrorMessage();
411 EVP_PKEY_CTX_free(pkeyCtx);
412 return false;
413 }
414 EVP_PKEY_CTX_free(pkeyCtx);
415 return true;
416 }
417
GetPublickeys(const CertChain & signCertChain,std::vector<std::string> & SignatureVec)418 bool HapVerifyOpensslUtils::GetPublickeys(const CertChain& signCertChain,
419 std::vector<std::string>& SignatureVec)
420 {
421 for (uint32_t i = 0; i < signCertChain.size(); i++) {
422 if (!GetPublickeyFromCertificate(signCertChain[i], SignatureVec)) {
423 HAPVERIFY_LOG_ERROR("%{public}ust Get Publickey failed", i);
424 return false;
425 }
426 }
427 return !SignatureVec.empty();
428 }
429
GetSignatures(const CertChain & signCertChain,std::vector<std::string> & SignatureVec)430 bool HapVerifyOpensslUtils::GetSignatures(const CertChain& signCertChain,
431 std::vector<std::string>& SignatureVec)
432 {
433 for (uint32_t i = 0; i < signCertChain.size(); i++) {
434 if (!GetDerCert(signCertChain[i], SignatureVec)) {
435 HAPVERIFY_LOG_ERROR("%{public}ust GetDerCert failed", i);
436 return false;
437 }
438 }
439 return !SignatureVec.empty();
440 }
441
GetDerCert(X509 * ptrX509,std::vector<std::string> & SignatureVec)442 bool HapVerifyOpensslUtils::GetDerCert(X509* ptrX509, std::vector<std::string>& SignatureVec)
443 {
444 if (ptrX509 == nullptr) {
445 return false;
446 }
447
448 int32_t certLen = i2d_X509(ptrX509, nullptr);
449 if (certLen <= 0) {
450 HAPVERIFY_LOG_ERROR("certLen %{public}d, i2d_X509 failed", certLen);
451 GetOpensslErrorMessage();
452 return false;
453 }
454 std::unique_ptr<unsigned char[]> derCertificate = std::make_unique<unsigned char[]>(certLen);
455 int32_t base64CertLen = HapCertVerifyOpensslUtils::CalculateLenAfterBase64Encode(certLen);
456 std::unique_ptr<unsigned char[]> base64Certificate = std::make_unique<unsigned char[]>(base64CertLen);
457 unsigned char* derCertificateBackup = derCertificate.get();
458 if (i2d_X509(ptrX509, &derCertificateBackup) <= 0) {
459 HAPVERIFY_LOG_ERROR("i2d_X509 failed");
460 GetOpensslErrorMessage();
461 return false;
462 }
463
464 /* base64 encode */
465 int32_t len = EVP_EncodeBlock(base64Certificate.get(), derCertificate.get(), certLen);
466 SignatureVec.emplace_back(std::string(reinterpret_cast<char*>(base64Certificate.get()), len));
467 return true;
468 }
469
GetPublickeyFromCertificate(const X509 * ptrX509,std::vector<std::string> & publicKeyVec)470 bool HapVerifyOpensslUtils::GetPublickeyFromCertificate(const X509* ptrX509, std::vector<std::string>& publicKeyVec)
471 {
472 if (ptrX509 == nullptr) {
473 return false;
474 }
475
476 std::string publicKey;
477 if (!HapCertVerifyOpensslUtils::GetPublickeyBase64(ptrX509, publicKey)) {
478 HAPVERIFY_LOG_ERROR("GetPublickeyBase64 Failed");
479 return false;
480 }
481 publicKeyVec.emplace_back(publicKey);
482 return true;
483 }
484
GetContentInfo(const PKCS7 * p7ContentInfo,HapByteBuffer & content)485 bool HapVerifyOpensslUtils::GetContentInfo(const PKCS7* p7ContentInfo, HapByteBuffer& content)
486 {
487 if ((p7ContentInfo == nullptr) || !PKCS7_type_is_data(p7ContentInfo)) {
488 HAPVERIFY_LOG_ERROR("p7ContentInfo is invalid");
489 return false;
490 }
491
492 ASN1_OCTET_STRING* strContentInfo = p7ContentInfo->d.data;
493 if (strContentInfo == nullptr) {
494 HAPVERIFY_LOG_ERROR("strContentInfo is invalid");
495 return false;
496 }
497
498 int32_t strContentInfoLen = strContentInfo->length;
499 unsigned char* strContentInfoData = strContentInfo->data;
500 if (strContentInfoData == nullptr || strContentInfoLen <= 0) {
501 HAPVERIFY_LOG_ERROR("ASN1_OCTET_STRING is invalid");
502 return false;
503 }
504
505 content.SetCapacity(strContentInfoLen);
506 content.PutData(0, reinterpret_cast<char*>(strContentInfoData), strContentInfoLen);
507 HAPVERIFY_LOG_DEBUG("strContentInfoLen: %{public}d", strContentInfoLen);
508 return true;
509 }
510
GetDigestAlgorithmOutputSizeBytes(int32_t nId)511 int32_t HapVerifyOpensslUtils::GetDigestAlgorithmOutputSizeBytes(int32_t nId)
512 {
513 return EVP_MD_size(EVP_get_digestbynid(nId));
514 }
515
CheckDigestParameter(const DigestParameter & digestParameter)516 bool HapVerifyOpensslUtils::CheckDigestParameter(const DigestParameter& digestParameter)
517 {
518 if (digestParameter.md == nullptr) {
519 HAPVERIFY_LOG_ERROR("md is nullptr");
520 return false;
521 }
522 if (digestParameter.ptrCtx == nullptr) {
523 HAPVERIFY_LOG_ERROR("ptrCtx is nullptr");
524 return false;
525 }
526 return true;
527 }
528
DigestInit(const DigestParameter & digestParameter)529 bool HapVerifyOpensslUtils::DigestInit(const DigestParameter& digestParameter)
530 {
531 if (!CheckDigestParameter(digestParameter)) {
532 return false;
533 }
534 if (EVP_DigestInit(digestParameter.ptrCtx, digestParameter.md) <= 0) {
535 GetOpensslErrorMessage();
536 HAPVERIFY_LOG_ERROR("EVP_DigestInit failed");
537 return false;
538 }
539 return true;
540 }
541
542 /* the caller must ensure that EVP_DigestInit was called before calling this function */
DigestUpdate(const DigestParameter & digestParameter,const unsigned char content[],int32_t len)543 bool HapVerifyOpensslUtils::DigestUpdate(const DigestParameter& digestParameter,
544 const unsigned char content[], int32_t len)
545 {
546 if (content == nullptr) {
547 HAPVERIFY_LOG_ERROR("content is nullptr");
548 return false;
549 }
550 if (!CheckDigestParameter(digestParameter)) {
551 return false;
552 }
553 if (EVP_DigestUpdate(digestParameter.ptrCtx, content, len) <= 0) {
554 GetOpensslErrorMessage();
555 HAPVERIFY_LOG_ERROR("EVP_DigestUpdate chunk failed");
556 return false;
557 }
558 return true;
559 }
560
GetDigest(const DigestParameter & digestParameter,unsigned char (& out)[EVP_MAX_MD_SIZE])561 int32_t HapVerifyOpensslUtils::GetDigest(const DigestParameter& digestParameter, unsigned char (&out)[EVP_MAX_MD_SIZE])
562 {
563 uint32_t outLen = 0;
564 if (!CheckDigestParameter(digestParameter)) {
565 return outLen;
566 }
567 if (EVP_DigestFinal(digestParameter.ptrCtx, out, &outLen) <= 0) {
568 GetOpensslErrorMessage();
569 HAPVERIFY_LOG_ERROR("EVP_DigestFinal failed");
570 outLen = 0;
571 }
572 return outLen;
573 }
574
GetDigest(const HapByteBuffer & chunk,const std::vector<OptionalBlock> & optionalBlocks,const DigestParameter & digestParameter,unsigned char (& out)[EVP_MAX_MD_SIZE])575 int32_t HapVerifyOpensslUtils::GetDigest(const HapByteBuffer& chunk, const std::vector<OptionalBlock>& optionalBlocks,
576 const DigestParameter& digestParameter, unsigned char (&out)[EVP_MAX_MD_SIZE])
577 {
578 int32_t chunkLen = chunk.Remaining();
579 uint32_t outLen = 0;
580 if (digestParameter.md == nullptr) {
581 HAPVERIFY_LOG_ERROR("md is nullprt");
582 return outLen;
583 }
584 if (digestParameter.ptrCtx == nullptr) {
585 HAPVERIFY_LOG_ERROR("ptrCtx is nullprt");
586 return outLen;
587 }
588
589 if (EVP_DigestInit(digestParameter.ptrCtx, digestParameter.md) <= 0) {
590 GetOpensslErrorMessage();
591 HAPVERIFY_LOG_ERROR("EVP_DigestInit failed");
592 return outLen;
593 }
594
595 if (EVP_DigestUpdate(digestParameter.ptrCtx, chunk.GetBufferPtr(), chunkLen) <= 0) {
596 GetOpensslErrorMessage();
597 HAPVERIFY_LOG_ERROR("EVP_DigestUpdate chunk failed");
598 return outLen;
599 }
600 for (int32_t i = 0; i < static_cast<int>(optionalBlocks.size()); i++) {
601 chunkLen = optionalBlocks[i].optionalBlockValue.GetCapacity();
602 if (EVP_DigestUpdate(digestParameter.ptrCtx, optionalBlocks[i].optionalBlockValue.GetBufferPtr(),
603 chunkLen) <= 0) {
604 GetOpensslErrorMessage();
605 HAPVERIFY_LOG_ERROR("EVP_DigestUpdate %{public}dst optional block failed", i);
606 return outLen;
607 }
608 }
609
610 if (EVP_DigestFinal(digestParameter.ptrCtx, out, &outLen) <= 0) {
611 GetOpensslErrorMessage();
612 HAPVERIFY_LOG_ERROR("EVP_DigestFinal failed");
613 outLen = 0;
614 }
615 return outLen;
616 }
617
GetOpensslErrorMessage()618 void HapVerifyOpensslUtils::GetOpensslErrorMessage()
619 {
620 unsigned long retOpenssl;
621 char errOpenssl[OPENSSL_ERR_MESSAGE_MAX_LEN];
622 while ((retOpenssl = ERR_get_error()) != 0) {
623 ERR_error_string(retOpenssl, errOpenssl);
624 HAPVERIFY_LOG_ERROR("openssl err: %{public}lu, message: %{public}s", retOpenssl, errOpenssl);
625 }
626 }
627
GetDigestAlgorithmId(int32_t signAlgorithm)628 int32_t HapVerifyOpensslUtils::GetDigestAlgorithmId(int32_t signAlgorithm)
629 {
630 switch (signAlgorithm) {
631 case ALGORITHM_SHA256_WITH_RSA_PSS:
632 case ALGORITHM_SHA256_WITH_RSA_PKCS1_V1_5:
633 case ALGORITHM_SHA256_WITH_ECDSA:
634 case ALGORITHM_SHA256_WITH_DSA:
635 return NID_sha256;
636 case ALGORITHM_SHA384_WITH_RSA_PSS:
637 case ALGORITHM_SHA384_WITH_RSA_PKCS1_V1_5:
638 case ALGORITHM_SHA384_WITH_ECDSA:
639 case ALGORITHM_SHA384_WITH_DSA:
640 return NID_sha384;
641 case ALGORITHM_SHA512_WITH_RSA_PSS:
642 case ALGORITHM_SHA512_WITH_RSA_PKCS1_V1_5:
643 case ALGORITHM_SHA512_WITH_ECDSA:
644 case ALGORITHM_SHA512_WITH_DSA:
645 return NID_sha512;
646 default:
647 HAPVERIFY_LOG_ERROR("signAlgorithm: %{public}d error", signAlgorithm);
648 return NID_undef;
649 }
650 }
651 } // namespace Verify
652 } // namespace Security
653 } // namespace OHOS
654