Detach Impl class on SignatureValidator 20/95420/6
authorsangwan.kwon <sangwan.kwon@samsung.com>
Thu, 3 Nov 2016 07:35:11 +0000 (16:35 +0900)
committersangwan.kwon <sangwan.kwon@samsung.com>
Tue, 8 Nov 2016 01:42:30 +0000 (10:42 +0900)
[AS-IS]
* check(), checkList() is implemented on Impl class.
[TO-BE]
* check(), checkList() should be implemented on derived class
  by using baseCheck(), baseCheckList() on BaseValidator.

Change-Id: I1d5b81d02e5f576e9c0c47b484e6429d3e9b88fa
Signed-off-by: sangwan.kwon <sangwan.kwon@samsung.com>
src/CMakeLists.txt
src/vcore/BaseValidator.cpp [new file with mode: 0644]
src/vcore/BaseValidator.h [new file with mode: 0644]
src/vcore/SignatureValidator.cpp
src/vcore/SignatureValidator.h

index 68ae230..8589ad6 100644 (file)
@@ -52,6 +52,7 @@ SET(VCORE_SOURCES
 
     vcore/api.cpp
     vcore/Base64.cpp
+    vcore/BaseValidator.cpp
     vcore/Certificate.cpp
     vcore/CertificateCollection.cpp
     vcore/CertificateConfigReader.cpp
diff --git a/src/vcore/BaseValidator.cpp b/src/vcore/BaseValidator.cpp
new file mode 100644 (file)
index 0000000..6917a6d
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        BaseValidator.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @author      Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of based validation protocol.
+ */
+#include <vcore/BaseValidator.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <dpl/log/log.h>
+
+#include <vcore/CertificateCollection.h>
+#include <vcore/Certificate.h>
+#include <vcore/ReferenceValidator.h>
+#include <vcore/ValidatorFactories.h>
+#include <vcore/SignatureReader.h>
+#include <vcore/SignatureFinder.h>
+#include <vcore/Ocsp.h>
+
+#ifdef TIZEN_PROFILE_MOBILE
+#include <cchecker/ocsp.h>
+#endif
+
+using namespace ValidationCore::CertStoreId;
+
+namespace {
+
+const std::string TOKEN_PREFIX          = "http://www.w3.org/ns/widgets-digsig#";
+const std::string TOKEN_ROLE_AUTHOR_URI = TOKEN_PREFIX + "role-author";
+const std::string TOKEN_ROLE_DIST_URI   = TOKEN_PREFIX + "role-distributor";
+const std::string TOKEN_PROFILE_URI     = TOKEN_PREFIX + "profile";
+
+enum class CertTimeStatus : int {
+       VALID,
+       NOT_YET,
+       EXPIRED
+};
+
+inline time_t _getMidTime(time_t lower, time_t upper)
+{
+       return (lower >> 1) + (upper >> 1);
+}
+
+inline CertTimeStatus _timeValidation(time_t lower, time_t upper, time_t current)
+{
+       if (current < lower)
+               return CertTimeStatus::NOT_YET;
+       else if (current > upper)
+               return CertTimeStatus::EXPIRED;
+       else
+               return CertTimeStatus::VALID;
+}
+
+inline bool _isTimeStrict(const Set &stores)
+{
+       return (stores.contains(TIZEN_TEST) || stores.contains(TIZEN_VERIFY))
+                  ? true : false;
+}
+
+} // namespace anonymous
+
+namespace ValidationCore {
+
+BaseValidator::BaseValidator(const SignatureFileInfo &info) :
+       m_fileInfo(info),
+       m_disregarded(false)
+{
+}
+
+bool BaseValidator::checkRoleURI(void)
+{
+       std::string roleURI = m_data.getRoleURI();
+
+       if (roleURI.empty()) {
+               LogWarning("URI attribute in Role tag couldn't be empty.");
+               return false;
+       }
+
+       if (roleURI != TOKEN_ROLE_AUTHOR_URI && m_data.isAuthorSignature()) {
+               LogWarning("URI attribute in Role tag does not "
+                                  "match with signature filename.");
+               return false;
+       }
+
+       if (roleURI != TOKEN_ROLE_DIST_URI && !m_data.isAuthorSignature()) {
+               LogWarning("URI attribute in Role tag does not "
+                                  "match with signature filename.");
+               return false;
+       }
+
+       return true;
+}
+
+bool BaseValidator::checkProfileURI(void)
+{
+       if (TOKEN_PROFILE_URI != m_data.getProfileURI()) {
+               LogWarning("Profile tag contains unsupported value "
+                                  "in URI attribute " << m_data.getProfileURI());
+               return false;
+       }
+
+       return true;
+}
+
+bool BaseValidator::checkObjectReferences(void)
+{
+       for (const auto &object : m_data.getObjectList()) {
+               if (!m_data.containObjectReference(object)) {
+                       LogWarning("Signature does not contain reference for object " << object);
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+VCerr BaseValidator::additionalCheck(VCerr result)
+{
+       try {
+               if (m_pluginHandler.fail()) {
+                       LogInfo("No validator plugin found. Skip additional check.");
+                       return result;
+               }
+
+               return m_pluginHandler.step(result, m_data);
+       } catch (...) {
+               LogError("Exception in additional check by plugin.");
+               return E_SIG_PLUGIN;
+       }
+}
+
+VCerr BaseValidator::parseSignature(void)
+{
+       try {
+               SignatureReader xml;
+               xml.initialize(m_data, SIGNATURE_SCHEMA_PATH);
+               xml.read(m_data);
+       } catch (ParserSchemaException::CertificateLoaderError &e) {
+               LogError("Certificate loader error: " << e.DumpToString());
+               return E_SIG_INVALID_CERT;
+       } catch (...) {
+               LogError("Failed to parse signature file by signature reader.");
+               return E_SIG_INVALID_FORMAT;
+       }
+
+       return E_SIG_NONE;
+}
+
+/*
+ *  Make SignatureData by parsing signature file.
+ *  and get certificate chain with attached certificate in signature
+ */
+VCerr BaseValidator::makeDataBySignature(bool completeWithSystemCert)
+{
+       LogDebug("Start to make chain.");
+       m_data = SignatureData(m_fileInfo.getFileName(), m_fileInfo.getFileNumber());
+
+       if (parseSignature()) {
+               LogError("Failed to parse signature.");
+               return E_SIG_INVALID_FORMAT;
+       }
+
+       if (!checkRoleURI() || !checkProfileURI())
+               return E_SIG_INVALID_FORMAT;
+
+       try {
+               CertificateCollection collection;
+               // Load Certificates and make chain.
+               collection.load(m_data.getCertList());
+
+               if (!collection.sort() || collection.empty()) {
+                       LogError("Certificates do not form valid chain.");
+                       return E_SIG_INVALID_CHAIN;
+               }
+
+               // Add root certificate to chain.
+               if (completeWithSystemCert && !collection.completeCertificateChain()) {
+                       if (m_data.isAuthorSignature() || m_data.getSignatureNumber() == 1) {
+                               LogError("Failed to complete cert chain with system cert");
+                               return E_SIG_INVALID_CHAIN;
+                       } else {
+                               LogDebug("Distributor N's certificate has got "
+                                                "unrecognized root CA certificate.");
+                               m_disregarded = true;
+                       }
+               }
+
+               m_data.setSortedCertificateList(collection.getChain());
+               LogDebug("Finish making chain successfully.");
+       } catch (const CertificateCollection::Exception::Base &e) {
+               LogError("CertificateCollection exception : " << e.DumpToString());
+               return E_SIG_INVALID_CHAIN;
+       } catch (const std::exception &e) {
+               LogError("std exception occured : " << e.what());
+               return E_SIG_UNKNOWN;
+       } catch (...) {
+               LogError("Unknown exception in BaseValidator::makeChainBySignature");
+               return E_SIG_UNKNOWN;
+       }
+
+       return E_SIG_NONE;
+}
+
+VCerr BaseValidator::preStep(void)
+{
+       // Make chain process.
+       VCerr result = makeDataBySignature(true);
+
+       if (result != E_SIG_NONE)
+               return result;
+
+       for (const auto &certptr : m_data.getCertList()) {
+               auto storeIdSet = createCertificateIdentifier().find(certptr);
+               if (!storeIdSet.contains(TIZEN_REVOKED))
+                       continue;
+
+               LogInfo("Revoked certificate: " << certptr->getOneLine());
+               return E_SIG_REVOKED;
+       }
+
+       // Get Identifier from fingerprint original, extention file.
+       LogDebug("Start to check certificate domain.");
+       auto certificatePtr = m_data.getCertList().back();
+       auto storeIdSet = createCertificateIdentifier().find(certificatePtr);
+
+       // Check root CA certificate has proper domain.
+       LogDebug("root certificate from " << storeIdSet.typeToString() << " domain");
+       if (m_data.isAuthorSignature()) {
+               if (!storeIdSet.contains(TIZEN_DEVELOPER)) {
+                       LogError("author-signature.xml's root certificate "
+                                        "isn't in tizen developer domain.");
+                       return E_SIG_INVALID_CHAIN;
+               }
+       } else {
+               if (storeIdSet.contains(TIZEN_DEVELOPER)) {
+                       LogError("distributor signautre root certificate "
+                                        "shouldn't be in tizen developer domain.");
+                       return E_SIG_INVALID_CHAIN;
+               }
+
+               if (m_data.getSignatureNumber() == 1 && !storeIdSet.isContainsVis()) {
+                       LogError("signature1.xml has got unrecognized root CA certificate.");
+                       return E_SIG_INVALID_CHAIN;
+               } else if (!storeIdSet.isContainsVis()) {
+                       LogDebug("signatureN.xml has got unrecognized root CA certificate.");
+                       m_disregarded = true;
+               }
+       }
+
+       m_data.setStorageType(storeIdSet);
+       LogDebug("Finish checking certificate domain.");
+       /*
+        * We add only Root CA certificate because the rest
+        * of certificates are present in signature files ;-)
+        */
+       m_context.signatureFile = m_data.getSignatureFileName();
+       m_context.certificatePtr = m_data.getCertList().back();
+       /* certificate time check */
+       time_t lower = m_data.getEndEntityCertificatePtr()->getNotBefore();
+       time_t upper = m_data.getEndEntityCertificatePtr()->getNotAfter();
+       time_t current = time(NULL);
+       CertTimeStatus status = _timeValidation(lower, upper, current);
+
+       if (status != CertTimeStatus::VALID) {
+               LogDebug("Certificate's time is invalid.");
+
+               if (_isTimeStrict(storeIdSet))
+                       return status == CertTimeStatus::EXPIRED
+                                  ? E_SIG_CERT_EXPIRED : E_SIG_CERT_NOT_YET;
+
+               time_t mid = _getMidTime(lower, upper);
+               LogInfo("Use middle notBeforeTime and notAfterTime."
+                               " lower: " << lower
+                               << " upper: " << upper
+                               << " mid: " << mid
+                               << " current: " << current);
+               m_context.validationTime = mid;
+       }
+
+       return E_SIG_NONE;
+}
+
+VCerr BaseValidator::baseCheck(const std::string &contentPath,
+                                                          bool checkOcsp,
+                                                          bool checkReferences)
+{
+       try {
+               // Make certificate chain, check certificate info
+               VCerr result = preStep();
+
+               if (result != E_SIG_NONE)
+                       return result;
+
+               // Since disregard case, uncheck root certs in signatureN.xml
+               if (!m_data.isAuthorSignature() && m_data.getSignatureNumber() != 1)
+                       m_context.allowBrokenChain = true;
+
+               // XmlSec validate
+               XmlSecSingleton::Instance().validate(m_context);
+               // Check reference of 'Object' tag - OID
+               m_data.setReference(m_context.referenceSet);
+
+               if (!checkObjectReferences()) {
+                       LogWarning("Failed to check Object References");
+                       return E_SIG_INVALID_REF;
+               }
+
+               // Check reference's existence
+               if (checkReferences) {
+                       ReferenceValidator fileValidator(contentPath);
+
+                       if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(m_data)) {
+                               LogWarning("Invalid package - file references broken");
+                               return E_SIG_INVALID_REF;
+                       }
+               }
+
+               // Check OCSP
+               if (checkOcsp && Ocsp::check(m_data) == Ocsp::Result::REVOKED) {
+                       LogError("Certificate is Revoked by OCSP server.");
+                       return E_SIG_REVOKED;
+               }
+
+               LogDebug("Signature validation check done successfully ");
+       } catch (const CertificateCollection::Exception::Base &e) {
+               LogError("CertificateCollection exception : " << e.DumpToString());
+               return E_SIG_INVALID_CHAIN;
+       } catch (const XmlSec::Exception::InternalError &e) {
+               LogError("XmlSec internal error : " << e.DumpToString());
+               return E_SIG_INVALID_FORMAT;
+       } catch (const XmlSec::Exception::InvalidFormat &e) {
+               LogError("XmlSec invalid format : " << e.DumpToString());
+               return E_SIG_INVALID_FORMAT;
+       } catch (const XmlSec::Exception::InvalidSig &e) {
+               LogError("XmlSec invalid signature : " << e.DumpToString());
+               return E_SIG_INVALID_SIG;
+       } catch (const XmlSec::Exception::OutOfMemory &e) {
+               LogError("XmlSec out of memory : " << e.DumpToString());
+               return E_SIG_OUT_OF_MEM;
+       } catch (const XmlSec::Exception::Base &e) {
+               LogError("XmlSec unknown exception : " << e.DumpToString());
+               return E_SIG_INVALID_FORMAT;
+       } catch (const Ocsp::Exception::OcspUnsupported &e) {
+               LogInfo("Ocsp unsupported : " << e.DumpToString());
+       } catch (const Ocsp::Exception::Base &e) {
+               LogInfo("Ocsp check throw exeption : " << e.DumpToString());
+#ifdef TIZEN_PROFILE_MOBILE
+               LogInfo("Launch cert-checker.");
+               try {
+                       if (cchecker_ocsp_request() != 0)
+                               LogError("Load cert-checker failed.");
+               } catch (const std::exception &e) {
+                       LogError("std exception occured while cchecker running : " << e.what());
+               } catch (...) {
+                       LogError("Unknown exception occuured while cchecker running. ");
+               }
+#endif
+       } catch (const std::exception &e) {
+               LogError("std exception occured : " << e.what());
+               return E_SIG_UNKNOWN;
+       } catch (...) {
+               LogError("Unknown exception in BaseValidator::check");
+               return E_SIG_UNKNOWN;
+       }
+
+       return m_disregarded ? E_SIG_DISREGARDED : E_SIG_NONE;
+}
+
+VCerr BaseValidator::baseCheckList(bool checkOcsp, const UriList &uriList)
+{
+       try {
+               // Make certificate chain, check certificate info
+               VCerr result = preStep();
+
+               if (result != E_SIG_NONE)
+                       return result;
+
+               // XmlSec validate
+               if (uriList.size() == 0)
+                       XmlSecSingleton::Instance().validateNoHash(m_context);
+               else
+                       XmlSecSingleton::Instance().validatePartialHash(m_context, uriList);
+
+               if (checkOcsp && Ocsp::check(m_data) == Ocsp::Result::REVOKED) {
+                       LogError("Certificate is Revoked by OCSP server.");
+                       return E_SIG_REVOKED;
+               }
+
+               LogDebug("Signature validation of check list done successfully ");
+       } catch (const CertificateCollection::Exception::Base &e) {
+               LogError("CertificateCollection exception : " << e.DumpToString());
+               return E_SIG_INVALID_CHAIN;
+       } catch (const XmlSec::Exception::InternalError &e) {
+               LogError("XmlSec internal error : " << e.DumpToString());
+               return E_SIG_INVALID_FORMAT;
+       } catch (const XmlSec::Exception::InvalidFormat &e) {
+               LogError("XmlSec invalid format : " << e.DumpToString());
+               return E_SIG_INVALID_FORMAT;
+       } catch (const XmlSec::Exception::InvalidSig &e) {
+               LogError("XmlSec invalid signature : " << e.DumpToString());
+               return E_SIG_INVALID_SIG;
+       } catch (const XmlSec::Exception::OutOfMemory &e) {
+               LogError("XmlSec out of memory : " << e.DumpToString());
+               return E_SIG_OUT_OF_MEM;
+       } catch (const XmlSec::Exception::Base &e) {
+               LogError("XmlSec unknown exception : " << e.DumpToString());
+               return E_SIG_INVALID_FORMAT;
+       } catch (const Ocsp::Exception::OcspUnsupported &e) {
+               LogInfo("Ocsp unsupported : " << e.DumpToString());
+       } catch (const Ocsp::Exception::Base &e) {
+               LogInfo("Ocsp check throw exeption : " << e.DumpToString());
+#ifdef TIZEN_PROFILE_MOBILE
+               LogInfo("Launch cert-checker.");
+               try {
+                       if (cchecker_ocsp_request() != 0)
+                               LogError("Load cert-checker failed.");
+               } catch (const std::exception &e) {
+                       LogError("std exception occured while cchecker running : " << e.what());
+               } catch (...) {
+                       LogError("Unknown exception occuured while cchecker running. ");
+               }
+#endif
+       } catch (...) {
+               LogError("Unknown exception in BaseValidator::checkList");
+               return E_SIG_UNKNOWN;
+       }
+
+       return m_disregarded ? E_SIG_DISREGARDED : E_SIG_NONE;
+}
+
+VCerr BaseValidator::makeChainBySignature(bool completeWithSystemCert,
+                                                                                 CertificateList &certList)
+{
+       VCerr result = makeDataBySignature(completeWithSystemCert);
+
+       if (result != E_SIG_NONE)
+               return result;
+
+       certList = m_data.getCertList();
+       return E_SIG_NONE;
+}
+
+std::string BaseValidator::errorToString(VCerr code)
+{
+       switch (code) {
+       case E_SIG_NONE:
+               return "Success.";
+
+       case E_SIG_INVALID_FORMAT:
+               return "Invalid format of signature file.";
+
+       case E_SIG_INVALID_CERT:
+               return "Invalid format of certificate in signature.";
+
+       case E_SIG_INVALID_CHAIN:
+               return "Invalid certificate chain with certificate in signature.";
+
+       case E_SIG_INVALID_SIG:
+               return "Invalid signature. Signed with wrong key, changed signature file or changed package file.";
+
+       case E_SIG_INVALID_REF:
+               return "Invalid file reference. An unsinged file was found.";
+
+       case E_SIG_CERT_EXPIRED:
+               return "Certificate in signature was expired.";
+
+       case E_SIG_CERT_NOT_YET:
+               return "Certificate in signature is not valid yet.";
+
+       case E_SIG_DISREGARDED:
+               return "Signature validation can be disregarded in some cases.";
+
+       case E_SIG_REVOKED:
+               return "One of certificate was revoked in certificate chain.";
+
+       case E_SIG_PLUGIN:
+               return "Failed to load plugin for additional validation check.";
+
+       case E_SIG_OUT_OF_MEM:
+               return "Out of memory.";
+
+       case E_SIG_UNKNOWN:
+               return "Unknown error.";
+
+       default:
+               return m_pluginHandler.errorToString(code);
+       }
+}
+
+} // namespace ValidationCore
diff --git a/src/vcore/BaseValidator.h b/src/vcore/BaseValidator.h
new file mode 100644 (file)
index 0000000..41e83e1
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/*
+ * @file        BaseValidator.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @author      Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of based validation protocol.
+ */
+#pragma once
+
+#include <string>
+#include <list>
+#include <memory>
+
+#include <vcore/Certificate.h>
+#include <vcore/SignatureData.h>
+#include <vcore/SignatureFinder.h>
+#include <vcore/PluginHandler.h>
+#include <vcore/XmlsecAdapter.h>
+#include <vcore/Error.h>
+
+namespace ValidationCore {
+
+using UriList = std::list<std::string>;
+
+class BaseValidator {
+public:
+       BaseValidator(const SignatureFileInfo &info);
+       virtual ~BaseValidator() {};
+
+       VCerr makeChainBySignature(bool completeWithSystemCert,
+                                                          CertificateList &certList);
+       std::string errorToString(VCerr code);
+
+protected:
+       VCerr baseCheck(const std::string &contentPath,
+                                       bool checkOcsp,
+                                       bool checkReferences);
+       VCerr baseCheckList(bool checkOcsp, const UriList &uriList);
+       VCerr additionalCheck(VCerr result);
+
+       SignatureData m_data;
+
+private:
+       VCerr makeDataBySignature(bool completeWithSystemCert);
+
+       VCerr parseSignature(void);
+       VCerr preStep(void);
+       bool checkRoleURI(void);
+       bool checkProfileURI(void);
+       bool checkObjectReferences(void);
+
+       PluginHandler m_pluginHandler;
+       SignatureFileInfo m_fileInfo;
+       XmlSec::XmlSecContext m_context;
+       bool m_disregarded;
+};
+
+} // namespace ValidationCore
index a130bee..29ef870 100644 (file)
  * @version     1.0
  * @brief       Implementatin of tizen signature validation protocol.
  */
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include <dpl/log/log.h>
-
-#include <vcore/CertificateCollection.h>
-#include <vcore/Certificate.h>
-#include <vcore/ReferenceValidator.h>
-#include <vcore/ValidatorFactories.h>
-#include <vcore/XmlsecAdapter.h>
-#include <vcore/SignatureReader.h>
-#include <vcore/SignatureFinder.h>
-#include <vcore/Ocsp.h>
-#include <vcore/PluginHandler.h>
-
 #include <vcore/SignatureValidator.h>
-
-#ifdef TIZEN_PROFILE_MOBILE
-#include <cchecker/ocsp.h>
-#endif
-
-using namespace ValidationCore::CertStoreId;
-
-namespace {
-
-const std::string TOKEN_PREFIX          = "http://www.w3.org/ns/widgets-digsig#";
-const std::string TOKEN_ROLE_AUTHOR_URI = TOKEN_PREFIX + "role-author";
-const std::string TOKEN_ROLE_DIST_URI   = TOKEN_PREFIX + "role-distributor";
-const std::string TOKEN_PROFILE_URI     = TOKEN_PREFIX + "profile";
-
-enum class CertTimeStatus : int {
-       VALID,
-       NOT_YET,
-       EXPIRED
-};
-
-inline time_t _getMidTime(time_t lower, time_t upper)
-{
-       return (lower >> 1) + (upper >> 1);
-}
-
-inline CertTimeStatus _timeValidation(time_t lower, time_t upper, time_t current)
-{
-       if (current < lower)
-               return CertTimeStatus::NOT_YET;
-       else if (current > upper)
-               return CertTimeStatus::EXPIRED;
-       else
-               return CertTimeStatus::VALID;
-}
-
-inline bool _isTimeStrict(const Set &stores)
-{
-       return (stores.contains(TIZEN_TEST) || stores.contains(TIZEN_VERIFY))
-                  ? true : false;
-}
-
-} // namespace anonymous
-
+#include <vcore/BaseValidator.h>
 
 namespace ValidationCore {
 
-class SignatureValidator::Impl {
+class SignatureValidator::Impl : public BaseValidator {
 public:
        Impl(const SignatureFileInfo &info);
        virtual ~Impl() {};
 
-       VCerr check(
-               const std::string &contentPath,
-               bool checkOcsp,
-               bool checkReferences,
-               SignatureData &outData);
-
-       VCerr checkList(
-               bool checkOcsp,
-               const UriList &uriList,
-               SignatureData &outData);
-
-       VCerr makeChainBySignature(
-               bool completeWithSystemCert,
-               CertificateList &certList);
-
-       std::string errorToString(VCerr code);
-
-private:
-       VCerr baseCheck(
-               const std::string &contentPath,
-               bool checkOcsp,
-               bool checkReferences);
-
-       VCerr baseCheckList(
-               bool checkOcsp,
-               const UriList &uriList);
-
-       VCerr makeDataBySignature(bool completeWithSystemCert);
-       VCerr additionalCheck(VCerr result);
-
-       VCerr parseSignature(void);
-       VCerr preStep(void);
-       bool checkRoleURI(void);
-       bool checkProfileURI(void);
-       bool checkObjectReferences(void);
-
-       PluginHandler m_pluginHandler;
-       SignatureFileInfo m_fileInfo;
-       XmlSec::XmlSecContext m_context;
-       SignatureData m_data;
-       bool m_disregarded;
+       VCerr check(const std::string &contentPath,
+                               bool checkOcsp,
+                               bool checkReferences,
+                               SignatureData &outData);
+       VCerr checkList(bool checkOcsp,
+                                       const UriList &uriList,
+                                       SignatureData &outData);
 };
 
-
 SignatureValidator::Impl::Impl(const SignatureFileInfo &info) :
-       m_fileInfo(info),
-       m_disregarded(false)
-{
-}
-
-bool SignatureValidator::Impl::checkRoleURI(void)
-{
-       std::string roleURI = m_data.getRoleURI();
-
-       if (roleURI.empty()) {
-               LogWarning("URI attribute in Role tag couldn't be empty.");
-               return false;
-       }
-
-       if (roleURI != TOKEN_ROLE_AUTHOR_URI && m_data.isAuthorSignature()) {
-               LogWarning("URI attribute in Role tag does not "
-                                  "match with signature filename.");
-               return false;
-       }
-
-       if (roleURI != TOKEN_ROLE_DIST_URI && !m_data.isAuthorSignature()) {
-               LogWarning("URI attribute in Role tag does not "
-                                  "match with signature filename.");
-               return false;
-       }
-
-       return true;
-}
-
-
-bool SignatureValidator::Impl::checkProfileURI(void)
-{
-       if (TOKEN_PROFILE_URI != m_data.getProfileURI()) {
-               LogWarning("Profile tag contains unsupported value "
-                                  "in URI attribute " << m_data.getProfileURI());
-               return false;
-       }
-
-       return true;
-}
-
-bool SignatureValidator::Impl::checkObjectReferences(void)
-{
-       for (const auto &object : m_data.getObjectList()) {
-               if (!m_data.containObjectReference(object)) {
-                       LogWarning("Signature does not contain reference for object " << object);
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-VCerr SignatureValidator::Impl::additionalCheck(VCerr result)
-{
-       try {
-               if (m_pluginHandler.fail()) {
-                       LogInfo("No validator plugin found. Skip additional check.");
-                       return result;
-               }
-
-               return m_pluginHandler.step(result, m_data);
-       } catch (...) {
-               LogError("Exception in additional check by plugin.");
-               return E_SIG_PLUGIN;
-       }
-}
-
-VCerr SignatureValidator::Impl::parseSignature(void)
-{
-       try {
-               SignatureReader xml;
-               xml.initialize(m_data, SIGNATURE_SCHEMA_PATH);
-               xml.read(m_data);
-       } catch (ParserSchemaException::CertificateLoaderError &e) {
-               LogError("Certificate loader error: " << e.DumpToString());
-               return E_SIG_INVALID_CERT;
-       } catch (...) {
-               LogError("Failed to parse signature file by signature reader.");
-               return E_SIG_INVALID_FORMAT;
-       }
-
-       return E_SIG_NONE;
-}
-
-/*
- *  Make SignatureData by parsing signature file.
- *  and get certificate chain with attached certificate in signature
- */
-VCerr SignatureValidator::Impl::makeDataBySignature(bool completeWithSystemCert)
-{
-       LogDebug("Start to make chain.");
-       m_data = SignatureData(m_fileInfo.getFileName(), m_fileInfo.getFileNumber());
-
-       if (parseSignature()) {
-               LogError("Failed to parse signature.");
-               return E_SIG_INVALID_FORMAT;
-       }
-
-       if (!checkRoleURI() || !checkProfileURI())
-               return E_SIG_INVALID_FORMAT;
-
-       try {
-               CertificateCollection collection;
-               // Load Certificates and make chain.
-               collection.load(m_data.getCertList());
-
-               if (!collection.sort() || collection.empty()) {
-                       LogError("Certificates do not form valid chain.");
-                       return E_SIG_INVALID_CHAIN;
-               }
-
-               // Add root certificate to chain.
-               if (completeWithSystemCert && !collection.completeCertificateChain()) {
-                       if (m_data.isAuthorSignature() || m_data.getSignatureNumber() == 1) {
-                               LogError("Failed to complete cert chain with system cert");
-                               return E_SIG_INVALID_CHAIN;
-                       } else {
-                               LogDebug("Distributor N's certificate has got "
-                                                "unrecognized root CA certificate.");
-                               m_disregarded = true;
-                       }
-               }
-
-               m_data.setSortedCertificateList(collection.getChain());
-               LogDebug("Finish making chain successfully.");
-       } catch (const CertificateCollection::Exception::Base &e) {
-               LogError("CertificateCollection exception : " << e.DumpToString());
-               return E_SIG_INVALID_CHAIN;
-       } catch (const std::exception &e) {
-               LogError("std exception occured : " << e.what());
-               return E_SIG_UNKNOWN;
-       } catch (...) {
-               LogError("Unknown exception in SignatureValidator::makeChainBySignature");
-               return E_SIG_UNKNOWN;
-       }
-
-       return E_SIG_NONE;
-}
-
-VCerr SignatureValidator::Impl::preStep(void)
-{
-       // Make chain process.
-       VCerr result = makeDataBySignature(true);
-
-       if (result != E_SIG_NONE)
-               return result;
-
-       for (const auto &certptr : m_data.getCertList()) {
-               auto storeIdSet = createCertificateIdentifier().find(certptr);
-               if (!storeIdSet.contains(TIZEN_REVOKED))
-                       continue;
-
-               LogInfo("Revoked certificate: " << certptr->getOneLine());
-               return E_SIG_REVOKED;
-       }
-
-       // Get Identifier from fingerprint original, extention file.
-       LogDebug("Start to check certificate domain.");
-       auto certificatePtr = m_data.getCertList().back();
-       auto storeIdSet = createCertificateIdentifier().find(certificatePtr);
-
-       // Check root CA certificate has proper domain.
-       LogDebug("root certificate from " << storeIdSet.typeToString() << " domain");
-       if (m_data.isAuthorSignature()) {
-               if (!storeIdSet.contains(TIZEN_DEVELOPER)) {
-                       LogError("author-signature.xml's root certificate "
-                                        "isn't in tizen developer domain.");
-                       return E_SIG_INVALID_CHAIN;
-               }
-       } else {
-               if (storeIdSet.contains(TIZEN_DEVELOPER)) {
-                       LogError("distributor signautre root certificate "
-                                        "shouldn't be in tizen developer domain.");
-                       return E_SIG_INVALID_CHAIN;
-               }
-
-               if (m_data.getSignatureNumber() == 1 && !storeIdSet.isContainsVis()) {
-                       LogError("signature1.xml has got unrecognized root CA certificate.");
-                       return E_SIG_INVALID_CHAIN;
-               } else if (!storeIdSet.isContainsVis()) {
-                       LogDebug("signatureN.xml has got unrecognized root CA certificate.");
-                       m_disregarded = true;
-               }
-       }
-
-       m_data.setStorageType(storeIdSet);
-       LogDebug("Finish checking certificate domain.");
-       /*
-        * We add only Root CA certificate because the rest
-        * of certificates are present in signature files ;-)
-        */
-       m_context.signatureFile = m_data.getSignatureFileName();
-       m_context.certificatePtr = m_data.getCertList().back();
-       /* certificate time check */
-       time_t lower = m_data.getEndEntityCertificatePtr()->getNotBefore();
-       time_t upper = m_data.getEndEntityCertificatePtr()->getNotAfter();
-       time_t current = time(NULL);
-       CertTimeStatus status = _timeValidation(lower, upper, current);
-
-       if (status != CertTimeStatus::VALID) {
-               LogDebug("Certificate's time is invalid.");
-
-               if (_isTimeStrict(storeIdSet))
-                       return status == CertTimeStatus::EXPIRED
-                                  ? E_SIG_CERT_EXPIRED : E_SIG_CERT_NOT_YET;
-
-               time_t mid = _getMidTime(lower, upper);
-               LogInfo("Use middle notBeforeTime and notAfterTime."
-                               " lower: " << lower
-                               << " upper: " << upper
-                               << " mid: " << mid
-                               << " current: " << current);
-               m_context.validationTime = mid;
-       }
-
-       return E_SIG_NONE;
-}
-
-VCerr SignatureValidator::Impl::baseCheck(
-       const std::string &contentPath,
-       bool checkOcsp,
-       bool checkReferences)
-{
-       try {
-               // Make certificate chain, check certificate info
-               VCerr result = preStep();
-
-               if (result != E_SIG_NONE)
-                       return result;
-
-               // Since disregard case, uncheck root certs in signatureN.xml
-               if (!m_data.isAuthorSignature() && m_data.getSignatureNumber() != 1)
-                       m_context.allowBrokenChain = true;
-
-               // XmlSec validate
-               XmlSecSingleton::Instance().validate(m_context);
-               // Check reference of 'Object' tag - OID
-               m_data.setReference(m_context.referenceSet);
-
-               if (!checkObjectReferences()) {
-                       LogWarning("Failed to check Object References");
-                       return E_SIG_INVALID_REF;
-               }
-
-               // Check reference's existence
-               if (checkReferences) {
-                       ReferenceValidator fileValidator(contentPath);
-
-                       if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(m_data)) {
-                               LogWarning("Invalid package - file references broken");
-                               return E_SIG_INVALID_REF;
-                       }
-               }
-
-               // Check OCSP
-               if (checkOcsp && Ocsp::check(m_data) == Ocsp::Result::REVOKED) {
-                       LogError("Certificate is Revoked by OCSP server.");
-                       return E_SIG_REVOKED;
-               }
-
-               LogDebug("Signature validation check done successfully ");
-       } catch (const CertificateCollection::Exception::Base &e) {
-               LogError("CertificateCollection exception : " << e.DumpToString());
-               return E_SIG_INVALID_CHAIN;
-       } catch (const XmlSec::Exception::InternalError &e) {
-               LogError("XmlSec internal error : " << e.DumpToString());
-               return E_SIG_INVALID_FORMAT;
-       } catch (const XmlSec::Exception::InvalidFormat &e) {
-               LogError("XmlSec invalid format : " << e.DumpToString());
-               return E_SIG_INVALID_FORMAT;
-       } catch (const XmlSec::Exception::InvalidSig &e) {
-               LogError("XmlSec invalid signature : " << e.DumpToString());
-               return E_SIG_INVALID_SIG;
-       } catch (const XmlSec::Exception::OutOfMemory &e) {
-               LogError("XmlSec out of memory : " << e.DumpToString());
-               return E_SIG_OUT_OF_MEM;
-       } catch (const XmlSec::Exception::Base &e) {
-               LogError("XmlSec unknown exception : " << e.DumpToString());
-               return E_SIG_INVALID_FORMAT;
-       } catch (const Ocsp::Exception::OcspUnsupported &e) {
-               LogInfo("Ocsp unsupported : " << e.DumpToString());
-       } catch (const Ocsp::Exception::Base &e) {
-               LogInfo("Ocsp check throw exeption : " << e.DumpToString());
-#ifdef TIZEN_PROFILE_MOBILE
-               LogInfo("Launch cert-checker.");
-               try {
-                       if (cchecker_ocsp_request() != 0)
-                               LogError("Load cert-checker failed.");
-               } catch (const std::exception &e) {
-                       LogError("std exception occured while cchecker running : " << e.what());
-               } catch (...) {
-                       LogError("Unknown exception occuured while cchecker running. ");
-               }
-#endif
-       } catch (const std::exception &e) {
-               LogError("std exception occured : " << e.what());
-               return E_SIG_UNKNOWN;
-       } catch (...) {
-               LogError("Unknown exception in SignatureValidator::check");
-               return E_SIG_UNKNOWN;
-       }
-
-       return m_disregarded ? E_SIG_DISREGARDED : E_SIG_NONE;
-}
-
-VCerr SignatureValidator::Impl::baseCheckList(
-       bool checkOcsp,
-       const UriList &uriList)
+       BaseValidator(info)
 {
-       try {
-               // Make certificate chain, check certificate info
-               VCerr result = preStep();
-
-               if (result != E_SIG_NONE)
-                       return result;
-
-               // XmlSec validate
-               if (uriList.size() == 0)
-                       XmlSecSingleton::Instance().validateNoHash(m_context);
-               else
-                       XmlSecSingleton::Instance().validatePartialHash(m_context, uriList);
-
-               if (checkOcsp && Ocsp::check(m_data) == Ocsp::Result::REVOKED) {
-                       LogError("Certificate is Revoked by OCSP server.");
-                       return E_SIG_REVOKED;
-               }
-
-               LogDebug("Signature validation of check list done successfully ");
-       } catch (const CertificateCollection::Exception::Base &e) {
-               LogError("CertificateCollection exception : " << e.DumpToString());
-               return E_SIG_INVALID_CHAIN;
-       } catch (const XmlSec::Exception::InternalError &e) {
-               LogError("XmlSec internal error : " << e.DumpToString());
-               return E_SIG_INVALID_FORMAT;
-       } catch (const XmlSec::Exception::InvalidFormat &e) {
-               LogError("XmlSec invalid format : " << e.DumpToString());
-               return E_SIG_INVALID_FORMAT;
-       } catch (const XmlSec::Exception::InvalidSig &e) {
-               LogError("XmlSec invalid signature : " << e.DumpToString());
-               return E_SIG_INVALID_SIG;
-       } catch (const XmlSec::Exception::OutOfMemory &e) {
-               LogError("XmlSec out of memory : " << e.DumpToString());
-               return E_SIG_OUT_OF_MEM;
-       } catch (const XmlSec::Exception::Base &e) {
-               LogError("XmlSec unknown exception : " << e.DumpToString());
-               return E_SIG_INVALID_FORMAT;
-       } catch (const Ocsp::Exception::OcspUnsupported &e) {
-               LogInfo("Ocsp unsupported : " << e.DumpToString());
-       } catch (const Ocsp::Exception::Base &e) {
-               LogInfo("Ocsp check throw exeption : " << e.DumpToString());
-#ifdef TIZEN_PROFILE_MOBILE
-               LogInfo("Launch cert-checker.");
-               try {
-                       if (cchecker_ocsp_request() != 0)
-                               LogError("Load cert-checker failed.");
-               } catch (const std::exception &e) {
-                       LogError("std exception occured while cchecker running : " << e.what());
-               } catch (...) {
-                       LogError("Unknown exception occuured while cchecker running. ");
-               }
-#endif
-       } catch (...) {
-               LogError("Unknown exception in SignatureValidator::checkList");
-               return E_SIG_UNKNOWN;
-       }
-
-       return m_disregarded ? E_SIG_DISREGARDED : E_SIG_NONE;
 }
 
-VCerr SignatureValidator::Impl::check(
-       const std::string &contentPath,
-       bool checkOcsp,
-       bool checkReferences,
-       SignatureData &outData)
+VCerr SignatureValidator::Impl::check(const std::string &contentPath,
+                                                                         bool checkOcsp,
+                                                                         bool checkReferences,
+                                                                         SignatureData &outData)
 {
        VCerr result;
        result = baseCheck(contentPath, checkOcsp, checkReferences);
@@ -529,110 +68,34 @@ VCerr SignatureValidator::Impl::checkList(
        return result;
 }
 
-VCerr SignatureValidator::Impl::makeChainBySignature(
-       bool completeWithSystemCert,
-       CertificateList &certList)
-{
-       VCerr result = makeDataBySignature(completeWithSystemCert);
-
-       if (result != E_SIG_NONE)
-               return result;
-
-       certList = m_data.getCertList();
-       return E_SIG_NONE;
-}
-
-std::string SignatureValidator::Impl::errorToString(VCerr code)
-{
-       switch (code) {
-       case E_SIG_NONE:
-               return "Success.";
-
-       case E_SIG_INVALID_FORMAT:
-               return "Invalid format of signature file.";
-
-       case E_SIG_INVALID_CERT:
-               return "Invalid format of certificate in signature.";
-
-       case E_SIG_INVALID_CHAIN:
-               return "Invalid certificate chain with certificate in signature.";
-
-       case E_SIG_INVALID_SIG:
-               return "Invalid signature. Signed with wrong key, changed signature file or changed package file.";
-
-       case E_SIG_INVALID_REF:
-               return "Invalid file reference. An unsinged file was found.";
-
-       case E_SIG_CERT_EXPIRED:
-               return "Certificate in signature was expired.";
-
-       case E_SIG_CERT_NOT_YET:
-               return "Certificate in signature is not valid yet.";
-
-       case E_SIG_DISREGARDED:
-               return "Signature validation can be disregarded in some cases.";
-
-       case E_SIG_REVOKED:
-               return "One of certificate was revoked in certificate chain.";
-
-       case E_SIG_PLUGIN:
-               return "Failed to load plugin for additional validation check.";
-
-       case E_SIG_OUT_OF_MEM:
-               return "Out of memory.";
-
-       case E_SIG_UNKNOWN:
-               return "Unknown error.";
-
-       default:
-               return m_pluginHandler.errorToString(code);
-       }
-}
-
-
 SignatureValidator::SignatureValidator(const SignatureFileInfo &info)
 {
-       std::unique_ptr<SignatureValidator::Impl> impl(new(std::nothrow) SignatureValidator::Impl(info));
+       using SVImpl = SignatureValidator::Impl;
+       std::unique_ptr<SVImpl> impl(new(std::nothrow) SVImpl(info));
        m_pImpl = std::move(impl);
 }
-SignatureValidator::~SignatureValidator() {}
-
-std::string SignatureValidator::errorToString(VCerr code)
-{
-       if (!m_pImpl)
-               return "out of memory. error.";
 
-       return m_pImpl->errorToString(code);
-}
+SignatureValidator::~SignatureValidator() {}
 
-VCerr SignatureValidator::check(
-       const std::string &contentPath,
-       bool checkOcsp,
-       bool checkReferences,
-       SignatureData &outData)
+VCerr SignatureValidator::check(const std::string &contentPath,
+                                                               bool checkOcsp,
+                                                               bool checkReferences,
+                                                               SignatureData &outData)
 {
        if (!m_pImpl)
                return E_SIG_OUT_OF_MEM;
 
-       return m_pImpl->check(
-                          contentPath,
-                          checkOcsp,
-                          checkReferences,
-                          outData);
+       return m_pImpl->check(contentPath, checkOcsp, checkReferences, outData);
 }
 
-VCerr SignatureValidator::checkList(
-       bool checkOcsp,
-       const UriList &uriList,
-       SignatureData &outData)
+VCerr SignatureValidator::checkList(bool checkOcsp,
+                                                                       const UriList &uriList,
+                                                                       SignatureData &outData)
 {
        if (!m_pImpl)
                return E_SIG_OUT_OF_MEM;
 
-       return m_pImpl->checkList(
-                          checkOcsp,
-                          uriList,
-                          outData);
+       return m_pImpl->checkList(checkOcsp, uriList, outData);
 }
 
 VCerr SignatureValidator::makeChainBySignature(
@@ -645,4 +108,12 @@ VCerr SignatureValidator::makeChainBySignature(
        return m_pImpl->makeChainBySignature(completeWithSystemCert, certList);
 }
 
+std::string SignatureValidator::errorToString(VCerr code)
+{
+       if (!m_pImpl)
+               return "out of memory. error.";
+
+       return m_pImpl->errorToString(code);
+}
+
 } // namespace ValidationCore
index 1c818a1..6541180 100644 (file)
@@ -71,24 +71,21 @@ public:
        SignatureValidator(const SignatureValidator &) = delete;
        const SignatureValidator &operator=(const SignatureValidator &) = delete;
 
-       VCerr check(
-               const std::string &contentPath,
-               bool checkOcsp,
-               bool checkReferences,
-               SignatureData &outData);
+       VCerr check(const std::string &contentPath,
+                               bool checkOcsp,
+                               bool checkReferences,
+                               SignatureData &outData);
 
-       VCerr checkList(
-               bool checkOcsp,
-               const UriList &uriList,
-               SignatureData &outData);
+       VCerr checkList(bool checkOcsp,
+                                       const UriList &uriList,
+                                       SignatureData &outData);
 
        /*
         *  @Remarks : cert list isn't completed with self-signed root CA system cert
         *             if completeWithSystemCert is false.
         */
-       VCerr makeChainBySignature(
-               bool completeWithSystemCert,
-               CertificateList &certList);
+       VCerr makeChainBySignature(bool completeWithSystemCert,
+                                                          CertificateList &certList);
 
        std::string errorToString(int code);