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