Check author signature using public key 39/157539/5
authorSangyoon Jang <jeremy.jang@samsung.com>
Wed, 25 Oct 2017 03:44:45 +0000 (12:44 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Wed, 25 Oct 2017 07:02:32 +0000 (07:02 +0000)
The certificate string value(in base64 format) will be changed when the
certificate is renewed. To verify whether two author of certificate
is same, using public key of certificate is correct instead of
entire certificate string value.

Change-Id: I99bcfce48a77b4dbf65df9d3274945db9ef27635
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/common/certificate_validation.cc
src/common/certificate_validation.h
src/common/step/security/step_check_old_certificate.cc
src/common/step/security/step_check_signature.cc

index 92f5957d16b4a307582aaedcda666ec415c72f0c..edd70700ef9bf77c9ea2ce8d3d216026baeceeb7 100644 (file)
@@ -368,4 +368,21 @@ bool ValidateMetadataPrivilege(common_installer::PrivilegeLevel level,
   return true;
 }
 
+bool IsSameAuthor(const std::string& cert_str1, const std::string& cert_str2) {
+  try {
+    ValidationCore::Certificate cert1 = ValidationCore::Certificate(
+        cert_str1, ValidationCore::Certificate::FormType::FORM_BASE64);
+    ValidationCore::Certificate cert2 = ValidationCore::Certificate(
+        cert_str2, ValidationCore::Certificate::FormType::FORM_BASE64);
+    return cert1.getPublicKeyString() == cert2.getPublicKeyString();
+  } catch (const ValidationCore::Certificate::Exception::Base &e) {
+    LOG(ERROR) << "Exception occured on cert-svc-vcore getBase64: "
+               << e.DumpToString();
+    return false;
+  } catch (...) {
+    LOG(ERROR) << "Error while getting Certificate";
+    return false;
+  }
+}
+
 }  // namespace common_installer
index f1ee387d11844d5f9922ac43ecb894f7b13643c7..858c332239479319b603a49eca05310d46accc32 100644 (file)
@@ -46,6 +46,8 @@ bool ValidateMetadataPrivilege(common_installer::PrivilegeLevel level,
     const char* api_version, GList* metadata_list,
     std::string* error_message);
 
+bool IsSameAuthor(const std::string& cert_str1, const std::string& cert_str2);
+
 }  // namespace common_installer
 
 #endif  // COMMON_CERTIFICATE_VALIDATION_H_
index 7e5f0f0b64d051f8e006dee8fefaf80b306b82db..43252ef28bdee56e998e8e43459d899abe5da2ae 100644 (file)
 #include <cstdlib>
 #include <string>
 
+#include "common/certificate_validation.h"
 #include "common/pkgmgr_query.h"
 
 namespace common_installer {
 namespace security {
 
 Step::Status StepCheckOldCertificate::process() {
-  std::string old_author_certificate =
+  std::string old_author_cert =
       QueryCertificateAuthorCertificate(context_->pkgid.get(),
                                         context_->uid.get());
   const auto& cert = context_->certificate_info.get().author_certificate.get();
 
-  if (!old_author_certificate.empty()) {
+  if (!old_author_cert.empty()) {
     if (!cert) {
       LOG(ERROR) << "Trying to update package without signature is not allowed "
                  << "when the previous version of package has signature";
       return Status::AUTHOR_CERT_NOT_FOUND;
     } else {
       try {
-        if (old_author_certificate != cert->getBase64()) {
+        if (!IsSameAuthor(old_author_cert, cert->getBase64())) {
           LOG(ERROR) << "Author signature doesn't match the previous one. "
                      << "Update must be aborted";
           return Status::AUTHOR_CERT_NOT_MATCH;
index 2715d55ecfae3d70f8bfd4a8f5726e9fcd9ffd19..40d95a84500d867e818560c5ef15a971ce866864 100644 (file)
@@ -21,13 +21,14 @@ namespace ci = common_installer;
 namespace {
 
 bool CheckPkgCertificateMismatch(const std::string& pkgid,
-                                 const std::string& old_certificate) {
+                                 const std::string& certificate) {
   bool certificate_mismatch = false;
   uid_t uid = G_MAXUINT;
-  auto certificate = ci::QueryCertificateAuthorCertificate(pkgid, uid);
+  auto old_certificate = ci::QueryCertificateAuthorCertificate(pkgid, uid);
 
-  if (!certificate.empty()) {
-    certificate_mismatch = (old_certificate != certificate);
+  if (!old_certificate.empty()) {
+    bool is_same = ci::IsSameAuthor(old_certificate, certificate);
+    certificate_mismatch = !is_same;
   }
   return certificate_mismatch;
 }