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