From facaf76403e753919525a5de6a8931e3489ed982 Mon Sep 17 00:00:00 2001 From: ligongshao Date: Fri, 15 Sep 2023 16:08:10 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=BE=80PKCS7=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=E4=B8=AD=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ligongshao --- utils/include/signer_info.h | 11 +++++ utils/src/signer_info.cpp | 90 ++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/utils/include/signer_info.h b/utils/include/signer_info.h index 077d0e0..8fbe428 100644 --- a/utils/include/signer_info.h +++ b/utils/include/signer_info.h @@ -27,11 +27,22 @@ namespace OHOS { namespace Security { namespace CodeSign { class SignerInfo { +public: + static const std::string SIGNER_OID; // 自定义OID + static const std::string SIGNER_OID_SHORT_NAME; + static const std::string SIGNER_OID_LONG_NAME; +public: + static ASN1_TYPE* GetSignedAttributeByOID(PKCS7_SIGNER_INFO *signerInfo, const char *oid, size_t oidLen); + static std::string ParseOwnerIdFromSignature(const ByteBuffer &sigbuffer); + static std::string ParseOwnerId(PKCS7_SIGNER_INFO *signerInfo); public: bool InitSignerInfo(X509 *cert, const EVP_MD *md, const ByteBuffer &contentData, bool carrySigningTime = false); bool AddSignatureInSignerInfo(const ByteBuffer &signature); uint8_t *GetDataToSign(uint32_t &len); PKCS7_SIGNER_INFO *GetSignerInfo(); + int AddOwnerID(std::string &ownerID); + std::string GetOwnerID(); + private: bool AddAttrsToSignerInfo(const ByteBuffer &contentData); bool ComputeDigest(const ByteBuffer &data, ByteBuffer &digest); diff --git a/utils/src/signer_info.cpp b/utils/src/signer_info.cpp index 869d16f..7e93368 100644 --- a/utils/src/signer_info.cpp +++ b/utils/src/signer_info.cpp @@ -18,7 +18,13 @@ #include "openssl/asn1.h" #include "openssl/pem.h" #include "openssl_utils.h" +#include +#include +#include +#include #include "securec.h" +#include +#include namespace OHOS { namespace Security { @@ -26,6 +32,10 @@ namespace CodeSign { static constexpr int INVALID_SIGN_ALGORITHM_NID = -1; static constexpr int MAX_SIGNATURE_SIZE = 1024; // 1024: max signature length +const std::string SignerInfo::SIGNER_OID = "2.3.4.5"; // 自定义OID +const std::string SignerInfo::SIGNER_OID_SHORT_NAME = "SIGNER short name"; +const std::string SignerInfo::SIGNER_OID_LONG_NAME = "SIGNER long name"; + bool SignerInfo::InitSignerInfo(X509 *cert, const EVP_MD *md, const ByteBuffer &contentData, bool carrySigningTime) { @@ -200,7 +210,85 @@ int SignerInfo::GetSignAlgorithmID(const X509 *cert) PKCS7_SIGNER_INFO *SignerInfo::GetSignerInfo() { return p7info_; +} + +// 使用OID获取signerInfo中的信息 +ASN1_TYPE* SignerInfo::GetSignedAttributeByOID(PKCS7_SIGNER_INFO *signerInfo, const char *oid, size_t oidLen) +{ + int idx; + X509_ATTRIBUTE *xa; + STACK_OF(X509_ATTRIBUTE) *sk = signerInfo->auth_attr; + const ASN1_OBJECT *obj = OBJ_txt2obj(oid, 1); + idx = X509at_get_attr_by_OBJ(sk, obj, -1); + xa = X509at_get_attr(sk, idx); + return X509_ATTRIBUTE_get0_type(xa, 0); +} + +int SignerInfo::AddOwnerID(std::string &ownerID) +{ + int nid = OBJ_txt2nid(SIGNER_OID.c_str()); + if (nid == NID_undef) { + ErrLogWithOpenSSLMsg("OBJ_txt2nid failed"); + return -1; + } + ASN1_STRING* ownerIDAsn1 = ASN1_STRING_new(); + ASN1_STRING_set(ownerIDAsn1, ownerID.c_str(), ownerID.length()); + int ret = PKCS7_add_signed_attribute(p7info_, nid, V_ASN1_OCTET_STRING, ownerIDAsn1); + if (ret == 0) { + ErrLogWithOpenSSLMsg("PKCS7_add_signed_attribute failed"); + return -1; + } + + return 0; +} + +std::string SignerInfo::GetOwnerID() +{ + return ParseOwnerId(p7info_); +} + +std::string SignerInfo::ParseOwnerId(PKCS7_SIGNER_INFO *signerInfo) +{ + std::string ownerID; + + ASN1_TYPE* asn1Type = GetSignedAttributeByOID(signerInfo, SIGNER_OID.c_str(), SIGNER_OID.length()); + if (asn1Type != NULL && asn1Type->type == V_ASN1_OCTET_STRING) { + ASN1_STRING* result = asn1Type->value.asn1_string; + ownerID.assign((const char *)ASN1_STRING_get0_data(result), ASN1_STRING_length(result)); + LOG_INFO(LABEL, "get attribute success, ownerID:%s", ownerID.c_str()); + } else { + ErrLogWithOpenSSLMsg("PKCS7_get_signed_attribute failed"); + } + + return ownerID; +} + +std::string SignerInfo::ParseOwnerIdFromSignature(const ByteBuffer &sigbuffer) +{ + std::string ownerID; + BIO *bio = BIO_new_mem_buf(sigbuffer.GetBuffer(), sigbuffer.GetSize()); + if(bio == NULL) { + ErrLogWithOpenSSLMsg("ParseOwnerIdFromSignature BIO_new_mem_buf failed"); + return ""; + } + PKCS7* p7 = d2i_PKCS7_bio(bio, NULL); + if(p7 == NULL) { + ErrLogWithOpenSSLMsg("ParseOwnerIdFromSignature d2i_PKCS7_bio failed"); + BIO_free(bio); + return ""; + } + STACK_OF(PKCS7_SIGNER_INFO) *signerInfosk = PKCS7_get_signer_info(p7); + for(int i=0;i Date: Sun, 8 Oct 2023 10:25:00 +0800 Subject: [PATCH 2/2] Add Signing interface --- .../include/local_code_sign_service.h | 1 + .../src/local_code_sign_service.cpp | 18 +++++++ utils/include/pkcs7_generator.h | 4 ++ utils/src/pkcs7_generator.cpp | 53 +++++++++++++++++++ 4 files changed, 76 insertions(+) diff --git a/services/local_code_sign/include/local_code_sign_service.h b/services/local_code_sign/include/local_code_sign_service.h index fd89d7f..7597f43 100644 --- a/services/local_code_sign/include/local_code_sign_service.h +++ b/services/local_code_sign/include/local_code_sign_service.h @@ -35,6 +35,7 @@ public: int32_t InitLocalCertificate(ByteBuffer &cert) override; int32_t SignLocalCode(const std::string &filePath, ByteBuffer &signature) override; + int32_t SignLocalCodeWithOwnerID(const std::string &ownerID, const std::string &filePath, ByteBuffer &signature); void DelayUnloadTask() override; private: bool Init(); diff --git a/services/local_code_sign/src/local_code_sign_service.cpp b/services/local_code_sign/src/local_code_sign_service.cpp index cafbe33..c5d803c 100644 --- a/services/local_code_sign/src/local_code_sign_service.cpp +++ b/services/local_code_sign/src/local_code_sign_service.cpp @@ -128,6 +128,24 @@ int32_t LocalCodeSignService::SignLocalCode(const std::string &filePath, ByteBuf return PKCS7Generator::GenerateSignature(LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), digest, signature); } + +int32_t LocalCodeSignService::SignLocalCodeWithOwnerID(const std::string &ownerID, const std::string &filePath, ByteBuffer &signature) +{ + ByteBuffer digest; + std::string realPath; + if (!OHOS::PathToRealPath(filePath, realPath)) { + LOG_INFO(LABEL, "Get real path failed, path = %{public}s", filePath.c_str()); + return CS_ERR_FILE_PATH; + } + if (!FsverityUtilsHelper::GetInstance().GenerateFormattedDigest(realPath.c_str(), digest)) { + LOG_ERROR(LABEL, "Generate formatted fsverity digest failed."); + return CS_ERR_COMPUTE_DIGEST; + } + return PKCS7Generator::GenerateSignatureWithOwnerID(LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + ownerID, digest, signature); +} + + } } } diff --git a/utils/include/pkcs7_generator.h b/utils/include/pkcs7_generator.h index 9d65b3f..9bf053c 100644 --- a/utils/include/pkcs7_generator.h +++ b/utils/include/pkcs7_generator.h @@ -29,6 +29,10 @@ class PKCS7Generator { public: static int32_t GenerateSignature(SignKey &key, const char *hashAlg, const ByteBuffer &contentData, ByteBuffer &out); + static int32_t GenerateSignatureWithOwnerID(SignKey& key, + const char* hashAlg, + const std::string& ownerID, const ByteBuffer& contentData, + ByteBuffer& out); private: static int32_t SignData(SignKey &key, SignerInfo &signerInfo); }; diff --git a/utils/src/pkcs7_generator.cpp b/utils/src/pkcs7_generator.cpp index 8766005..68df94b 100644 --- a/utils/src/pkcs7_generator.cpp +++ b/utils/src/pkcs7_generator.cpp @@ -77,6 +77,59 @@ int32_t PKCS7Generator::GenerateSignature(SignKey &key, const char *hashAlg, return ret; } +int32_t PKCS7Generator::GenerateSignatureWithOwnerID(SignKey& key, + const char* hashAlg, + const std::string& ownerID, const ByteBuffer& contentData, + ByteBuffer& out) +{ + LOG_INFO(LABEL, "GenerateSignature called."); + int32_t ret = CS_ERR_OPENSSL_PKCS7; + X509 *cert = nullptr; + do { + const ByteBuffer *certBuffer = key.GetSignCert(); + if (certBuffer == nullptr) { + ret = CS_ERR_HUKS_OBTAIN_CERT; + break; + } + cert = LoadCertFromBuffer(certBuffer->GetBuffer(), certBuffer->GetSize()); + if (cert == nullptr) { + ret = CS_ERR_OPENSSL_LOAD_CERT; + break; + } + const EVP_MD *md = EVP_get_digestbyname(hashAlg); + if (md == nullptr) { + break; + } + PKCS7Data pkcs7(md, cert); + if (!pkcs7.InitPKCS7Data(key.GetCarriedCerts())) { + break; + } + SignerInfo signerInfo; + if (!signerInfo.InitSignerInfo(cert, md, contentData)) { + break; + } + // 增加ownerID + signerInfo.AddOwnerID(ownerID); + if (!pkcs7.AddSignerInfo(signerInfo.GetSignerInfo())) { + break; + } + ret = SignData(key, signerInfo); + if (ret != CS_SUCCESS) { + break; + } + if (!pkcs7.GetPKCS7Data(out)) { + ret = CS_ERR_OPENSSL_PKCS7; + break; + } + ret = CS_SUCCESS; + } while (0); + X509_free(cert); + if (ret != CS_SUCCESS) { + LOG_ERROR(LABEL, "Generate signature failed, ret = %{public}d", ret); + } + return ret; +} + int32_t PKCS7Generator::SignData(SignKey &key, SignerInfo &signerInfo) { uint32_t dataSize = 0; -- Gitee