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