From: Jinkun Jang Date: Fri, 15 Mar 2013 16:17:48 +0000 (+0900) Subject: merge with master X-Git-Tag: 2.1b_release~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b7943bcf07e0df015f327a626e348251a902cfb;p=platform%2Fcore%2Fsecurity%2Fcert-svc.git merge with master --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 900eae0..323e67d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,10 @@ INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH ) INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty + DESTINATION /opt/share/cert-svc/certs/code-signing/tizen + FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH +) +INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty DESTINATION /opt/share/cert-svc/certs/sim/operator FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH ) diff --git a/debian/changelog b/debian/changelog index cf5f4e7..72859de 100755 --- a/debian/changelog +++ b/debian/changelog @@ -103,3 +103,236 @@ cert-svc (1.0.1-28) unstable; urgency=low * Tag : cert-svc_1.0.1-28 -- Tomasz Swierczek Mon, 13 Aug 2012 18:51:00 +0200 + +cert-svc (1.0.1-27) unstable; urgency=low + + * Selection screen added as separate EFL gadget + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-27 + + -- Tomasz Swierczek Tue, 31 Jul 2012 17:14:00 +0200 + +cert-svc (1.0.1-26) unstable; urgency=low + + * Selection screen runs correctly with another EFL app + * Added test for selection screen + * Corrected comments in cert-ui-api.h + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-26 + + -- Tomasz Swierczek Wed, 25 Jul 2012 18:39:00 +0200 + +cert-svc (1.0.1-25) unstable; urgency=low + + * another RPMization + * added selection screen + * added pkcs12 container install/browse menu + * added cert-svc-ui-api library + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-25 + + -- Tomasz Swierczek Tue, 24 Jul 2012 22:55:00 +0200 + +cert-svc (1.0.1-24) unstable; urgency=low + + * added selection screen + * added pkcs12 container install/browse menu + * added cert-svc-ui-api library + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-24 + + -- Tomasz Swierczek Tue, 24 Jul 2012 22:55:00 +0200 + +cert-svc (1.0.1-23) unstable; urgency=low + + * Redebianized. + * Remove deprecated dependency from tapi and pkgmgr. + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-23 + + -- Bartlomiej Grzelewski Mon, 18 Jul 2012 18:05:11 +0100 + +cert-svc (1.0.1-22) unstable; urgency=low + + * Redebianized. + * Remove deprecated function call from lib. + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-22 + + -- Bartlomiej Grzelewski Mon, 17 Jul 2012 18:15:00 +0100 + +cert-svc (1.0.1-19) unstable; urgency=low + + * Redebianized + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-19 + + -- Tomasz Swierczek Mon, 04 Jun 2012 17:41:00 +0100 + +cert-svc (1.0.1-18) unstable; urgency=low + + * Move VCore to cert-svc repository + * Add test for vcore c-api. + * Added Cert UI Package + + * Git : slp/pkgs/c/cert-svc + * Tag : cert-svc_1.0.1-18 + + -- Tomasz Swierczek Mon, 04 Jun 2012 17:20:00 +0100 + +cert-svc (1.0.1-17) unstable; urgency=low + + * add certificate store for MDM + * Git: slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-17 + + -- Kidong Kim Thu, 02 Feb 2012 09:29:17 +0900 + +cert-svc (1.0.1-16) unstable; urgency=low + + * 11/12/21 + * - remove self-signed certificate from certificate chain + * Git: slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-16 + + -- Kidong Kim Wed, 21 Dec 2011 10:06:41 +0900 + +cert-svc (1.0.1-15) unstable; urgency=low + + * 11/12/07 + * - add boiler-plate on testcases + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-15 + + -- Kidong Kim Wed, 07 Dec 2011 09:47:17 +0900 + +cert-svc (1.0.1-14) unstable; urgency=low + + * 11/12/02 + * - change license : LGPL -> apache + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-14 + + -- Kidong Kim Fri, 02 Dec 2011 16:59:02 +0900 + +cert-svc (1.0.1-13) unstable; urgency=low + + * 11/11/30 + * - make all certificate stores and change ownership and permission of those + * - use dlog instead of console(fprintf) for logging + * - get length of private key when using PFX format certificate + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-13 + + -- Kidong Kim Wed, 30 Nov 2011 16:17:49 +0900 + +cert-svc (1.0.1-12) unstable; urgency=low + + * add testcases + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-12 + + -- Kidong Kim Fri, 14 Oct 2011 14:00:11 +0900 + +cert-svc (1.0.1-11) unstable; urgency=low + + * fix dependency problem + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-11 + + -- Kidong Kim Mon, 29 Aug 2011 09:39:01 +0900 + +cert-svc (1.0.1-10) unstable; urgency=low + + * remove dnet dependency + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-10 + + -- Kidong Kim Fri, 26 Aug 2011 10:18:08 +0900 + +cert-svc (1.0.1-9) unstable; urgency=low + + * fix name field parsing problem (temp) + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-9 + + -- Kidong Kim Mon, 25 Jul 2011 17:22:13 +0900 + +cert-svc (1.0.1-8) unstable; urgency=low + + * fix search problem + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-8 + + -- Kidong Kim Thu, 14 Jul 2011 10:04:11 +0900 + +cert-svc (1.0.1-7) unstable; urgency=low + + * fix install bug + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-7 + + -- Kidong Kim Wed, 13 Jul 2011 12:27:53 +0900 + +cert-svc (1.0.1-6) unstable; urgency=low + + * fix boiler-plate + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-6 + + -- Kidong Kim Wed, 13 Jul 2011 10:12:13 +0900 + +cert-svc (1.0.1-5) unstable; urgency=low + + * fix bug - verify certificate, postinst + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-5 + + -- Kidong Kim Thu, 23 Jun 2011 15:27:48 +0900 + +cert-svc (1.0.1-4) unstable; urgency=low + + * fix bug - cannot calculate message length if message is not character string + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-4 + + -- Kidong Kim Sat, 18 Jun 2011 12:56:47 +0900 + +cert-svc (1.0.1-3) unstable; urgency=low + + * fix full-build error + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-3 + + -- Kidong Kim Tue, 14 Jun 2011 10:15:33 +0900 + +cert-svc (1.0.1-2) unstable; urgency=low + + * fix installation bug + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-2 + + -- Kidong Kim Sat, 11 Jun 2011 10:36:30 +0900 + +cert-svc (1.0.1-1) unstable; urgency=low + + * add dpkg-pki-sig, fix some bugs + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.1-1 + + -- Kidong Kim Fri, 10 Jun 2011 11:38:26 +0900 + +cert-svc (1.0.0-1) unstable; urgency=low + + * Initial Release + * Git: 165.213.180.234:slp/pkgs/c/cert-svc + * Tag: cert-svc_1.0.0-1 + + -- Kidong Kim Tue, 07 Jun 2011 13:48:44 +0900 diff --git a/packaging/cert-svc.spec b/packaging/cert-svc.spec index ac5c5f8..05b86f9 100644 --- a/packaging/cert-svc.spec +++ b/packaging/cert-svc.spec @@ -112,6 +112,7 @@ fi %dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs %dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/code-signing %dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/code-signing/wac +%dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/code-signing/tizen %dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/sim %dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/sim/operator %dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/sim/thirdparty diff --git a/vcore/src/CMakeLists.txt b/vcore/src/CMakeLists.txt index b10b23f..031158e 100644 --- a/vcore/src/CMakeLists.txt +++ b/vcore/src/CMakeLists.txt @@ -58,6 +58,7 @@ SET(VCORE_SOURCES ${VCORE_SRC_DIR}/ValidatorFactories.cpp ${VCORE_SRC_DIR}/VCore.cpp ${VCORE_SRC_DIR}/WrtSignatureValidator.cpp + ${VCORE_SRC_DIR}/SignatureValidator.cpp ${VCORE_SRC_DIR}/XmlsecAdapter.cpp ${VCORE_SRC_DIR}/pkcs12.c ) @@ -118,6 +119,7 @@ INSTALL(FILES ${VCORE_SRC_DIR}/SignatureFinder.h ${VCORE_SRC_DIR}/SignatureReader.h ${VCORE_SRC_DIR}/WrtSignatureValidator.h + ${VCORE_SRC_DIR}/SignatureValidator.h ${VCORE_SRC_DIR}/VerificationStatus.h ${VCORE_SRC_DIR}/VCore.h DESTINATION ${INCLUDEDIR}/cert-svc/vcore diff --git a/vcore/src/vcore/CertStoreType.h b/vcore/src/vcore/CertStoreType.h index de3affc..c3af27d 100644 --- a/vcore/src/vcore/CertStoreType.h +++ b/vcore/src/vcore/CertStoreType.h @@ -41,6 +41,15 @@ const Type TIZEN_MEMBER = 1 << 4; // RootCA certificates used by orange const Type ORANGE_LEGACY = 1 << 5; +// RootCA's visibility level : public +const Type VIS_PUBLIC = 1 << 6; +// RootCA's visibility level : partner +const Type VIS_PARTNER = 1 << 7; +// RootCA's visibility level : partner-operator +const Type VIS_PARTNER_OPERATOR = 1 << 8; +// RootCA's visibility level : partner-manufacturer +const Type VIS_PARTNER_MANUFACTURER = 1 << 9; + class Set { public: diff --git a/vcore/src/vcore/CertificateConfigReader.cpp b/vcore/src/vcore/CertificateConfigReader.cpp index 608dda2..872aa7d 100644 --- a/vcore/src/vcore/CertificateConfigReader.cpp +++ b/vcore/src/vcore/CertificateConfigReader.cpp @@ -40,6 +40,11 @@ const std::string TOKEN_VALUE_DEVELOPER = "developer"; const std::string TOKEN_VALUE_TIZEN_MEMBER = "tizenmember"; const std::string TOKEN_VALUE_ORANGE_LEGACY = "orangelegacy"; +const std::string TOKEN_VALUE_VISIBILITY_PUBLIC = "tizen-public"; +const std::string TOKEN_VALUE_VISIBILITY_PARTNER = "tizen-partner"; +const std::string TOKEN_VALUE_VISIBILITY_PARTNER_OPERATOR = "tizen-partner-operator"; +const std::string TOKEN_VALUE_VISIBILITY_PARTNER_MANUFACTURER = "tizen-partner-manufacturer"; + int hexCharToInt(char c) { if (c >= 'a' && c <= 'f') { @@ -112,7 +117,15 @@ void CertificateConfigReader::tokenCertificateDomain(CertificateIdentifier &) m_certificateDomain = CertStoreId::TIZEN_MEMBER; } else if (name == TOKEN_VALUE_ORANGE_LEGACY) { m_certificateDomain = CertStoreId::ORANGE_LEGACY; - } else { + } else if (name == TOKEN_VALUE_VISIBILITY_PUBLIC) { + m_certificateDomain = CertStoreId::VIS_PUBLIC; + } else if (name == TOKEN_VALUE_VISIBILITY_PARTNER) { + m_certificateDomain = CertStoreId::VIS_PARTNER; + } else if (name == TOKEN_VALUE_VISIBILITY_PARTNER_OPERATOR) { + m_certificateDomain = CertStoreId::VIS_PARTNER_OPERATOR; + } else if (name == TOKEN_VALUE_VISIBILITY_PARTNER_MANUFACTURER) { + m_certificateDomain = CertStoreId::VIS_PARTNER_MANUFACTURER; + } else { LogWarning("This domain will be ignored: " << name); m_certificateDomain = 0; } diff --git a/vcore/src/vcore/SignatureData.h b/vcore/src/vcore/SignatureData.h index bfb5e1f..eb744b4 100644 --- a/vcore/src/vcore/SignatureData.h +++ b/vcore/src/vcore/SignatureData.h @@ -128,6 +128,22 @@ class SignatureData return m_storeIdSet; } + const CertStoreId::Type getVisibilityLevel(void) const + { + if (m_storeIdSet.contains(CertStoreId::VIS_PUBLIC) == true) + return CertStoreId::VIS_PUBLIC; + else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER) == true) + return CertStoreId::VIS_PARTNER; + else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER_OPERATOR) == true) + return CertStoreId::VIS_PARTNER_OPERATOR; + else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER_MANUFACTURER) == true) + return CertStoreId::VIS_PARTNER_MANUFACTURER; + else { + LogWarning("Visibility level was broken."); + return 0; + } + } + const IMEIList& getIMEIList() const { return m_imeiList; @@ -155,6 +171,7 @@ class SignatureData } friend class SignatureReader; + private: ReferenceSet m_referenceSet; CertificateList m_certList; diff --git a/vcore/src/vcore/SignatureValidator.cpp b/vcore/src/vcore/SignatureValidator.cpp new file mode 100644 index 0000000..650b48d --- /dev/null +++ b/vcore/src/vcore/SignatureValidator.cpp @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2011 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 SignatureValidator.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Implementatin of tizen signature validation protocol. + */ +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace { +const time_t TIMET_DAY = 60 * 60 * 24; + +const std::string TOKEN_ROLE_AUTHOR_URI = + "http://www.w3.org/ns/widgets-digsig#role-author"; +const std::string TOKEN_ROLE_DISTRIBUTOR_URI = + "http://www.w3.org/ns/widgets-digsig#role-distributor"; +const std::string TOKEN_PROFILE_URI = + "http://www.w3.org/ns/widgets-digsig#profile"; +} // namespace anonymouse + +namespace ValidationCore { + +class SignatureValidator::ImplSignatureValidator { +public: + virtual SignatureValidator::Result check( + SignatureData &data, + const std::string &widgetContentPath) = 0; + + explicit ImplSignatureValidator(bool ocspEnable, + bool crlEnable, + bool complianceMode) + : m_ocspEnable(ocspEnable) + , m_crlEnable(crlEnable) + , m_complianceModeEnabled(complianceMode) + {} + + virtual ~ImplSignatureValidator(){} + + bool checkRoleURI(const SignatureData &data) { + std::string roleURI = data.getRoleURI(); + + if (roleURI.empty()) { + LogWarning("URI attribute in Role tag couldn't be empty."); + return false; + } + + if (roleURI != TOKEN_ROLE_AUTHOR_URI && data.isAuthorSignature()) { + LogWarning("URI attribute in Role tag does not " + "match with signature filename."); + return false; + } + + if (roleURI != TOKEN_ROLE_DISTRIBUTOR_URI && !data.isAuthorSignature()) { + LogWarning("URI attribute in Role tag does not " + "match with signature filename."); + return false; + } + return true; + } + + bool checkProfileURI(const SignatureData &data) { + if (TOKEN_PROFILE_URI != data.getProfileURI()) { + LogWarning( + "Profile tag contains unsupported value in URI attribute(" << + data.getProfileURI() << ")."); + return false; + } + return true; + } + + bool checkObjectReferences(const SignatureData &data) { + ObjectList objectList = data.getObjectList(); + ObjectList::const_iterator iter; + for (iter = objectList.begin(); iter != objectList.end(); ++iter) { + if (!data.containObjectReference(*iter)) { + LogWarning("Signature does not contain reference for object " << + *iter); + return false; + } + } + return true; + } +protected: + bool m_ocspEnable; + bool m_crlEnable; + bool m_complianceModeEnabled; +}; + +class ImplTizenSignatureValidator : public SignatureValidator::ImplSignatureValidator +{ + public: + SignatureValidator::Result check(SignatureData &data, + const std::string &widgetContentPath); + + explicit ImplTizenSignatureValidator(bool ocspEnable, + bool crlEnable, + bool complianceMode) + : ImplSignatureValidator(ocspEnable, crlEnable, complianceMode) + {} + + virtual ~ImplTizenSignatureValidator() {} +}; + +SignatureValidator::Result ImplTizenSignatureValidator::check( + SignatureData &data, + const std::string &widgetContentPath) +{ + bool disregard = false; + + if (!checkRoleURI(data)) { + return SignatureValidator::SIGNATURE_INVALID; + } + + if (!checkProfileURI(data)) { + return SignatureValidator::SIGNATURE_INVALID; + } + + // CertificateList sortedCertificateList = data.getCertList(); + + CertificateCollection collection; + collection.load(data.getCertList()); + + // First step - sort certificate + if (!collection.sort()) { + LogWarning("Certificates do not form valid chain."); + return SignatureValidator::SIGNATURE_INVALID; + } + + // Check for error + if (collection.empty()) { + LogWarning("Certificate list in signature is empty."); + return SignatureValidator::SIGNATURE_INVALID; + } + + CertificateList sortedCertificateList = collection.getChain(); + + // TODO move it to CertificateCollection + // Add root CA and CA certificates (if chain is incomplete) + sortedCertificateList = + OCSPCertMgrUtil::completeCertificateChain(sortedCertificateList); + + CertificatePtr root = sortedCertificateList.back(); + + // Is Root CA certificate trusted? + CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root); + + LogDebug("Is root certificate from WAC_PUBLISHER domain: " + << storeIdSet.contains(CertStoreId::WAC_PUBLISHER)); + LogDebug("Is root certificate from WAC_DEVELOPER domain: " + << storeIdSet.contains(CertStoreId::DEVELOPER)); + LogDebug("Is root certificate from WAC_ROOT domain: " + << storeIdSet.contains(CertStoreId::WAC_ROOT)); + LogDebug("Is root certificate from WAC_MEMBER domain: " + << storeIdSet.contains(CertStoreId::WAC_MEMBER)); + LogDebug("Is root certificate from TIZEN_MEMBER domain: " + << storeIdSet.contains(CertStoreId::TIZEN_MEMBER)); + LogDebug("Is root certificate from TIZEN_ORANGE domain: " + << storeIdSet.contains(CertStoreId::ORANGE_LEGACY)); + + LogDebug(" visibility level is public : " + << storeIdSet.contains(CertStoreId::VIS_PUBLIC)); + LogDebug(" visibility level is partner : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER)); + LogDebug(" visibility level is partner-operator : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_OPERATOR)); + LogDebug(" visibility level is partner-manufacturer : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_MANUFACTURER)); + +/* + // WAC chapter 3.2.1 - verified definition + if (data.isAuthorSignature()) { + if (!storeIdSet.contains(CertStoreId::WAC_PUBLISHER)) { + LogWarning("Author signature has got unrecognized Root CA " + "certificate. Signature will be disregarded."); + disregard = true; + } + LogDebug("Root CA for author signature is correct."); + } else { + if (!storeIdSet.contains(CertStoreId::DEVELOPER) && + !storeIdSet.contains(CertStoreId::TIZEN_MEMBER)) + { + LogWarning("Distiributor signature has got unrecognized Root CA " + "certificate. Signature will be disregarded."); + disregard = true; + } else + LogDebug("Root CA for distributor signature is correct."); + } + */ + + data.setStorageType(storeIdSet); + data.setSortedCertificateList(sortedCertificateList); + + // We add only Root CA certificate because WAC ensure that the rest + // of certificates are present in signature files ;-) + XmlSec::XmlSecContext context; + context.signatureFile = data.getSignatureFileName(); + context.certificatePtr = root; + + // Now we should have full certificate chain. + // If the end certificate is not ROOT CA we should disregard signature + // but still signature must be valid... Aaaaaa it's so stupid... + if (!(root->isSignedBy(root))) { + LogWarning("Root CA certificate not found. Chain is incomplete."); + context.allowBrokenChain = true; + } + + // WAC 2.0 SP-2066 The wrt must not block widget installation + // due to expiration of the author certificate. + time_t notAfter = data.getEndEntityCertificatePtr()->getNotAfter(); + bool expired = notAfter < time(NULL); + if (data.isAuthorSignature() && expired) { + context.validationTime = notAfter - TIMET_DAY; + } + // end + + if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) { + LogWarning("Installation break - invalid package!"); + return SignatureValidator::SIGNATURE_INVALID; + } + + data.setReference(context.referenceSet); + + if (!checkObjectReferences(data)) { + return SignatureValidator::SIGNATURE_INVALID; + } + + ReferenceValidator fileValidator(widgetContentPath); + if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) { + LogWarning("Invalid package - file references broken"); + return SignatureValidator::SIGNATURE_INVALID; + } + + // It is good time to do OCSP check + // ocspCheck will throw an exception on any error. + // TODO Probably we should catch this exception and add + // some information to SignatureData. + if (!m_complianceModeEnabled && !data.isAuthorSignature()) { + CertificateCollection coll; + coll.load(sortedCertificateList); + + if (!coll.sort()) { + LogDebug("Collection does not contain chain!"); + return SignatureValidator::SIGNATURE_INVALID; + } + + // If ORANGE_LEGACY is set we cannot check ocsp + bool runOCSP = storeIdSet.contains(CertStoreId::ORANGE_LEGACY) ? + false : m_ocspEnable; + + CertificateVerifier verificator(runOCSP, m_crlEnable); + VerificationStatus result = verificator.check(coll); + + if (result == VERIFICATION_STATUS_REVOKED) { + return SignatureValidator::SIGNATURE_REVOKED; + } + + if (result == VERIFICATION_STATUS_UNKNOWN || + result == VERIFICATION_STATUS_ERROR) + { + disregard = true; + } + } + + if (disregard) { + LogWarning("Signature is disregard."); + return SignatureValidator::SIGNATURE_DISREGARD; + } + return SignatureValidator::SIGNATURE_VERIFIED; +} + +class ImplWacSignatureValidator : public SignatureValidator::ImplSignatureValidator +{ + public: + SignatureValidator::Result check(SignatureData &data, + const std::string &widgetContentPath); + + explicit ImplWacSignatureValidator(bool ocspEnable, + bool crlEnable, + bool complianceMode) + : ImplSignatureValidator(ocspEnable, crlEnable, complianceMode) + {} + + virtual ~ImplWacSignatureValidator() {} +}; + +SignatureValidator::Result ImplWacSignatureValidator::check( + SignatureData &data, + const std::string &widgetContentPath) +{ + bool disregard = false; + + if (!checkRoleURI(data)) { + return SignatureValidator::SIGNATURE_INVALID; + } + + if (!checkProfileURI(data)) { + return SignatureValidator::SIGNATURE_INVALID; + } + + // CertificateList sortedCertificateList = data.getCertList(); + + CertificateCollection collection; + collection.load(data.getCertList()); + + // First step - sort certificate + if (!collection.sort()) { + LogWarning("Certificates do not form valid chain."); + return SignatureValidator::SIGNATURE_INVALID; + } + + // Check for error + if (collection.empty()) { + LogWarning("Certificate list in signature is empty."); + return SignatureValidator::SIGNATURE_INVALID; + } + + CertificateList sortedCertificateList = collection.getChain(); + + // TODO move it to CertificateCollection + // Add root CA and CA certificates (if chain is incomplete) + sortedCertificateList = + OCSPCertMgrUtil::completeCertificateChain(sortedCertificateList); + + CertificatePtr root = sortedCertificateList.back(); + + // Is Root CA certificate trusted? + CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root); + + LogDebug("Is root certificate from WAC_PUBLISHER domain: " + << storeIdSet.contains(CertStoreId::WAC_PUBLISHER)); + LogDebug("Is root certificate from WAC_DEVELOPER domain: " + << storeIdSet.contains(CertStoreId::DEVELOPER)); + LogDebug("Is root certificate from WAC_ROOT domain: " + << storeIdSet.contains(CertStoreId::WAC_ROOT)); + LogDebug("Is root certificate from WAC_MEMBER domain: " + << storeIdSet.contains(CertStoreId::WAC_MEMBER)); + LogDebug("Is root certificate from TIZEN_MEMBER domain: " + << storeIdSet.contains(CertStoreId::TIZEN_MEMBER)); + LogDebug("Is root certificate from ORANGE_LEGACY domain: " + << storeIdSet.contains(CertStoreId::ORANGE_LEGACY)); + + LogDebug(" visibility level is public : " + << storeIdSet.contains(CertStoreId::VIS_PUBLIC)); + LogDebug(" visibility level is partner : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER)); + LogDebug(" visibility level is partner-operator : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_OPERATOR)); + LogDebug(" visibility level is partner-manufacturer : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_MANUFACTURER)); + + // WAC chapter 3.2.1 - verified definition + if (data.isAuthorSignature()) { + if (!storeIdSet.contains(CertStoreId::WAC_PUBLISHER)) { + LogWarning("Author signature has got unrecognized Root CA " + "certificate. Signature will be disregarded."); + disregard = true; + } + LogDebug("Root CA for author signature is correct."); + } else { + if (!storeIdSet.contains(CertStoreId::DEVELOPER) && + !storeIdSet.contains(CertStoreId::WAC_ROOT) && + !storeIdSet.contains(CertStoreId::WAC_MEMBER)) + { + LogWarning("Distiributor signature has got unrecognized Root CA " + "certificate. Signature will be disregarded."); + disregard = true; + } else { + LogDebug("Root CA for distributor signature is correct."); + } + } + + data.setStorageType(storeIdSet); + data.setSortedCertificateList(sortedCertificateList); + + // We add only Root CA certificate because WAC ensure that the rest + // of certificates are present in signature files ;-) + XmlSec::XmlSecContext context; + context.signatureFile = data.getSignatureFileName(); + context.certificatePtr = root; + + // Now we should have full certificate chain. + // If the end certificate is not ROOT CA we should disregard signature + // but still signature must be valid... Aaaaaa it's so stupid... + if (!(root->isSignedBy(root))) { + LogWarning("Root CA certificate not found. Chain is incomplete."); + context.allowBrokenChain = true; + } + + // WAC 2.0 SP-2066 The wrt must not block widget installation + // due to expiration of the author certificate. + time_t notAfter = data.getEndEntityCertificatePtr()->getNotAfter(); + bool expired = notAfter < time(NULL); + if (data.isAuthorSignature() && expired) { + context.validationTime = notAfter - TIMET_DAY; + } + // end + + if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) { + LogWarning("Installation break - invalid package!"); + return SignatureValidator::SIGNATURE_INVALID; + } + + data.setReference(context.referenceSet); + + if (!checkObjectReferences(data)) { + return SignatureValidator::SIGNATURE_INVALID; + } + + ReferenceValidator fileValidator(widgetContentPath); + if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) { + LogWarning("Invalid package - file references broken"); + return SignatureValidator::SIGNATURE_INVALID; + } + + // It is good time to do OCSP check + // ocspCheck will throw an exception on any error. + // TODO Probably we should catch this exception and add + // some information to SignatureData. + if (!m_complianceModeEnabled && !data.isAuthorSignature()) { + CertificateCollection coll; + coll.load(sortedCertificateList); + + if (!coll.sort()) { + LogDebug("Collection does not contain chain!"); + return SignatureValidator::SIGNATURE_INVALID; + } + + CertificateVerifier verificator(m_ocspEnable, m_crlEnable); + VerificationStatus result = verificator.check(coll); + + if (result == VERIFICATION_STATUS_REVOKED) { + return SignatureValidator::SIGNATURE_REVOKED; + } + + if (result == VERIFICATION_STATUS_UNKNOWN || + result == VERIFICATION_STATUS_ERROR) + { + disregard = true; + } + } + + if (disregard) { + LogWarning("Signature is disregard."); + return SignatureValidator::SIGNATURE_DISREGARD; + } + return SignatureValidator::SIGNATURE_VERIFIED; +} + +// Implementation of SignatureValidator + +SignatureValidator::SignatureValidator( + AppType appType, + bool ocspEnable, + bool crlEnable, + bool complianceMode) + : m_impl(0) +{ + if (appType == TIZEN) + m_impl = new ImplTizenSignatureValidator(ocspEnable,crlEnable,complianceMode); + else + m_impl = new ImplWacSignatureValidator(ocspEnable,crlEnable,complianceMode); +} + +SignatureValidator::~SignatureValidator() { + delete m_impl; +} + +SignatureValidator::Result SignatureValidator::check( + SignatureData &data, + const std::string &widgetContentPath) +{ + return m_impl->check(data, widgetContentPath); +} + +} // namespace ValidationCore + diff --git a/vcore/src/vcore/SignatureValidator.h b/vcore/src/vcore/SignatureValidator.h new file mode 100644 index 0000000..041366f --- /dev/null +++ b/vcore/src/vcore/SignatureValidator.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011 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 SignatureValidator.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Implementatin of tizen signature validation protocol. + */ +#ifndef _VALIDATION_CORE_SIGNATUREVALIDATOR_H_ +#define _VALIDATION_CORE_SIGNATUREVALIDATOR_H_ + +#include + +#include + +#include + +namespace ValidationCore { + +class SignatureValidator : public DPL::Noncopyable { +public: + class ImplSignatureValidator; + + enum AppType + { + TIZEN, + WAC20 + }; + + enum Result + { + SIGNATURE_VALID, + SIGNATURE_INVALID, + SIGNATURE_VERIFIED, + SIGNATURE_DISREGARD, // no ocsp response or ocsp return unknown status + SIGNATURE_REVOKED + }; + + explicit SignatureValidator( + AppType appType, + bool ocspEnable, + bool crlEnable, + bool complianceMode); + + virtual ~SignatureValidator(); + + Result check( + SignatureData &data, + const std::string &widgetContentPath); + +private: + ImplSignatureValidator *m_impl; +}; + +} // namespace ValidationCore + +#endif // _VALIDATION_CORE_TIZENSIGNATUREVALIDATOR_H_ + diff --git a/vcore/src/vcore/WrtSignatureValidator.cpp b/vcore/src/vcore/WrtSignatureValidator.cpp index 7138e8a..2309bfa 100644 --- a/vcore/src/vcore/WrtSignatureValidator.cpp +++ b/vcore/src/vcore/WrtSignatureValidator.cpp @@ -180,6 +180,15 @@ WrtSignatureValidator::Result ImplTizen::check( LogDebug("Is root certificate from TIZEN_ORANGE domain: " << storeIdSet.contains(CertStoreId::ORANGE_LEGACY)); + LogDebug(" visibility level is public : " + << storeIdSet.contains(CertStoreId::VIS_PUBLIC)); + LogDebug(" visibility level is partner : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER)); + LogDebug(" visibility level is partner-operator : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_OPERATOR)); + LogDebug(" visibility level is partner-manufacturer : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_MANUFACTURER)); + // WAC chapter 3.2.1 - verified definition if (data.isAuthorSignature()) { if (!storeIdSet.contains(CertStoreId::WAC_PUBLISHER)) { @@ -351,6 +360,15 @@ WrtSignatureValidator::Result ImplWac::check( LogDebug("Is root certificate from ORANGE_LEGACY domain: " << storeIdSet.contains(CertStoreId::ORANGE_LEGACY)); + LogDebug(" visibility level is public : " + << storeIdSet.contains(CertStoreId::VIS_PUBLIC)); + LogDebug(" visibility level is partner : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER)); + LogDebug(" visibility level is partner-operator : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_OPERATOR)); + LogDebug(" visibility level is partner-manufacturer : " + << storeIdSet.contains(CertStoreId::VIS_PARTNER_MANUFACTURER)); + // WAC chapter 3.2.1 - verified definition if (data.isAuthorSignature()) { if (!storeIdSet.contains(CertStoreId::WAC_PUBLISHER)) {