• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <vector>
16 
17 #include "constant.h"
18 #include "pkcs7_data.h"
19 #include "local_signer.h"
20 #include "signer_config.h"
21 #include "signature_tools_log.h"
22 #include "signature_algorithm_helper.h"
23 #include "signature_tools_errno.h"
24 #include "bc_signeddata_generator.h"
25 
26 namespace OHOS {
27 namespace SignatureTools {
28 
GenerateSignedData(const std::string & content,SignerConfig * signerConfig,std::string & ret)29 int BCSignedDataGenerator::GenerateSignedData(const std::string& content,
30                                               SignerConfig* signerConfig, std::string& ret)
31 {
32     std::string sigAlg;
33     int result = RET_OK;
34     if (content.empty()) {
35         PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR,
36                             "digest content is empty, generate signed data failed");
37         return INVALIDPARAM_ERROR;
38     }
39     if (signerConfig == NULL) {
40         PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR,
41                             "signerConfig is NULL");
42         return INVALIDPARAM_ERROR;
43     }
44     std::shared_ptr<Signer> signer = signerConfig->GetSigner();
45     if (signer == NULL) {
46         PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR,
47                             "signer is NULL");
48         return INVALIDPARAM_ERROR;
49     }
50     result = GetSigAlg(signerConfig, sigAlg);
51     if (result < 0) {
52         SIGNATURE_TOOLS_LOGE("get sign algorithm from signerConfig failed");
53         return INVALIDPARAM_ERROR;
54     }
55     result = PackageSignedData(content, signer, sigAlg, ret);
56     if (result < 0) {
57         SIGNATURE_TOOLS_LOGE("package signed data failed");
58         return result;
59     }
60     return result;
61 }
62 
SetOwnerId(const std::string & ownerID)63 void BCSignedDataGenerator::SetOwnerId(const std::string& ownerID)
64 {
65     m_ownerID = ownerID;
66 }
67 
PackageSignedData(const std::string & content,const std::shared_ptr<Signer> & signer,const std::string & sigAlg,std::string & ret)68 int BCSignedDataGenerator::PackageSignedData(const std::string& content, const std::shared_ptr<Signer>& signer,
69                                              const std::string& sigAlg, std::string& ret)
70 {
71     int result = RET_OK;
72     PKCS7Data p7Data(PKCS7_DETACHED_FLAGS);
73     std::vector<PKCS7Attr> attrs;
74     if (m_ownerID.empty() == false) {
75         if (AddOwnerID(attrs, m_ownerID) < 0) {
76             PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR,
77                                 "create ownerIDOid failed");
78             return INVALIDPARAM_ERROR;
79         }
80     }
81     // Generate PKCS#7
82     result = p7Data.Sign(content, signer, sigAlg, ret, attrs);
83     if (result < 0) {
84         SIGNATURE_TOOLS_LOGE("generate pkcs7 signed data block failed");
85         return SIGN_ERROR;
86     }
87     // Verify after parsing
88     result = p7Data.Parse(ret);
89     if (result < 0) {
90         SIGNATURE_TOOLS_LOGE("verify pkcs7 signed data block bytes failed");
91         return PARSE_ERROR;
92     }
93     result = p7Data.Verify(content);
94     if (result < 0) {
95         SIGNATURE_TOOLS_LOGE("verify pkcs7 signed data block failed");
96         return VERIFY_ERROR;
97     }
98     return result;
99 }
100 
GetSigAlg(SignerConfig * signerConfig,std::string & sigAlg)101 int BCSignedDataGenerator::GetSigAlg(SignerConfig* signerConfig, std::string& sigAlg)
102 {
103     std::vector<SignatureAlgorithmHelper> sigs = signerConfig->GetSignatureAlgorithms();
104     if (sigs.size() != 1) {
105         PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, "sigAlg count not equal to 1");
106         return INVALIDPARAM_ERROR;
107     }
108     SignatureAlgorithmHelper signatureAlg = sigs[0];
109     if (signatureAlg.m_id == SignatureAlgorithmId::ECDSA_WITH_SHA256) {
110         sigAlg = SIGN_ALG_SHA256;
111     } else if (signatureAlg.m_id == SignatureAlgorithmId::ECDSA_WITH_SHA384) {
112         sigAlg = SIGN_ALG_SHA384;
113     } else {
114         PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR,
115                             sigAlg + "is invalid sigAlg, please use SHA256withECDSA/SHA384withECDSA, sign failed");
116         return NOT_SUPPORT_ERROR;
117     }
118     return RET_OK;
119 }
120 
CreateNIDFromOID(const std::string & oid,const std::string & shortName,const std::string & longName)121 int BCSignedDataGenerator::CreateNIDFromOID(const std::string& oid, const std::string& shortName,
122                                             const std::string& longName)
123 {
124     int nid = OBJ_txt2nid(oid.c_str());
125     if (nid == NID_undef) {
126         nid = OBJ_create(oid.c_str(), shortName.c_str(), longName.c_str());
127     }
128     return nid;
129 }
130 
AddOwnerID(std::vector<PKCS7Attr> & attrs,const std::string & ownerID)131 int BCSignedDataGenerator::AddOwnerID(std::vector<PKCS7Attr>& attrs, const std::string& ownerID)
132 {
133     PKCS7Attr attr;
134     int nid = CreateNIDFromOID(OWNERID_OID, OWNERID_OID_SHORT_NAME, OWNERID_OID_LONG_NAME);
135     if (nid == NID_undef) {
136         return RET_FAILED;
137     }
138     ASN1_STRING* ownerIDAsn1 = ASN1_STRING_new();
139     if (ownerIDAsn1 == NULL) {
140         SIGNATURE_TOOLS_LOGE("asn1 string create error!\n");
141         return RET_FAILED;
142     }
143     ASN1_STRING_set(ownerIDAsn1, ownerID.c_str(), ownerID.length());
144     attr.nid = nid;
145     attr.atrtype = V_ASN1_UTF8STRING;
146     attr.value = ownerIDAsn1;
147     attrs.push_back(attr);
148     return RET_OK;
149 }
150 } // namespace SignatureTools
151 } // namespace OHOS