1 /* 2 * Copyright (c) 2022 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 #ifndef PKCS7_SIGNED_DATA_H 17 #define PKCS7_SIGNED_DATA_H 18 19 #include <vector> 20 #include <openssl/pkcs7.h> 21 #include <openssl/x509.h> 22 #include "pkg_manager.h" 23 24 namespace Hpackage { 25 using DataBuffer = struct { 26 std::vector<char> buffer; 27 size_t length; 28 }; 29 30 using SignatureInfo = struct { 31 DataBuffer overall; 32 DataBuffer hashResult; 33 int nid; 34 }; 35 36 struct Pkcs7SignerInfo { 37 X509_NAME *issuerName = nullptr; 38 ASN1_INTEGER *serialNumber = nullptr; 39 int32_t digestNid {}; 40 int32_t digestEncryptNid {}; 41 std::vector<uint8_t> digestEncryptData; 42 const unsigned char *buffer; 43 size_t length; 44 }; 45 46 enum { 47 PKCS7_SUCCESS = 0, 48 PKCS7_INIT_ERR = 200, 49 PKCS7_INVALID_PARAM_ERR, 50 PKCS7_INVALID_VALUE_ERR, 51 PKCS7_HAS_NO_VALID_SIG_ERR, 52 PKCS7_PARSING_ERR, 53 PKCS7_VERIFY_FAIL_ERR, 54 }; 55 56 class VerifyHelper { 57 public: 58 virtual int32_t GetDigestFromSubBlocks( 59 std::vector<uint8_t> &digestBlock, SignatureInfo &signatureInfo, std::vector<uint8_t> &digest) = 0; 60 ~VerifyHelper()61 virtual ~VerifyHelper() {} 62 }; 63 64 class Pkcs7SignedData { 65 public: Pkcs7SignedData()66 Pkcs7SignedData() : pkcs7_(nullptr), digest_(), signerInfos_(), signatureInfo() {} 67 68 ~Pkcs7SignedData(); 69 70 int32_t GetHashFromSignBlock(const uint8_t *srcData, const size_t dataLen, 71 std::vector<uint8_t> &hash); 72 73 int32_t ParsePkcs7Data(const uint8_t *srcData, const size_t dataLen); 74 75 int32_t Verify() const; 76 77 int32_t Verify(const std::vector<uint8_t> &hash, const std::vector<uint8_t> &sig, bool sigInSignerInfo) const; 78 79 void RegisterVerifyHelper(std::unique_ptr<VerifyHelper> ptr); 80 81 static Pkcs7SignedData &GetInstance(); 82 83 int32_t GetDigest(std::vector<uint8_t> &digestBlock, SignatureInfo &signatureInfo, std::vector<uint8_t> &digest); 84 85 int32_t ReadSig(const uint8_t *sourceData, const uint32_t sourceDataLen, std::vector<std::vector<uint8_t>> &sigs); 86 private: 87 int32_t Init(const uint8_t *sourceData, const uint32_t sourceDataLen); 88 int32_t DoParse(); 89 int32_t ParseContentInfo(std::vector<uint8_t> &digestBlock) const; 90 int32_t GetDigestFromContentInfo(std::vector<uint8_t> &digestBlock); 91 int32_t DoUpdateVerify(std::vector<uint8_t> &digestBlock); 92 int32_t SignerInfosParse(); 93 int32_t SignerInfoParse(PKCS7_SIGNER_INFO *p7SignerInfo, Pkcs7SignerInfo &signerInfo); 94 int32_t Pkcs7SignleSignerVerify(const Pkcs7SignerInfo &signerInfo, const std::vector<uint8_t> &hash, 95 const std::vector<uint8_t> &sig) const; 96 int32_t VerifyDigest(X509 *cert, const Pkcs7SignerInfo &signer, const std::vector<uint8_t> &hash, 97 const std::vector<uint8_t> &sig) const; 98 private: 99 PKCS7 *pkcs7_; 100 std::vector<uint8_t> digest_; 101 std::vector<Pkcs7SignerInfo> signerInfos_; 102 SignatureInfo signatureInfo; 103 std::unique_ptr<VerifyHelper> helper_ {}; 104 }; 105 106 class Pkcs7VerifyHelper : public VerifyHelper { 107 public: 108 Pkcs7VerifyHelper() = default; 109 110 ~Pkcs7VerifyHelper() override; 111 112 int32_t GetDigestFromSubBlocks( 113 std::vector<uint8_t> &digestBlock, SignatureInfo &signatureInfo, std::vector<uint8_t> &digest) override; 114 }; 115 } // namespace Hpackage 116 #endif 117