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 20namespace OHOS { 21namespace SignatureTools { 22 23bool 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 42bool 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 95int 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