1 /*
2 * Copyright (c) 2023-2024 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 "pkcs7_data.h"
17
18 #include <string>
19 #include <openssl/asn1.h>
20 #include <securec.h>
21
22 #include "log.h"
23 #include "openssl_utils.h"
24
25
26 namespace OHOS {
27 namespace Security {
28 namespace CodeSign {
PKCS7Data(const EVP_MD * md,X509 * cert)29 PKCS7Data::PKCS7Data(const EVP_MD *md, X509 *cert)
30 : cert_(cert), md_(md)
31 {
32 }
33
~PKCS7Data()34 PKCS7Data::~PKCS7Data()
35 {
36 cert_ = nullptr;
37 md_ = nullptr;
38 if (p7_ != nullptr) {
39 // signerinfo would be freed with p7
40 PKCS7_free(p7_);
41 p7_ = nullptr;
42 }
43 }
44
InitPKCS7Data(const std::vector<ByteBuffer> & certChain)45 bool PKCS7Data::InitPKCS7Data(const std::vector<ByteBuffer> &certChain)
46 {
47 uint32_t flags = PKCS7_BINARY | PKCS7_DETACHED | PKCS7_NOATTR | PKCS7_PARTIAL;
48 STACK_OF(X509) *certs = nullptr;
49 if (certChain.empty()) {
50 flags = flags | PKCS7_NOCERTS;
51 } else {
52 certs = MakeStackOfCerts(certChain);
53 }
54 p7_ = PKCS7_sign(nullptr, nullptr, certs, nullptr, static_cast<int>(flags));
55 if (p7_ == nullptr) {
56 sk_X509_pop_free(certs, X509_free);
57 return false;
58 }
59 return true;
60 }
61
GetPKCS7Data(ByteBuffer & pkcs7Data)62 bool PKCS7Data::GetPKCS7Data(ByteBuffer &pkcs7Data)
63 {
64 BIO *bio = BIO_new(BIO_s_mem());
65 bool ret = false;
66 do {
67 if (bio == nullptr) {
68 break;
69 }
70 if (!i2d_PKCS7_bio(bio, p7_)) {
71 ERR_LOG_WITH_OPEN_SSL_MSG("Encode pkcs7 data failed.");
72 break;
73 }
74 uint8_t *tmp = nullptr;
75 long tmpSize = BIO_get_mem_data(bio, &tmp);
76 if ((tmpSize < 0) || (tmpSize > UINT32_MAX)) {
77 break;
78 }
79 if (!pkcs7Data.CopyFrom(tmp, static_cast<uint32_t>(tmpSize))) {
80 break;
81 }
82 ret = true;
83 } while (0);
84 BIO_free(bio);
85 return ret;
86 }
87
AddSignerInfo(PKCS7_SIGNER_INFO * p7i)88 bool PKCS7Data::AddSignerInfo(PKCS7_SIGNER_INFO *p7i)
89 {
90 if (!PKCS7_add_signer(p7_, p7i)) {
91 PKCS7_SIGNER_INFO_free(p7i);
92 LOG_ERROR("Add signer to pkcs7 failed");
93 return false;
94 }
95 return true;
96 }
97 }
98 }
99 }