1 /*
2 * Copyright (c) 2024-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 "cms_utils.h"
17 #include "bc_signeddata_generator.h"
18 #include "constant.h"
19
20 namespace OHOS {
21 namespace SignatureTools {
22
VerifySignDataWithUnsignedDataDigest(const std::vector<int8_t>& unsignedDataDigest, const std::vector<int8_t>& signedData)23 bool CmsUtils::VerifySignDataWithUnsignedDataDigest(const std::vector<int8_t>& unsignedDataDigest,
24 const std::vector<int8_t>& signedData)
25 {
26 int ret = 0;
27 std::string unsignedDataDigest_(unsignedDataDigest.begin(), unsignedDataDigest.end());
28 PKCS7Data p7Data(PKCS7_DETACHED_FLAGS);
29 ret = p7Data.Parse(signedData);
30 if (ret < 0) {
31 SIGNATURE_TOOLS_LOGE("verify pkcs7 signed data block bytes failed");
32 return false;
33 }
34 ret = p7Data.Verify(unsignedDataDigest_);
35 if (ret < 0) {
36 SIGNATURE_TOOLS_LOGE("verify pkcs7 signed datablock failed");
37 return false;
38 }
39 return true;
40 }
41
CheckOwnerID(const std::string& signature, const std::string& profileOwnerID, const std::string& profileType)42 bool CmsUtils::CheckOwnerID(const std::string& signature, const std::string& profileOwnerID,
43 const std::string& profileType)
44 {
45 std::string ownerID = profileOwnerID;
46 if (DEBUG_STR == profileType) ownerID = DEBUG_LIB_ID;
47 int nid = CreateNIDFromOID(OWNERID_OID, OWNERID_OID_SHORT_NAME, OWNERID_OID_LONG_NAME);
48 const unsigned char* data = reinterpret_cast<const unsigned char*>(signature.c_str());
49 PKCS7* p7 = d2i_PKCS7(NULL, &data, static_cast<long>(signature.size()));
50 if (p7 == nullptr) {
51 PrintErrorNumberMsg("PARSE_ERROR", PARSE_ERROR, "invalid data, parse pkcs7 failed");
52 return false;
53 }
54 STACK_OF(PKCS7_SIGNER_INFO)* signerInfosk = PKCS7_get_signer_info(p7);
55 if (signerInfosk == nullptr) {
56 PKCS7_free(p7);
57 PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, "can't get signerinfo from pkcs7");
58 return true;
59 }
60 for (int i = 0; i < sk_PKCS7_SIGNER_INFO_num(signerInfosk); i++) {
61 PKCS7_SIGNER_INFO* signerInfo = sk_PKCS7_SIGNER_INFO_value(signerInfosk, i);
62 ASN1_TYPE* asn1Type = PKCS7_get_signed_attribute(signerInfo, nid);
63 if (asn1Type == nullptr) {
64 if (DEBUG_STR == profileType)
65 continue;
66 if (ownerID.empty()) {
67 continue;
68 } else {
69 PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "app-identifier is not in the signature");
70 PKCS7_free(p7);
71 return false;
72 }
73 }
74 if (ownerID.empty()) {
75 PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "app-identifier in profile is null,in signature exist");
76 PKCS7_free(p7);
77 return false;
78 }
79 if (asn1Type->type == V_ASN1_UTF8STRING) {
80 ASN1_STRING* result = asn1Type->value.asn1_string;
81 std::string result_ownerID;
82 result_ownerID.assign(reinterpret_cast<const char*>(ASN1_STRING_get0_data(result)),
83 ASN1_STRING_length(result));
84 if (ownerID != result_ownerID) {
85 PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "app-identifier in signature is invalid");
86 PKCS7_free(p7);
87 return false;
88 }
89 }
90 }
91 PKCS7_free(p7);
92 return true;
93 }
94
CreateNIDFromOID(const std::string& oid, const std::string& shortName, const std::string& longName)95 int CmsUtils::CreateNIDFromOID(const std::string& oid, const std::string& shortName,
96 const std::string& longName)
97 {
98 int nid = OBJ_txt2nid(oid.c_str());
99 if (nid == NID_undef) {
100 nid = OBJ_create(oid.c_str(), shortName.c_str(), longName.c_str());
101 }
102 return nid;
103 }
104
105 } // namespace SignatureTools
106 } // namespace OHOS