Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:51:23 +0000 (01:51 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:51:23 +0000 (01:51 +0900)
137 files changed:
CMakeLists.txt
LICENSE.APLv2 [new file with mode: 0644]
NOTICE [new file with mode: 0755]
build-stamp [new file with mode: 0644]
cert-svc-vcore.pc.in [new file with mode: 0644]
debian/changelog [changed mode: 0644->0755]
debian/changelog.app [new file with mode: 0755]
debian/changelog.ug [new file with mode: 0755]
debian/com.samsung.mgr-app-0.install.in [new file with mode: 0755]
debian/com.samsung.mgr-app-dbg.install.in [new file with mode: 0755]
debian/com.samsung.mgr-app.desktop.in [new file with mode: 0755]
debian/com.samsung.mgr-app.postinst.in [new file with mode: 0755]
debian/control [changed mode: 0644->0755]
debian/control.app [new file with mode: 0755]
debian/control.ug [new file with mode: 0755]
debian/libcert-svc-dev.install [new file with mode: 0644]
debian/libcert-svc1-test.install [new file with mode: 0644]
debian/libcert-svc1-ui.install [new file with mode: 0644]
debian/libcert-svc1.dirs [new file with mode: 0644]
debian/libcert-svc1.install [new file with mode: 0644]
debian/libcert-svc1.links [new file with mode: 0644]
debian/libcert-svc1.postinst [new file with mode: 0755]
debian/rules
etc/CMakeLists.txt [new file with mode: 0644]
etc/cert_svc_create_clean_db.sh [new file with mode: 0755]
etc/empty/.gitignore [new file with mode: 0644]
include/cert-service-process.h
include/cert-service.h
packaging/cert-svc.manifest [new file with mode: 0644]
packaging/cert-svc.spec
srcs/cert-service-process.c
srcs/cert-service-store.c
srcs/cert-service-util.c
srcs/cert-service.c
srcs/dpkg-pki-sig.c
vcore/CMakeLists.txt [new file with mode: 0644]
vcore/cert_svc_vcore_db.sql [new file with mode: 0644]
vcore/src/CMakeLists.txt [new file with mode: 0644]
vcore/src/cert-svc/ccert.h [new file with mode: 0644]
vcore/src/cert-svc/ccrl.h [new file with mode: 0644]
vcore/src/cert-svc/cerror.h [new file with mode: 0644]
vcore/src/cert-svc/cinstance.h [new file with mode: 0644]
vcore/src/cert-svc/cocsp.h [new file with mode: 0644]
vcore/src/cert-svc/cpkcs12.h [new file with mode: 0644]
vcore/src/cert-svc/cprimitives.h [new file with mode: 0644]
vcore/src/cert-svc/cstring.h [new file with mode: 0644]
vcore/src/orm/DESCRIPTION [new file with mode: 0644]
vcore/src/orm/gen_db_md5.sh [new file with mode: 0755]
vcore/src/orm/orm_generator_vcore.h [new file with mode: 0644]
vcore/src/orm/vcore_db [new file with mode: 0644]
vcore/src/orm/vcore_db_definitions [new file with mode: 0644]
vcore/src/orm/vcore_db_sql_generator.h [new file with mode: 0644]
vcore/src/orm/version_db [new file with mode: 0644]
vcore/src/vcore/Base64.cpp [new file with mode: 0644]
vcore/src/vcore/Base64.h [new file with mode: 0644]
vcore/src/vcore/CRL.cpp [new file with mode: 0644]
vcore/src/vcore/CRL.h [new file with mode: 0644]
vcore/src/vcore/CRLCacheDAO.cpp [new file with mode: 0644]
vcore/src/vcore/CRLCacheDAO.h [new file with mode: 0644]
vcore/src/vcore/CRLCacheInterface.h [new file with mode: 0644]
vcore/src/vcore/CRLImpl.cpp [new file with mode: 0644]
vcore/src/vcore/CRLImpl.h [new file with mode: 0644]
vcore/src/vcore/CachedCRL.cpp [new file with mode: 0644]
vcore/src/vcore/CachedCRL.h [new file with mode: 0644]
vcore/src/vcore/CachedOCSP.cpp [new file with mode: 0644]
vcore/src/vcore/CachedOCSP.h [new file with mode: 0644]
vcore/src/vcore/CertStoreType.cpp [new file with mode: 0644]
vcore/src/vcore/CertStoreType.h [new file with mode: 0644]
vcore/src/vcore/Certificate.cpp [new file with mode: 0644]
vcore/src/vcore/Certificate.h [new file with mode: 0644]
vcore/src/vcore/CertificateCacheDAO.cpp [new file with mode: 0644]
vcore/src/vcore/CertificateCacheDAO.h [new file with mode: 0644]
vcore/src/vcore/CertificateCollection.cpp [new file with mode: 0644]
vcore/src/vcore/CertificateCollection.h [new file with mode: 0644]
vcore/src/vcore/CertificateConfigReader.cpp [new file with mode: 0644]
vcore/src/vcore/CertificateConfigReader.h [new file with mode: 0644]
vcore/src/vcore/CertificateIdentifier.h [new file with mode: 0644]
vcore/src/vcore/CertificateLoader.cpp [new file with mode: 0644]
vcore/src/vcore/CertificateLoader.h [new file with mode: 0644]
vcore/src/vcore/CertificateStorage.h [new file with mode: 0644]
vcore/src/vcore/CertificateVerifier.cpp [new file with mode: 0644]
vcore/src/vcore/CertificateVerifier.h [new file with mode: 0644]
vcore/src/vcore/Config.cpp [new file with mode: 0644]
vcore/src/vcore/Config.h [new file with mode: 0644]
vcore/src/vcore/CryptoHash.cpp [new file with mode: 0644]
vcore/src/vcore/CryptoHash.h [new file with mode: 0644]
vcore/src/vcore/Database.cpp [new file with mode: 0644]
vcore/src/vcore/Database.h [new file with mode: 0644]
vcore/src/vcore/DeveloperModeValidator.cpp [new file with mode: 0644]
vcore/src/vcore/DeveloperModeValidator.h [new file with mode: 0644]
vcore/src/vcore/IAbstractResponseCache.h [new file with mode: 0644]
vcore/src/vcore/OCSP.cpp [new file with mode: 0644]
vcore/src/vcore/OCSP.h [new file with mode: 0644]
vcore/src/vcore/OCSPCertMgrUtil.cpp [new file with mode: 0644]
vcore/src/vcore/OCSPCertMgrUtil.h [new file with mode: 0644]
vcore/src/vcore/OCSPImpl.cpp [new file with mode: 0644]
vcore/src/vcore/OCSPImpl.h [new file with mode: 0644]
vcore/src/vcore/OCSPUtil.c [new file with mode: 0644]
vcore/src/vcore/ParserSchema.h [new file with mode: 0644]
vcore/src/vcore/ReferenceValidator.cpp [new file with mode: 0644]
vcore/src/vcore/ReferenceValidator.h [new file with mode: 0644]
vcore/src/vcore/RevocationCheckerBase.cpp [new file with mode: 0644]
vcore/src/vcore/RevocationCheckerBase.h [new file with mode: 0644]
vcore/src/vcore/SSLContainers.h [new file with mode: 0644]
vcore/src/vcore/SaxReader.cpp [new file with mode: 0644]
vcore/src/vcore/SaxReader.h [new file with mode: 0644]
vcore/src/vcore/SignatureData.h [new file with mode: 0644]
vcore/src/vcore/SignatureFinder.cpp [new file with mode: 0644]
vcore/src/vcore/SignatureFinder.h [new file with mode: 0644]
vcore/src/vcore/SignatureReader.cpp [new file with mode: 0644]
vcore/src/vcore/SignatureReader.h [new file with mode: 0644]
vcore/src/vcore/SoupMessageSendAsync.cpp [new file with mode: 0644]
vcore/src/vcore/SoupMessageSendAsync.h [new file with mode: 0644]
vcore/src/vcore/SoupMessageSendBase.cpp [new file with mode: 0644]
vcore/src/vcore/SoupMessageSendBase.h [new file with mode: 0644]
vcore/src/vcore/SoupMessageSendSync.cpp [new file with mode: 0644]
vcore/src/vcore/SoupMessageSendSync.h [new file with mode: 0644]
vcore/src/vcore/TimeConversion.cpp [new file with mode: 0644]
vcore/src/vcore/TimeConversion.h [new file with mode: 0644]
vcore/src/vcore/VCore.cpp [new file with mode: 0644]
vcore/src/vcore/VCore.h [new file with mode: 0644]
vcore/src/vcore/VCorePrivate.h [new file with mode: 0644]
vcore/src/vcore/ValidatorCommon.h [new file with mode: 0644]
vcore/src/vcore/ValidatorFactories.cpp [new file with mode: 0644]
vcore/src/vcore/ValidatorFactories.h [new file with mode: 0644]
vcore/src/vcore/VerificationStatus.cpp [new file with mode: 0644]
vcore/src/vcore/VerificationStatus.h [new file with mode: 0644]
vcore/src/vcore/WacOrigin.cpp [new file with mode: 0644]
vcore/src/vcore/WacOrigin.h [new file with mode: 0644]
vcore/src/vcore/WrtSignatureValidator.cpp [new file with mode: 0644]
vcore/src/vcore/WrtSignatureValidator.h [new file with mode: 0644]
vcore/src/vcore/XmlsecAdapter.cpp [new file with mode: 0644]
vcore/src/vcore/XmlsecAdapter.h [new file with mode: 0644]
vcore/src/vcore/api.cpp [new file with mode: 0644]
vcore/src/vcore/pkcs12.c [new file with mode: 0644]
vcore/src/vcore/pkcs12.h [new file with mode: 0644]
vcore/src/vcore/scoped_gpointer.h [new file with mode: 0644]

index 3cbc2b1..900eae0 100644 (file)
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(certsvc C)
+PROJECT(certsvc)
 
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-SET(EXEC_PREFIX "\${prefix}")
-SET(LIBDIR "\${prefix}/lib")
-SET(INCLUDEDIR "\${prefix}/include")
-SET(VERSION_MAJOR 1)
-SET(VERSION "${VERSION_MAJOR}.0.0")
+INCLUDE(FindPkgConfig)
 
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+SET(SO_VERSION 1)
+SET(VERSION "${SO_VERSION}.0.0")
 
-INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED openssl dlog)
+# define debug output
+SET(DEBUG_OUTPUT "-DCERT_SVC_LOG")             # for debug
+#SET(DEBUG_OUTPUT "-DCERT_SVC_LOG_CONSOLE")     # for debug
 
-FOREACH(flag ${pkgs_CFLAGS})
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
+SET(TARGET_CERT_SVC_LIB "cert-svc")
+SET(TARGET_VCORE_LIB "cert-svc-vcore")
+SET(TARGET_SIGN_TOOL "dpkg-pki-sig")
 
-SET(source_dir "./srcs")
-SET(include_dir "./include")
+# compiler options
+SET(CMAKE_C_FLAGS_RELEASE "-fvisibility=hidden -Wall -O2")
+SET(CMAKE_CXX_FLAGS_RELEASE "-std=c++0x -Wall -O2")
 
-# About debug
-SET(debug "-DCERT_SVC_LOG")                    # for debug
-#SET(debug "-DCERT_SVC_LOG_CONSOLE")   # for debug
+SET(CMAKE_C_FLAGS_DEBUG "-fvisibility=hidden -Wall -O0 -g")
+SET(CMAKE_CXX_FLAGS_DEBUG "-std=c++0x -Wall -O0 -g")
 
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_CCOV "-fvisibility=hidden -Wall -O2 --coverage")
+SET(CMAKE_CXX_FLAGS_CCOV "-std=c++0x -Wall -O2 --coverage")
 
-###################################################################################################
+SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+SET(CMAKE_SKIP_RPATH "TRUE")
+
+################################################################################
 # for libcert-svc.so
-SET(libcert-svc_SOURCES 
-               ${source_dir}/cert-service.c 
-               ${source_dir}/cert-service-util.c 
-               ${source_dir}/cert-service-store.c 
-               ${source_dir}/cert-service-process.c )
-SET(libcert-svc_LDFLAGS " -module -avoid-version ${pkgs_LDFALGS} ")
-SET(libcert-svc_CFLAGS " ${CFLAGS} -fvisibility=hidden -g -fPIC -I${CMAKE_CURRENT_SOURCE_DIR}/include ${debug} ")
-SET(libcert-svc_CPPFLAGS " -DPIC ")
-
-ADD_LIBRARY(cert-svc SHARED ${libcert-svc_SOURCES})
-TARGET_LINK_LIBRARIES(cert-svc ${pkgs_LDFLAGS} -L${prefix}/lib -lpthread)
-SET_TARGET_PROPERTIES(cert-svc PROPERTIES COMPILE_FLAGS "${libcert-svc_CFLAGS} ${libcert-svc_CPPFLAGS}")
-SET_TARGET_PROPERTIES(cert-svc PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(cert-svc PROPERTIES VERSION ${VERSION})
-###################################################################################################
-
-###################################################################################################
+################################################################################
+
+PKG_CHECK_MODULES(CERT_SVC_DEPS
+    openssl
+    dlog
+    glib-2.0
+    REQUIRED
+)
+
+SET(CERT_SVC_SOURCES
+    ${PROJECT_SOURCE_DIR}/srcs/cert-service.c
+    ${PROJECT_SOURCE_DIR}/srcs/cert-service-util.c
+    ${PROJECT_SOURCE_DIR}/srcs/cert-service-store.c
+    ${PROJECT_SOURCE_DIR}/srcs/cert-service-process.c
+)
+
+IF(DEFINED DEBUG_OUTPUT)
+    SET_SOURCE_FILES_PROPERTIES(${CERT_SVC_SOURCES}
+        PROPERTIES COMPILE_FLAGS ${DEBUG_OUTPUT})
+ENDIF(DEFINED DEBUG_OUTPUT)
+
+INCLUDE_DIRECTORIES(
+    ${PROJECT_SOURCE_DIR}/include
+    ${CERT_SVC_DEPS_INCLUDE_DIRS}
+)
+
+ADD_LIBRARY(${TARGET_CERT_SVC_LIB} SHARED ${CERT_SVC_SOURCES})
+
+SET_TARGET_PROPERTIES(${TARGET_CERT_SVC_LIB} PROPERTIES
+    SOVERSION ${SO_VERSION}
+    VERSION ${VERSION}
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_CERT_SVC_LIB}
+    pthread
+    ${CERT_SVC_DEPS_LIBRARIES}
+)
+
+################################################################################
 # for dpkg-pki-sig
-SET(PackageSignVerify_SOURCES
-               ${source_dir}/dpkg-pki-sig.c
-               ${source_dir}/cert-service-util.c )
-SET(PackageSignVerify_CFLAGS " -fvisibility=hidden -I. -I${CMAKE_CURRENT_SOURCE_DIR}/include ${debug} ")
-SET(PackageSignVerify_LDFALGS " -module -avoid-version ${pkgs_LDFLAGS} ")
+################################################################################
+
+SET(SIGN_TOOL_SOURCES
+    ${PROJECT_SOURCE_DIR}/srcs/dpkg-pki-sig.c
+    ${PROJECT_SOURCE_DIR}/srcs/cert-service-process.c
+    ${PROJECT_SOURCE_DIR}/srcs/cert-service-util.c
+)
 
-ADD_EXECUTABLE(dpkg-pki-sig ${PackageSignVerify_SOURCES})
-TARGET_LINK_LIBRARIES(dpkg-pki-sig ${pkgs_LDFLAGS} cert-svc)
-SET_TARGET_PROPERTIES(dpkg-pki-sig PROPERTIES COMPILE_FLAGS "${PackageSignVerify_CFLAGS} ")
-###################################################################################################
+ADD_EXECUTABLE(${TARGET_SIGN_TOOL} ${SIGN_TOOL_SOURCES})
+
+TARGET_LINK_LIBRARIES(${TARGET_SIGN_TOOL}
+    ${TARGET_CERT_SVC_LIB}
+    ${CERT_SVC_DEPS_LIBRARIES}
+)
+
+################################################################################
 
 CONFIGURE_FILE(cert-svc.pc.in cert-svc.pc @ONLY)
+CONFIGURE_FILE(cert-svc-vcore.pc.in cert-svc-vcore.pc @ONLY)
+
+INSTALL(TARGETS ${TARGET_CERT_SVC_LIB} DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries)
+INSTALL(PROGRAMS ${TARGET_SIGN_TOOL} DESTINATION ${BINDIR})
+INSTALL(FILES
+    ${CMAKE_CURRENT_BINARY_DIR}/cert-svc.pc
+    ${CMAKE_CURRENT_BINARY_DIR}/cert-svc-vcore.pc
+    DESTINATION ${LIBDIR}/pkgconfig
+)
+INSTALL(FILES ${PROJECT_SOURCE_DIR}/targetinfo DESTINATION /opt/share/cert-svc/)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/cert-service.h DESTINATION ${INCLUDEDIR})
+
+# Now we must create empty directory for certificates.
+# Without this directories rpm package will fail during build.
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /usr/share/cert-svc/ca-certs/code-signing/native
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /usr/share/cert-svc/ca-certs/code-signing/wac
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/certs/code-signing/wac
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/certs/sim/operator
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/certs/sim/thirdparty
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/certs/user
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/certs/trusteduser
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/certs/mdm/security
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/certs/mdm/security/cert
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
+INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/etc/empty
+    DESTINATION /opt/share/cert-svc/pkcs12
+    FILES_MATCHING PATTERN THISPATTERNMUSTNOTMATCH
+)
 
-INSTALL(TARGETS cert-svc DESTINATION lib COMPONENT RuntimeLibraries)
-INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/dpkg-pki-sig DESTINATION bin)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/cert-svc.pc DESTINATION lib/pkgconfig)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/targetinfo DESTINATION /opt/share/cert-svc/)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/cert-service.h DESTINATION include)
+ADD_SUBDIRECTORY(vcore)
+ADD_SUBDIRECTORY(etc)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..a795f06
--- /dev/null
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   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.
+
diff --git a/NOTICE b/NOTICE
new file mode 100755 (executable)
index 0000000..0e0f016
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/build-stamp b/build-stamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/cert-svc-vcore.pc.in b/cert-svc-vcore.pc.in
new file mode 100644 (file)
index 0000000..bf42d5a
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@/cert-svc
+
+Name: cert-svc-vcore
+Description: cert-svc-vcore
+Version: @VERSION@
+Requires: cert-svc libxml-2.0 libxslt openssl libsoup-2.4 dpl-efl secure-storage xmlsec1
+Libs: -lcert-svc-vcore -L${libdir}
+Cflags: -I${includedir}
+
old mode 100644 (file)
new mode 100755 (executable)
index 37d341c..cf5f4e7
-cert-svc (1.0.1-17) unstable; urgency=low
+cert-svc (1.0.1-38) unstable; urgency=low
 
-  * add certificate store for MDM 
-  * Git: pkgs/c/cert-svc
-  * Tag: cert-svc_1.0.1-17
+  * Removed unused certificate files.
+  * Removed unused fingerprint_list files.
+  * Added Tizenmember domain.
+  * Refactored build script for cert-svc lib.
 
- -- Kidong Kim <kd0228.kim@samsung.com>  Thu, 02 Feb 2012 09:29:17 +0900
+  * Git : framework/security/cert-svc
 
-cert-svc (1.0.1-16) unstable; urgency=low
+ -- Bartlomiej Grzelewski <b.grzelewski@samsung.com>  Thu, 25 Oct 2012 11:12:00 +0100
 
-  * 11/12/21
-  *  - remove self-signed certificate from certificate chain
-  * Git: pkgs/c/cert-svc
-  * Tag: cert-svc_1.0.1-16
+cert-svc (1.0.1-37) unstable; urgency=low
 
- -- Kidong Kim <kd0228.kim@samsung.com>  Wed, 21 Dec 2011 10:06:41 +0900
+  * Fixed crash with adding pfx certificates to Microsoft Exchange account
+  * Fixed crash when cyclic directory structure detected
+  * License file copied to /usr/share/license/
+  * Added CryptoHash module to cert-svc-vcore
+  * Fixed CMakeLists.txt for proper permissions to SO file cert-svc-vcore
 
-cert-svc (1.0.1-15) unstable; urgency=low
+  * Git : framework/security/cert-svc
 
-  * 11/12/07
-  *  - add boiler-plate on testcases
-  * Git: pkgs/c/cert-svc
-  * Tag: cert-svc_1.0.1-15
+ -- Tomasz Swierczek <t.swierczek@samsung.com>  Fri, 19 Oct 2012 16:19:00 +0100
 
- -- Kidong Kim <kd0228.kim@samsung.com>  Wed, 07 Dec 2011 09:47:17 +0900
+cert-svc (1.0.1-36) unstable; urgency=low
+
+  * Added access to Email Address field in certificate
+  * Added tests for access to private keys for two distinct processes
+  * Added manifest for "define" section only
+  * Refactored vcore headers/api
+  * Changed location of symbolic link to openssl certificates
+
+  * Git : framework/security/cert-svc
+  * Tag : cert-svc_1.0.1-36
+
+ -- Tomasz Swierczek <t.swierczek@samsung.com>  Fri, 05 Oct 2012 17:03:00 +0100
+
+cert-svc (1.0.1-35) unstable; urgency=low
+
+  * Merged pkcs#12 tests cases made by Bartlomiej Grzelewski and Jacek Migacz. Some test cases were duplicated.
+  * Added creation of empty pkcs12 subfolder.
+
+  * Git : framework/security/cert-svc
+  * Tag : cert-svc_1.0.1-35
+
+ -- Tomasz Swierczek <t.swierczek@samsung.com>  Fri, 21 Sep 2012 12:13:00 +0200
+
+cert-svc (1.0.1-34) unstable; urgency=low
+
+  * Fixed loading container with intermediate certificates.
+
+  * Git : framework/security/cert-svc
+  * Tag : cert-svc_1.0.1-34
+
+ -- Tomasz Swierczek <t.swierczek@samsung.com>  Mon, 10 Sep 2012 14:15:00 +0200
+
+cert-svc (1.0.1-33) unstable; urgency=low
+
+   * Fixed issue while reading private key from PFX container
+   * Fixed segmentation fault while fetching certificates list from container w/o certificates
+
+  * Git : framework/security/cert-svc
+  * Tag : cert-svc_1.0.1-33
+
+ -- Tomasz Swierczek <t.swierczek@samsung.com>  Mon, 03 Sep 2012 14:22:00 +0200
+
+cert-svc (1.0.1-31) unstable; urgency=low
+
+  * Add dependencies to xmlsec1 and libxml-2.0.
+
+  * Git : framework/security/cert-svc
+  * Tag : cert-svc_1.0.1-31
+
+ -- Bartlomiej Grzelewski <b.grzelewski@samsung.com>  Thu, 17 Aug 2012 10:45:00 +0200
+
+cert-svc (1.0.1-30) unstable; urgency=low
+
+  * Remove UI from cert-svc repository.
+
+  * Git : slp/pkgs/c/cert-svc
+  * Tag : cert-svc_1.0.1-30
+
+ -- Bartlomiej Grzelewski <b.grzelewski@samsung.com>  Thu, 16 Aug 2012 16:25:00 +0200
+
+cert-svc (1.0.1-29) unstable; urgency=low
+
+  * Fixed cert-svc-vcore pc file
+
+  * Git : slp/pkgs/c/cert-svc
+  * Tag : cert-svc_1.0.1-29
+
+ -- Tomasz Swierczek <t.swierczek@samsung.com>  Tue, 14 Aug 2012 10:12:00 +0200
+
+
+cert-svc (1.0.1-28) unstable; urgency=low
+
+  * Remove "com.samsung" from source
+  * Add an "delete pkcs12/pfx" funcionality and screen to Cert UI
+  * Switch dependencies from ui-gadget to ui-gadget-1
+  * Link ubuntu certificates into cert-svc store.
+  * Fix api.
+
+  * Git : framework/security/cert-svc
+  * Tag : cert-svc_1.0.1-28
+
+ -- Tomasz Swierczek <t.swierczek@samsung.com>  Mon, 13 Aug 2012 18:51:00 +0200
diff --git a/debian/changelog.app b/debian/changelog.app
new file mode 100755 (executable)
index 0000000..bc77315
--- /dev/null
@@ -0,0 +1,6 @@
+mgr-app (0.0.1-1) unstable; urgency=low
+
+  * first source package for building
+
+ -- ManHyun Hwang <mh222.hwang@samsung.com>  Thu, 30 JUN 2011 13:43:34 +0900
+
diff --git a/debian/changelog.ug b/debian/changelog.ug
new file mode 100755 (executable)
index 0000000..a6205af
--- /dev/null
@@ -0,0 +1,6 @@
+libug-setting-manage-application-efl (0.0.1-1) unstable; urgency=low
+
+  * first source package for building
+
+ -- ManHyun Hwang <mh222.hwang@samsung.com>  Thu, 30 JUN 2011 13:43:34 +0900
+
diff --git a/debian/com.samsung.mgr-app-0.install.in b/debian/com.samsung.mgr-app-0.install.in
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/debian/com.samsung.mgr-app-dbg.install.in b/debian/com.samsung.mgr-app-dbg.install.in
new file mode 100755 (executable)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/debian/com.samsung.mgr-app.desktop.in b/debian/com.samsung.mgr-app.desktop.in
new file mode 100755 (executable)
index 0000000..8be86fa
--- /dev/null
@@ -0,0 +1,24 @@
+Name=manage application
+Exec=${PREFIX}/bin/mgr-app
+Hidden=False
+Version=@VERSION@
+Type=Application
+X-TIZEN-TaskManage=True
+X-TIZEN-Multiple=False
+
+Name[en_US]=manage application
+Name[nl_NL]=manage application
+Name[de_DE]=manage application
+Name[zh_HK]=manage application
+Name[zh_CN]=manage application
+Name[ru_RU]=manage application
+Name[ko_KR]=manage application
+Name[zh_TW]=manage application
+Name[ja_JP]=manage application
+Name[es_ES]=manage application
+Name[el_GR]=manage application
+Name[it_IT]=manage application
+Name[tr_TR]=manage application
+Name[pt_PT]=manage application
+Name[fr_FR]=manage application
+
diff --git a/debian/com.samsung.mgr-app.postinst.in b/debian/com.samsung.mgr-app.postinst.in
new file mode 100755 (executable)
index 0000000..8c57239
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# file owner
+if [ ${USER} == "root" ]
+then
+       echo "Test if"
+else
+       eche "Test else"
+fi
+
old mode 100644 (file)
new mode 100755 (executable)
index 7b97d80..a4d4ac5
@@ -2,25 +2,70 @@ Source: cert-svc
 Section: libs
 Priority: extra
 Maintainer: KiDong Kim <kd0228.kim@samsung.com>
-Uploaders: 
-Build-Depends: libssl-dev, dlog-dev, ca-certificates
-Standards-Version: 1.0.0
-Homepage: N/A
+Build-Depends: debhelper (>= 5),
+ libappcore-efl-dev,
+ autotools-dev,
+ libelm-dev,
+ libslp-setting-dev,
+ libui-gadget-dev,
+ libbundle-dev,
+ libaul-1-dev,
+ libefreet-dev,
+ libeina-dev,
+ shared-mime-info,
+# java-runtime-dev,
+ libail-0-dev,
+ libpkgmgr-client-dev,
+ libjava-parser-dev,
+ debhelper (>= 7.0.50), 
+ libssl-dev, 
+ dlog-dev, 
+ ca-certificates, 
+ wrt-commons-dev, 
+ libxmlsec1-dev, 
+ libsoup2.4-dev, 
+ libecore-dev, 
+ libxml2-dev, 
+ libpcre-dev, 
+ libslp-tapi-dev,
+ libappsvc-dev
 
-Package: libcert-svc-dev
+Package: libcert-svc1-ui
 Section: libs
 Architecture: any
-Depends: ${misc:Depends}, libcert-svc-0 (= ${Source-Version}), libssl-dev, dlog-dev
+Depends: ${shlibs:Depends}, ${misc:Depends}, libappsvc-dev
+Description: Manage Application package
+
+#Package: libug-setting-manage-application-efl-dbg
+#Section: debug
+#Architecture: any
+#Depends: ${shlibs:Depends}, ${misc:Depends}, libug-setting-manage-application-efl-0 (= ${binary:Version})
+#Description: Manage Application debug(unstripped) package
+
+Package: libcert-svc-dev
+Section: libdevel
+Architecture: any
+Depends: ${misc:Depends}, libcert-svc1 (= ${binary:Version}), libssl-dev, dlog-dev
 Description: Certification service development package
 
-Package: libcert-svc-0
+Package: libcert-svc1
 Section: libs
 Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
+Provides: libcert-svc-0
+Replaces: libcert-svc-0
+Depends: ${shlibs:Depends}, ${misc:Depends}, sqlite3
 Description: Certification service library and executable
 
-Package: libcert-svc-dbg
+Package: libcert-svc1-dbg
 Section: debug
 Architecture: any
-Depends: ${misc:Depends}, libcert-svc-0
+Provides: libcert-svc-dbg
+Replaces: libcert-svc-dbg
+Depends: ${misc:Depends}, libcert-svc1 (= ${binary:Version})
 Description: debug package of cert-svc library
+
+Package: libcert-svc1-test
+Section: libs
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}, libcert-svc1 (= ${binary:Version})
+Description: test program for cert-svc
diff --git a/debian/control.app b/debian/control.app
new file mode 100755 (executable)
index 0000000..b70bc27
--- /dev/null
@@ -0,0 +1,31 @@
+Source: mgr-app
+Section: libs
+Priority: extra
+Maintainer: SangJun Na <juni.na@samsung.com>, Manhyun Hwang <mh222.hwang@samsung.com>, Eunmi Son <eunmi.son@samsung.com>
+Build-Depends: debhelper (>= 5),
+ libappcore-efl-dev,
+ autotools-dev,
+ libelm-dev,
+ libslp-setting-dev,
+ libui-gadget-dev,
+ libbundle-dev,
+ libaul-1-dev,
+ libefreet-dev,
+ libeina-dev,
+ shared-mime-info,
+# java-runtime-dev,
+ libail-0-dev,
+ libpkgmgr-client-dev,
+ libjava-parser-dev
+
+Package: mgr-app-0
+Section: libs
+Architecture: armel
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Manage Application package
+
+Package: mgr-app-dbg
+Section: debug
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, mgr-app-0 (= ${binary:Version})
+Description: Manage Application debug(unstripped) package
diff --git a/debian/control.ug b/debian/control.ug
new file mode 100755 (executable)
index 0000000..2084fb5
--- /dev/null
@@ -0,0 +1,31 @@
+Source: libug-setting-manage-application-efl
+Section: libs
+Priority: extra
+Maintainer: SangJun Na <juni.na@samsung.com>, Manhyun Hwang <mh222.hwang@samsung.com>, Eunmi Son <eunmi.son@samsung.com>
+Build-Depends: debhelper (>= 5),
+ libappcore-efl-dev,
+ autotools-dev,
+ libelm-dev,
+ libslp-setting-dev,
+ libui-gadget-dev,
+ libbundle-dev,
+ libaul-1-dev,
+ libefreet-dev,
+ libeina-dev,
+ shared-mime-info,
+# java-runtime-dev,
+ libail-0-dev,
+ libpkgmgr-client-dev,
+ libjava-parser-dev
+
+Package: libug-setting-manage-application-efl-0
+Section: libs
+Architecture: armel
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Manage Application package
+
+Package: libug-setting-manage-application-efl-dbg
+Section: debug
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libug-setting-manage-application-efl-0 (= ${binary:Version})
+Description: Manage Application debug(unstripped) package
diff --git a/debian/libcert-svc-dev.install b/debian/libcert-svc-dev.install
new file mode 100644 (file)
index 0000000..a3d41f0
--- /dev/null
@@ -0,0 +1,3 @@
+/usr/include/*
+/usr/lib/pkgconfig/*
+/usr/lib/*.so
diff --git a/debian/libcert-svc1-test.install b/debian/libcert-svc1-test.install
new file mode 100644 (file)
index 0000000..f1becfa
--- /dev/null
@@ -0,0 +1,6 @@
+/usr/bin/cert-svc-test*
+/opt/apps/widget/tests/vcore_widget_uncompressed/*
+/opt/apps/widget/tests/vcore_keys/*
+/opt/apps/widget/tests/vcore_certs/*
+/opt/apps/widget/tests/pkcs12/*
+/opt/share/cert-svc/certs/code-signing/wac/root_cacert0.pem
diff --git a/debian/libcert-svc1-ui.install b/debian/libcert-svc1-ui.install
new file mode 100644 (file)
index 0000000..2b88b10
--- /dev/null
@@ -0,0 +1,7 @@
+/opt/ug/lib/libmgr-cert-common.so
+/opt/ug/lib/libmgr-cert-view.so
+/opt/ug/lib/libug-setting-manage-certificates-efl.so.*
+/opt/ug/lib/libug-setting-manage-certificates-efl.so
+/opt/ug/res/edje/ug-setting-manage-certificates-efl/
+/opt/ug/res/images/ug-setting-manage-certificates-efl/
+/opt/ug/res/locale/*/*/ug-setting-manage-certificates-efl.mo
diff --git a/debian/libcert-svc1.dirs b/debian/libcert-svc1.dirs
new file mode 100644 (file)
index 0000000..6fd0611
--- /dev/null
@@ -0,0 +1,15 @@
+/usr/share/cert-svc/ca-certs/code-signing/java/operator
+/usr/share/cert-svc/ca-certs/code-signing/java/manufacture
+/usr/share/cert-svc/ca-certs/code-signing/java/thirdparty
+/usr/share/cert-svc/ca-certs/code-signing/debian
+/usr/share/cert-svc/ca-certs/code-signing/wac
+/opt/share/cert-svc/certs/code-signing/java/operator
+/opt/share/cert-svc/certs/code-signing/java/manufacture
+/opt/share/cert-svc/certs/code-signing/java/thirdparty
+/opt/share/cert-svc/certs/code-signing/wac
+/opt/share/cert-svc/certs/sim/operator
+/opt/share/cert-svc/certs/sim/thirdparty
+/opt/share/cert-svc/certs/ssl
+/opt/share/cert-svc/certs/user
+/opt/share/cert-svc/certs/trusteduser
+/opt/share/cert-svc/certs/mdm/security/cert
diff --git a/debian/libcert-svc1.install b/debian/libcert-svc1.install
new file mode 100644 (file)
index 0000000..73f8c2f
--- /dev/null
@@ -0,0 +1,13 @@
+/usr/bin/cert_svc_create_clean_db.sh
+/usr/lib/*.so.*
+/usr/bin/dpkg-pki-sig
+/opt/share/cert-svc/targetinfo
+/usr/share/cert-svc/cert_svc_vcore_db.sql
+/usr/share/cert-svc/fingerprint_list.xml
+/usr/share/cert-svc/fingerprint_list.xsd
+/usr/share/cert-svc/schema.xsd
+/opt/share/cert-svc/certs/code-signing/wac/wac0.root.preproduction.pem
+/opt/share/cert-svc/certs/code-signing/wac/wac0.root.production.pem
+/opt/share/cert-svc/certs/code-signing/wac/wac0.publisherid.pem
+/opt/share/cert-svc/certs/code-signing/wac/tizen0.root.preproduction.cert.pem
+
diff --git a/debian/libcert-svc1.links b/debian/libcert-svc1.links
new file mode 100644 (file)
index 0000000..d422ef3
--- /dev/null
@@ -0,0 +1 @@
+/opt/etc/ssl/certs/ /usr/share/cert-svc/ca-certs/ssl
diff --git a/debian/libcert-svc1.postinst b/debian/libcert-svc1.postinst
new file mode 100755 (executable)
index 0000000..fef53d3
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh -e
+
+USE_CERT=6524
+
+case "$1" in
+    configure)
+    if [ `whoami` = "root" ]
+    then
+        chown -R root:${USE_CERT} /opt/share/cert-svc/certs/
+        chmod -R 0775 /opt/share/cert-svc/certs/
+    fi
+
+    if [ -z ${2} ]
+    then
+        echo "This is new install of wrt-security"
+        echo "Calling /usr/bin/cert_svc_create_clean_db.sh"
+        /usr/bin/cert_svc_create_clean_db.sh
+    else
+        # Find out old and new version of databases
+        VCORE_OLD_DB_VERSION=`sqlite3 /opt/dbspace/.cert_svc_vcore.db ".tables" | grep "DB_VERSION_"`
+        VCORE_NEW_DB_VERSION=`cat /usr/share/cert-svc/cert_svc_vcore_db.sql | tr '[:blank:]' '\n' | grep DB_VERSION_`
+        echo "OLD vcore database version ${VCORE_OLD_DB_VERSION}"
+        echo "NEW vcore database version ${VCORE_NEW_DB_VERSION}"
+
+        if [ ${VCORE_OLD_DB_VERSION} -a ${VCORE_NEW_DB_VERSION} ]
+        then
+            if [ ${VCORE_OLD_DB_VERSION} = ${VCORE_NEW_DB_VERSION} ]
+            then
+                echo "Equal database detected so db installation ignored"
+            else
+                echo "Calling /usr/bin/cert_svc_create_clean_db.sh"
+                /usr/bin/cert_svc_create_clean_db.sh
+            fi
+        else
+            echo "Calling /usr/bin/cert_svc_create_clean_db.sh"
+            /usr/bin/cert_svc_create_clean_db.sh
+        fi
+    fi
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
index b8bc22c..a9214ef 100755 (executable)
@@ -9,68 +9,75 @@
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
 
+ppTYPE ?= ugapp
+
 CFLAGS ?= -Wall -g
-CXXFLAGS ?=  -Wall -g
-LDFLAGS ?= 
-PREFIX ?= /usr
-DATADIR ?= /opt
+LDFLAGS ?=
+ifneq (,$(findstring app,$(TYPE)))
+               PKGNAME ?= mgr-app
+               PREFIX ?= /opt/apps/mgr-app
+               RESDIR ?= /opt/apps/mgr-app/res
+               DATADIR ?= /opt/apps/mgr-app/data
+else
+               PKGNAME ?= libug-setting-manage-certificates-efl
+               PREFIX ?= /opt/ug
+               RESDIR ?= /opt/ug/res
+               DATADIR ?= /opt/ug/res/etc
+endif
 
 ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-       CFLAGS += -O0
-       CXXFLAGS += -O0
+       CFLAGS += -O0 
+       BUILD_TYPE=Debug
 else
-       CFLAGS += -O2
-       CXXFLAGS += -O2
+       CFLAGS += -O2 
+       BUILD_TYPE=Release
 endif
 
 LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
 
+CMAKE_BUILD_DIR ?= $(CURDIR)/cmake_build_tmp
+CMAKE_CERT_SVC_BUILD_DIR ?= $(CURDIR)/library
+
+
 configure: configure-stamp
 configure-stamp:
        dh_testdir
        # Add here commands to configure the package.
-       CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX)
-
-       touch configure-stamp
+       cd $(CMAKE_CERT_SVC_BUILD_DIR) && cmake .
+       mkdir -p $(CMAKE_BUILD_DIR) && cd $(CMAKE_BUILD_DIR) && CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" cmake ../ui/ -DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_BUILD_TYPE="$(BUILD_TYPE)" -DPKGNAME="$(PKGNAME)" -DTYPE="$(TYPE)"
+       touch $(CMAKE_BUILD_DIR)/configure-stamp
+       touch $(CMAKE_CERT_SVC_BUILD_DIR)/configure-stamp
 
 build: build-stamp
-
-build-stamp: configure-stamp 
+build-stamp: configure-stamp
        dh_testdir
 
        # Add here commands to compile the package.
-       $(MAKE)
-       #docbook-to-man debian/wavplayer.sgml > wavplayer.1
-
-       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+       cd $(CMAKE_CERT_SVC_BUILD_DIR) && $(MAKE)
+       cd $(CMAKE_BUILD_DIR) && $(MAKE)
+    
+       for f in `find $(CURDIR)/debian/ -name "$(PREFIX)*.in"`; do \
                cat $$f > $${f%.in}; \
                sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+               sed -i -e "s#@RESDIR@#$(RESDIR)#g" $${f%.in}; \
                sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+               sed -i -e "s#@PKGNAME@#$(PKGNAME)#g" $${f%.in}; \
        done
 
-
-       touch $@
+       touch $(CMAKE_BUILD_DIR)/$@
+       touch $(CMAKE_CERT_SVC_BUILD_DIR)/$@
 
 clean:
        dh_testdir
        dh_testroot
        rm -f build-stamp configure-stamp
 
-       # Add here commands to clean up after the build process.
-       -$(MAKE) clean
-       rm -rf CMakeCache.txt
-       rm -rf CMakeFiles
-       rm -rf cmake_install.cmake
-       rm -rf Makefile
-       rm -rf install_manifest.txt
-       rm -rf *.so
-       rm -rf *.pc
-       rm -rf *.service
+    # Add here commands to clean up after the build process.
+       rm -rf $(CMAKE_BUILD_DIR)
 
        for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
                rm -f $${f%.in}; \
        done
-
        dh_clean
 
 install: build
@@ -79,8 +86,8 @@ install: build
        dh_clean -k 
        dh_installdirs
 
-       # Add here commands to install the package into debian/wavplayer.
-       $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+       cd $(CMAKE_BUILD_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+       cd $(CMAKE_CERT_SVC_BUILD_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
 
 
 # Build architecture-independent files here.
@@ -91,26 +98,26 @@ binary-indep: build install
 binary-arch: build install
        dh_testdir
        dh_testroot
-       dh_installchangelogs 
-       dh_installdocs
-       dh_installexamples
+       #dh_installchangelogs 
+       #dh_installdocs
+       #dh_installexamples
        dh_install --sourcedir=debian/tmp
-#      dh_installmenu
-#      dh_installdebconf       
-#      dh_installlogrotate
-#      dh_installemacsen
-#      dh_installpam
-#      dh_installmime
-#      dh_python
-#      dh_installinit
-#      dh_installcron
-#      dh_installinfo
+       #dh_installmenu
+       #dh_installdebconf   
+       #dh_installlogrotate
+       #dh_installemacsen
+       #dh_installpam
+       #dh_installmime
+       #dh_python
+       #dh_installinit
+       #dh_installcron
+       #dh_installinfo
        dh_installman
        dh_link
-       dh_strip --dbg-package=libcert-svc-dbg
+       #dh_strip --dbg-package=$(PKGNAME)-dbg
        dh_compress
        dh_fixperms
-#      dh_perl
+       #dh_perl
        dh_makeshlibs
        dh_installdeb
        dh_shlibdeps
@@ -120,3 +127,4 @@ binary-arch: build install
 
 binary: binary-indep binary-arch
 .PHONY: build clean binary-indep binary-arch binary install configure
+
diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d4b5e97
--- /dev/null
@@ -0,0 +1,6 @@
+SET(ETC_DIR ${PROJECT_SOURCE_DIR}/etc)
+
+INSTALL(FILES
+    ${ETC_DIR}/cert_svc_create_clean_db.sh
+    DESTINATION /usr/bin
+    )
diff --git a/etc/cert_svc_create_clean_db.sh b/etc/cert_svc_create_clean_db.sh
new file mode 100755 (executable)
index 0000000..241e05e
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+# 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.
+#
+for name in cert_svc_vcore
+do
+    rm -f /opt/dbspace/.$name.db
+    rm -f /opt/dbspace/.$name.db-journal
+    SQL="PRAGMA journal_mode = PERSIST;"
+    sqlite3 /opt/dbspace/.$name.db "$SQL"
+    SQL=".read /usr/share/cert-svc/"$name"_db.sql"
+    sqlite3 /opt/dbspace/.$name.db "$SQL"
+    touch /opt/dbspace/.$name.db-journal
+    chown root:6026 /opt/dbspace/.$name.db
+    chown root:6026 /opt/dbspace/.$name.db-journal
+    chmod 660 /opt/dbspace/.$name.db
+    chmod 660 /opt/dbspace/.$name.db-journal
+done
+
+
diff --git a/etc/empty/.gitignore b/etc/empty/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
index d085f51..81d58ff 100644 (file)
@@ -32,14 +32,17 @@ extern "C" {
 /* Variable definitions                                                          */
 /*********************************************************************************/
 
+struct cert_svc_inode_set;
+
 /*********************************************************************************/
 /* Variable definitions                                                          */
 /*********************************************************************************/
 int parse_name_fld_data(unsigned char* str, cert_svc_name_fld_data* fld);
 int parse_time_fld_data(unsigned char* before, unsigned char* after, cert_svc_validity_fld_data* fld);
 int search_data_field(search_field fldName, char* fldData, cert_svc_cert_descriptor* certDesc);
-int get_filelist_recur(char* dirName, cert_svc_filename_list* fileNames, int* fileNum);
-int get_all_certificates(cert_svc_filename_list* allCerts);
+int get_filelist_recur(char* dirName, cert_svc_filename_list* fileNames,
+        struct cert_svc_inode_set *visited);
+int get_all_certificates(cert_svc_filename_list** allCerts);
 
 int sort_cert_chain(cert_svc_linked_list** unsorted, cert_svc_linked_list** sorted);
 cert_svc_linked_list* find_issuer_from_list(cert_svc_linked_list* list, cert_svc_linked_list* p);
index 44cf2b3..b80b2c9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * certification service
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact: Kidong Kim <kd0228.kim@samsung.com>
  *
@@ -54,10 +54,10 @@ extern "C" {
 #define CERT_SVC_ERR_PERMISSION_DENIED -16
 #define CERT_SVC_ERR_IS_EXPIRED        -17
 /* default certificate file path */
-#define CERT_SVC_STORE_PATH    "/opt/share/cert-svc/certs/"
-#define CERT_SVC_STORE_PATH_DEFAULT    "/opt/share/cert-svc/certs/ssl/"
-#define CERT_SVC_SEARCH_PATH_RO        "/usr/share/cert-svc/ca-certs/"
-#define CERT_SVC_SEARCH_PATH_RW        "/opt/share/cert-svc/certs/"
+#define CERT_SVC_STORE_PATH         "/opt/share/cert-svc/certs/"
+#define CERT_SVC_STORE_PATH_DEFAULT "/opt/share/cert-svc/certs/ssl/"
+#define CERT_SVC_SEARCH_PATH_RO     "/usr/share/cert-svc/ca-certs/"
+#define CERT_SVC_SEARCH_PATH_RW     "/opt/share/cert-svc/certs/"
 
 /*********************************************************************************/
 /* Type definitions                                                              */
diff --git a/packaging/cert-svc.manifest b/packaging/cert-svc.manifest
new file mode 100644 (file)
index 0000000..ec63f04
--- /dev/null
@@ -0,0 +1,13 @@
+<manifest>
+       <define>
+               <domain name="cert-svc" />
+               <provide>
+                       <label name="cert-svc::private-key" />
+                       <label name="cert-svc::certs-sharing" />
+                       <label name="cert-svc::db" />
+               </provide>
+       </define>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
index 22ef4a9..ac5c5f8 100644 (file)
-Name:      cert-svc
-Summary:    Certification service 
-Version:    1.0.1
-Release:    0
-Group:      System/Libraries
-License:    Apache2.0
-Source0:    cert-svc-%{version}.tar.gz
-Requires(post): /sbin/ldconfig
+#sbs-git:slp/pkgs/c/cert-svc cert-svc 1.0.1 ad7eb7efcefb37b06017c69cb2fc44e6f7b6cab7
+Name:    cert-svc
+Summary: Certification service
+Version: 1.0.1
+Release: 45
+Group:   System/Libraries
+License: SAMSUNG
+Source0: %{name}-%{version}.tar.gz
+Source1: %{name}.manifest
+
+Requires(post):   /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 
 BuildRequires: cmake
-
-BuildRequires: pkgconfig(dnet)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(openssl)
-
+BuildRequires: pkgconfig(evas)
+BuildRequires: pkgconfig(dpl-efl)
+BuildRequires: pkgconfig(libsoup-2.4)
+BuildRequires: pkgconfig(libpcre)
+BuildRequires: pkgconfig(libpcrecpp)
+BuildRequires: pkgconfig(xmlsec1)
+BuildRequires: pkgconfig(secure-storage)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(libxml-2.0)
+BuildRequires: pkgconfig(libxslt)
+
+Provides: libcert-svc-vcore.so.1
 
 %description
-Certification service 
+Certification service
 
 
 %package devel
-Summary:    Download agent
+Summary:    Certification service (development files)
 Group:      Development/Libraries
 Requires:   %{name} = %{version}-%{release}
 
 %description devel
-Certification service  (developement files)
+Certification service (developement files)
 
 %prep
 %setup -q
 
-
 %build
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
-
-
+%{!?build_type:%define build_type "Release"}
+cmake . -DPREFIX=%{_prefix} \
+        -DEXEC_PREFIX=%{_exec_prefix} \
+        -DLIBDIR=%{_libdir} \
+        -DBINDIR=%{_bindir} \
+        -DINCLUDEDIR=%{_includedir} \
+        -DCMAKE_BUILD_TYPE=%{build_type}
 make %{?jobs:-j%jobs}
 
 %install
 rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
 %make_install
+install -D %{SOURCE1} %{buildroot}%{_datadir}/%{name}.manifest
+ln -sf /opt/etc/ssl/certs %{buildroot}/opt/share/cert-svc/certs/ssl
+touch %{buildroot}/opt/share/cert-svc/pkcs12/storage
+chmod 766 %{buildroot}/opt/share/cert-svc/pkcs12/storage
 
+%clean
+rm -rf %{buildroot}
 
-%post -p /sbin/ldconfig
-
-%postun -p /sbin/ldconfig
-
+%post
+/sbin/ldconfig
+if [ -z ${2} ]; then
+    echo "This is new install of wrt-security"
+    echo "Calling /usr/bin/cert_svc_create_clean_db.sh"
+    /usr/bin/cert_svc_create_clean_db.sh
+else
+    # Find out old and new version of databases
+    VCORE_OLD_DB_VERSION=`sqlite3 /opt/dbspace/.cert_svc_vcore.db ".tables" | grep "DB_VERSION_"`
+    VCORE_NEW_DB_VERSION=`cat /usr/share/cert-svc/cert_svc_vcore_db.sql | tr '[:blank:]' '\n' | grep DB_VERSION_`
+    echo "OLD vcore database version ${VCORE_OLD_DB_VERSION}"
+    echo "NEW vcore database version ${VCORE_NEW_DB_VERSION}"
+
+    if [ ${VCORE_OLD_DB_VERSION} -a ${VCORE_NEW_DB_VERSION} ]; then
+        if [ ${VCORE_OLD_DB_VERSION} = ${VCORE_NEW_DB_VERSION} ]; then
+            echo "Equal database detected so db installation ignored"
+        else
+            echo "Calling /usr/bin/cert_svc_create_clean_db.sh"
+            /usr/bin/cert_svc_create_clean_db.sh
+        fi
+    else
+        echo "Calling /usr/bin/cert_svc_create_clean_db.sh"
+        /usr/bin/cert_svc_create_clean_db.sh
+    fi
+fi
+
+%postun
+/sbin/ldconfig
 
 %files
 %defattr(-,root,root,-)
-/usr/bin/dpkg-pki-sig
+%manifest %{_datadir}/%{name}.manifest
+%attr(0755,root,root) %{_bindir}/cert_svc_create_clean_db.sh
+%{_libdir}/*.so.*
+%{_bindir}/dpkg-pki-sig
 /opt/share/cert-svc/targetinfo
-/usr/lib/libcert-svc.so.1
-/usr/lib/libcert-svc.so.1.0.0
+%{_datadir}/cert-svc/cert_svc_vcore_db.sql
+%{_datadir}/license/%{name}
+%dir %attr(0755,root,use_cert) /usr/share/cert-svc
+%dir %attr(0755,root,use_cert) /usr/share/cert-svc/ca-certs
+%dir %attr(0755,root,use_cert) /usr/share/cert-svc/ca-certs/code-signing
+%dir %attr(0755,root,use_cert) /usr/share/cert-svc/ca-certs/code-signing/native
+%dir %attr(0755,root,use_cert) /usr/share/cert-svc/ca-certs/code-signing/wac
+%dir %attr(0775,root,use_cert) /opt/share/cert-svc
+%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/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
+%dir %attr(0777,root,use_cert) /opt/share/cert-svc/certs/user
+%dir %attr(0777,root,use_cert) /opt/share/cert-svc/certs/trusteduser
+%dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/mdm
+%dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/mdm/security
+%dir %attr(0775,root,use_cert) /opt/share/cert-svc/certs/mdm/security/cert
+%dir %attr(0777,root,use_cert) /opt/share/cert-svc/pkcs12
+/opt/share/cert-svc/certs/ssl
+/opt/share/cert-svc/pkcs12/storage
 
 %files devel
 %defattr(-,root,root,-)
-/usr/lib/pkgconfig/cert-svc.pc
-/usr/lib/libcert-svc.so
-/usr/include/cert-service.h
-
-
+%{_includedir}/*
+%{_libdir}/pkgconfig/*
+%{_libdir}/*.so
index 5c78414..725f986 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * certification service
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact: Kidong Kim <kd0228.kim@samsung.com>
  *
@@ -25,6 +25,8 @@
 #include <dirent.h>
 #include <error.h>
 #include <sys/stat.h>
+#include <sys/types.h>
+#include <fts.h>
 
 #include <openssl/x509.h>
 
@@ -81,8 +83,12 @@ int parse_name_fld_data(unsigned char* str, cert_svc_name_fld_data* fld)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
        char **prev_field = NULL;
-       int i = 0, l;
-       memset(fld, 0, sizeof(fld));
+       int i = 0, l = 0;
+    if (fld == NULL) {
+        ret = CERT_SVC_ERR_INVALID_PARAMETER;
+        return ret;
+    }
+       memset(fld, 0, sizeof(cert_svc_name_fld_data));
        while (str[i] != '\0') {
                int tag_len;
                char **field = __get_field_by_tag(str + i, &tag_len, fld);
@@ -190,7 +196,6 @@ int _parse_name_fld_data(unsigned char* str, cert_svc_name_fld_data* fld)
        else
                (*fld).emailAddress = NULL;
 
-err:
        return ret;
 }
 
@@ -263,7 +268,7 @@ cert_svc_linked_list* find_issuer_from_list(cert_svc_linked_list* list, cert_svc
        for(q = list; q != NULL; q = q->next) {
                tmp2 = (cert_svc_cert_descriptor*)malloc(sizeof(cert_svc_cert_descriptor));
                memset(tmp2, 0x00, sizeof(cert_svc_cert_descriptor));
-       
+
                _extract_certificate_data(q->certificate, tmp2);
 
                if(!strncmp(tmp2->info.subjectStr, tmp1->info.issuerStr, strlen(tmp1->info.issuerStr))) {       // success
@@ -513,7 +518,7 @@ int _remove_selfsigned_cert_in_chain(cert_svc_linked_list** certList)
                        SLOGE("[ERR][%s] Fail to extract certificate data.\n", __func__);
                        goto err;
                }
-               
+
                if(!strncmp(certdesc->info.subjectStr, certdesc->info.issuerStr, strlen(certdesc->info.issuerStr))) { // self-signed
                        if(first_tag == 0) { // first cert is self-signed
                                start = start->next;
@@ -561,7 +566,6 @@ int _verify_certificate(cert_svc_mem_buff* certBuf, cert_svc_linked_list** certL
        cert_svc_cert_descriptor* findRoot = NULL;
        cert_svc_filename_list* fileNames = NULL;
        cert_svc_mem_buff* CACert = NULL;
-       int fileNum = 0;
        int isCA = -1, isExpired = -1;
        // variables for verification
        int certNum = 0;
@@ -602,7 +606,7 @@ int _verify_certificate(cert_svc_mem_buff* certBuf, cert_svc_linked_list** certL
 
                ret = _extract_certificate_data(p->certificate, findRoot);
        }
-       else 
+       else
                ret = _extract_certificate_data(certBuf, findRoot);
 
        if(ret != CERT_SVC_ERR_NO_ERROR) {
@@ -663,12 +667,12 @@ int _verify_certificate(cert_svc_mem_buff* certBuf, cert_svc_linked_list** certL
                ret = CERT_SVC_ERR_INVALID_OPERATION;
                goto err;
        }
-       
+
        certContent = certBuf->data;
        d2i_X509(&targetCert, &certContent, certBuf->size);
-       
+
        q = sorted; // first item is the certificate that user want to verify
-                       
+
        // insert all certificate(s) into chain
        if(q != NULL) { // has 2 or more certificates
                certIndex = 0;
@@ -769,7 +773,7 @@ int _verify_signature(cert_svc_mem_buff* certBuf, unsigned char* message, int ms
                ret = CERT_SVC_ERR_INVALID_CERTIFICATE;
                goto err;
        }
-       
+
        /* load signature and decode */
        sigLen = strlen(signature);
        decodedSigLen = ((sigLen / 4) * 3) + 1;
@@ -932,7 +936,7 @@ int _extract_certificate_data(cert_svc_mem_buff* cert, cert_svc_cert_descriptor*
        publicKeyAlgoLen = strlen(publicKeyAlgo);
        certDesc->info.pubKeyAlgo = (unsigned char*)malloc(sizeof(unsigned char) * (publicKeyAlgoLen + 1));
        memset(certDesc->info.pubKeyAlgo, 0x00, (publicKeyAlgoLen + 1));
-       memcpy(certDesc->info.pubKeyAlgo, publicKeyAlgo, publicKeyAlgoLen);     
+       memcpy(certDesc->info.pubKeyAlgo, publicKeyAlgo, publicKeyAlgoLen);
        /* get public key */
        if((evp = X509_get_pubkey(x)) == NULL) {
                SLOGE("[ERR][%s] Public key is null.\n", __func__);
@@ -951,7 +955,7 @@ int _extract_certificate_data(cert_svc_mem_buff* cert, cert_svc_cert_descriptor*
                memset(certDesc->info.issuerUID, 0x00, (issuerUidLen + 1));
                memcpy(certDesc->info.issuerUID, x->cert_info->issuerUID->data, issuerUidLen);
        }
-       else 
+       else
                certDesc->info.issuerUID = NULL;
 
        /* get subject UID */
@@ -961,7 +965,7 @@ int _extract_certificate_data(cert_svc_mem_buff* cert, cert_svc_cert_descriptor*
                memset(certDesc->info.subjectUID, 0x00, (subjectUidLen + 1));
                memcpy(certDesc->info.subjectUID, x->cert_info->subjectUID->data, subjectUidLen);
        }
-       else 
+       else
                certDesc->info.subjectUID = NULL;
        /* get extension fields */
        if(x->cert_info->extensions != NULL) {
@@ -977,7 +981,7 @@ int _extract_certificate_data(cert_svc_mem_buff* cert, cert_svc_cert_descriptor*
                                certDesc->ext.fields[i].name = (unsigned char*)malloc(sizeof(unsigned char) * (extObjLen + 1));
                                memset(certDesc->ext.fields[i].name, 0x00, (extObjLen + 1));
                                memcpy(certDesc->ext.fields[i].name, extObject, extObjLen);
-       
+
                                extValue = ext->value->data;
                                extValLen = ext->value->length;
                                certDesc->ext.fields[i].data = (unsigned char*)malloc(sizeof(unsigned char) * (extValLen + 1));
@@ -1014,93 +1018,6 @@ err:
        return ret;
 }
 
-int get_filelist_recur(char* dirName, cert_svc_filename_list* fileNames, int* fileNum)
-{
-       int ret = CERT_SVC_ERR_NO_ERROR;
-       struct dirent **items;
-       int nItems, i;
-       char tmpDirName[CERT_SVC_MAX_FILE_NAME_SIZE];
-       char tmpFileName[CERT_SVC_MAX_FILE_NAME_SIZE];
-       cert_svc_filename_list* new = NULL;
-       cert_svc_filename_list* p = NULL;
-
-       /* find file path with location */
-       if(chdir(dirName) < 0) {
-               SLOGE("[ERR][%s] Fail to open directory: [%s]\n", __func__, dirName);
-               perror("open dir");
-               ret = CERT_SVC_ERR_INVALID_OPERATION;
-               goto err;
-       }
-
-       /* get all items in current directory */
-       nItems = scandir(".", &items, NULL, alphasort);
-
-       for(i = 0; i < nItems; i++) {
-               struct stat fstat;
-               
-               // ignore current dir, parent dir
-               if(!strncmp(items[i]->d_name, ".", 1) || !strncmp(items[i]->d_name, "..", 2))
-                       continue;
-
-               // if directory, recursive call
-               stat(items[i]->d_name, &fstat);
-               if((fstat.st_mode & S_IFDIR) == S_IFDIR) {
-                       memset(tmpDirName, 0x00, CERT_SVC_MAX_FILE_NAME_SIZE);
-                       strncpy(tmpDirName, dirName, strlen(dirName));
-                       strncat(tmpDirName, items[i]->d_name, strlen(items[i]->d_name));
-                       strncat(tmpDirName, "/", 1);
-
-                       if((ret = get_filelist_recur(tmpDirName, fileNames, fileNum)) != CERT_SVC_ERR_NO_ERROR) {
-                               SLOGE("[ERR][%s] Fail to search file.\n", __func__);
-                               goto err;
-                       }
-                       continue;
-               }
-               else {  // if file, get filename into filelist
-                       memset(tmpFileName, 0x00, CERT_SVC_MAX_FILE_NAME_SIZE);
-                       strncpy(tmpFileName, dirName, strlen(dirName));
-                       strncat(tmpFileName, items[i]->d_name, strlen(items[i]->d_name));
-
-                       (*fileNum)++;
-                       p = fileNames;
-
-                       if(p->filename == NULL) {
-                               if(!(p->filename = (char*)malloc(sizeof(char) * CERT_SVC_MAX_FILE_NAME_SIZE))) {
-                                       SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
-                                       ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
-                                       goto err;
-                               }
-                               memset(p->filename, 0x00, CERT_SVC_MAX_FILE_NAME_SIZE);
-                               strncpy(p->filename, tmpFileName, strlen(tmpFileName));
-                               p->next = NULL;
-                       }
-                       else {
-                               while(p->next != NULL)
-                                       p = p->next;
-
-                               new = (cert_svc_filename_list*)malloc(sizeof(cert_svc_filename_list));
-                               memset(new, 0x00, sizeof(cert_svc_filename_list));
-                               new->filename = (char*)malloc(sizeof(char) * CERT_SVC_MAX_FILE_NAME_SIZE);
-                               memset(new->filename, 0x00, CERT_SVC_MAX_FILE_NAME_SIZE);
-
-                               strncpy(new->filename, tmpFileName, strlen(tmpFileName));
-                               new->next = NULL;
-                       
-                               p->next = new;
-                       }
-               }
-       }
-
-       chdir("..");
-
-err:
-       for(i = 0; i < nItems; i++)
-               free(items[i]);
-       free(items);
-
-       return ret;
-}
-
 int search_data_field(search_field fldName, char* fldData, cert_svc_cert_descriptor* certDesc)
 {
        int ret = -1;
@@ -1290,27 +1207,87 @@ int search_data_field(search_field fldName, char* fldData, cert_svc_cert_descrip
        return ret;
 }
 
-int get_all_certificates(cert_svc_filename_list* allCerts)
+int _get_all_certificates(char* const *paths, cert_svc_filename_list **lst) {
+    int ret = CERT_SVC_ERR_NO_ERROR;
+    FTS *fts = NULL;
+    FTSENT *ftsent;
+
+    char tmp[10];
+    int len;
+    cert_svc_filename_list *local = NULL;
+    cert_svc_filename_list *el;
+
+    if (NULL == (fts = fts_open(paths, FTS_LOGICAL, NULL))) {
+        ret = CERT_SVC_ERR_FILE_IO;
+        SLOGE("[ERR][%s] Fail to open directories.\n", __func__);
+        goto out;
+    }
+
+    while ((ftsent = fts_read(fts)) != NULL) {
+
+        if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
+            ret = CERT_SVC_ERR_FILE_IO;
+            SLOGE("[ERR][%s] Fail to read directories.\n", __func__);
+            goto out;
+        }
+
+        if (ftsent->fts_info != FTS_F)
+            continue;
+
+        if (-1 != readlink(ftsent->fts_path, tmp, 10))
+            continue;
+
+        el = (cert_svc_filename_list*)malloc(sizeof(cert_svc_filename_list));
+        if (!el) {
+            ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
+            SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
+            goto out;
+        }
+        el->next = local;
+        local = el;
+
+        len = strlen(ftsent->fts_path);
+        local->filename = (char*)malloc(len+1);
+        if (!local->filename) {
+            ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
+            SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
+            goto out;
+        }
+        strncpy(local->filename, ftsent->fts_path, len+1);
+    }
+
+    *lst = local;
+    local = NULL;
+
+out:
+    while (local) {
+        el = local;
+        local = local->next;
+        free(el->filename);
+        free(el);
+    }
+
+    if (fts != NULL)
+        fts_close(fts);
+    return ret;
+}
+
+int get_all_certificates(cert_svc_filename_list** allCerts)
 {
-       int ret = CERT_SVC_ERR_NO_ERROR;
-       int fileNum = 0;
-       char buf[1024] = {0, };
-       getcwd(buf, 1024);
+    int ret;
+    char ** buffer[] = {CERT_SVC_SEARCH_PATH_RO, CERT_SVC_SEARCH_PATH_RW, NULL};
 
-       if((ret = get_filelist_recur(CERT_SVC_SEARCH_PATH_RO, allCerts, &fileNum)) != CERT_SVC_ERR_NO_ERROR) {
-               SLOGE("[ERR][%s] Fail to get filelist.\n", __func__);
-               ret = CERT_SVC_ERR_INVALID_OPERATION;
-               goto err;
-       }
-       if((ret = get_filelist_recur(CERT_SVC_SEARCH_PATH_RW, allCerts, &fileNum)) != CERT_SVC_ERR_NO_ERROR) {
-               SLOGE("[ERR][%s] Fail to get filelist.\n", __func__);
-               ret = CERT_SVC_ERR_INVALID_OPERATION;
-               goto err;
-       }
+    if (!allCerts) {
+        SLOGE("[ERR][%s] Invalid argument.\n", __func__);
+        return CERT_SVC_ERR_INVALID_PARAMETER;
+    }
 
-err:
-       chdir(buf);
-       return ret;
+    if ((ret = _get_all_certificates((char* const *) buffer, allCerts)) != CERT_SVC_ERR_NO_ERROR) {
+        SLOGE("[ERR][%s] Fail to get filelist.\n", __func__);
+        return ret;
+    }
+
+    return CERT_SVC_ERR_NO_ERROR;
 }
 
 int _search_certificate(cert_svc_filename_list** fileNames, search_field fldName, char* fldData)
@@ -1325,16 +1302,7 @@ int _search_certificate(cert_svc_filename_list** fileNames, search_field fldName
        int matched = 0;
        struct stat file_info;
 
-       /* get all certificates from device */
-       if(!(allCerts = (cert_svc_filename_list*)malloc(sizeof(cert_svc_filename_list)))) {
-               SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
-               ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
-               goto err;
-       }
-       allCerts->filename = NULL;
-       allCerts->next = NULL;
-
-       if((ret = get_all_certificates(allCerts)) != CERT_SVC_ERR_NO_ERROR) {
+       if((ret = get_all_certificates(&allCerts)) != CERT_SVC_ERR_NO_ERROR) {
                SLOGE("[ERR][%s] Fail to get all certificate file list, ret: [%d]\n", __func__, ret);
                goto err;
        }
@@ -1344,7 +1312,7 @@ int _search_certificate(cert_svc_filename_list** fileNames, search_field fldName
 
        while(1) {
                if((lstat(p->filename, &file_info)) < 0) {      // get file information
-                       SLOGE("[ERR][%s] Fail to get file information.\n", __func__);
+                       SLOGE("[ERR][%s] Fail to get file(%s) information.\n", __func__, p->filename);
                        ret = CERT_SVC_ERR_INVALID_OPERATION;
                        goto err;
                }
@@ -1359,21 +1327,23 @@ int _search_certificate(cert_svc_filename_list** fileNames, search_field fldName
                        ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
                        goto err;
                }
-               if(!(certDesc = (cert_svc_cert_descriptor*)malloc(sizeof(cert_svc_cert_descriptor)))) {
-                       SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
-                       ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
-                       goto err;
-               }
 
-               // load content into descriptor buffer
+               // load content into buffer
                if((ret = cert_svc_util_load_file_to_buffer(p->filename, certBuf)) != CERT_SVC_ERR_NO_ERROR) {
                        SLOGE("[ERR][%s] Fail to load file to buffer, filename: [%s], ret: [%d]\n", __func__, p->filename, ret);
                        free(certBuf);
                        certBuf = NULL;
-                       free(certDesc);
-                       certDesc = NULL;
                        goto fail_to_load_file;
                }
+
+               // allocate memory
+               if(!(certDesc = (cert_svc_cert_descriptor*)malloc(sizeof(cert_svc_cert_descriptor)))) {
+                       SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
+                       ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
+                       goto err;
+               }
+
+               // load content into descriptor buffer
                if((ret = _extract_certificate_data(certBuf, certDesc)) != CERT_SVC_ERR_NO_ERROR) {
                        SLOGE("[ERR][%s] Fail to extract certificate data, filename: [%s], ret: [%d]\n", __func__, p->filename, ret);
                        goto fail_to_extract_file;
@@ -1391,10 +1361,11 @@ int _search_certificate(cert_svc_filename_list** fileNames, search_field fldName
                        if(!(new->filename = (char*)malloc(sizeof(char) * CERT_SVC_MAX_FILE_NAME_SIZE))) {
                                SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
                                ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
+                               free(new);
                                goto err;
                        }
                        memset(new->filename, 0x00, CERT_SVC_MAX_FILE_NAME_SIZE);
-               
+
                        strncpy(new->filename, p->filename, strlen(p->filename));
                        new->next = NULL;
 
@@ -1529,16 +1500,18 @@ int release_cert_list(cert_svc_linked_list* certList)
        while(1) {
                curCert = startCert;
                startCert = startCert->next;
-
-               if(curCert->certificate->data != NULL) {
-                       free(curCert->certificate->data);
-                       curCert->certificate->data = NULL;
-               }
+       
                if(curCert->certificate != NULL) {
+                       if(curCert->certificate->data != NULL) {
+                               free(curCert->certificate->data);
+                               curCert->certificate->data = NULL;
+                       }
                        free(curCert->certificate);
                        curCert->certificate = NULL;
                }
+
                curCert->next = NULL;
+
                if(curCert != NULL) {
                        free(curCert);
                        curCert = NULL;
index b992534..2c9aafe 100644 (file)
@@ -44,10 +44,10 @@ int get_file_full_path(char* originalName, const char* location, char* outBuf)
        memset(pathLocation, 0x00, CERT_SVC_MAX_FILE_NAME_SIZE);
 
        if(location == NULL)    // use default path
-               strncpy(buf, CERT_SVC_STORE_PATH_DEFAULT, strlen(CERT_SVC_STORE_PATH_DEFAULT));
+               strncpy(buf, CERT_SVC_STORE_PATH_DEFAULT, strlen(CERT_SVC_STORE_PATH_DEFAULT)+1);
        else {
                strncpy(pathLocation, location, strlen(location));
-               strncpy(buf, CERT_SVC_STORE_PATH, strlen(CERT_SVC_STORE_PATH));
+               strncpy(buf, CERT_SVC_STORE_PATH, strlen(CERT_SVC_STORE_PATH)+1);
                token = strtok(pathLocation, seps);
                while(token) {
                        strncat(buf, token, strlen(token));
index 5b2a157..6cc7a59 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * certification service
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved 
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact: Kidong Kim <kd0228.kim@samsung.com>
  *
 #include "cert-service.h"
 #include "cert-service-util.h"
 #include "cert-service-debug.h"
+#include "cert-service-process.h"
 
 #ifndef CERT_SVC_API
 #define CERT_SVC_API   __attribute__((visibility("default")))
 #endif
 
+#define CERT_BODY_PREFIX  "-----BEGIN CERTIFICATE-----"
+#define CERT_BODY_SUFIX   "-----END CERTIFICATE-----"
+#define ICERT_BODY_PREFIX "-----BEGIN TRUSTED CERTIFICATE-----"
+#define ICERT_BODY_SUFIX  "-----END TRUSTED CERTIFICATE-----"
+
 /* Tables for base64 operation */
 static const char base64Table[] = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', //  0 ~ 15
@@ -63,17 +69,34 @@ static int base64DecodeTable[256] = {
 int get_content_into_buf_PEM(unsigned char* content, cert_svc_mem_buff* cert)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
-       char* startPEM = "-----BEGIN CERTIFICATE-----";
-       char* endPEM = "-----END CERTIFICATE-----";
-       int size = 0;
+       char *startPEM, *endPEM;
+       long size = 0;
        char* original = NULL;
        char* decoded = NULL;
        int decodedSize = 0;
        int i = 0, j = 0;
 
-       startPEM = strstr((const char*)content, startPEM) + strlen(startPEM) + 1;
-       endPEM = strstr((const char*)content, endPEM) - 1;
-       size = (int)endPEM - (int)startPEM;
+        if(!content) {
+            ret = CERT_SVC_ERR_INVALID_PARAMETER;
+            goto err;
+        }
+        startPEM = strstr((const char *)content, CERT_BODY_PREFIX);
+        startPEM = (startPEM) ? startPEM + strlen(CERT_BODY_PREFIX) : NULL;
+        endPEM = strstr((const char *)content, CERT_BODY_SUFIX);
+        if(!startPEM || !endPEM) {
+            startPEM = strstr((const char *)content, ICERT_BODY_PREFIX);
+            startPEM = (startPEM) ? startPEM + strlen(ICERT_BODY_PREFIX) : NULL;
+            endPEM = strstr((const char *)content, ICERT_BODY_SUFIX);
+        }
+        if(!startPEM || !endPEM) {
+            ret = CERT_SVC_ERR_UNKNOWN_ERROR;
+            goto err;
+        }
+        else {
+            ++startPEM;
+            --endPEM;
+            size = (long)endPEM - (long)startPEM;
+        }
 
        if(!(original = (char*)malloc(sizeof(char) * (size + 1)))) {
                SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
@@ -81,8 +104,8 @@ int get_content_into_buf_PEM(unsigned char* content, cert_svc_mem_buff* cert)
                goto err;
        }
        memset(original, 0x00, (size + 1));
-       
-       for(i = 0; i < size; i++) {
+
+       for(i = 0, j = 0; i < size; i++) {
                if(startPEM[i] != '\n')
                        original[j++] = startPEM[i];
        }
@@ -98,17 +121,17 @@ int get_content_into_buf_PEM(unsigned char* content, cert_svc_mem_buff* cert)
        memset(decoded, 0x00, decodedSize);
        if((ret = cert_svc_util_base64_decode(original, size, decoded, &decodedSize)) != CERT_SVC_ERR_NO_ERROR) {
                SLOGE("[ERR][%s] Fail to base64 decode.\n", __func__);
+               free(decoded);
                ret = CERT_SVC_ERR_INVALID_OPERATION;
                goto err;
        }
 
        cert->data = (unsigned char*)decoded;
        cert->size = decodedSize;
-       
+
 err:
-       if(original != NULL)
-               free(original);
-       
+    if(original != NULL)
+        free(original);
        return ret;
 }
 
@@ -148,10 +171,53 @@ int cert_svc_util_get_file_size(const char* filepath, unsigned long int* length)
 err:
        if(fp_in != NULL)
                fclose(fp_in);
-       
+
        return ret;
 }
 
+/* The dark side of cert-svc. */
+int cert_svc_util_get_extension(const char* filePath, cert_svc_mem_buff* certBuf) {
+    int ret = CERT_SVC_ERR_NO_ERROR;
+    FILE *in = NULL;
+    X509 *x = NULL;
+
+    if ((in = fopen(filePath, "r")) == NULL) {
+        SLOGE("[ERR] Error opening file %s\n", filePath);
+        ret = CERT_SVC_ERR_FILE_IO;
+        goto end;
+    }
+
+    if ((x = PEM_read_X509(in, NULL, NULL, NULL)) != NULL) {
+        strncpy(certBuf->type, "PEM", sizeof(certBuf->type));
+        goto end;
+    }
+
+    fseek(in, 0L, SEEK_SET);
+
+    if ((x = PEM_read_X509_AUX(in, NULL, NULL, NULL)) != NULL) {
+        strncpy(certBuf->type, "PEM", sizeof(certBuf->type));
+        goto end;
+    }
+
+    fseek(in, 0L, SEEK_SET);
+
+    if ((x = d2i_X509_fp(in, NULL)) != NULL) {
+        strncpy(certBuf->type, "DER", sizeof(certBuf->type));
+        goto end;
+    }
+
+    SLOGE("[ERR] Unknown file type: %s\n", filePath);
+    ret = CERT_SVC_ERR_FILE_IO;
+
+end:
+    if (in && fclose(in)) {
+        SLOGE("[ERR] Fail in fclose.");
+        ret = CERT_SVC_ERR_FILE_IO;
+    }
+    X509_free(x);
+    return ret;
+}
+
 int cert_svc_util_load_file_to_buffer(const char* filePath, cert_svc_mem_buff* certBuf)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
@@ -176,57 +242,51 @@ int cert_svc_util_load_file_to_buffer(const char* filePath, cert_svc_mem_buff* c
                goto err;
        }
 
-       if(!(content = (unsigned char*)malloc(sizeof(unsigned char) * (unsigned int)fileSize))) {
+       if(!(content = (unsigned char*)malloc(sizeof(unsigned char) * (unsigned int)(fileSize + 1)))) {
                SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
                ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
                goto err;
        }
+    memset(content, 0x00, (fileSize + 1));  //ensuring that content[] will be NULL terminated
        if(fread(content, sizeof(unsigned char), fileSize, fp_in) != fileSize) {
                SLOGE("[ERR][%s] Fail to read file, [%s]\n", __func__, filePath);
                ret = CERT_SVC_ERR_FILE_IO;
                goto err;
        }
-       
+
        /* find out certificate type */
        memset(certBuf->type, 0x00, 4);
-       extension = filePath + (strlen(filePath) - 3);
-       if(!strncmp(extension, "pem", 3) || !strncmp(extension, "PEM", 3) ||
-                       !strncmp(extension, "cer", 3) || !strncmp(extension, "CER", 3) ||
-                       !strncmp(extension, "crt", 3) || !strncmp(extension, "CRT", 3))
-               strncpy(certBuf->type, "PEM", 3);
-       else if(!strncmp(extension, "der", 3) || !strncmp(extension, "DER", 3))
-               strncpy(certBuf->type, "DER", 3);
-       else {
-               SLOGE("[ERR][%s] Cannot get certificate type, [%s]\n", __func__, extension);
-               ret = CERT_SVC_ERR_INVALID_CERTIFICATE;
-               goto err;
-       }
-       
+    if (cert_svc_util_get_extension(filePath, certBuf) != CERT_SVC_ERR_NO_ERROR) {
+        SLOGE("[ERR] cert_svc_util_get_extension failed to identify %s\n", filePath);
+        ret = CERT_SVC_ERR_FILE_IO;
+        goto err;
+    }
+
        /* load file into buffer */
-       if(!strncmp(certBuf->type, "PEM", 3)) { // PEM format
+       if(!strncmp(certBuf->type, "PEM", sizeof(certBuf->type))) {     // PEM format
                if((ret = get_content_into_buf_PEM(content, certBuf)) != CERT_SVC_ERR_NO_ERROR) {
                        SLOGE("[ERR][%s] Fail to load file to buffer, [%s]\n", __func__, filePath);
                        goto err;
                }
        }
-       else if(!strncmp(certBuf->type, "DER", 3)) {    // DER format
+       else if(!strncmp(certBuf->type, "DER", sizeof(certBuf->type))) {        // DER format
                if((ret = get_content_into_buf_DER(content, certBuf)) != CERT_SVC_ERR_NO_ERROR) {
                        SLOGE("[ERR][%s] Fail to load file to buffer, [%s]\n", __func__, filePath);
                        goto err;
                }
        }
-       
+
 err:
        if(fp_in != NULL)
                fclose(fp_in);
 
        if(content != NULL)
                free(content);
-       
+
        return ret;
 }
 
-int push_cert_into_linked_list(cert_svc_linked_list* certLink, X509* popedCert)
+int push_cert_into_linked_list(cert_svc_linked_list** certLink, X509* popedCert)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
        cert_svc_linked_list* cur = NULL;
@@ -242,6 +302,7 @@ int push_cert_into_linked_list(cert_svc_linked_list* certLink, X509* popedCert)
        }
        if(!(new->certificate = (cert_svc_mem_buff*)malloc(sizeof(cert_svc_mem_buff)))) {
                SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
+               free(new);
                ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
                goto err;
        }
@@ -249,12 +310,14 @@ int push_cert_into_linked_list(cert_svc_linked_list* certLink, X509* popedCert)
        /* get certificate data and store in certLink */
        if((certLen = i2d_X509(popedCert, NULL)) < 0) {
                SLOGE("[ERR][%s] Fail to convert certificate.\n", __func__);
+               release_cert_list(new);
                ret = CERT_SVC_ERR_INVALID_OPERATION;
                goto err;
        }
        if(!(bufCert = (unsigned char*)malloc(sizeof(unsigned char) * certLen))) {
                SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
                ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
+               release_cert_list(new);
                goto err;
        }
        pCert = bufCert;
@@ -263,17 +326,14 @@ int push_cert_into_linked_list(cert_svc_linked_list* certLink, X509* popedCert)
        new->certificate->data = bufCert;
        new->certificate->size = certLen;
 
-       /* attach to linked list */
-       cur = certLink;
-       if(cur == NULL) {       // first item
-               cur = new;
+       if(NULL == *certLink) { // first item
+               *certLink = new;
        }
        else {
-               while(1) {
-                       if(cur->next == NULL)
-                               break;
+           /* attach to linked list */
+           cur = *certLink;
+               while(cur->next)
                        cur = cur->next;
-               }
                cur->next = new;
        }
 
@@ -313,7 +373,7 @@ int cert_svc_util_load_PFX_file_to_buffer(const char* filePath, cert_svc_mem_buf
                ret = CERT_SVC_ERR_INVALID_CERTIFICATE;
                goto err;
        }
-       
+
        /* parse PKCS#12 certificate */
        if((ret = PKCS12_parse(p12, passPhrase, &pkey, &cert, &ca)) != 1) {
                SLOGE("[ERR][%s] Fail to parse PKCS#12 certificate.\n", __func__);
@@ -323,8 +383,8 @@ int cert_svc_util_load_PFX_file_to_buffer(const char* filePath, cert_svc_mem_buf
        ret = CERT_SVC_ERR_NO_ERROR;
        /* find out certificate type */
        memset(certBuf->type, 0x00, 4);
-       strncpy(certBuf->type, "PFX", 3);
-       
+       strncpy(certBuf->type, "PFX", sizeof(certBuf->type));
+
        /* load certificate into buffer */
        if((certLen = i2d_X509(cert, NULL)) < 0) {
                SLOGE("[ERR][%s] Fail to convert certificate.\n", __func__);
@@ -367,7 +427,7 @@ int cert_svc_util_load_PFX_file_to_buffer(const char* filePath, cert_svc_mem_buf
                        goto err;
                }
        }
-       
+
 err:
        if(fp_in != NULL)
                fclose(fp_in);
@@ -380,7 +440,7 @@ err:
        if(ca != NULL)
                sk_X509_pop_free(ca, X509_free);
        EVP_cleanup();
-       
+
        return ret;
 }
 
@@ -390,7 +450,7 @@ int cert_svc_util_base64_encode(char* in, int inLen, char* out, int* outLen)
        int ret = CERT_SVC_ERR_NO_ERROR;
        int inputLen = 0, i = 0;
        char* cur = NULL;
-       
+
        if((in == NULL) || (inLen < 1)) {
                SLOGE("[ERR][%s] Check your parameter.\n", __func__);
                ret = CERT_SVC_ERR_INVALID_PARAMETER;
@@ -429,7 +489,7 @@ int cert_svc_util_base64_encode(char* in, int inLen, char* out, int* outLen)
        out[i] = '\0';
        (*outLen) = i;
 
-err:   
+err:
        return ret;
 }
 CERT_SVC_API
@@ -460,7 +520,7 @@ int cert_svc_util_base64_decode(char* in, int inLen, char* out, int* outLen)
                        else
                                tmpBuf[j] = base64DecodeTable[(int)cur[j]];
                }
-               
+
                out[i++] = ((tmpBuf[0] & 0x3f) << 2) + ((tmpBuf[1] & 0x30) >> 4);
                out[i++] = ((tmpBuf[1] & 0x0f) << 4) + ((tmpBuf[2] & 0x3c) >> 2);
                out[i++] = ((tmpBuf[2] & 0x03) << 6) + (tmpBuf[3] & 0x3f);
index 720d7df..7337034 100644 (file)
@@ -96,7 +96,6 @@ CERT_SVC_API
 int cert_svc_verify_certificate(CERT_CONTEXT* ctx, int* validity)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
-       int i = 0, first = 0;
 
        if((ctx == NULL) || (ctx->certBuf == NULL)) {
                SLOGE("[ERR][%s] Check your parameter. Cannot find certificate.\n", __func__);
@@ -143,7 +142,6 @@ CERT_SVC_API
 int cert_svc_verify_signature(CERT_CONTEXT* ctx, unsigned char* message, int msgLen, unsigned char* signature, char* algo, int* validity)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
-       cert_svc_mem_buff* certBuf = NULL;
 
        if((message == NULL) || (signature == NULL) || (ctx == NULL) || (ctx->certBuf == NULL)) {
                SLOGE("[ERR][%s] Invalid parameter, please check your parameter\n", __func__);
@@ -208,7 +206,6 @@ CERT_SVC_API
 int cert_svc_search_certificate(CERT_CONTEXT* ctx, search_field fldName, char* fldData)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
-       int i = 0;
 
        /* check parameter */
        if((ctx == NULL) || (fldName < SEARCH_FIELD_START ) || (fldName > SEARCH_FIELD_END) || (fldData == NULL)) {
@@ -238,7 +235,6 @@ err:
 CERT_SVC_API
 CERT_CONTEXT* cert_svc_cert_context_init()
 {
-       int ret = CERT_SVC_ERR_NO_ERROR;
        CERT_CONTEXT* ctx = NULL;
 
        if(!(ctx = (CERT_CONTEXT*)malloc(sizeof(CERT_CONTEXT)))) {
@@ -260,8 +256,6 @@ CERT_SVC_API
 int cert_svc_cert_context_final(CERT_CONTEXT* context)
 {
        int ret = CERT_SVC_ERR_NO_ERROR;
-       cert_svc_linked_list* pLink = NULL;
-       cert_svc_filename_list* pFile = NULL;
 
        if(context == NULL)     // already be freed
                goto err;
@@ -330,6 +324,7 @@ int cert_svc_load_buf_to_context(CERT_CONTEXT* ctx, unsigned char* buf)
        if((ret = cert_svc_util_base64_decode(buf, size, decodedStr, &decodedSize)) != CERT_SVC_ERR_NO_ERROR) {
                SLOGE("[ERR][%s] Fail to decode string, ret: [%d]\n", __func__, ret);
                ret = CERT_SVC_ERR_INVALID_OPERATION;
+               free(decodedStr);
                goto err;
        }
 
@@ -405,6 +400,7 @@ int cert_svc_push_buf_into_context(CERT_CONTEXT *ctx, unsigned char* buf)
        }
        if(!(new->certificate = (cert_svc_mem_buff*)malloc(sizeof(cert_svc_mem_buff)))) {
                SLOGE("[ERR][%s] Fail to allcate memory.\n", __func__);
+               free(new);
                ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
                goto err;
        }
@@ -415,6 +411,7 @@ int cert_svc_push_buf_into_context(CERT_CONTEXT *ctx, unsigned char* buf)
 
        if(!(decodedStr = (char*)malloc(sizeof(char) * decodedSize))) {
                SLOGE("[ERR][%s] Fail to allocate memory.\n", __func__);
+               release_cert_list(new);
                ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
                goto err;
        }
@@ -422,6 +419,8 @@ int cert_svc_push_buf_into_context(CERT_CONTEXT *ctx, unsigned char* buf)
        /* decode */
        if((ret = cert_svc_util_base64_decode(buf, size, decodedStr, &decodedSize)) != CERT_SVC_ERR_NO_ERROR) {
                SLOGE("[ERR][%s] Fail to decode string, ret: [%d]\n", __func__, ret);
+               release_cert_list(new);
+               free(decodedStr);
                ret = CERT_SVC_ERR_INVALID_OPERATION;
                goto err;
        }
@@ -436,12 +435,8 @@ int cert_svc_push_buf_into_context(CERT_CONTEXT *ctx, unsigned char* buf)
                ctx->certLink = new;
        else {
                cur = ctx->certLink;
-               while(1) {
-                       if(cur->next == NULL)
-                               break;
+               while(cur->next)
                        cur = cur->next;
-               }
-
                cur->next = new;
        }
        
@@ -475,6 +470,7 @@ int cert_svc_push_file_into_context(CERT_CONTEXT *ctx, const char* filePath)
        if(!(new->certificate = (cert_svc_mem_buff*)malloc(sizeof(cert_svc_mem_buff)))) {
                SLOGE("[ERR][%s] Fail to allcate memory.\n", __func__);
                ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
+               free(new);
                goto err;
        }
        memset(new->certificate, 0x00, sizeof(cert_svc_mem_buff));
@@ -482,6 +478,7 @@ int cert_svc_push_file_into_context(CERT_CONTEXT *ctx, const char* filePath)
        /* get content to ctx->certBuf */
        if((ret = cert_svc_util_load_file_to_buffer(filePath, new->certificate)) != CERT_SVC_ERR_NO_ERROR) {
                SLOGE("[ERR][%s] Fail to load file, filepath: [%s], ret: [%d]\n", __func__, filePath, ret);
+               release_cert_list(new);
                ret = CERT_SVC_ERR_INVALID_OPERATION;
                goto err;
        }
index 7b56937..1d3906f 100644 (file)
@@ -26,6 +26,7 @@
 #include <time.h>
 #include <dirent.h>
 #include <error.h>
+#include <limits.h>
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -96,9 +97,9 @@ int delete_directory(const char* path)
 
        if(rmdir(path) != 0) {
                fprintf(stderr, "[ERR][%s] Fail to remove directory, [%s]\n", __func__, path);
-               ret = DPS_FILE_ERR;
-               goto err;
-       }
+           ret = DPS_FILE_ERR;
+        goto err;
+    }
                        
 err:
        if(dir != NULL) closedir(dir);
@@ -115,14 +116,21 @@ int get_files_from_deb(FILE* fp_deb)
        FILE* fp_control = NULL;
        FILE* fp_data = NULL;
        FILE* fp_sig = NULL;
-       char tempbuf[64];
-       char filename[16];
-       char filelen[10];
+       /* size+1 for null termination */
+       char tempbuf[65];
+       char filename[17];
+       char filelen[11];
        char* buf = NULL;
 
-       memset(tempbuf, 0x00, 64);
-       memset(filename, 0x00, 16);
-       memset(filelen, 0x00, 10);
+    if (fp_deb == NULL) {
+               fprintf(stderr, "[ERR] Null file pointer passed to function\n");
+               ret = DPS_FILE_ERR;
+        return ret;
+    }
+
+       memset(tempbuf, 0x00, 65);
+       memset(filename, 0x00, 17);
+       memset(filelen, 0x00, 11);
 
        if(!(fp_control = fopen("./temp/control.tar.gz", "wb"))) {
                fprintf(stderr, "[ERR][%s] Fail to open file, [control.tar.gz]\n", __func__);
@@ -142,15 +150,21 @@ int get_files_from_deb(FILE* fp_deb)
 
        while(fgets(tempbuf, 64, fp_deb)) {
                strncpy(filename, tempbuf, 16);
-               if(memcmp(filename, "!<arch>\n", 8) == 0)
+               if(memcmp(filename, "!<arch>\n", 8) == 0) {
+                       memset(tempbuf, 0x00, 65);
                        continue;
+               }
                if((memcmp(filename, "control.tar.gz", 14) == 0) ||
                                (memcmp(filename, "data.tar.gz", 11) == 0) ||
                                (memcmp(filename, "_sigandcert", 11) == 0)
                                ) {
                        strncpy(filelen, tempbuf + 48, 10);
                        size = strtoul(filelen, NULL, 10);
-                       
+                       if((int)size <= 0) {
+                               fprintf(stderr, "[ERR][%s] Fail to get filelen\n", __func__);
+                               ret = DPS_FILE_ERR;
+                               goto err;
+                       }
                        if(!(buf = (char*)malloc(sizeof(char) * (int)size))) {
                                fprintf(stderr, "[ERR][%s] Fail to allocate memory\n", __func__);
                                ret = DPS_MEMORY_ERR;
@@ -226,7 +240,11 @@ int sha256_hashing_file(FILE* fp_file, char* out)
        int ret = DPS_OPERATION_SUCCESS;
        
        fseek(fp_file, 0L, SEEK_END);
-       filelen = ftell(fp_file);
+       if (-1 == (filelen = ftell(fp_file))) {
+               fprintf(stderr, "[ERR] Error returned by ftell()");
+               ret = DPS_FILE_ERR;
+               goto err;
+    }
        fseek(fp_file, 0L, SEEK_SET);
 
        if(!(in = (char*)malloc(sizeof(char) * (filelen + 1)))) {
@@ -260,7 +278,7 @@ int sha256_hashing_file(FILE* fp_file, char* out)
 err:
        if(in != NULL) free(in);
        if(hashout != NULL) free(hashout);
-       
+
        return ret;
 }
 
@@ -271,20 +289,18 @@ int get_target_info(char* info)
        char* token = NULL;
        char seps[] = " \t\n\r";
        char buf[16];
-       int ret = DPS_OPERATION_SUCCESS;
 
        memset(buf, 0x00, 16);
 
        if(!(fp_info = fopen(TARGET_INFO, "r"))) {      // error
                fprintf(stderr, "[ERR][%s] Fail to open file, [%s]\n", __func__, TARGET_INFO);
-               ret = DPS_FILE_ERR;
-               goto err;
+               return DPS_FILE_ERR;
        }
 
        fgets(buf, 16, fp_info);
        if(buf[0] == '0') {     // not used
                // do nothing
-               strncpy(info, "NOT USED", 8);
+               strncpy(info, "NOT USED", sizeof("NOT USED"));
        }
        else if(buf[0] == '1') {
                memset(buf, 0x00, 16);
@@ -293,12 +309,12 @@ int get_target_info(char* info)
        }
        else {
                fprintf(stderr, "[ERR][%s] Check your targetinfo file.\n", __func__);
-               ret = DPS_INVALID_OPERATION;
-               goto err;
+                fclose(fp_info);
+               return DPS_INVALID_OPERATION;
        }
 
-err:
-       return ret;
+        fclose(fp_info);
+       return DPS_OPERATION_SUCCESS;
 }
 
 int generate_sdk_cert(int argc, const char** argv)
@@ -358,7 +374,7 @@ int package_sign(int argc, const char** argv)
        int ret = DPS_OPERATION_SUCCESS;
        int ch = 0, i = 0;
        int certwrite = 0;
-       unsigned long int privlen = 0;
+       unsigned long int  privlen = 0;
        unsigned long int encodedlen = 0;
        unsigned long int certlen = 0;
        unsigned long int sigfilelen = 0;
@@ -488,6 +504,12 @@ int package_sign(int argc, const char** argv)
        privlen = ftell(fp_priv);
        fseek(fp_priv, 0L, SEEK_SET);
 
+       if((int)privlen <= 0){
+               fprintf(stderr, "[ERR][%s] Fail to get file lengh\n", __func__);
+               ret = DPS_FILE_ERR;
+               goto err;
+       }
+
        if(!(prikey = (char*)malloc(sizeof(char) * (int)privlen))) {
                fprintf(stderr, "[ERR][%s] Fail to allocate memory\n", __func__);
                ret = DPS_FILE_ERR;
@@ -573,7 +595,15 @@ int package_sign(int argc, const char** argv)
                ret = DPS_FILE_ERR;
                goto err;
        }
+
        fseek(fp_cert, 0L, SEEK_END);
+
+       if(ftell(fp_cert) < 0) {
+               fprintf(stderr, "[ERR][%s] Fail to find EOF\n", __func__);
+               ret = DPS_FILE_ERR;
+               goto err;
+       }
+
        certlen = ftell(fp_cert);
        fseek(fp_cert, 0L, SEEK_SET);
 
@@ -605,7 +635,12 @@ int package_sign(int argc, const char** argv)
        }
 
        /* insert file into deb archive */
-       sigfilelen = ftell(fp_sig);
+    if (-1 == (sigfilelen = ftell(fp_sig))) {
+        fprintf(stderr, "[ERR] Failed to get filesize by ftell()\n");
+        ret = DPS_FILE_ERR;
+        goto err;
+    }
+
        fseek(fp_sig, 0L, SEEK_SET);
        fseek(fp_deb, 0L, SEEK_END);
 
@@ -693,62 +728,96 @@ int package_verify(int argc, const char** argv)
                fprintf(stderr, "[ERR][%s] Fail to make temporary directory, [%s]\n", __func__, "./temp");
                ret = DPS_INVALID_OPERATION;
                goto err;
-       }       
-       
+       }
+
        /* extract files from .deb */
        if((fp_deb = fopen(argv[0], "rb")) == NULL) {
                fprintf(stderr, "[ERR][%s] Fail to open file. [%s]\n", __func__, argv[0]);
                ret = DPS_FILE_ERR;
                goto err;
        }
-       
+
        if((ret = get_files_from_deb(fp_deb)) != DPS_OPERATION_SUCCESS) {
                fprintf(stderr, "[ERR][%s] Fail to extract files.\n", __func__);
                goto err;
        }
-       
+
        /* get msg, sig, cert from_sigandcert */
        if((fp_sig = fopen("./temp/_sigandcert", "r")) == NULL) {
                fprintf(stderr, "[ERR][%s] Fail to open file. [_sigandcert]\n", __func__);
                ret = DPS_FILE_ERR;
                goto err;
        }
-       
+
        memset(filebuf, 0x00, 64);
        while(fgets(filebuf, 64, fp_sig) != NULL) {
-               if(!strncmp(filebuf, "MESSAGES:", 9)) {
-                       fgets(filebuf, 64, fp_sig);
-                       msglen = (int)strtoul(filebuf, NULL, 10);
-                       msg = (char*)malloc(sizeof(char) * (msglen + 1));
-                       memset(msg, 0x00, (msglen + 1));
-                       if(fread(msg, sizeof(char), msglen, fp_sig) != msglen) {
-                               fprintf(stderr, "[ERR][%s] Fail to get contents from file, [messages]\n", __func__); 
-                               ret = DPS_INVALID_OPERATION;
-                               goto err;
-                       }
-               }
-               else if(!strncmp(filebuf, "SIGNATURE:", 10)) {
-                       fgets(filebuf, 64, fp_sig);
-                       siglen = (int)strtoul(filebuf, NULL, 10);
-                       sig = (char*)malloc(sizeof(char) * (siglen + 1));
-                       memset(sig, 0x00, (siglen + 1));
-                       if(fread(sig, sizeof(char), siglen, fp_sig) != siglen) {
-                               fprintf(stderr, "[ERR][%s] Fail to get contents from file, [signature]\n", __func__); 
-                               ret = DPS_INVALID_OPERATION;
-                               goto err;
-                       }
-               }
-               else if(!strncmp(filebuf, "CERTIFICATE:", 12)) {
-                       fgets(filebuf, 64, fp_sig);
-                       certlen = (int)strtoul(filebuf, NULL, 10);
-                       cert = (char*)malloc(sizeof(char) * (certlen + 1));
-                       memset(cert, 0x00, (certlen + 1));
-                       if(fread(cert, sizeof(char), certlen, fp_sig) != certlen) {
-                               fprintf(stderr, "[ERR][%s] Fail to get contents from file, [certificate]\n", __func__); 
-                               ret = DPS_INVALID_OPERATION;
-                               goto err;
-                       }
-               }
+        if(!strncmp(filebuf, "MESSAGES:", 9)) {
+            fgets(filebuf, 64, fp_sig);
+            msglen = (int)strtoul(filebuf, NULL, 10);
+            if ((msglen < 1) || (msglen >= INT_MAX)) {
+                fprintf(stderr, "[ERR][%s] Fail to get length of certificate\n", __func__);
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+
+            msg = (char*)malloc(sizeof(char) * (msglen + 1));
+            if(!msg){
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+
+            memset(msg, 0x00, (msglen + 1));
+            if(fread(msg, sizeof(char), msglen, fp_sig) != msglen) {
+                fprintf(stderr, "[ERR][%s] Fail to get contents from file, [messages]\n", __func__); 
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+
+            free(msg);
+            msg = NULL;
+        }
+        else if(!strncmp(filebuf, "SIGNATURE:", 10)) {
+            fgets(filebuf, 64, fp_sig);
+            siglen = (int)strtoul(filebuf, NULL, 10);
+            if ((siglen < 1) || (siglen >= INT_MAX)) {
+                fprintf(stderr, "[ERR][%s] Fail to get length of certificate\n", __func__);
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+            sig = (char*)malloc(sizeof(char) * (siglen + 1));
+            if(!sig){
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+
+            memset(sig, 0x00, (siglen + 1));
+            if(fread(sig, sizeof(char), siglen, fp_sig) != siglen) {
+                fprintf(stderr, "[ERR][%s] Fail to get contents from file, [signature]\n", __func__); 
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+
+            free(sig);
+            sig = NULL;
+        }
+        else if(!strncmp(filebuf, "CERTIFICATE:", 12)) {
+            fgets(filebuf, 64, fp_sig);
+            certlen = (int)strtoul(filebuf, NULL, 10);
+            if ((certlen < 1) || (certlen >= INT_MAX)) {
+                fprintf(stderr, "[ERR][%s] Fail to get length of certificate\n", __func__);
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+            cert = (char*)malloc(sizeof(char) * (certlen + 1));
+            memset(cert, 0x00, (certlen + 1));
+            if(fread(cert, sizeof(char), certlen, fp_sig) != certlen) {
+                fprintf(stderr, "[ERR][%s] Fail to get contents from file, [certificate]\n", __func__); 
+                ret = DPS_INVALID_OPERATION;
+                goto err;
+            }
+            free(cert);
+            cert = NULL;
+        }
        }
 
        /* get certificate data */
@@ -788,7 +857,7 @@ int package_verify(int argc, const char** argv)
                        }
                }
        }
-       
+
        /* verify certificate */
        if((ret = cert_svc_verify_certificate(ctx, &val_cert)) != CERT_SVC_ERR_NO_ERROR) {
                fprintf(stderr, "[ERR][%s] Fail to verify certificate, [%d]\n", __func__, ret);
@@ -828,10 +897,10 @@ err:
        if(msg != NULL) free(msg);
        if(sig != NULL) free(sig);
        if(cert != NULL) free(cert);
-       if(target_info != NULL) free(target_info);
+       if(target_info != NULL) free(target_info);
 
        cert_svc_cert_context_final(ctx);
-       
+
        return ret;
 }
 
diff --git a/vcore/CMakeLists.txt b/vcore/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4fdf270
--- /dev/null
@@ -0,0 +1,36 @@
+#DB vcore
+PKG_CHECK_MODULES(VCORE_DB_DEP
+    dpl-efl
+    REQUIRED)
+
+ADD_CUSTOM_COMMAND(
+    OUTPUT ${CMAKE_BINARY_DIR}/vcore/src/database_checksum_vcore.h
+    COMMAND ${CMAKE_SOURCE_DIR}/vcore/src/orm/gen_db_md5.sh
+    ARGS ${CMAKE_BINARY_DIR}/vcore/src/database_checksum_vcore.h
+         ${CMAKE_SOURCE_DIR}/vcore/src/orm/vcore_db
+    DEPENDS ${CMAKE_SOURCE_DIR}/vcore/src/orm/vcore_db
+            ${CMAKE_SOURCE_DIR}/vcore/src/orm/gen_db_md5.sh
+    COMMENT "Generating VCORE database checksum"
+    )
+
+STRING(REPLACE ";" ":" DEPENDENCIES "${VCORE_DB_DEP_INCLUDE_DIRS}")
+
+ADD_CUSTOM_COMMAND( OUTPUT .cert_svc_vcore.db
+  COMMAND rm -f ${CMAKE_CURRENT_BINARY_DIR}/.cert_svc_vcore.db
+  COMMAND CPATH=${DEPENDENCIES} gcc -Wall -include ${CMAKE_BINARY_DIR}/vcore/src/database_checksum_vcore.h -I${PROJECT_SOURCE_DIR}/vcore/src/orm -E ${PROJECT_SOURCE_DIR}/vcore/src/orm/vcore_db_sql_generator.h | grep --invert-match "^#" > ${CMAKE_CURRENT_BINARY_DIR}/cert_svc_vcore_db.sql
+  COMMAND sqlite3 ${CMAKE_CURRENT_BINARY_DIR}/.cert_svc_vcore.db ".read ${CMAKE_CURRENT_BINARY_DIR}/cert_svc_vcore_db.sql" || rm -f ${CMAKE_CURRENT_BINARY_DIR}/.cert_svc_vcore.db
+  DEPENDS ${CMAKE_BINARY_DIR}/vcore/src/database_checksum_vcore.h ${PROJECT_SOURCE_DIR}/vcore/src/orm/vcore_db_sql_generator.h ${PROJECT_SOURCE_DIR}/vcore/src/orm/vcore_db
+  )
+
+ADD_CUSTOM_COMMAND( OUTPUT .cert_svc_vcore.db-journal
+  COMMAND touch
+  ARGS  ${CMAKE_CURRENT_BINARY_DIR}/.cert_svc_vcore.db-journal
+  )
+
+ADD_CUSTOM_TARGET(Sqlite3DbVCORE ALL DEPENDS .cert_svc_vcore.db .cert_svc_vcore.db-journal)
+
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/cert_svc_vcore_db.sql
+    DESTINATION /usr/share/cert-svc/
+    )
+
+ADD_SUBDIRECTORY(src)
diff --git a/vcore/cert_svc_vcore_db.sql b/vcore/cert_svc_vcore_db.sql
new file mode 100644 (file)
index 0000000..b1254c1
--- /dev/null
@@ -0,0 +1,27 @@
+
+
+
+PRAGMA foreign_keys = ON; BEGIN TRANSACTION;
+
+
+
+CREATE TABLE OCSPResponseStorage (
+    cert_chain TEXT not null,
+    end_entity_check INT ,
+    ocsp_status INT ,
+    next_update_time BIGINT ,
+    PRIMARY KEY(cert_chain, end_entity_check) ,
+
+
+CHECK(1) );
+
+CREATE TABLE CRLResponseStorage (
+    distribution_point TEXT primary key not null,
+    crl_body TEXT not null,
+    next_update_time BIGINT ,
+CHECK(1) );
+
+COMMIT;
+BEGIN TRANSACTION; CREATE TABLE DB_VERSION_6d8092083d41289ab1c349aeaad617bc (version INT); COMMIT;
+
+
diff --git a/vcore/src/CMakeLists.txt b/vcore/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b10b23f
--- /dev/null
@@ -0,0 +1,138 @@
+INCLUDE(FindPkgConfig)
+
+PKG_CHECK_MODULES(VCORE_DEPS
+    dpl-efl
+    dpl-db-efl
+    ecore
+    appcore-efl
+    libxml-2.0
+    libsoup-2.4
+    libpcre
+    libpcrecpp
+    openssl
+    xmlsec1
+    secure-storage
+    REQUIRED)
+
+SET(VCORE_DIR
+    ${PROJECT_SOURCE_DIR}/vcore
+    )
+
+SET(VCORE_SRC_DIR
+    ${VCORE_DIR}/src/vcore
+    )
+
+SET(VCORE_SOURCES
+    ${VCORE_SRC_DIR}/api.cpp
+    ${VCORE_SRC_DIR}/Base64.cpp
+    ${VCORE_SRC_DIR}/CachedCRL.cpp
+    ${VCORE_SRC_DIR}/CachedOCSP.cpp
+    ${VCORE_SRC_DIR}/Certificate.cpp
+    ${VCORE_SRC_DIR}/CertificateCacheDAO.cpp
+    ${VCORE_SRC_DIR}/CertificateCollection.cpp
+    ${VCORE_SRC_DIR}/CertificateConfigReader.cpp
+    ${VCORE_SRC_DIR}/CertificateLoader.cpp
+    ${VCORE_SRC_DIR}/CertificateVerifier.cpp
+    ${VCORE_SRC_DIR}/CertStoreType.cpp
+    ${VCORE_SRC_DIR}/Config.cpp
+    ${VCORE_SRC_DIR}/CRL.cpp
+    ${VCORE_SRC_DIR}/CRLImpl.cpp
+    ${VCORE_SRC_DIR}/CRLCacheDAO.cpp
+    ${VCORE_SRC_DIR}/CryptoHash.cpp
+    ${VCORE_SRC_DIR}/Database.cpp
+    ${VCORE_SRC_DIR}/DeveloperModeValidator.cpp
+    ${VCORE_SRC_DIR}/OCSP.cpp
+    ${VCORE_SRC_DIR}/OCSPImpl.cpp
+    ${VCORE_SRC_DIR}/OCSPCertMgrUtil.cpp
+    ${VCORE_SRC_DIR}/OCSPUtil.c
+    ${VCORE_SRC_DIR}/ReferenceValidator.cpp
+    ${VCORE_SRC_DIR}/RevocationCheckerBase.cpp
+    ${VCORE_SRC_DIR}/SaxReader.cpp
+    ${VCORE_SRC_DIR}/SignatureFinder.cpp
+    ${VCORE_SRC_DIR}/SignatureReader.cpp
+    ${VCORE_SRC_DIR}/SoupMessageSendBase.cpp
+    ${VCORE_SRC_DIR}/SoupMessageSendSync.cpp
+    ${VCORE_SRC_DIR}/SoupMessageSendAsync.cpp
+    ${VCORE_SRC_DIR}/TimeConversion.cpp
+    ${VCORE_SRC_DIR}/VerificationStatus.cpp
+    ${VCORE_SRC_DIR}/ValidatorFactories.cpp
+    ${VCORE_SRC_DIR}/VCore.cpp
+    ${VCORE_SRC_DIR}/WrtSignatureValidator.cpp
+    ${VCORE_SRC_DIR}/XmlsecAdapter.cpp
+    ${VCORE_SRC_DIR}/pkcs12.c
+    )
+
+SET(VCORE_INCLUDES
+    ${VCORE_DEPS_INCLUDE_DIRS}
+    ${VCORE_SRC_DIR}
+    ${VCORE_DIR}/src
+    ${VCORE_DIR}/src/orm
+    ${VCORE_DIR}/src/legacy
+    ${CMAKE_BINARY_DIR}/vcore/src
+    )
+
+ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS})
+ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS_OTHER})
+ADD_DEFINITIONS("-DSEPARATED_SINGLETON_IMPLEMENTATION")
+ADD_DEFINITIONS("-DDPL_LOGS_ENABLED")
+
+INCLUDE_DIRECTORIES(${VCORE_INCLUDES})
+
+# cert-svc headers
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
+
+ADD_LIBRARY(${TARGET_VCORE_LIB} SHARED ${VCORE_SOURCES})
+SET_TARGET_PROPERTIES(${TARGET_VCORE_LIB} PROPERTIES
+    SOVERSION ${SO_VERSION}
+    VERSION ${VERSION})
+
+ADD_DEPENDENCIES(${TARGET_VCORE_LIB} Sqlite3DbWTF)
+
+TARGET_LINK_LIBRARIES(${TARGET_VCORE_LIB}
+    ${VCORE_DEPS_LIBRARIES}
+    ${TARGET_CERT_SVC_LIB}
+  )
+
+INSTALL(TARGETS ${TARGET_VCORE_LIB}
+    DESTINATION ${LIBDIR}
+    )
+
+INSTALL(FILES
+    ${VCORE_SRC_DIR}/Base64.h
+    ${VCORE_SRC_DIR}/CachedCRL.h
+    ${VCORE_SRC_DIR}/CachedOCSP.h
+    ${VCORE_SRC_DIR}/Certificate.h
+    ${VCORE_SRC_DIR}/CertificateCollection.h
+    ${VCORE_SRC_DIR}/CertStoreType.h
+    ${VCORE_SRC_DIR}/CRL.h
+    ${VCORE_SRC_DIR}/CRLCacheInterface.h
+    ${VCORE_SRC_DIR}/CryptoHash.h
+    ${VCORE_SRC_DIR}/DeveloperModeValidator.h
+    ${VCORE_SRC_DIR}/IAbstractResponseCache.h
+    ${VCORE_SRC_DIR}/OCSP.h
+    ${VCORE_SRC_DIR}/OCSPCertMgrUtil.h
+    ${VCORE_SRC_DIR}/ParserSchema.h
+    ${VCORE_SRC_DIR}/ReferenceValidator.h
+    ${VCORE_SRC_DIR}/SaxReader.h
+    ${VCORE_SRC_DIR}/SignatureData.h
+    ${VCORE_SRC_DIR}/SignatureFinder.h
+    ${VCORE_SRC_DIR}/SignatureReader.h
+    ${VCORE_SRC_DIR}/WrtSignatureValidator.h
+    ${VCORE_SRC_DIR}/VerificationStatus.h
+    ${VCORE_SRC_DIR}/VCore.h
+    DESTINATION ${INCLUDEDIR}/cert-svc/vcore
+    )
+
+INSTALL(FILES
+    ${VCORE_DIR}/src/cert-svc/ccert.h
+    ${VCORE_DIR}/src/cert-svc/ccrl.h
+    ${VCORE_DIR}/src/cert-svc/cinstance.h
+    ${VCORE_DIR}/src/cert-svc/cerror.h
+    ${VCORE_DIR}/src/cert-svc/cocsp.h
+    ${VCORE_DIR}/src/cert-svc/cpkcs12.h
+    ${VCORE_DIR}/src/cert-svc/cprimitives.h
+    ${VCORE_DIR}/src/cert-svc/cstring.h
+    DESTINATION ${INCLUDEDIR}/cert-svc/cert-svc
+    )
+
+#FILE(MAKE_DIRECTORY /opt/share/cert-svc/pkcs12)
diff --git a/vcore/src/cert-svc/ccert.h b/vcore/src/cert-svc/ccert.h
new file mode 100644 (file)
index 0000000..dd288b2
--- /dev/null
@@ -0,0 +1,325 @@
+/**
+ * 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        ccert.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is part of C api for ValidationCore.
+ */
+#ifndef _CERTSVC_CCERT_H_
+#define _CERTSVC_CCERT_H_
+
+#include <time.h>
+
+#include <cert-svc/cinstance.h>
+#include <cert-svc/cstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct CertSvcCertificate_t {
+    int privateHandler;
+    CertSvcInstance privateInstance;
+} CertSvcCertificate;
+
+typedef struct CertSvcCertificateList_t {
+    int privateHandler;
+    CertSvcInstance privateInstance;
+} CertSvcCertificateList;
+
+typedef enum CertSvcCertificateForm_t {
+/*    CERTSVC_FORM_PEM, */
+    CERTSVC_FORM_DER,
+    CERTSVC_FORM_DER_BASE64
+} CertSvcCertificateForm;
+
+typedef enum CertSvcCertificateField_t {
+    CERTSVC_SUBJECT,
+    CERTSVC_SUBJECT_COMMON_NAME,
+    CERTSVC_SUBJECT_COUNTRY_NAME,
+    CERTSVC_SUBJECT_STATE_NAME,
+    CERTSVC_SUBJECT_ORGANIZATION_NAME,
+    CERTSVC_SUBJECT_ORGANIZATION_UNIT_NAME,
+    CERTSVC_SUBJECT_EMAIL_ADDRESS,
+    CERTSVC_ISSUER,
+    CERTSVC_ISSUER_COMMON_NAME,
+    CERTSVC_ISSUER_COUNTRY_NAME,
+    CERTSVC_ISSUER_STATE_NAME,
+    CERTSVC_ISSUER_ORGANIZATION_NAME,
+    CERTSVC_ISSUER_ORGANIZATION_UNIT_NAME,
+    CERTSVC_VERSION,
+    CERTSVC_SERIAL_NUMBER,
+    CERTSVC_KEY_USAGE,
+    CERTSVC_KEY,
+    CERTSVC_SIGNATURE_ALGORITHM
+} CertSvcCertificateField;
+
+/**
+ * Read certificate from file. Certificate must be in PEM/CER/DER format.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] location Path to file with certificate file.
+ * @param[out] certificate Certificate id assigned to loaded certificate.
+ * @return CERTSVC_SUCCESS, CERTSVC_BAD_ALLOC, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_new_from_file(CertSvcInstance instance,
+                                      const char *location,
+                                      CertSvcCertificate *certificate);
+
+/**
+ * Read certificate stored in memory.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] memory Pointer to memory with certificate data.
+ * @param[in] len Size of certificate.
+ * @param[in] form Certificate format.
+ * @param[out] certificate Certificate id assigned to loaded certificate.
+ * @return CERTSVC_SUCCESS, CERTSVC_BAD_ALLOC, CERTSVC_FAIL
+ */
+int certsvc_certificate_new_from_memory(CertSvcInstance instance,
+                                        const unsigned char *memory,
+                                        int len,
+                                        CertSvcCertificateForm form,
+                                        CertSvcCertificate *certificate);
+
+/**
+ * Free structures connected with certificate.
+ *
+ * @param[in] certificate Certificate id.
+ */
+void certsvc_certificate_free(CertSvcCertificate certificate);
+
+/**
+ * Save certificate to file. It saves certificate in DER format.
+ *
+ * @param[in] certificate Certificate id.
+ * @param[in] location Path to file.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_save_file(CertSvcCertificate certificate, const char *location);
+
+/**
+ * Search certificate with specific data. Result is stored in CertSvcInstance.
+ * This function will erase all preverious results stored in CertSvcInstance but
+ * it will not erase any CertSvcCertificate.
+ *
+ * You can search by fields: CERTSVC_SUBJECT, CERTSVC_ISSUER, CERTSVC_SUBJECT_COMMON_NAME
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] field Certificate filed name.
+ * @param[in] value Value to search for.
+ * @param[out] handler Handler to search result.
+ * @return CERTSVC_SUCCESS, CERTSVC_BAD_ALLOC, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_search(CertSvcInstance instance,
+                               CertSvcCertificateField field,
+                               const char *value,
+                               CertSvcCertificateList *handler);
+
+/**
+ * This function will return certificate id founded by certsvc_certificate_search.
+ * You can call this function multiple times to get all results.
+ *
+ * @param[in] hadler Hander to search results.
+ * @param[in] position
+ * @param[out] certificate Certficate id.
+ * @return CERTSVC_SUCCESS, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_list_get_one(CertSvcCertificateList handler,
+                                     int position,
+                                     CertSvcCertificate *certificate);
+
+/**
+ * Return number of elements on the list.
+ *
+ * @param[in] handler Handler to certifiacte list.
+ * @param[out] length Size of list.
+ * @return CERTSVC_SUCCESS, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_list_get_length(CertSvcCertificateList handler,
+                                        int *size);
+
+/**
+ * This function will free list. It will not free certificates on the list.
+ * You may free each certificate with certsvc_certificate_free.
+ *
+ * @param[in] handler Handler to search result.
+ */
+void certsvc_certificate_list_free(CertSvcCertificateList handler);
+
+/**
+ * Compare parent certificate subject with child issuer field.
+ *
+ * @param[in] child
+ * @param[in] parent
+ * @param[out] status CERTSVC_TRUE if "signer" was used to sign "child" certificate in other cases it will return CERTSVC_FALSE.
+ * @return CERTSVC_SUCCESS, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_is_signed_by(CertSvcCertificate child,
+                                     CertSvcCertificate parent,
+                                     int *status);
+
+/**
+ * Extract specific data from certificate. Data in buffer could be free
+ * by certsvc_free_string function or by
+ * certsvc_instance_free or vcore_instance_reset.
+ *
+ * @param[in] certificate Certificate id.
+ * @param[in] field Type of data to extract.
+ * @param[out] buffer Extracted data.
+ * return CERTSVC_SUCCESS, CERTSVC_BAD_ALLOC, CERTSVC_FAIL
+ */
+int certsvc_certificate_get_string_field(CertSvcCertificate certificate,
+                                         CertSvcCertificateField field,
+                                         CertSvcString *buffer);
+
+/**
+ * Extract NOT AFTER data from certificate.
+ *
+ * @param[in] certificate Certificate id.
+ * @param[out] result date
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_get_not_after(CertSvcCertificate certificate, time_t *result);
+
+/**
+ * Extract NOT AFTER data from certificate.
+ *
+ * @param[in] certificate Certificate id.
+ * @param[out] result date
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_get_not_before(CertSvcCertificate certificate, time_t *result);
+
+/**
+ * Check certificate. This fuction compares SUBJECT and ISSUER fields.
+ * TODO: This fuction should also check ROOTCA field in certificate.
+ *
+ * @param[in] certificate Certificate id.
+ * @param[out] status CERTSVC_TRUE or CERTSVC_FALSE
+ * @return CERTSVC_SUCCESS, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_is_root_ca(CertSvcCertificate certificate, int *status);
+
+/**
+ * Extract all distribution point from certificate.
+ *
+ * @param[in] certificate Certificate with distribution points.
+ * @param[out] hander Handler to set of string.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ *
+ * Usage example:
+ *
+ * int max;
+ * CertSvcStringList handler;
+ * certsvc_certificate_get_crl_distribution_points(instance, some_certificate, &handler);
+ * certsvc_certificate_list_get_length(handler, &max);
+ * for(int i=0; i<max; ++i)
+ *   char *buffer;
+ *   int len;
+ *   CertSvcString string;
+ *   certsvc_string_list_get_one(handler, i, &string);
+ *   printf("%s\n", buffer);
+ *   certsvc_string_free(buffer); // optional
+ * }
+ * certsvc_string_list_free(handler); // optional
+ */
+int certsvc_certificate_get_crl_distribution_points(CertSvcCertificate certificate,
+                                                    CertSvcStringList *handler);
+
+/**
+ * Sort certificates chain. This fuction modifies certificate_array.
+ *
+ * If function success:
+ *  * certificate array will contain end entity certificate as first element
+ *  * last element on the certificate_array will contain Root CA certificate or
+ *    CA certificate (if Root CA is not present).
+ *
+ * @param[in/out] certificate_array
+ * @param[in] size Size of certificate_array
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC
+ */
+int certsvc_certificate_chain_sort(CertSvcCertificate *unsortedChain, int size);
+
+/**
+ * Base64 string will be connected with same instance as message.
+ * You can free base64 string with certsvc_string_free (or certsvc_instance_reset).
+ *
+ * @param[in] message Buffer with input data.
+ * @param[out] base64 Buffer with output data.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_base64_encode(CertSvcString message, CertSvcString *base64);
+
+/**
+ * Message string will be connected with same certsvc instance as base64.
+ * You can free base64 string with certsvc_string_free (or certsvc_instance_reset).
+ *
+ * @param[in] base64 Buffer with input data.
+ * @param[out] message Buffer with output data.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_base64_decode(CertSvcString base64, CertSvcString *message);
+
+/**
+ * Use certificate to verify message.
+ *
+ * @param[in] certificate
+ * @param[in] message
+ * @param[in] algorithm May be set to NULL.
+ * @param[out] status Will be set only if function return CERTSVC_SUCCESS.
+ *                    It could be set to: CERTSVC_SUCCESS, CERTSVC_INVALID_SIGNATURE
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_ALGORITHM
+ */
+int certsvc_message_verify(
+    CertSvcCertificate certificate,
+    CertSvcString message,
+    CertSvcString signature,
+    const char *algorithm,
+    int *status);
+
+/**
+ * This function will create full chain and verify in.
+ *
+ * First argument of function will be treatet as endentity certificate.
+ *
+ * This function will success if root CA certificate is stored in
+ * trusted array.
+ *
+ * @param[in] certificate Certificate to verify.
+ * @param[in] trusted Array with trusted certificates.
+ * @param[in] trustedSize Number of trusted certificates in array.
+ * @param[in] untrusted Array with untrusted certificates.
+ * @param[in] untrustedSize Number of untrusted certificate in array.
+ * @param[out] status Will be set only if function return CERTSVC_SUCCESS.
+ *                    It could be set to: CERTSVC_SUCCESS, CERTSVC_FAIL
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_certificate_verify(
+    CertSvcCertificate certificate,
+    CertSvcCertificate *trusted,
+    int trustedSize,
+    CertSvcCertificate *untrusted,
+    int untrustedSize,
+    int *status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/vcore/src/cert-svc/ccrl.h b/vcore/src/cert-svc/ccrl.h
new file mode 100644 (file)
index 0000000..02f8a7a
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * 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        ccrl.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is part of C api for ValidationCore.
+ */
+#ifndef _CERTSVC_CCRL_H_
+#define _CERTSVC_CCRL_H_
+
+#include <time.h>
+
+#include <cert-svc/ccert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CERTSVC_CRL_GOOD                 (1<<0)
+#define CERTSVC_CRL_REVOKED              (1<<1)
+#define CERTSVC_CRL_VERIFICATION_ERROR   (1<<3)
+#define CERTSVC_CRL_NO_SUPPORT           (1<<4)
+
+typedef void (*CertSvcCrlCacheWrite)(
+    const char *distributionPoint,
+    const char *body,
+    int bodySize,
+    time_t nextUpdateTime,
+    void *userParam);
+
+typedef int (*CertSvcCrlCacheRead)(
+    const char *distributionPoint,
+    char **body,
+    int *bodySize,
+    time_t *nextUpdateTime,
+    void *userParam);
+
+typedef void (*CertSvcCrlFree)(
+    char *buffer,
+    void *userParam);
+
+void certsvc_crl_cache_functions(
+    CertSvcInstance instance,
+    CertSvcCrlCacheWrite writePtr,
+    CertSvcCrlCacheRead readPtr,
+    CertSvcCrlFree freePtr);
+
+int certsvc_crl_check(
+    CertSvcCertificate certificate,
+    CertSvcCertificate *trustedStore,
+    int storeSize,
+    int force,
+    int *status,
+    void *userParam);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/vcore/src/cert-svc/cerror.h b/vcore/src/cert-svc/cerror.h
new file mode 100644 (file)
index 0000000..0566152
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * 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        cerror.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is part of C api for ValidationCore.
+ */
+
+#ifndef _CERTSVC_CERROR_H_
+#define _CERTSVC_CERROR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CERTSVC_TRUE              (1)
+#define CERTSVC_FALSE             (0)
+
+#define CERTSVC_SUCCESS           (1)
+#define CERTSVC_FAIL              (0)    /* Openssl internal error. */
+#define CERTSVC_BAD_ALLOC         (-2)   /* Memmory allcation error. */
+//#define CERTSVC_FILE_NOT_FOUND    (-3)   /* Certificate file does not exists. */
+#define CERTSVC_WRONG_ARGUMENT    (-4)   /* Function argumnet is wrong. */
+#define CERTSVC_INVALID_ALGORITHM (-5)   /* Algorithm is not supported. */
+#define CERTSVC_INVALID_SIGNATURE (-6)   /* Signature and message does not match. */
+#define CERTSVC_IO_ERROR          (-7)   /* Certificate file IO error. */
+#define CERTSVC_INVALID_PASSWORD  (-8)   /* Certificate container password mismatch. */
+#define CERTSVC_DUPLICATED_ALIAS  (-9)   /* User-provided alias is aleady taken. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CERTSVC_CERROR_H_
diff --git a/vcore/src/cert-svc/cinstance.h b/vcore/src/cert-svc/cinstance.h
new file mode 100644 (file)
index 0000000..93ee23d
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ * 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        cinstance.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is part of C api for ValidationCore.
+ */
+#ifndef _CERTSVC_CINSTANCE_H_
+#define _CERTSVC_CINSTANCE_H_
+
+#include <cert-svc/cerror.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct CertSvcInstance_t {
+    void *privatePtr;
+} CertSvcInstance;
+
+/**
+ * Allocate internal data of CertSvc library and put it in the CertSvcInstance structure.
+ * Initialize Openssl interanal structures, initialize all structures required by libsoup
+ * (libsoup is used by ocps and crl functions).
+ *
+ * @param[out] instance Pointer to CertSvcInstance.
+ * @return CERTSVC_SUCCESS or CERTSVC_FAIL.
+ */
+int certsvc_instance_new(CertSvcInstance *instance);
+
+/**
+ * This function will free all allocated data. All certificate identificator will
+ * be released and all strings allocated by certsvc_certificate_get_string field will be
+ * released also.
+ *
+ * This fucntion does not release CertSvcInstnace!
+ *
+ * Plese note: It is safe to use this function after use certsvc_string_free.
+ *
+ * @param[in] instance CertSvcInstance object.
+ */
+void certsvc_instance_reset(CertSvcInstance instance);
+
+/**
+ * This function will free all allocated data. All certificate identificator will
+ * be released and all strings allocated by certsvc_certificate_get_string field will be
+ * released also.
+ *
+ * This fucntion also release CertSvcInstnace!
+ *
+ * Please note: It is safe use this function after use certsvc_string_free.
+ *
+ * @param[in] instance CertSvcInstance object
+ */
+void certsvc_instance_free(CertSvcInstance instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CERTSVC_CINSTANCE_H_
+
diff --git a/vcore/src/cert-svc/cocsp.h b/vcore/src/cert-svc/cocsp.h
new file mode 100644 (file)
index 0000000..da37d2b
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * 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        cocsp.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is C api for ValidationCore.
+ */
+#ifndef _CERTSVC_OCSP_C_API_H_
+#define _CERTSVC_OCSP_C_API_H_
+
+#include <time.h>
+
+#include <cert-svc/ccert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CERTSVC_OCSP_GOOD                (1<<0)
+#define CERTSVC_OCSP_REVOKED             (1<<1)
+#define CERTSVC_OCSP_UNKNOWN             (1<<2)
+#define CERTSVC_OCSP_VERIFICATION_ERROR  (1<<3)
+#define CERTSVC_OCSP_NO_SUPPORT          (1<<4)
+#define CERTSVC_OCSP_ERROR               (1<<5)
+
+/**
+ * Implementation of ocsp call.
+ *
+ * Please note: to verify certificate you need certificate and his parrent.
+ * This function will always verify chain_size-1 certificates from the chain.
+ *
+ * @param[in] chain Certificate to check.
+ * @param[in] chain_size Size of certificate_array
+ * @param[in] trusted Store with trusted certificates (additional certificates
+ *                    that may by reqired during verification process).
+ * @param[in] trusted_size Size of trusted certificate store.
+ * @param[in] url Force OCSP to use specific server. Pass NULL to use OCSP server defined in certificate.
+ * @param[out] status Bit field with description of chain validation.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_ocsp_check(CertSvcCertificate *chain,
+                       int chainSize,
+                       CertSvcCertificate *trusted,
+                       int truestedSize,
+                       const char *url,
+                       int *status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/vcore/src/cert-svc/cpkcs12.h b/vcore/src/cert-svc/cpkcs12.h
new file mode 100644 (file)
index 0000000..328afd9
--- /dev/null
@@ -0,0 +1,133 @@
+/**
+ * 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        cpkcs12.h
+ * @author      Jacek Migacz (j.migacz@samsung.com)
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @brief       This is part of C api for PKCS#12/PFX storage routines.
+ */
+#ifndef _CERTSVC_CPKCS12_H_
+#define _CERTSVC_CPKCS12_H_
+
+#include <cert-svc/cinstance.h>
+#include <cert-svc/cstring.h>
+#include <cert-svc/ccert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Query PKCS#12 storage to find out whenever new alias proposal is unique.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] proposal Desired alias name.
+ * @param[out] is_unique CERTSVC_TRUE (if there isn't such alias already) or CERTSVC_FALSE.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_pkcs12_alias_exists(CertSvcInstance instance,
+                                CertSvcString alias,
+                                int *is_unique);
+
+/**
+ * Import PKCS#12 container from file.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] path Path to container file.
+ * @param[in] password Container password (can be empty or NULL).
+ * @param[in] alias Logical name for certificate bundle idenification (can't be empty).
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_INVALID_PASSWORD, CERTSVC_WRONG_ARGUMENT, CERTSVC_DUPLICATED_ALIAS
+ */
+int certsvc_pkcs12_import_from_file(CertSvcInstance instance,
+                                    CertSvcString path,
+                                    CertSvcString password,
+                                    CertSvcString alias);
+
+/**
+ * Get a list of PKCS#12 bundles from storage. This list could be freed by:
+ * certsvc_string_list_free, certsvc_instance_reset, certsvc_instance_free.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[out] pfxIdStringList List of PKCS#12 aliases.
+ * @return CERTSVC_SUCCESS, CERTSVC_BAD_ALLOC, CERTSVC_FAIL
+ */
+int certsvc_pkcs12_get_id_list(CertSvcInstance instance,
+                               CertSvcStringList *pfxIdStringList);
+
+/**
+ * Check whenever PKCS#12 container is password protected.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] path Path to container file.
+ * @param[out] has_password CERTSVC_TRUE (if container is password protected) or CERTSVC_FALSE.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_pkcs12_has_password(CertSvcInstance instance,
+                                CertSvcString filepath,
+                                int *has_password);
+
+/**
+ * Get a list of certificates from PKCS#12 bundle. You may free this list by:
+ * certsvc_certificate_list_free. You may free certificates from list with:
+ * certsvc_certificate_free.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] pfxIdString Identification of pfx/pkcs file.
+ * @param[out] certificateList List of certificates.
+ * @return CERTSVC_SUCCESS, CERTSVC_BAD_ALLOC, CERTSVC_FAIL, CERTSVC_IO_ERROR
+ */
+int certsvc_pkcs12_load_certificate_list(CertSvcInstance instance,
+                                         CertSvcString alias,
+                                         CertSvcCertificateList* certificateList);
+
+/**
+ * This function will load to memory private file content. This functin will
+ * not parse it in any way.
+ * This memory must be freed by certsvc_private_key_free.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] prfIdString Container bundle identifier.
+ * @param[out] buffer Poiner to newly-allocated memory with private key data.
+ * @param[out] size Size of the newly-allocated buffer. Zero means there is no key.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_pkcs12_private_key_dup(CertSvcInstance instance,
+                                   CertSvcString alias,
+                                   char **buffer,
+                                   size_t *size);
+
+/**
+ * Couter-routine for certsvc_pkcs12_private_key_dup.
+ *
+ * @param[in] pointer Memory claimed by private key.
+ */
+void certsvc_pkcs12_private_key_free(char *buffer);
+
+/**
+ * Remove logical PKCS#12 container with associated certificates and private key.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] alias Container bundle identifier.
+ * @return CERTSVC_SUCCESS, CERTSVC_IO_ERROR, CERTSVC_BAD_ALLOC
+ */
+int certsvc_pkcs12_delete(CertSvcInstance instance,
+                          CertSvcString alias);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/vcore/src/cert-svc/cprimitives.h b/vcore/src/cert-svc/cprimitives.h
new file mode 100644 (file)
index 0000000..da6fae6
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * 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        vcore_api_extension.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is C api for ValidationCore.
+ */
+#ifndef _CERTSVC_C_API_EXTENDED_H_
+#define _CERTSVC_C_API_EXTENDED_H_
+
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#include <cert-svc/ccert.h>
+#include <cert-svc/cstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This will return pointer to X509 base openssl struct. This struct must be release by function
+ * certsvc_certificate_free_x509.
+ *
+ * vcore_instance_free or vcore_instance_reset will not free memory allocated by this function!
+ *
+ * @param[in] certificate Pointer to certificate.
+ * @param[out] cert Duplicate of certificate.
+ * @return CERTSVC_SUCCESS, CERTSVC_WRONG_ARGUMENT, CERTSVC_FAIL
+ */
+int certsvc_certificate_dup_x509(CertSvcCertificate certificate, X509** cert);
+
+/**
+ * Release X509 struct allocated by certsvc_certificate_new_x509_copy function.
+ *
+ * @param[in] x509_copy Pointer to openssl struct.
+ */
+void certsvc_certificate_free_x509(X509 *x509_copy);
+
+/**
+ * This will return pointer to EVP_PKEY base openssl struct. This struct must
+ * be release with function certsvc_pkcs12_free_evp_pkey
+ *
+ * @param[in] instance
+ * @param[in] alias Pkcs12 identificator.
+ * @param[out] pkey Duplicate of private key.
+ * @return CERTSVC_SUCCESS, CERT_FAIL
+ */
+
+int certsvc_pkcs12_dup_evp_pkey(CertSvcInstance instance,
+                                CertSvcString alias,
+                                EVP_PKEY** pkey);
+
+void certsvc_pkcs12_free_evp_pkey(EVP_PKEY* pkey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/vcore/src/cert-svc/cstring.h b/vcore/src/cert-svc/cstring.h
new file mode 100644 (file)
index 0000000..a9f4b32
--- /dev/null
@@ -0,0 +1,134 @@
+/**
+ * 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        cstring.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is part of C api for ValidationCore.
+ */
+#ifndef _CERTSVC_CSTRING_H_
+#define _CERTSVC_CSTRING_H_
+
+#include <cert-svc/cinstance.h>
+#include <cert-svc/cstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct CertSvcStringList_t {
+    int privateHandler;
+    CertSvcInstance privateInstance;
+} CertSvcStringList;
+
+typedef struct CertSvcString_t {
+    /*
+     * You are not allowed to use private fields of this structure. It is internal
+     * implementation of strings and it may change at any time without notice!
+     * To extract data use certsvc_string_to_cstring function!
+     */
+    char* privateHandler;
+    int privateLength;
+    CertSvcInstance privateInstance;
+} CertSvcString;
+
+/**
+ * This function will duplicate input data. Data in ouput string will be managed by certsvc.
+ *
+ * @param[in] instance CertSvcString will be conected with this instance.
+ * @param[in] input Input data.
+ * @param[in] size Input buffer size.
+ * @param[out] output Buffer with output data.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_string_new(
+    CertSvcInstance instance,
+    const char *input,
+    int size,
+    CertSvcString *output);
+
+/**
+ * This function wont duplicate input data. Output param will contain pointer to input
+ * so input could not be free as long as ouput param is used.
+ *
+ * @param[in] instance CertSvcString will be conected with this instance.
+ * @param[in] input Input data.
+ * @param[in] size Input buffer size.
+ * @param[out] output Buffer with output data.
+ * @return CERTSVC_SUCCESS, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_string_not_managed(
+    CertSvcInstance instance,
+    const char *input,
+    int size,
+    CertSvcString *output);
+
+/**
+ * Extract next result from result set. Function certsvc_string_list_free
+ * does not free results returned by this function. CertSvcString is valid
+ * until certsvc_string_free or vcore_instance_reset or vcore_instance_free
+ * is called.
+ *
+ * @param[in] handler Handler to set of strings.
+ * @param[out] buffer The buffer will be pointing to string with distrubution point url or will be set to NULL if error occures.
+ * @param[out] size Size of data pointed by buffer or 0 if error occures.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC
+ */
+int certsvc_string_list_get_one(CertSvcStringList hander,
+                                int position,
+                                CertSvcString *buffer);
+
+/**
+ * Extract CertSvcStringList size.
+ *
+ * @param[in] handler Handler to string list.
+ * @param[out] size Number of elements on the list.
+ * @return CERTSVC_SUCCESS, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_string_list_get_length(CertSvcStringList hander,int *size);
+
+/**
+ * Free data.
+ *
+ * @param[in] string Data allocated by certsvc_certificate_get_string_field
+ */
+void certsvc_string_free(CertSvcString string);
+
+/**
+ * Free string list.
+ *
+ * Note: This function does not free strings returned by certsvc_string_list_get_one_result.
+ *
+ * @param[in] handler String set handler.
+ */
+void certsvc_string_list_free(CertSvcStringList handler);
+
+/**
+ * Convert CertSvcStringPtr into pure c pointer. Please note that this pointer is valid as long as CertSvcString is valid.
+ *
+ * @param[in] string CertSvcStringPtr.
+ * @param[out] buffer cstring
+ * @param[out] len Length of cstring
+ */
+void certsvc_string_to_cstring(CertSvcString string, const char **buffer, int *len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/vcore/src/orm/DESCRIPTION b/vcore/src/orm/DESCRIPTION
new file mode 100644 (file)
index 0000000..7d25d0d
--- /dev/null
@@ -0,0 +1 @@
+Scripts required to create vcoredatabase.
diff --git a/vcore/src/orm/gen_db_md5.sh b/vcore/src/orm/gen_db_md5.sh
new file mode 100755 (executable)
index 0000000..a81d5f7
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+CHECKSUM=`cat ${2} ${3} 2>/dev/null | md5sum 2>/dev/null | cut -d\  -f1 2>/dev/null`
+echo "#define DB_CHECKSUM DB_VERSION_${CHECKSUM}" > ${1}
+echo "#define DB_CHECKSUM_STR \"DB_VERSION_${CHECKSUM}\"" >> ${1}
+
diff --git a/vcore/src/orm/orm_generator_vcore.h b/vcore/src/orm/orm_generator_vcore.h
new file mode 100644 (file)
index 0000000..862bc80
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#ifndef ORM_GENERATOR_VCORE_H
+#define ORM_GENERATOR_VCORE_H
+
+#define ORM_GENERATOR_DATABASE_NAME vcore_db_definitions
+#include <dpl/db/orm_generator.h>
+#undef ORM_GENERATOR_DATABASE_NAME
+
+#endif // ORM_GENERATOR_VCORE_H
diff --git a/vcore/src/orm/vcore_db b/vcore/src/orm/vcore_db
new file mode 100644 (file)
index 0000000..6947255
--- /dev/null
@@ -0,0 +1,23 @@
+SQL(
+    PRAGMA foreign_keys = ON;
+    BEGIN TRANSACTION;
+)
+CREATE_TABLE(OCSPResponseStorage)
+    COLUMN_NOT_NULL(cert_chain,        TEXT,)
+    COLUMN(end_entity_check,           INT,)
+    COLUMN(ocsp_status,                INT,)
+    COLUMN(next_update_time,           BIGINT,)
+    TABLE_CONSTRAINTS(
+      PRIMARY KEY(cert_chain, end_entity_check)
+    )
+CREATE_TABLE_END()
+
+CREATE_TABLE(CRLResponseStorage)
+    COLUMN_NOT_NULL(distribution_point,TEXT,       primary key)
+    COLUMN_NOT_NULL(crl_body,          TEXT,)
+    COLUMN(next_update_time,           BIGINT,)
+CREATE_TABLE_END()
+
+SQL(
+    COMMIT;
+)
diff --git a/vcore/src/orm/vcore_db_definitions b/vcore/src/orm/vcore_db_definitions
new file mode 100644 (file)
index 0000000..61018c4
--- /dev/null
@@ -0,0 +1,6 @@
+DATABASE_START(vcore)
+
+#include "vcore_db"
+#include "version_db"
+
+DATABASE_END()
diff --git a/vcore/src/orm/vcore_db_sql_generator.h b/vcore/src/orm/vcore_db_sql_generator.h
new file mode 100644 (file)
index 0000000..76f0448
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+//Do not include this file directly! It is used only for SQL code generation.
+
+#include <dpl/db/orm_macros.h>
+
+#include "vcore_db_definitions"
diff --git a/vcore/src/orm/version_db b/vcore/src/orm/version_db
new file mode 100644 (file)
index 0000000..7e20d8d
--- /dev/null
@@ -0,0 +1,5 @@
+SQL(
+    BEGIN TRANSACTION;
+    CREATE TABLE DB_CHECKSUM (version INT);
+    COMMIT;
+)
diff --git a/vcore/src/vcore/Base64.cpp b/vcore/src/vcore/Base64.cpp
new file mode 100644 (file)
index 0000000..88a9b28
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+#include <algorithm>
+#include <string>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+
+#include <dpl/log/log.h>
+#include <dpl/scoped_free.h>
+
+#include <vcore/Base64.h>
+
+namespace ValidationCore {
+Base64Encoder::Base64Encoder() :
+    m_b64(0),
+    m_bmem(0),
+    m_finalized(false)
+{
+}
+
+void Base64Encoder::append(const std::string &data)
+{
+    if (m_finalized) {
+        LogWarning("Already finalized.");
+        ThrowMsg(Exception::AlreadyFinalized, "Already finalized");
+    }
+
+    if (!m_b64) {
+        reset();
+    }
+    BIO_write(m_b64, data.c_str(), data.size());
+}
+
+void Base64Encoder::finalize()
+{
+    if (m_finalized) {
+        LogWarning("Already finalized.");
+        ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+    }
+    m_finalized = true;
+    BIO_flush(m_b64);
+}
+
+std::string Base64Encoder::get()
+{
+    if (!m_finalized) {
+        LogWarning("Not finalized");
+        ThrowMsg(Exception::NotFinalized, "Not finalized");
+    }
+    BUF_MEM *bptr = 0;
+    BIO_get_mem_ptr(m_b64, &bptr);
+    if (bptr == 0) {
+        LogError("Bio internal error");
+        ThrowMsg(Exception::InternalError, "Bio internal error");
+    }
+
+    if (bptr->length > 0) {
+        return std::string(bptr->data, bptr->length);
+    }
+    return std::string();
+}
+
+void Base64Encoder::reset()
+{
+    m_finalized = false;
+    BIO_free_all(m_b64);
+    m_b64 = BIO_new(BIO_f_base64());
+    BIO_set_flags(m_b64, BIO_FLAGS_BASE64_NO_NL);
+    m_bmem = BIO_new(BIO_s_mem());
+    if (!m_b64 || !m_bmem) {
+        LogError("Error during allocation memory in BIO");
+        ThrowMsg(Exception::InternalError,
+                 "Error during allocation memory in BIO");
+    }
+    m_b64 = BIO_push(m_b64, m_bmem);
+}
+
+Base64Encoder::~Base64Encoder()
+{
+    BIO_free_all(m_b64);
+}
+
+Base64Decoder::Base64Decoder() :
+    m_finalized(false)
+{
+}
+
+void Base64Decoder::append(const std::string &data)
+{
+    if (m_finalized) {
+        LogWarning("Already finalized.");
+        ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+    }
+    m_input.append(data);
+}
+
+static bool whiteCharacter(char a)
+{
+    if (a == '\n') { return true; }
+    return false;
+}
+
+bool Base64Decoder::finalize()
+{
+    if (m_finalized) {
+        LogWarning("Already finalized.");
+        ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+    }
+
+    m_finalized = true;
+
+    m_input.erase(std::remove_if(m_input.begin(),
+                                 m_input.end(),
+                                 whiteCharacter),
+                  m_input.end());
+
+    for (size_t i = 0; i<m_input.size(); ++i) {
+        if (isalnum(m_input[i])
+            || m_input[i] == '+'
+            || m_input[i] == '/'
+            || m_input[i] == '=')
+        {
+            continue;
+        }
+        LogError("Base64 input contains illegal chars: " << m_input[i]);
+        return false;
+    }
+
+    BIO *b64, *bmem;
+    size_t len = m_input.size();
+
+    DPL::ScopedFree<char> buffer(static_cast<char*>(malloc(len)));
+
+    if (!buffer) {
+        LogError("Error in malloc.");
+        ThrowMsg(Exception::InternalError, "Error in malloc.");
+    }
+
+    memset(buffer.Get(), 0, len);
+    b64 = BIO_new(BIO_f_base64());
+    if (!b64) {
+        LogError("Couldn't create BIO object.");
+        ThrowMsg(Exception::InternalError, "Couldn't create BIO object.");
+    }
+    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+    DPL::ScopedFree<char> tmp(strdup(m_input.c_str()));
+    m_input.clear();
+
+    bmem = BIO_new_mem_buf(tmp.Get(), len);
+
+    if (!bmem) {
+        BIO_free(b64);
+        LogError("Internal error in BIO");
+        ThrowMsg(Exception::InternalError, "Internal error in BIO");
+    }
+
+    bmem = BIO_push(b64, bmem);
+
+    if (!bmem) {
+        BIO_free(b64);
+        LogError("Internal error in BIO");
+        ThrowMsg(Exception::InternalError, "Internal error in BIO");
+    }
+
+    int readlen = BIO_read(bmem, buffer.Get(), len);
+    m_output.clear();
+
+    bool status = true;
+
+    if (readlen > 0) {
+        m_output.append(buffer.Get(), readlen);
+    } else {
+        status = false;
+    }
+
+    BIO_free_all(bmem);
+    return status;
+}
+
+std::string Base64Decoder::get() const
+{
+    if (!m_finalized) {
+        LogWarning("Not finalized.");
+        ThrowMsg(Exception::NotFinalized, "Not finalized");
+    }
+    return m_output;
+}
+
+void Base64Decoder::reset()
+{
+    m_finalized = false;
+    m_input.clear();
+    m_output.clear();
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/Base64.h b/vcore/src/vcore/Base64.h
new file mode 100644 (file)
index 0000000..520662e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+#ifndef _BASE64_H_
+#define _BASE64_H_
+
+#include <string>
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+
+struct bio_st;
+typedef bio_st BIO;
+
+namespace ValidationCore {
+class Base64Encoder : public DPL::Noncopyable
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, InternalError)
+        DECLARE_EXCEPTION_TYPE(Base, NotFinalized)
+        DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized)
+    };
+    Base64Encoder();
+    void append(const std::string &data);
+    void finalize();
+    std::string get();
+    void reset();
+    ~Base64Encoder();
+
+  private:
+    BIO *m_b64;
+    BIO *m_bmem;
+    bool m_finalized;
+};
+
+class Base64Decoder : public DPL::Noncopyable
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, InternalError)
+        DECLARE_EXCEPTION_TYPE(Base, NotFinalized)
+        DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized)
+    };
+    Base64Decoder();
+    void append(const std::string &data);
+
+    /*
+     *  Function will return false when BIO_read fails
+     *  (for example: when string was not in base64 format).
+     */
+    bool finalize();
+    std::string get() const;
+    void reset();
+    ~Base64Decoder()
+    {
+    }
+
+  private:
+    std::string m_input;
+    std::string m_output;
+    bool m_finalized;
+};
+} // namespace ValidationCore
+
+#endif
diff --git a/vcore/src/vcore/CRL.cpp b/vcore/src/vcore/CRL.cpp
new file mode 100644 (file)
index 0000000..cb9fb39
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski(b.grzelewski@samsung.com)
+ * @version     0.2
+ * @file        CRL.cpp
+ * @brief       Routines for certificate validation over CRL
+ */
+
+#include <vcore/CRL.h>
+#include <vcore/CRLImpl.h>
+
+namespace ValidationCore {
+
+CRL::CRL(CRLCacheInterface *ptr)
+  : m_impl(new CRLImpl(ptr))
+{}
+
+CRL::~CRL() {
+    delete m_impl;
+}
+
+CRL::RevocationStatus CRL::checkCertificate(const CertificatePtr &argCert) {
+    return m_impl->checkCertificate(argCert);
+}
+
+CRL::RevocationStatus CRL::checkCertificateChain(
+    CertificateCollection certChain)
+{
+    return m_impl->checkCertificateChain(certChain);
+}
+
+VerificationStatus CRL::checkEndEntity(CertificateCollection &chain) {
+    return m_impl->checkEndEntity(chain);
+}
+
+void CRL::addToStore(const CertificatePtr &argCert) {
+    m_impl->addToStore(argCert);
+}
+
+bool CRL::updateList(const CertificatePtr &argCert,
+                     const UpdatePolicy updatePolicy)
+{
+    return m_impl->updateList(argCert, updatePolicy);
+}
+
+void CRL::addToStore(const CertificateCollection &collection) {
+    m_impl->addToStore(collection);
+}
+
+bool CRL::updateList(const CertificateCollection &collection,
+                     UpdatePolicy updatePolicy)
+{
+    return m_impl->updateList(collection, updatePolicy);
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CRL.h b/vcore/src/vcore/CRL.h
new file mode 100644 (file)
index 0000000..2acda27
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.5
+ * @file        CRL.h
+ * @brief       Routines for certificate validation over CRL
+ */
+
+#ifndef _VALIDATION_CORE_ENGINE_CRL_H_
+#define _VALIDATION_CORE_ENGINE_CRL_H_
+
+#include <list>
+#include <string>
+
+#include <dpl/exception.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+
+#include <vcore/Certificate.h>
+#include <vcore/CertificateCollection.h>
+#include <vcore/VerificationStatus.h>
+#include <vcore/CRLCacheInterface.h>
+
+namespace ValidationCore {
+
+namespace CRLException {
+DECLARE_EXCEPTION_TYPE(DPL::Exception, CRLException)
+DECLARE_EXCEPTION_TYPE(CRLException, StorageError)
+DECLARE_EXCEPTION_TYPE(CRLException, DownloadFailed)
+DECLARE_EXCEPTION_TYPE(CRLException, InternalError)
+DECLARE_EXCEPTION_TYPE(CRLException, InvalidParameter)
+} // namespace CRLException
+
+class CRLImpl;
+
+class CRL : DPL::Noncopyable
+{
+public:
+    typedef std::list<std::string> StringList;
+
+    enum UpdatePolicy
+    {
+        UPDATE_ON_EXPIRED,  /**< Download and update CRL only when next update
+                                date has expired */
+        UPDATE_ON_DEMAND    /**< Download and update CRL regardless next update
+                                date */
+    };
+
+    struct RevocationStatus
+    {
+        bool isCRLValid;    /**< True when CRL was valid during
+                                certificate validation */
+        bool isRevoked;     /**< True when certificate is revoked */
+    };
+
+    CRL(CRLCacheInterface *ptr);
+    virtual ~CRL();
+
+    /**
+     * @brief Checks if given certificate is revoked.
+     *
+     * @details This function doesn't update CRL list. If related CRL
+     * is out of date the #isCRLValid return parameter is set to false.
+     *
+     * @param[in] argCert The certificate to check against revocation.
+     * @return RevocationStatus.isRevoked True when certificate is revoked,
+     *          false otherwise.
+     *         RevocationStatus.isCRLValid True if related CRL has not expired,
+     *          false otherwise.
+     */
+    RevocationStatus checkCertificate(const CertificatePtr &argCert);
+
+    /**
+     * @brief Checks if any certificate from certificate chain is revoked.
+     *
+     * @details This function doesn't update CRL lists. If any of related
+     * CRL is out of date the #isCRLValid parameter is set to true.
+     * This function adds valid certificates from the chain to internal storage
+     * map so they'll be available in further check operations for current
+     * CRL object.
+     *
+     * @param[in] argCert The certificate chain to check against revocation.
+     * @return RevocationStatus.isRevoked True when any from certificate chain
+     *          is revoked, false otherwise.
+     *         RevocationStatus.isCRLValid True if all of related CRLs has
+     *          not expired, false otherwise.
+     */
+    RevocationStatus checkCertificateChain(CertificateCollection certChain);
+
+    VerificationStatus checkEndEntity(CertificateCollection &chain);
+
+    /**
+     * @brief Updates CRL related with given certificate.
+     *
+     * @details This function updates CRL list related with given certificate.
+     * If CRL related with given certificate is not stored in database
+     * then this function will download CRL and store it in database.
+     *
+     * @param[in] argCert The certificate for which the CRL will be updated
+     * @param[in] updatePolicy Determine when CRL will be downloaded and updated
+     * @return True when CRL for given certificate was updated successfully,
+     *          false otherwise.
+     */
+    bool updateList(const CertificatePtr &argCert,
+                    const UpdatePolicy updatePolicy);
+
+    /**
+     * @brief Updates CRL related with given certificates.
+     *
+     * @details This function updates CRL lists related with given certificates.
+     * If CRL related with given certificate is not stored in database
+     * then this function will download CRL and store it in database.
+     *
+     * @param[in] collection The certificate collection for which the CRL will
+     *            be updated
+     * @param[in] updatePolicy Determine when CRL will be downloaded and updated
+     * @return True when CRL for given certificate was updated successfully,
+     *          false otherwise.
+     */
+    bool updateList(const CertificateCollection &collection,
+                    const UpdatePolicy updatePolisy);
+
+    /**
+     * @brief Add certificates to trusted certificates store.
+     *
+     * @param[in] collection The certificate collection which will be
+     *            added to known certificate store.
+     */
+    void addToStore(const CertificateCollection &collection);
+
+    /**
+     * @brief Add one certificate to trusted certificates store.
+     *
+     * @param[in] collection The certificate collection which will be
+     *            added to known certificate store.
+     */
+    void addToStore(const CertificatePtr &argCert);
+private:
+    friend class CachedCRL;
+    CRLImpl *m_impl;
+};
+
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_ENGINE_CRL_H_
diff --git a/vcore/src/vcore/CRLCacheDAO.cpp b/vcore/src/vcore/CRLCacheDAO.cpp
new file mode 100644 (file)
index 0000000..ad7fc86
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Bartlomiej Grzelewski(b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        CRLCacheDAO.cpp
+ * @brief       CRLCacheInterface implementation.
+ */
+
+#include <vcore/CRLCacheDAO.h>
+#include <vcore/CertificateCacheDAO.h>
+
+namespace ValidationCore {
+
+bool CRLCacheDAO::getCRLResponse(CRLCachedData *ptr){
+    return CertificateCacheDAO::getCRLResponse(ptr);
+}
+
+void CRLCacheDAO::setCRLResponse(CRLCachedData *ptr){
+    CertificateCacheDAO::setCRLResponse(ptr);
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CRLCacheDAO.h b/vcore/src/vcore/CRLCacheDAO.h
new file mode 100644 (file)
index 0000000..2dca09b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        CRLCacheDAO.h
+ * @brief       CRLCacheInterface implementation.
+ */
+#ifndef _CRLCACHEDAO_H_
+#define _CRLCACHEDAO_H_
+
+#include <vcore/CRLCacheInterface.h>
+
+namespace ValidationCore {
+
+class CRLCacheDAO : public CRLCacheInterface {
+public:
+    virtual bool getCRLResponse(CRLCachedData *ptr);
+    virtual void setCRLResponse(CRLCachedData *ptr);
+};
+
+} // namespace ValidationCore
+
+#endif
diff --git a/vcore/src/vcore/CRLCacheInterface.h b/vcore/src/vcore/CRLCacheInterface.h
new file mode 100644 (file)
index 0000000..1d17078
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski(b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        CRLCacheInterface.h
+ * @brief       CRLCacheInterface definition.
+ */
+#ifndef _CRLCACHEINTERFACE_H_
+#define _CRLCACHEINTERFACE_H_
+
+#include <string>
+
+namespace ValidationCore {
+
+struct CRLCachedData
+{
+    std::string distribution_point;
+    std::string crl_body;
+    time_t next_update_time;
+};
+
+class CRLCacheInterface {
+public:
+    virtual bool getCRLResponse(CRLCachedData *ptr) = 0;
+    virtual void setCRLResponse(CRLCachedData *ptr) = 0;
+};
+
+} // namespace ValidationCore
+
+#endif
diff --git a/vcore/src/vcore/CRLImpl.cpp b/vcore/src/vcore/CRLImpl.cpp
new file mode 100644 (file)
index 0000000..2fc4345
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version     0.2
+ * @file        CRLImpl.h
+ * @brief       Routines for certificate validation over CRL
+ */
+
+#include <vcore/CRL.h>
+#include <vcore/CRLImpl.h>
+
+#include <set>
+#include <algorithm>
+
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/ocsp.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_ptr.h>
+#include <dpl/scoped_array.h>
+#include <dpl/db/orm.h>
+#include <dpl/foreach.h>
+
+#include <vcore/Base64.h>
+#include <vcore/Certificate.h>
+#include <vcore/SoupMessageSendSync.h>
+#include <vcore/CRLCacheInterface.h>
+
+namespace {
+const char *CRL_LOOKUP_DIR_1 = "/usr/share/cert-svc/ca-certs/code-signing/wac";
+const char *CRL_LOOKUP_DIR_2 = "/opt/share/cert-svc/certs/code-signing/wac";
+} //anonymous namespace
+
+namespace ValidationCore {
+
+CRL::StringList CRLImpl::getCrlUris(const CertificatePtr &argCert)
+{
+    CRL::StringList result = argCert->getCrlUris();
+
+    if (!result.empty()) {
+        return result;
+    }
+    LogInfo("No distribution points found. Getting from CA cert.");
+    X509_STORE_CTX *ctx = createContext(argCert);
+    X509_OBJECT obj;
+
+    //Try to get distribution points from CA certificate
+    int retVal = X509_STORE_get_by_subject(ctx, X509_LU_X509,
+                                           X509_get_issuer_name(argCert->
+                                                                    getX509()),
+                                           &obj);
+    X509_STORE_CTX_free(ctx);
+    if (0 >= retVal) {
+        LogError("No dedicated CA certificate available");
+        return result;
+    }
+    CertificatePtr caCert(new Certificate(obj.data.x509));
+    X509_OBJECT_free_contents(&obj);
+    return caCert->getCrlUris();
+}
+
+CRLImpl::CRLImpl(CRLCacheInterface *ptr)
+  : m_crlCache(ptr)
+{
+    Assert(m_crlCache != NULL);
+
+    LogInfo("CRL storage initialization.");
+    m_store = X509_STORE_new();
+    if (!m_store) {
+        LogError("Failed to create new store.");
+        ThrowMsg(CRLException::StorageError,
+                 "Not possible to create new store.");
+    }
+    m_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir());
+    if (!m_lookup) {
+        cleanup();
+        LogError("Failed to add hash dir lookup");
+        ThrowMsg(CRLException::StorageError,
+                 "Not possible to add hash dir lookup.");
+    }
+    // Add hash dir pathname for CRL checks
+    bool retVal = X509_LOOKUP_add_dir(m_lookup,
+                                      CRL_LOOKUP_DIR_1, X509_FILETYPE_PEM) == 1;
+    retVal &= retVal && (X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR_1,
+                                             X509_FILETYPE_ASN1) == 1);
+    retVal &= retVal && (X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR_2,
+                                             X509_FILETYPE_PEM) == 1);
+    retVal &= retVal && (X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR_2,
+                                             X509_FILETYPE_ASN1) == 1);
+    if (!retVal) {
+        LogError("Failed to add lookup dir for PEM files.");
+        cleanup();
+        ThrowMsg(CRLException::StorageError,
+                 "Failed to add lookup dir for PEM files.");
+    }
+    LogInfo("CRL storage initialization complete.");
+}
+
+CRLImpl::~CRLImpl()
+{
+    cleanup();
+    delete m_crlCache;
+}
+
+void CRLImpl::cleanup()
+{
+    LogInfo("Free CRL storage");
+    // STORE is responsible for LOOKUP release
+    //    X509_LOOKUP_free(m_lookup);
+    X509_STORE_free(m_store);
+}
+
+CRL::RevocationStatus CRLImpl::checkCertificate(const CertificatePtr &argCert)
+{
+    CRL::RevocationStatus retStatus = {false, false};
+    int retVal = 0;
+    CRL::StringList crlUris = getCrlUris(argCert);
+    FOREACH(it, crlUris) {
+        CRLDataPtr crl = getCRL(*it);
+        if (!crl) {
+            LogDebug("CRL not found for URI: " << *it);
+            continue;
+        }
+        X509_CRL *crlInternal = convertToInternal(crl);
+
+        //Check date
+        if (X509_CRL_get_nextUpdate(crlInternal)) {
+            retVal = X509_cmp_current_time(
+                    X509_CRL_get_nextUpdate(crlInternal));
+            retStatus.isCRLValid = retVal > 0;
+        } else {
+            // If nextUpdate is not set assume it is actual.
+            retStatus.isCRLValid = true;
+        }
+        LogInfo("CRL valid: " << retStatus.isCRLValid);
+        X509_REVOKED rev;
+        rev.serialNumber = X509_get_serialNumber(argCert->getX509());
+        // sk_X509_REVOKED_find returns index if serial number is found on list
+        retVal = sk_X509_REVOKED_find(crlInternal->crl->revoked, &rev);
+        X509_CRL_free(crlInternal);
+        retStatus.isRevoked = retVal != -1;
+        LogInfo("CRL revoked: " << retStatus.isRevoked);
+
+        if (!retStatus.isRevoked && isOutOfDate(crl)) {
+            LogDebug("Certificate is not Revoked, but CRL is outOfDate.");
+            continue;
+        }
+
+        return retStatus;
+    }
+    // If there is no CRL for any of URIs it means it's not possible to
+    // tell anything about revocation status but it's is not an error.
+    return retStatus;
+}
+
+CRL::RevocationStatus CRLImpl::checkCertificateChain(CertificateCollection
+                                                 certChain)
+{
+    if (!certChain.sort()) {
+        LogError("Certificate list doesn't create chain.");
+        ThrowMsg(CRLException::InvalidParameter,
+                 "Certificate list doesn't create chain.");
+    }
+
+    CRL::RevocationStatus ret;
+    ret.isCRLValid = true;
+    ret.isRevoked = false;
+    const CertificateList &certList = certChain.getChain();
+    FOREACH(it, certList) {
+        if (!(*it)->isRootCert()) {
+            LogInfo("Certificate common name: " << *((*it)->getCommonName()));
+            CRL::RevocationStatus certResult = checkCertificate(*it);
+            ret.isCRLValid &= certResult.isCRLValid;
+            ret.isRevoked |= certResult.isRevoked;
+            if (ret.isCRLValid && !ret.isRevoked) {
+                addToStore(*it);
+            }
+            if (ret.isRevoked) {
+                return ret;
+            }
+        }
+    }
+    return ret;
+}
+
+VerificationStatus CRLImpl::checkEndEntity(CertificateCollection &chain)
+{
+    if (!chain.sort() && !chain.empty()) {
+        LogInfo("Could not find End Entity certificate. "
+                "Collection does not form chain.");
+        return VERIFICATION_STATUS_ERROR;
+    }
+    CertificateList::const_iterator iter = chain.begin();
+    CRL::RevocationStatus stat = checkCertificate(*iter);
+    if (stat.isRevoked) {
+        return VERIFICATION_STATUS_REVOKED;
+    }
+    if (stat.isCRLValid) {
+        return VERIFICATION_STATUS_GOOD;
+    }
+    return VERIFICATION_STATUS_ERROR;
+}
+
+void CRLImpl::addToStore(const CertificatePtr &argCert)
+{
+    X509_STORE_add_cert(m_store, argCert->getX509());
+}
+
+bool CRLImpl::isOutOfDate(const CRLDataPtr &crl) const {
+    X509_CRL *crlInternal = convertToInternal(crl);
+
+    bool result = false;
+    if (X509_CRL_get_nextUpdate(crlInternal)) {
+        if (0 > X509_cmp_current_time(X509_CRL_get_nextUpdate(crlInternal))) {
+            result = true;
+        } else {
+            result = false;
+        }
+    } else {
+        result = true;
+    }
+    X509_CRL_free(crlInternal);
+    return result;
+}
+
+bool CRLImpl::updateList(const CertificatePtr &argCert,
+    const CRL::UpdatePolicy updatePolicy)
+{
+    LogInfo("Update CRL for certificate");
+
+    // Retrieve distribution points
+    CRL::StringList crlUris = getCrlUris(argCert);
+    FOREACH(it, crlUris) {
+        // Try to get CRL from database
+        LogInfo("Getting CRL for URI: " << *it);
+
+        bool downloaded = false;
+
+        CRLDataPtr crl;
+
+        // If updatePolicy == UPDATE_ON_DEMAND we dont care
+        // about data in cache. New crl must be downloaded.
+        if (updatePolicy == CRL::UPDATE_ON_EXPIRED) {
+            crl = getCRL(*it);
+        }
+
+        if (!!crl && isOutOfDate(crl)) {
+            LogDebug("Crl out of date - downloading.");
+            crl = downloadCRL(*it);
+            downloaded = true;
+        }
+
+        if (!crl) {
+            LogDebug("Crl not found in cache - downloading.");
+            crl = downloadCRL(*it);
+            downloaded = true;
+        }
+
+        if (!crl) {
+            LogDebug("Failed to obtain CRL. URL: " << *it);
+            continue;
+        }
+
+        if (!!crl && isOutOfDate(crl)) {
+            LogError("CRL out of date. Broken URL: " << *it);
+        }
+
+        // Make X509 internal structure
+        X509_CRL *crlInternal = convertToInternal(crl);
+
+        //Check if CRL is signed
+        if (!verifyCRL(crlInternal, argCert)) {
+            LogError("Failed to verify CRL. URI: " << crl->uri);
+            X509_CRL_free(crlInternal);
+            return false;
+        }
+        X509_CRL_free(crlInternal);
+
+        if (downloaded) {
+            updateCRL(crl);
+        }
+        return true;
+    }
+
+    return false;
+}
+
+void CRLImpl::addToStore(const CertificateCollection &collection)
+{
+    FOREACH(it, collection){
+        addToStore(*it);
+    }
+}
+
+bool CRLImpl::updateList(const CertificateCollection &collection,
+    CRL::UpdatePolicy updatePolicy)
+{
+    bool failed = false;
+
+    FOREACH(it, collection){
+        failed |= !updateList(*it, updatePolicy);
+    }
+
+    return !failed;
+}
+
+bool CRLImpl::verifyCRL(X509_CRL *crl,
+                    const CertificatePtr &cert)
+{
+    X509_OBJECT obj;
+    X509_STORE_CTX *ctx = createContext(cert);
+
+    /* get issuer certificate */
+    int retVal = X509_STORE_get_by_subject(ctx, X509_LU_X509,
+                                           X509_CRL_get_issuer(crl), &obj);
+    X509_STORE_CTX_free(ctx);
+    if (0 >= retVal) {
+        LogError("Unknown CRL issuer certificate!");
+        return false;
+    }
+
+    /* extract public key and verify signature */
+    EVP_PKEY *pkey = X509_get_pubkey(obj.data.x509);
+    X509_OBJECT_free_contents(&obj);
+    if (!pkey) {
+        LogError("Failed to get issuer's public key.");
+        return false;
+    }
+    retVal = X509_CRL_verify(crl, pkey);
+    EVP_PKEY_free(pkey);
+    if (0 > retVal) {
+        LogError("Failed to verify CRL.");
+        return false;
+    } else if (0 == retVal) {
+        LogError("CRL is invalid");
+        return false;
+    }
+    LogInfo("CRL is valid.");
+    return true;
+}
+
+bool CRLImpl::isPEMFormat(const CRLDataPtr &crl) const
+{
+    const char *pattern = "-----BEGIN X509 CRL-----";
+    std::string content(crl->buffer, crl->length);
+    if (content.find(pattern) != std::string::npos) {
+        LogInfo("CRL is in PEM format.");
+        return true;
+    }
+    LogInfo("CRL is in DER format.");
+    return false;
+}
+
+X509_CRL *CRLImpl::convertToInternal(const CRLDataPtr &crl) const
+{
+    //At this point it's not clear does crl have DER or PEM format
+    X509_CRL *ret = NULL;
+    if (isPEMFormat(crl)) {
+        BIO *bmem = BIO_new_mem_buf(crl->buffer, crl->length);
+        if (!bmem) {
+            LogError("Failed to allocate memory in BIO");
+            ThrowMsg(CRLException::InternalError,
+                     "Failed to allocate memory in BIO");
+        }
+        ret = PEM_read_bio_X509_CRL(bmem, NULL, NULL, NULL);
+        BIO_free_all(bmem);
+    } else {
+        //If it's not PEM it must be DER format
+        std::string content(crl->buffer, crl->length);
+        const unsigned char *buffer =
+            reinterpret_cast<unsigned char*>(crl->buffer);
+        ret = d2i_X509_CRL(NULL, &buffer, crl->length);
+    }
+    if (!ret) {
+        LogError("Failed to convert to internal structure");
+        ThrowMsg(CRLException::InternalError,
+                 "Failed to convert to internal structure");
+    }
+    return ret;
+}
+
+X509_STORE_CTX *CRLImpl::createContext(const CertificatePtr &argCert)
+{
+    X509_STORE_CTX *ctx;
+    ctx = X509_STORE_CTX_new();
+    if (!ctx) {
+        ThrowMsg(CRLException::StorageError, "Failed to create new context.");
+    }
+    X509_STORE_CTX_init(ctx, m_store, argCert->getX509(), NULL);
+    return ctx;
+}
+
+CRLImpl::CRLDataPtr CRLImpl::downloadCRL(const std::string &uri)
+{
+    using namespace SoupWrapper;
+
+    char *cport = 0, *chost = 0,*cpath = 0;
+    int use_ssl = 0;
+
+    if (!OCSP_parse_url(const_cast<char*>(uri.c_str()),
+                        &chost,
+                        &cport,
+                        &cpath,
+                        &use_ssl))
+    {
+        LogWarning("Error in OCSP_parse_url");
+        return CRLDataPtr();
+    }
+
+    std::string host = chost;
+    if (cport) {
+        host += ":";
+        host += cport;
+    }
+
+    free(cport);
+    free(chost);
+    free(cpath);
+
+    SoupMessageSendSync message;
+    message.setHost(uri);
+    message.setHeader("Host", host);
+
+    if (SoupMessageSendSync::REQUEST_STATUS_OK != message.sendSync()) {
+        LogWarning("Error in sending network request.");
+        return CRLDataPtr();
+    }
+
+    SoupMessageSendBase::MessageBuffer mBuffer = message.getResponse();
+    return CRLDataPtr(new CRLData(mBuffer,uri));
+}
+
+CRLImpl::CRLDataPtr CRLImpl::getCRL(const std::string &uri) const
+{
+    CRLCachedData cachedCrl;
+    cachedCrl.distribution_point = uri;
+    if (!(m_crlCache->getCRLResponse(&cachedCrl))) {
+        LogInfo("CRL not present in database. URI: " << uri);
+        return CRLDataPtr();
+    }
+
+    std::string body = cachedCrl.crl_body;
+
+    LogInfo("CRL found in database.");
+    //TODO: remove when ORM::blob available
+    //Encode buffer to base64 format to store in database
+
+    Base64Decoder decoder;
+    decoder.append(body);
+    if (!decoder.finalize()) {
+        LogError("Failed to decode base64 format.");
+        ThrowMsg(CRLException::StorageError, "Failed to decode base64 format.");
+    }
+    std::string crlBody = decoder.get();
+
+    DPL::ScopedArray<char> bodyBuffer(new char[crlBody.length()]);
+    crlBody.copy(bodyBuffer.Get(), crlBody.length());
+    return CRLDataPtr(new CRLData(bodyBuffer.Release(), crlBody.length(),
+                                  uri));
+}
+
+void CRLImpl::updateCRL(const CRLDataPtr &crl)
+{
+    //TODO: remove when ORM::blob available
+    //Encode buffer to base64 format to store in database
+    Base64Encoder encoder;
+    if (!crl || !crl->buffer) {
+        ThrowMsg(CRLException::InternalError, "CRL buffer is empty");
+    }
+    encoder.append(std::string(crl->buffer, crl->length));
+    encoder.finalize();
+    std::string b64CRLBody = encoder.get();
+
+    time_t nextUpdateTime = 0;
+    X509_CRL *crlInternal = convertToInternal(crl);
+
+    if (X509_CRL_get_nextUpdate(crlInternal)) {
+        asn1TimeToTimeT(X509_CRL_get_nextUpdate(crlInternal),
+                        &nextUpdateTime);
+    }
+
+    X509_CRL_free(crlInternal);
+    //Update/insert crl body
+    CRLCachedData data;
+    data.distribution_point = crl->uri;
+    data.crl_body = b64CRLBody;
+    data.next_update_time = nextUpdateTime;
+
+    m_crlCache->setCRLResponse(&data);
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CRLImpl.h b/vcore/src/vcore/CRLImpl.h
new file mode 100644 (file)
index 0000000..e9f90c4
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version     0.4
+ * @file        CRLImpl.h
+ * @brief       Routines for certificate validation over CRL
+ */
+
+#ifndef _VALIDATION_CORE_ENGINE_CRLIMPL_H_
+#define _VALIDATION_CORE_ENGINE_CRLIMPL_H_
+
+#include <dpl/exception.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/log.h>
+
+#include <openssl/x509.h>
+
+#include <vcore/CRL.h>
+#include <vcore/Certificate.h>
+#include <vcore/CertificateCollection.h>
+#include <vcore/SoupMessageSendBase.h>
+#include <vcore/VerificationStatus.h>
+#include <vcore/CRLCacheInterface.h>
+#include <vcore/TimeConversion.h>
+
+namespace ValidationCore {
+
+class CRLImpl : DPL::Noncopyable
+{
+  protected:
+    X509_STORE *m_store;
+    X509_LOOKUP *m_lookup;
+    CRLCacheInterface *m_crlCache;
+
+    class CRLData : DPL::Noncopyable
+    {
+      public:
+        //TODO: change to SharedArray when available
+        char *buffer;
+        size_t length;
+        std::string uri;
+
+        CRLData(char* _buffer,
+                size_t _length,
+                const std::string &_uri) :
+            buffer(_buffer),
+            length(_length),
+            uri(_uri)
+        {
+        }
+
+        CRLData(const SoupWrapper::SoupMessageSendBase::MessageBuffer &mBuff,
+                const std::string &mUri)
+        : uri(mUri)
+        {
+            buffer = new char[mBuff.size()];
+            length = mBuff.size();
+            memcpy(buffer, &mBuff[0], mBuff.size());
+        }
+
+        ~CRLData()
+        {
+            LogInfo("Delete buffer");
+            delete[] buffer;
+        }
+    };
+    typedef DPL::SharedPtr<CRLData> CRLDataPtr;
+
+    CRLDataPtr getCRL(const std::string &uri) const;
+    CRLDataPtr downloadCRL(const std::string &uri);
+    X509_STORE_CTX *createContext(const CertificatePtr &argCert);
+    void updateCRL(const CRLDataPtr &crl);
+    X509_CRL *convertToInternal(const CRLDataPtr &crl) const;
+    CRL::StringList getCrlUris(const CertificatePtr &argCert);
+    bool isPEMFormat(const CRLDataPtr &crl) const;
+    bool verifyCRL(X509_CRL *crl,
+                   const CertificatePtr &cert);
+    void cleanup();
+    bool isOutOfDate(const CRLDataPtr &crl) const;
+
+    friend class CachedCRL;
+  public:
+    CRLImpl(CRLCacheInterface *ptr);
+    ~CRLImpl();
+
+    /**
+     * @brief Checks if given certificate is revoked.
+     *
+     * @details This function doesn't update CRL list. If related CRL
+     * is out of date the #isCRLValid return parameter is set to false.
+     *
+     * @param[in] argCert The certificate to check against revocation.
+     * @return RevocationStatus.isRevoked True when certificate is revoked,
+     *          false otherwise.
+     *         RevocationStatus.isCRLValid True if related CRL has not expired,
+     *          false otherwise.
+     */
+    CRL::RevocationStatus checkCertificate(const CertificatePtr &argCert);
+
+    /**
+     * @brief Checks if any certificate from certificate chain is revoked.
+     *
+     * @details This function doesn't update CRL lists. If any of related
+     * CRL is out of date the #isCRLValid parameter is set to true.
+     * This function adds valid certificates from the chain to internal storage
+     * map so they'll be available in further check operations for current
+     * CRL object.
+     *
+     * @param[in] argCert The certificate chain to check against revocation.
+     * @return RevocationStatus.isRevoked True when any from certificate chain
+     *          is revoked, false otherwise.
+     *         RevocationStatus.isCRLValid True if all of related CRLs has
+     *          not expired, false otherwise.
+     */
+    CRL::RevocationStatus checkCertificateChain(CertificateCollection certChain);
+
+    VerificationStatus checkEndEntity(CertificateCollection &chain);
+
+    /**
+     * @brief Updates CRL related with given certificate.
+     *
+     * @details This function updates CRL list related with given certificate.
+     * If CRL related with given certificate is not stored in database
+     * then this function will download CRL and store it in database.
+     *
+     * @param[in] argCert The certificate for which the CRL will be updated
+     * @param[in] updatePolicy Determine when CRL will be downloaded and updated
+     * @return True when CRL for given certificate was updated successfully,
+     *          false otherwise.
+     */
+    bool updateList(const CertificatePtr &argCert,
+                    const CRL::UpdatePolicy updatePolicy);
+
+    /**
+     * @brief Updates CRL related with given certificates.
+     *
+     * @details This function updates CRL lists related with given certificates.
+     * If CRL related with given certificate is not stored in database
+     * then this function will download CRL and store it in database.
+     *
+     * @param[in] collection The certificate collection for which the CRL will
+     *            be updated
+     * @param[in] updatePolicy Determine when CRL will be downloaded and updated
+     * @return True when CRL for given certificate was updated successfully,
+     *          false otherwise.
+     */
+    bool updateList(const CertificateCollection &collection,
+                    const CRL::UpdatePolicy updatePolisy);
+
+    /**
+     * @brief Add certificates to trusted certificates store.
+     *
+     * @param[in] collection The certificate collection which will be
+     *            added to known certificate store.
+     */
+    void addToStore(const CertificateCollection &collection);
+
+    /**
+     * @brief Add one certificate to trusted certificates store.
+     *
+     * @param[in] collection The certificate collection which will be
+     *            added to known certificate store.
+     */
+    void addToStore(const CertificatePtr &argCert);
+};
+
+} // ValidationCore
+
+#endif // _VALIDATION_CORE_ENGINE_CRLIMPL_H_
diff --git a/vcore/src/vcore/CachedCRL.cpp b/vcore/src/vcore/CachedCRL.cpp
new file mode 100644 (file)
index 0000000..dfcd04b
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * 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       CachedCRL.cpp
+ * @author     Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version    0.2
+ * @brief      Cached CRL class implementation
+ */
+#include <vcore/CachedCRL.h>
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+
+#include <vcore/CRLImpl.h>
+#include <vcore/CertificateCacheDAO.h>
+#include <vcore/CRLCacheDAO.h>
+
+namespace {
+
+const time_t CRL_minTimeValid = 3600;          // one hour in seconds
+
+const time_t CRL_maxTimeValid = 3600 * 24 * 7; // one week in seconds
+
+const time_t CRL_refreshBefore = 3600;         // one hour in seconds
+
+time_t getNextUpdateTime(time_t now, time_t response_validity)
+{
+    time_t min = now + CRL_minTimeValid;
+    time_t max = now + CRL_maxTimeValid;
+    if (response_validity < min) {
+        return min;
+    }
+    if (response_validity > max) {
+        return max;
+    }
+    return response_validity;
+}
+
+} // namespace anonymous
+
+namespace ValidationCore {
+
+time_t CachedCRL::getCRLMinTimeValid() {
+    return CRL_minTimeValid;
+}
+
+time_t CachedCRL::getCRLMaxTimeValid() {
+    return CRL_maxTimeValid;
+}
+
+time_t CachedCRL::getCRLRefreshBefore() {
+    return CRL_refreshBefore;
+}
+
+CachedCRL::CachedCRL(){}
+CachedCRL::~CachedCRL(){}
+
+VerificationStatus CachedCRL::check(const CertificateCollection &certs)
+{
+    CRLImpl crl(new CRLCacheDAO);
+    bool allValid = true;
+    // we dont check CRL validity since
+    // we may use crl for longer time
+    // in smart cache than in regular CRL class (time clamping)
+    crl.addToStore(certs);
+    FOREACH(cert, certs){
+        CRL::StringList crlUris = crl.getCrlUris(*cert);
+        FOREACH(uri, crlUris) {
+            allValid = allValid && updateCRLForUri(*uri,false);
+        }
+    }
+    if (!allValid) {
+        // problems with CRL validity
+        LogDebug("Some CRLs not valid");
+    }
+    CRL::RevocationStatus stat;
+    Try {
+        stat = crl.checkCertificateChain(certs);
+    } Catch(CRLException::InvalidParameter) {
+        // List does not form a chain
+        return VERIFICATION_STATUS_ERROR;
+    }
+    if (stat.isRevoked) {
+        LogDebug("Status REVOKED");
+        return VERIFICATION_STATUS_REVOKED;
+    }
+    LogDebug("Status GOOD");
+    return VERIFICATION_STATUS_GOOD;
+}
+
+VerificationStatus CachedCRL::checkEndEntity(CertificateCollection &certs)
+{
+    if (certs.empty()) {
+        LogError("Collection empty. This should never happen.");
+        LogDebug("Status ERROR");
+        return VERIFICATION_STATUS_ERROR;
+    }
+    if (!certs.sort()) {
+        LogError("Could not find End Entity certificate. "
+                "Collection does not form chain.");
+        LogDebug("Status ERROR");
+        return VERIFICATION_STATUS_ERROR;
+    }
+    CRLImpl crl(new CRLCacheDAO);
+    bool allValid = true;
+    // we dont check CRL validity since
+    // we may use crl for longer time
+    // in smart cache than in regular CRL class (time clamping)
+    crl.addToStore(certs);
+    CertificateList::const_iterator icert = certs.begin();
+    if (icert != certs.end()) {
+        CRL::StringList crlUris = crl.getCrlUris(*icert);
+        FOREACH(uri, crlUris) {
+            allValid = allValid && updateCRLForUri(*uri,false);
+        }
+    }
+    if (!allValid) {
+        // problems with CRL validity
+        LogDebug("Some CRLs not valid");
+    }
+    CertificateList::const_iterator iter = certs.begin();
+    CRL::RevocationStatus stat = crl.checkCertificate(*iter);
+    if (stat.isRevoked) {
+        LogDebug("Status REVOKED");
+        return VERIFICATION_STATUS_REVOKED;
+    }
+    LogDebug("Status GOOD");
+    return VERIFICATION_STATUS_GOOD;
+}
+
+void CachedCRL::updateCache()
+{
+    CRLCachedDataList list;
+    CertificateCacheDAO::getCRLResponseList(&list);
+    FOREACH(db_crl, list) {
+        updateCRLForUri(db_crl->distribution_point, true);
+    }
+}
+
+bool CachedCRL::updateCRLForUri(const std::string &uri, bool useExpiredShift)
+{
+    using namespace ValidationCore;
+    CRLCachedData cachedCRL;
+    cachedCRL.distribution_point = uri;
+    time_t now;
+    time(&now);
+    if (useExpiredShift) {
+        now += CRL_refreshBefore;
+    }
+    if (CertificateCacheDAO::getCRLResponse(&cachedCRL)) {
+        if (now < cachedCRL.next_update_time) {
+            LogDebug("Cached CRL still valid for: " << uri);
+            return true;
+        }
+    }
+    // need to download new CRL
+    CRLImpl crl(new CRLCacheDAO);
+    CRLImpl::CRLDataPtr list = crl.downloadCRL(uri);
+    if (!list) {
+        LogWarning("Could not retreive CRL from " << uri);
+        return false;
+    }
+    crl.updateCRL(list);
+    CertificateCacheDAO::getCRLResponse(&cachedCRL); // save it the way CRL does
+    cachedCRL.next_update_time =
+            getNextUpdateTime(now,cachedCRL.next_update_time);
+    CertificateCacheDAO::setCRLResponse(cachedCRL.distribution_point,
+                                        cachedCRL.crl_body,
+                                        cachedCRL.next_update_time);
+    return true;
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CachedCRL.h b/vcore/src/vcore/CachedCRL.h
new file mode 100644 (file)
index 0000000..f9ae64b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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       CachedCRL.h
+ * @author     Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version    0.2
+ * @brief      Header file for smart cached CRL class
+ */
+
+#ifndef _VALIDATION_CORE_CACHED_CRL_H_
+#define _VALIDATION_CORE_CACHED_CRL_H_
+
+#include <ctime>
+#include <string>
+
+#include <vcore/Certificate.h>
+#include <vcore/CertificateCollection.h>
+#include <vcore/VerificationStatus.h>
+#include <vcore/IAbstractResponseCache.h>
+
+namespace ValidationCore {
+
+class CachedCRL : public IAbstractResponseCache {
+public:
+    // cache can't be refreshed more frequently than CRL_minTimeValid
+    static time_t getCRLMinTimeValid();
+
+    // to be even more secure, cache will be refreshed for certificate at least
+    // after CRL_maxTimeValid from last response
+    static time_t getCRLMaxTimeValid();
+
+    // upon cache refresh, responses that will be invalid in CRL_refreshBefore
+    // seconds will be refreshed
+    static time_t getCRLRefreshBefore();
+
+    VerificationStatus check(const CertificateCollection &certs);
+    VerificationStatus checkEndEntity(CertificateCollection &certs);
+    void updateCache();
+
+    CachedCRL();
+
+    virtual ~CachedCRL();
+
+private:
+
+    // updates CRL cache for distributor URI
+    // useExpiredShift ==true should be used in cron/global cache update
+    // since it updates all CRLs that will be out of date in next
+    // CRL_refreshBefore seconds
+    bool updateCRLForUri(const std::string & uri, bool useExpiredShift);
+};
+
+} // namespace ValidationCore
+
+#endif /* _VALIDATION_CORE_CACHED_CRL_ */
diff --git a/vcore/src/vcore/CachedOCSP.cpp b/vcore/src/vcore/CachedOCSP.cpp
new file mode 100644 (file)
index 0000000..5bff52a
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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       CachedOCSP.cpp
+ * @author     Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version    0.1
+ * @brief      Cached OCSP class implementation
+ */
+
+#include <string>
+#include <time.h>
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/foreach.h>
+
+#include <vcore/OCSP.h>
+#include <vcore/OCSPImpl.h>
+#include <vcore/CachedOCSP.h>
+#include <vcore/Certificate.h>
+#include <vcore/CertificateCacheDAO.h>
+
+namespace {
+
+// one hour in seconds
+const time_t OCSP_minTimeValid = 3600;      // one hour in seconds
+
+// one week in seconds
+const time_t OCSP_maxTimeValid = 3600 * 24 * 7;
+
+// one hour in seconds
+const time_t OCSP_refreshBefore = 3600;
+
+} // anonymous namespace
+
+namespace ValidationCore {
+
+time_t CachedOCSP::getOCSPMinTimeValid() {
+    return OCSP_minTimeValid;
+}
+
+time_t CachedOCSP::getOCSPMaxTimeValid() {
+    return OCSP_maxTimeValid;
+}
+
+time_t CachedOCSP::getOCSPRefreshBefore() {
+    return OCSP_refreshBefore;
+}
+
+CachedOCSP::CachedOCSP(){}
+
+CachedOCSP::~CachedOCSP(){}
+
+VerificationStatus CachedOCSP::check(const CertificateCollection &certs)
+{
+    OCSPCachedStatus db_status;
+    time_t now;
+    time(&now);
+
+    db_status.cert_chain = certs.toBase64String();
+    db_status.end_entity_check = false;
+
+    if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
+        LogDebug("Found cache entry for OCSP");
+        if (now < db_status.next_update_time) {
+            LogDebug("Cache response valid");
+            return db_status.ocsp_status;
+        }
+    }
+
+    // here we need to get OCSP result and add/update cache
+    OCSP ocsp;
+    CertificateList list = certs.getChain();
+    ocsp.setTrustedStore(list);
+
+    VerificationStatusSet statusSet = ocsp.validateCertificateList(list);
+    db_status.ocsp_status = statusSet.convertToStatus();
+    db_status.next_update_time = ocsp.getResponseValidity();
+    CertificateCacheDAO::setOCSPStatus(db_status.cert_chain,
+                                       db_status.ocsp_status,
+                                       db_status.end_entity_check,
+                                       getNextUpdateTime(
+                                           now,
+                                           db_status.next_update_time));
+    return db_status.ocsp_status;
+}
+
+VerificationStatus CachedOCSP::checkEndEntity(CertificateCollection &certs)
+{
+    OCSPCachedStatus db_status;
+    time_t now;
+    time(&now);
+
+    db_status.cert_chain = certs.toBase64String();
+    db_status.end_entity_check = true;
+
+    if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
+        LogDebug("Found cache entry for OCSP");
+        if (now < db_status.next_update_time) {
+            LogDebug("Cache response valid");
+            return db_status.ocsp_status;
+        }
+    }
+
+    // here we need to send request via OCSP and add/update cache
+    CertificateList clst;
+    getCertsForEndEntity(certs, &clst);
+
+    OCSP ocsp;
+    ocsp.setTrustedStore(certs.getCertificateList());
+
+    const char *defResponderURI = getenv(OCSPImpl::DEFAULT_RESPONDER_URI_ENV);
+
+    if (defResponderURI) {
+        ocsp.setUseDefaultResponder(true);
+        ocsp.setDefaultResponder(defResponderURI);
+    }
+
+    VerificationStatusSet statusSet = ocsp.validateCertificateList(clst);
+    db_status.ocsp_status = statusSet.convertToStatus();
+    db_status.next_update_time = ocsp.getResponseValidity();
+
+    CertificateCacheDAO::setOCSPStatus(db_status.cert_chain,
+                                       db_status.ocsp_status,
+                                       db_status.end_entity_check,
+                                       getNextUpdateTime(
+                                           now,
+                                           db_status.next_update_time));
+
+    return db_status.ocsp_status;
+}
+
+void CachedOCSP::updateCache()
+{
+    time_t now;
+    time(&now);
+    now += OCSP_refreshBefore;
+    OCSPCachedStatusList list;
+    CertificateCacheDAO::getOCSPStatusList(&list);
+    FOREACH(db_status, list) {
+        if (now >= db_status->next_update_time) {
+            // this response needs to be refreshed
+            CertificateCollection col;
+            col.load(db_status->cert_chain);
+            if (!col.sort()) {
+                LogError("Certificate collection does not create chain.");
+                continue;
+            }
+
+            OCSP ocsp;
+            CertificateList chain = col.getChain();
+            ocsp.setTrustedStore(chain);
+
+            VerificationStatusSet statusSet;
+
+            if (db_status->end_entity_check) {
+                CertificateList clst;
+                getCertsForEndEntity(col, &clst);
+                statusSet = ocsp.validateCertificateList(clst);
+            } else {
+                statusSet = ocsp.validateCertificateList(chain);
+            }
+
+            db_status->ocsp_status = statusSet.convertToStatus();
+            db_status->next_update_time = ocsp.getResponseValidity();
+
+            CertificateCacheDAO::setOCSPStatus(db_status->cert_chain,
+                                               db_status->ocsp_status,
+                                               db_status->end_entity_check,
+                                               db_status->next_update_time);
+        }
+    }
+}
+
+void CachedOCSP::getCertsForEndEntity(
+        const CertificateCollection &certs, CertificateList* clst)
+{
+    if (NULL == clst) {
+        LogError("NULL pointer");
+        return;
+    }
+
+    if (certs.isChain() && certs.size() >= 2) {
+        CertificateList::const_iterator icert = certs.begin();
+        clst->push_back(*icert);
+        ++icert;
+        clst->push_back(*icert);
+    }
+}
+
+time_t CachedOCSP::getNextUpdateTime(time_t now, time_t response_validity)
+{
+    long min = now + OCSP_minTimeValid;
+    long max = now + OCSP_maxTimeValid;
+    if (response_validity < min) {
+        return min;
+    }
+    if (response_validity > max) {
+        return max;
+    }
+    return response_validity;
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CachedOCSP.h b/vcore/src/vcore/CachedOCSP.h
new file mode 100644 (file)
index 0000000..a6fe714
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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       CachedOCSP.h
+ * @author     Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version    0.1
+ * @brief      Header file for smart cached OCSP class
+ */
+
+#ifndef _SRC_VALIDATION_CORE_CACHED_OCSP_
+#define _SRC_VALIDATION_CORE_CACHED_OCSP_
+
+#include <vcore/OCSP.h>
+#include <vcore/IAbstractResponseCache.h>
+
+namespace ValidationCore {
+
+class CachedOCSP : public IAbstractResponseCache {
+  public:
+    // cache can't be refreshed more frequently than OCSP_minTimeValid
+    static time_t getOCSPMinTimeValid();
+    // to be even more secure, cache will be refreshed for certificate at least
+    // after OCSP_minTimeValid from last response
+    static time_t getOCSPMaxTimeValid();
+
+    // upon cache refresh, responses that will be invalid in OCSP_refreshBefore
+    // seconds will be refreshed
+    static time_t getOCSPRefreshBefore();
+
+    VerificationStatus check(const CertificateCollection &certs);
+    VerificationStatus checkEndEntity(CertificateCollection &certs);
+    void updateCache();
+
+    CachedOCSP();
+
+    virtual ~CachedOCSP();
+
+  private:
+
+    void getCertsForEndEntity(const CertificateCollection &certs,
+                              CertificateList* clst);
+    time_t getNextUpdateTime(time_t now, time_t response_validity);
+};
+
+} // namespace ValidationCore
+
+#endif /* _SRC_VALIDATION_CORE_CACHED_OCSP_ */
diff --git a/vcore/src/vcore/CertStoreType.cpp b/vcore/src/vcore/CertStoreType.cpp
new file mode 100644 (file)
index 0000000..9122b4f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @file        CertStoreType.cpp
+ * @version     1.0
+ * @brief       Identification of certificate domain. Certificate domains
+ *              were defined in WAC 1.0 documentation. This is a part
+ *              should be implemented in wrt-installer.
+ */
+#include <vcore/CertStoreType.h>
+
+namespace ValidationCore {
+namespace CertStoreId {
+
+Set::Set()
+  : m_certificateStorage(0)
+{}
+
+void Set::add(Type second) {
+    m_certificateStorage |= second;
+}
+
+bool Set::contains(Type second) const {
+    return static_cast<bool>(m_certificateStorage & second);
+}
+
+bool Set::isEmpty() const {
+    return m_certificateStorage == 0;
+}
+
+} // namespace CertStoreId
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CertStoreType.h b/vcore/src/vcore/CertStoreType.h
new file mode 100644 (file)
index 0000000..de3affc
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @file        CertStoreType.h
+ * @version     1.0
+ * @brief       Identification of certificate domain. Certificate domains
+ *              were defined in WAC 1.0 documentation. This is a part
+ *              should be implemented in wrt-installer.
+ */
+#ifndef _VALIDATION_CORE_CERTSTORETYPE_H_
+#define _VALIDATION_CORE_CERTSTORETYPE_H_
+
+namespace ValidationCore {
+namespace CertStoreId {
+typedef unsigned int Type;
+
+// RootCA certificates for developer mode.
+const Type DEVELOPER = 1;
+// RootCA certificates for author signatures.
+const Type WAC_PUBLISHER = 1 << 1;
+// RootCA certificates for wac-signed widgets.
+const Type WAC_ROOT = 1 << 2;
+// RootCA certificates for wac-members ie. operators, manufacturers.
+const Type WAC_MEMBER = 1 << 3;
+// RootCA certificates for tizen-member ie. samsung and operators
+const Type TIZEN_MEMBER = 1 << 4;
+// RootCA certificates used by orange
+const Type ORANGE_LEGACY = 1 << 5;
+
+class Set
+{
+  public:
+    Set();
+
+    void add(Type second);
+
+    bool contains(Type second) const;
+
+    bool isEmpty() const;
+
+  private:
+    Type m_certificateStorage;
+};
+
+} // namespace CertStoreId
+} // namespace ValidationCore
+
+#endif //  _VALIDATION_CORE_CERTSTORETYPE_H_
diff --git a/vcore/src/vcore/Certificate.cpp b/vcore/src/vcore/Certificate.cpp
new file mode 100644 (file)
index 0000000..45c751d
--- /dev/null
@@ -0,0 +1,563 @@
+/*
+ * 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        Certificate.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include <vcore/Certificate.h>
+
+#include <memory>
+#include <sstream>
+#include <iomanip>
+
+#include <openssl/x509v3.h>
+#include <openssl/bn.h>
+
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+
+#include <vcore/Base64.h>
+#include <vcore/TimeConversion.h>
+
+namespace ValidationCore {
+
+Certificate::Certificate(X509 *cert)
+{
+    Assert(cert);
+    m_x509 = X509_dup(cert);
+    if (!m_x509) {
+        LogWarning("Internal Openssl error in d2i_X509 function.");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Internal Openssl error in d2i_X509 function.");
+    }
+}
+
+Certificate::Certificate(cert_svc_mem_buff &buffer)
+{
+    Assert(buffer.data);
+    const unsigned char *ptr = buffer.data;
+    m_x509 = d2i_X509(NULL, &ptr, buffer.size);
+    if (!m_x509) {
+        LogWarning("Internal Openssl error in d2i_X509 function.");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Internal Openssl error in d2i_X509 function.");
+    }
+}
+
+Certificate::Certificate(const std::string &der,
+                         Certificate::FormType form)
+{
+    Assert(der.size());
+
+    int size;
+    const unsigned char *ptr;
+    std::string tmp;
+
+    if (FORM_BASE64 == form) {
+        Base64Decoder base64;
+        base64.reset();
+        base64.append(der);
+        base64.finalize();
+        tmp = base64.get();
+        ptr = reinterpret_cast<const unsigned char*>(tmp.c_str());
+        size = static_cast<int>(tmp.size());
+    } else {
+        ptr = reinterpret_cast<const unsigned char*>(der.c_str());
+        size = static_cast<int>(der.size());
+    }
+
+    m_x509 = d2i_X509(NULL, &ptr, size);
+    if (!m_x509) {
+        LogError("Internal Openssl error in d2i_X509 function.");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Internal Openssl error in d2i_X509 function.");
+    }
+}
+
+Certificate::~Certificate()
+{
+    X509_free(m_x509);
+}
+
+X509* Certificate::getX509(void) const
+{
+    return m_x509;
+}
+
+std::string Certificate::getDER(void) const
+{
+    unsigned char *rawDer = NULL;
+    int size = i2d_X509(m_x509, &rawDer);
+    if (!rawDer || size <= 0) {
+        LogError("i2d_X509 failed");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "i2d_X509 failed");
+    }
+
+    std::string output(reinterpret_cast<char*>(rawDer), size);
+    OPENSSL_free(rawDer);
+    return output;
+}
+
+std::string Certificate::getBase64(void) const
+{
+    Base64Encoder base64;
+    base64.reset();
+    base64.append(getDER());
+    base64.finalize();
+    return base64.get();
+}
+
+bool Certificate::isSignedBy(const CertificatePtr &parent) const
+{
+    if (!parent) {
+        LogDebug("Invalid certificate parameter.");
+        return false;
+    }
+    return 0 == X509_NAME_cmp(X509_get_subject_name(parent->m_x509),
+                              X509_get_issuer_name(m_x509));
+}
+
+Certificate::Fingerprint Certificate::getFingerprint(
+        Certificate::FingerprintType type) const
+{
+    size_t fingerprintlength = EVP_MAX_MD_SIZE;
+    unsigned char fingerprint[EVP_MAX_MD_SIZE];
+    Fingerprint raw;
+
+    if (type == FINGERPRINT_MD5) {
+        if (!X509_digest(m_x509, EVP_md5(), fingerprint, &fingerprintlength)) {
+            LogError("MD5 digest counting failed!");
+            ThrowMsg(Exception::OpensslInternalError,
+                     "MD5 digest counting failed!");
+        }
+    }
+
+    if (type == FINGERPRINT_SHA1) {
+        if (!X509_digest(m_x509, EVP_sha1(), fingerprint,
+                         &fingerprintlength))
+        {
+            LogError("SHA1 digest counting failed");
+            ThrowMsg(Exception::OpensslInternalError,
+                     "SHA1 digest counting failed!");
+        }
+    }
+
+    raw.resize(fingerprintlength); // improve performance
+    std::copy(fingerprint, fingerprint + fingerprintlength, raw.begin());
+
+    return raw;
+}
+
+X509_NAME *Certificate::getX509Name(FieldType type) const
+{
+    X509_NAME *name = NULL;
+
+    switch (type) {
+    case FIELD_ISSUER:
+        name = X509_get_issuer_name(m_x509);
+        break;
+    case FIELD_SUBJECT:
+        name = X509_get_subject_name(m_x509);
+        break;
+    default:
+        Assert("Invalid field type.");
+    }
+
+    if (!name) {
+        LogError("Error during x509 name extraction.");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error during x509 name extraction.");
+    }
+
+    return name;
+}
+
+DPL::String Certificate::getOneLine(FieldType type) const
+{
+    X509_NAME *name = getX509Name(type);
+    static const int MAXB = 1024;
+    char buffer[MAXB];
+    X509_NAME_oneline(name, buffer, MAXB);
+    return DPL::FromUTF8String(buffer);
+}
+
+DPL::OptionalString Certificate::getField(FieldType type,
+                                     int fieldNid) const
+{
+    X509_NAME *subjectName = getX509Name(type);
+    X509_NAME_ENTRY *subjectEntry = NULL;
+    DPL::Optional < DPL::String > output;
+    int entryCount = X509_NAME_entry_count(subjectName);
+
+    for (int i = 0; i < entryCount; ++i) {
+        subjectEntry = X509_NAME_get_entry(subjectName,
+                                           i);
+
+        if (!subjectEntry) {
+            continue;
+        }
+
+        int nid = OBJ_obj2nid(
+            static_cast<ASN1_OBJECT*>(
+                    X509_NAME_ENTRY_get_object(subjectEntry)));
+
+        if (nid != fieldNid) {
+            continue;
+        }
+
+        ASN1_STRING* pASN1Str = subjectEntry->value;
+
+        unsigned char* pData = NULL;
+        int nLength = ASN1_STRING_to_UTF8(&pData,
+                                          pASN1Str);
+
+        if (nLength < 0) {
+            LogError("Reading field error.");
+            ThrowMsg(Exception::OpensslInternalError,
+                     "Reading field error.");
+        }
+
+        std::string strEntry(reinterpret_cast<char*>(pData),
+                             nLength);
+        output = DPL::FromUTF8String(strEntry);
+        OPENSSL_free(pData);
+    }
+    return output;
+}
+
+DPL::OptionalString Certificate::getCommonName(FieldType type) const
+{
+    return getField(type, NID_commonName);
+}
+
+DPL::OptionalString Certificate::getCountryName(FieldType type) const
+{
+    return getField(type, NID_countryName);
+}
+
+DPL::OptionalString Certificate::getStateOrProvinceName(FieldType type) const
+{
+    return getField(type, NID_stateOrProvinceName);
+}
+
+DPL::OptionalString Certificate::getLocalityName(FieldType type) const
+{
+    return getField(type, NID_localityName);
+}
+
+DPL::OptionalString Certificate::getOrganizationName(FieldType type) const
+{
+    return getField(type, NID_organizationName);
+}
+
+DPL::OptionalString Certificate::getOrganizationalUnitName(FieldType type) const
+{
+    return getField(type, NID_organizationalUnitName);
+}
+
+DPL::OptionalString Certificate::getEmailAddres(FieldType type) const
+{
+    return getField(type, NID_pkcs9_emailAddress);
+}
+
+DPL::OptionalString Certificate::getOCSPURL() const
+{
+    // TODO verify this code
+    DPL::OptionalString retValue;
+    AUTHORITY_INFO_ACCESS *aia = static_cast<AUTHORITY_INFO_ACCESS*>(
+            X509_get_ext_d2i(m_x509,
+                             NID_info_access,
+                             NULL,
+                             NULL));
+
+    // no AIA extension in the cert
+    if (NULL == aia) {
+        return retValue;
+    }
+
+    int count = sk_ACCESS_DESCRIPTION_num(aia);
+
+    for (int i = 0; i < count; ++i) {
+        ACCESS_DESCRIPTION* ad = sk_ACCESS_DESCRIPTION_value(aia, i);
+
+        if (OBJ_obj2nid(ad->method) == NID_ad_OCSP &&
+            ad->location->type == GEN_URI)
+        {
+            void* data = ASN1_STRING_data(ad->location->d.ia5);
+            retValue = DPL::OptionalString(DPL::FromUTF8String(
+                    static_cast<char*>(data)));
+
+            break;
+        }
+    }
+    sk_ACCESS_DESCRIPTION_free(aia);
+    return retValue;
+}
+
+Certificate::AltNameSet Certificate::getAlternativeNameDNS() const
+{
+    AltNameSet set;
+
+    GENERAL_NAME *namePart = NULL;
+
+    STACK_OF(GENERAL_NAME)* san =
+        static_cast<STACK_OF(GENERAL_NAME)*>(
+            X509_get_ext_d2i(m_x509,NID_subject_alt_name,NULL,NULL));
+
+    while (sk_GENERAL_NAME_num(san) > 0) {
+        namePart = sk_GENERAL_NAME_pop(san);
+        if (GEN_DNS == namePart->type) {
+            std::string temp =
+                reinterpret_cast<char*>(ASN1_STRING_data(namePart->d.dNSName));
+            DPL::String altDNSName = DPL::FromASCIIString(temp);
+            set.insert(altDNSName);
+            LogDebug("FOUND GEN_DNS: " << temp);
+        } else {
+            LogDebug("FOUND GEN TYPE ID: " << namePart->type);
+        }
+    }
+    return set;
+}
+
+time_t Certificate::getNotAfter() const
+{
+    ASN1_TIME *time = X509_get_notAfter(m_x509);
+    if (!time) {
+        LogError("Reading Not After error.");
+        ThrowMsg(Exception::OpensslInternalError, "Reading Not After error.");
+    }
+    time_t output;
+    if (asn1TimeToTimeT(time, &output)) {
+        LogError("Converting ASN1_time to time_t error.");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Converting ASN1_time to time_t error.");
+    }
+    return output;
+}
+
+time_t Certificate::getNotBefore() const
+{
+    ASN1_TIME *time = X509_get_notBefore(m_x509);
+    if (!time) {
+        LogError("Reading Not Before error.");
+        ThrowMsg(Exception::OpensslInternalError, "Reading Not Before error.");
+    }
+    time_t output;
+    if (asn1TimeToTimeT(time, &output)) {
+        LogError("Converting ASN1_time to time_t error.");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Converting ASN1_time to time_t error.");
+    }
+    return output;
+}
+
+bool Certificate::isRootCert()
+{
+    // based on that root certificate has the same subject as issuer name
+    return isSignedBy(this->SharedFromThis());
+}
+
+std::list<std::string>
+Certificate::getCrlUris() const
+{
+    std::list<std::string> result;
+
+    STACK_OF(DIST_POINT)* distPoints =
+        static_cast<STACK_OF(DIST_POINT)*>(
+            X509_get_ext_d2i(
+                getX509(),
+                NID_crl_distribution_points,
+                NULL,
+                NULL));
+    if (!distPoints) {
+        LogDebug("No distribution points in certificate.");
+        return result;
+    }
+
+    int count = sk_DIST_POINT_num(distPoints);
+    for (int i = 0; i < count; ++i) {
+        DIST_POINT* point = sk_DIST_POINT_value(distPoints, i);
+        if (!point) {
+            LogError("Failed to get distribution point.");
+            continue;
+        }
+        if (point->distpoint != NULL &&
+            point->distpoint->name.fullname != NULL)
+        {
+            int countName =
+                sk_GENERAL_NAME_num(point->distpoint->name.fullname);
+            for (int j = 0; j < countName; ++j) {
+                GENERAL_NAME* name = sk_GENERAL_NAME_value(
+                        point->distpoint->name.fullname, j);
+                if (name != NULL && GEN_URI == name->type) {
+                    char *crlUri =
+                    reinterpret_cast<char*>(name->d.ia5->data);
+                    if (!crlUri) {
+                        LogError("Failed to get URI.");
+                        continue;
+                    }
+                    result.push_back(crlUri);
+                }
+            }
+        }
+    }
+    sk_DIST_POINT_pop_free(distPoints, DIST_POINT_free);
+    return result;
+}
+
+long Certificate::getVersion() const
+{
+    return X509_get_version(m_x509);
+}
+
+DPL::String Certificate::getSerialNumberString() const
+{
+    ASN1_INTEGER *ai = X509_get_serialNumber(m_x509);
+    if (NULL == ai) {
+        LogError("Error in X509_get_serialNumber");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error in X509_get_serialNumber");
+    }
+    std::stringstream stream;
+    stream << std::hex << std::setfill('0');
+    if (ai->type == V_ASN1_NEG_INTEGER) {
+        stream << "(Negetive) ";
+    }
+    for (int i=0; i<ai->length; ++i) {
+        stream << std::setw(2) << (int)ai->data[i] << ":";
+    }
+    std::string data = stream.str();
+    if (!data.empty()) {
+        data.erase(--data.end());
+    }
+    return DPL::FromUTF8String(data);
+}
+
+DPL::String Certificate::getKeyUsageString() const
+{
+    // Extensions were defined in RFC 3280
+    const char *usage[] = {
+        "digitalSignature",
+        "nonRepudiation",
+        "keyEncipherment",
+        "dataEncipherment",
+        "keyAgreement",
+        "keyCertSign",
+        "cRLSign",
+        "encipherOnly",
+        "decipherOnly"
+    };
+    int crit = -1;
+    int idx = -1;
+    ASN1_BIT_STRING *keyUsage = (ASN1_BIT_STRING*)
+        X509_get_ext_d2i(m_x509, NID_key_usage, &crit, &idx);
+
+    std::stringstream stream;
+    for(int i=0; i<9; ++i) {
+        if (ASN1_BIT_STRING_get_bit(keyUsage, i)) {
+            stream << usage[i] << ",";
+        }
+    }
+    std::string result = stream.str();
+    if (!result.empty()) {
+        result.erase(--result.end());
+    }
+    return DPL::FromUTF8String(result);
+}
+
+DPL::String Certificate::getSignatureAlgorithmString() const
+{
+    std::unique_ptr<BIO, std::function<int(BIO*)>>
+        b(BIO_new(BIO_s_mem()),BIO_free);
+
+    if (b.get() == NULL) {
+        LogError("Error in BIO_new");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error in BIO_new");
+    }
+    if (i2a_ASN1_OBJECT(b.get(), m_x509->cert_info->signature->algorithm) < 0) {
+        LogError("Error in i2a_ASN1_OBJECT");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error in i2a_ASN1_OBJECT");
+    }
+    BUF_MEM *bptr = 0;
+    BIO_get_mem_ptr(b.get(), &bptr);
+    if (bptr == 0) {
+        LogError("Error in BIO_get_mem_ptr");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error in BIO_get_mem_ptr");
+    }
+    std::string result(bptr->data, bptr->length);
+    return DPL::FromUTF8String(result);
+}
+
+DPL::String Certificate::getPublicKeyString() const
+{
+    std::unique_ptr<BIO, std::function<int(BIO*)>>
+        b(BIO_new(BIO_s_mem()),BIO_free);
+
+    if (b.get() == NULL) {
+        LogError("Error in BIO_new");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error in BIO_new");
+    }
+    EVP_PKEY *pkey = X509_get_pubkey(m_x509);
+    if (pkey == NULL) {
+        LogError("Error in X509_get_pubkey");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error in X509_get_pubkey");
+    }
+    EVP_PKEY_print_public(b.get(), pkey, 16, NULL);
+    EVP_PKEY_free(pkey);
+
+    BUF_MEM *bptr = 0;
+    BIO_get_mem_ptr(b.get(), &bptr);
+    if (bptr == 0) {
+        LogError("Error in BIO_get_mem_ptr");
+        ThrowMsg(Exception::OpensslInternalError,
+                 "Error in BIO_get_mem_ptr");
+    }
+    std::string result(bptr->data, bptr->length);
+    return DPL::FromUTF8String(result);
+}
+
+int Certificate::isCA() const {
+    return X509_check_ca(m_x509);
+}
+
+std::string Certificate::FingerprintToColonHex(
+        const Certificate::Fingerprint &fingerprint)
+{
+    std::string outString;
+    char buff[8];
+
+    for (size_t i = 0; i < fingerprint.size(); ++i) {
+        snprintf(buff,
+                 sizeof(buff),
+                 "%02X:",
+                 static_cast<unsigned int>(fingerprint[i]));
+        outString += buff;
+    }
+
+    // remove trailing ":"
+    outString.erase(outString.end() - 1);
+    return outString;
+}
+
+} //  namespace ValidationCore
diff --git a/vcore/src/vcore/Certificate.h b/vcore/src/vcore/Certificate.h
new file mode 100644 (file)
index 0000000..5e94d7c
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * 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        Certificate.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.1
+ * @brief
+ */
+#ifndef _VALIDATION_CORE_CERTIFICATE_H_
+#define _VALIDATION_CORE_CERTIFICATE_H_
+
+#include <list>
+#include <set>
+#include <string>
+#include <vector>
+#include <ctime>
+
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/enable_shared_from_this.h>
+#include <dpl/optional.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/string.h>
+
+#include <cert-service.h>
+
+extern "C" {
+struct x509_st;
+typedef struct x509_st X509;
+struct X509_name_st;
+typedef struct X509_name_st X509_NAME;
+}
+
+namespace ValidationCore {
+
+class Certificate;
+
+typedef DPL::SharedPtr<Certificate> CertificatePtr;
+typedef std::list<CertificatePtr> CertificateList;
+
+class Certificate : public DPL::EnableSharedFromThis<Certificate>
+{
+  public:
+    typedef std::vector<unsigned char> Fingerprint;
+    typedef DPL::String AltName;
+    typedef std::set<AltName> AltNameSet;
+
+    enum FingerprintType
+    {
+        FINGERPRINT_MD5,
+        FINGERPRINT_SHA1
+    };
+    enum FieldType
+    {
+        FIELD_ISSUER,
+        FIELD_SUBJECT
+    };
+
+    enum FormType
+    {
+        FORM_DER,
+        FORM_BASE64
+    };
+
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, OpensslInternalError)
+    };
+
+    explicit Certificate(X509 *cert);
+
+    explicit Certificate(cert_svc_mem_buff &buffer);
+
+    explicit Certificate(const std::string &der,
+                         FormType form = FORM_DER);
+
+    ~Certificate();
+
+    // It returns pointer to internal structure!
+    // Do not free this pointer!
+    X509 *getX509(void) const;
+
+    std::string getDER(void) const;
+
+    std::string getBase64(void) const;
+
+    // This const is cheating here because you have no
+    // guarantee that X509_get_subject_name will not
+    // change X509 object.
+    bool isSignedBy(const CertificatePtr &parent) const;
+
+    Fingerprint getFingerprint(FingerprintType type) const;
+
+    // getName uses deprecated functions. Usage is strongly discouraged.
+    DPL::String getOneLine(FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getCommonName(FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getCountryName(FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getStateOrProvinceName(
+            FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getLocalityName(FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getOrganizationName(
+            FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getOrganizationalUnitName(
+            FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getEmailAddres(FieldType type = FIELD_SUBJECT) const;
+    DPL::OptionalString getOCSPURL() const;
+
+    // Openssl supports 9 types of alternative name filed.
+    // 4 of them are "string similar" types so it is possible
+    // to create more generic function.
+    AltNameSet getAlternativeNameDNS() const;
+
+    time_t getNotAfter() const;
+
+    time_t getNotBefore() const;
+
+    /**
+     * @brief This is convenient function.
+     *
+     * @details It can't be const function (however it doesn't change internal
+     * object). For details see #isSignedBy() function description.
+     */
+    bool isRootCert();
+
+    /**
+     * @brief Gets list of CRL distribution's points URIs
+     */
+    std::list<std::string> getCrlUris() const;
+
+    long getVersion() const;
+
+    DPL::String getSerialNumberString() const;
+
+    DPL::String getKeyUsageString() const;
+
+    DPL::String getSignatureAlgorithmString() const;
+
+    DPL::String getPublicKeyString() const;
+
+    /*
+     * 0 - not CA
+     * 1 - CA
+     * 2 - deprecated and not used
+     * 3 - older version of CA
+     * 4 - older version of CA
+     * 5 - netscape CA
+     */
+    int isCA() const;
+
+    static std::string FingerprintToColonHex(
+            const Fingerprint &fingerprint);
+
+  protected:
+    X509_NAME *getX509Name(FieldType type) const;
+
+    DPL::OptionalString getField(FieldType type,
+                            int fieldNid) const;
+
+    X509 *m_x509;
+};
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_CERTIFICATE_H_
diff --git a/vcore/src/vcore/CertificateCacheDAO.cpp b/vcore/src/vcore/CertificateCacheDAO.cpp
new file mode 100644 (file)
index 0000000..483702c
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * 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       CertificateCacheDAO.cpp
+ * @author     Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version    0.1
+ * @brief      CertificateCacheDAO implementation
+ */
+
+#include <vcore/CertificateCacheDAO.h>
+#include <vcore/VCorePrivate.h>
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+#include <dpl/db/orm.h>
+#include <orm_generator_vcore.h>
+#include <vcore/Database.h>
+
+using namespace DPL::DB::ORM;
+using namespace DPL::DB::ORM::vcore;
+
+namespace ValidationCore {
+
+void CertificateCacheDAO::setOCSPStatus(const std::string& cert_chain,
+                                        VerificationStatus ocsp_status,
+                                        bool end_entity_check,
+                                        time_t next_update_time)
+{
+    Try {
+        ScopedTransaction transaction(&ThreadInterface());
+        OCSPCachedStatus status;
+        status.cert_chain = cert_chain;
+        status.end_entity_check = end_entity_check;
+        if (getOCSPStatus(&status)) {
+            // only need to update data in DB
+            Equals<OCSPResponseStorage::cert_chain> e1(
+                            DPL::FromUTF8String(cert_chain));
+            Equals<OCSPResponseStorage::end_entity_check> e2(
+                            end_entity_check ? 1 : 0);
+
+            OCSPResponseStorage::Row row;
+
+            row.Set_ocsp_status(ocsp_status);
+            row.Set_next_update_time(next_update_time);
+
+            VCORE_DB_UPDATE(update, OCSPResponseStorage, &ThreadInterface())
+            update->Where(And(e1,e2));
+            update->Values(row);
+            update->Execute();
+        } else {
+            // need to insert data
+            OCSPResponseStorage::Row row;
+
+            row.Set_cert_chain(DPL::FromUTF8String(cert_chain));
+            row.Set_ocsp_status(ocsp_status);
+            row.Set_next_update_time(next_update_time);
+            row.Set_end_entity_check(end_entity_check ? 1 : 0);
+
+            VCORE_DB_INSERT(insert, OCSPResponseStorage, &ThreadInterface())
+            insert->Values(row);
+            insert->Execute();
+        }
+        transaction.Commit();
+    } Catch(DPL::DB::SqlConnection::Exception::Base) {
+        ReThrowMsg(Exception::DatabaseError, "Failed to setOCSPStatus");
+    }
+}
+
+bool CertificateCacheDAO::getOCSPStatus(OCSPCachedStatus* cached_status)
+{
+    if (NULL == cached_status) {
+        LogError("NULL pointer");
+        return false;
+    }
+    Try {
+        Equals<OCSPResponseStorage::cert_chain> e1(
+                DPL::FromUTF8String(cached_status->cert_chain));
+        Equals<OCSPResponseStorage::end_entity_check> e2(
+                cached_status->end_entity_check ? 1 : 0);
+
+        VCORE_DB_SELECT(select, OCSPResponseStorage, &ThreadInterface())
+
+        select->Where(And(e1,e2));
+        std::list<OCSPResponseStorage::Row> rows = select->GetRowList();
+        if (1 == rows.size()) {
+            OCSPResponseStorage::Row row = rows.front();
+            cached_status->ocsp_status = intToVerificationStatus(
+                    *(row.Get_ocsp_status()));
+            cached_status->next_update_time = *(row.Get_next_update_time());
+            return true;
+        }
+
+        LogDebug("Cached OCSP status not found");
+        return false;
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base) {
+        ReThrowMsg(Exception::DatabaseError, "Failed to getOCSPStatus");
+    }
+}
+
+void CertificateCacheDAO::getOCSPStatusList(
+        OCSPCachedStatusList* cached_status_list)
+{
+    if (NULL == cached_status_list) {
+        LogError("NULL pointer");
+        return;
+    }
+    Try {
+        VCORE_DB_SELECT(select, OCSPResponseStorage, &ThreadInterface())
+        typedef std::list<OCSPResponseStorage::Row> RowList;
+        RowList list = select->GetRowList();
+
+        FOREACH(i, list) {
+            OCSPCachedStatus status;
+            status.cert_chain = DPL::ToUTF8String(i->Get_cert_chain());
+            status.ocsp_status = intToVerificationStatus(
+                    *(i->Get_ocsp_status()));
+            status.end_entity_check =
+                    *(i->Get_end_entity_check()) == 1 ? true : false;
+            status.next_update_time = *(i->Get_next_update_time());
+            cached_status_list->push_back(status);
+        }
+
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base) {
+        ReThrowMsg(Exception::DatabaseError, "Failed to getOCSPStatusList");
+    }
+}
+
+
+void CertificateCacheDAO::setCRLResponse(const std::string& distribution_point,
+                                         const std::string& crl_body,
+                                         time_t next_update_time)
+{
+    Try {
+        ScopedTransaction transaction(&ThreadInterface());
+        CRLCachedData data;
+        data.distribution_point = distribution_point;
+        if (getCRLResponse(&data)) {
+            // only need to update data in DB
+            VCORE_DB_UPDATE(update, CRLResponseStorage, &ThreadInterface())
+            Equals<CRLResponseStorage::distribution_point> e1(
+                            DPL::FromUTF8String(distribution_point));
+            CRLResponseStorage::Row row;
+
+            update->Where(e1);
+            row.Set_crl_body(DPL::FromUTF8String(crl_body));
+            row.Set_next_update_time(next_update_time);
+            update->Values(row);
+            update->Execute();
+        } else {
+            // need to insert data
+            VCORE_DB_INSERT(insert, CRLResponseStorage, &ThreadInterface())
+            CRLResponseStorage::Row row;
+
+            row.Set_distribution_point(DPL::FromUTF8String(distribution_point));
+            row.Set_crl_body(DPL::FromUTF8String(crl_body));
+            row.Set_next_update_time(next_update_time);
+            insert->Values(row);
+            insert->Execute();
+        }
+        transaction.Commit();
+    } Catch(DPL::DB::SqlConnection::Exception::Base) {
+        ReThrowMsg(Exception::DatabaseError, "Failed to setOCSPStatus");
+    }
+}
+
+bool CertificateCacheDAO::getCRLResponse(CRLCachedData* cached_data)
+{
+    if (NULL == cached_data) {
+        LogError("NULL pointer");
+        return false;
+    }
+    Try {
+        VCORE_DB_SELECT(select, CRLResponseStorage, &ThreadInterface())
+        Equals<CRLResponseStorage::distribution_point> e1(
+                DPL::FromUTF8String(cached_data->distribution_point));
+
+        select->Where(e1);
+        std::list<CRLResponseStorage::Row> rows = select->GetRowList();
+        if (1 == rows.size()) {
+            CRLResponseStorage::Row row = rows.front();
+            cached_data->crl_body = DPL::ToUTF8String(row.Get_crl_body());
+            cached_data->next_update_time = *(row.Get_next_update_time());
+            return true;
+        }
+
+        LogDebug("Cached CRL not found");
+        return false;
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base) {
+        ReThrowMsg(Exception::DatabaseError, "Failed to getCRLResponse");
+    }
+}
+
+void CertificateCacheDAO::getCRLResponseList(
+        CRLCachedDataList* cached_data_list)
+{
+    if (NULL == cached_data_list) {
+        LogError("NULL pointer");
+        return;
+    }
+    Try {
+        VCORE_DB_SELECT(select, CRLResponseStorage, &ThreadInterface())
+        typedef std::list<CRLResponseStorage::Row> RowList;
+        RowList list = select->GetRowList();
+
+        FOREACH(i, list) {
+            CRLCachedData response;
+            response.distribution_point = DPL::ToUTF8String(
+                    i->Get_distribution_point());
+            response.crl_body = DPL::ToUTF8String(i->Get_crl_body());
+            response.next_update_time = *(i->Get_next_update_time());
+            cached_data_list->push_back(response);
+        }
+
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base) {
+        ReThrowMsg(Exception::DatabaseError, "Failed to getCRLResponses");
+    }
+}
+
+void CertificateCacheDAO::clearCertificateCache()
+{
+    Try {
+        ScopedTransaction transaction(&ThreadInterface());
+        VCORE_DB_DELETE(del1, OCSPResponseStorage, &ThreadInterface())
+        del1->Execute();
+        VCORE_DB_DELETE(del2, CRLResponseStorage, &ThreadInterface())
+        del2->Execute();
+        transaction.Commit();
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base) {
+        ReThrowMsg(Exception::DatabaseError, "Failed to clearUserSettings");
+    }
+}
+
+VerificationStatus CertificateCacheDAO::intToVerificationStatus(int p)
+{
+    switch (p) {
+    case 1:
+        return VERIFICATION_STATUS_GOOD;
+    case 1 << 1:
+        return VERIFICATION_STATUS_REVOKED;
+    case 1 << 2:
+        return VERIFICATION_STATUS_UNKNOWN;
+    case 1 << 3:
+        return VERIFICATION_STATUS_VERIFICATION_ERROR;
+    case 1 << 4:
+        return VERIFICATION_STATUS_NOT_SUPPORT;
+    case 1 << 5:
+        return VERIFICATION_STATUS_CONNECTION_FAILED;
+    case 1 << 6:
+        return VERIFICATION_STATUS_ERROR;
+    default:
+        return VERIFICATION_STATUS_ERROR;
+    }
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CertificateCacheDAO.h b/vcore/src/vcore/CertificateCacheDAO.h
new file mode 100644 (file)
index 0000000..59102da
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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       CertificateCacheDAO.h
+ * @author     Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version    0.1
+ * @brief      Header file for class managing CRL and OCSP cached responses
+ */
+
+#ifndef _WRT_SRC_CONFIGURATION_CERTIFICATE_CACHE_DAO_H_
+#define _WRT_SRC_CONFIGURATION_CERTIFICATE_CACHE_DAO_H_
+
+#include <string>
+#include <list>
+
+#include <dpl/exception.h>
+
+#include <vcore/VerificationStatus.h>
+#include <vcore/CRLCacheInterface.h>
+
+namespace ValidationCore {
+
+struct OCSPCachedStatus
+{
+    std::string cert_chain;
+    VerificationStatus ocsp_status;
+    bool end_entity_check;
+    time_t next_update_time;
+};
+
+typedef std::list<OCSPCachedStatus> OCSPCachedStatusList;
+
+typedef std::list<CRLCachedData> CRLCachedDataList;
+
+class CertificateCacheDAO {
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, DatabaseError)
+    };
+
+    // OCSP statuses
+
+    static void setOCSPStatus(const std::string& cert_chain,
+                              VerificationStatus ocsp_status,
+                              bool end_entity_check,
+                              time_t next_update_time);
+
+    /*
+     * fill cert_chain and end_entity_check in cached_status
+     * returns true iff cached status found without errors
+     */
+    static bool getOCSPStatus(OCSPCachedStatus* cached_status);
+    static void getOCSPStatusList(OCSPCachedStatusList* cached_status_list);
+
+    // CRL responses
+
+    static void setCRLResponse(const std::string& distribution_point,
+                               const std::string& crl_body,
+                               time_t next_update_time);
+    static void setCRLResponse(CRLCachedData *ptr) {
+        setCRLResponse(
+            ptr->distribution_point,
+            ptr->crl_body,
+            ptr->next_update_time);
+    }
+    /*
+     * fill distribution_point
+     * returns true iff cached list for dist. point found without errors
+     */
+    static bool getCRLResponse(CRLCachedData* cached_data);
+    static void getCRLResponseList(CRLCachedDataList* cached_data_list);
+
+
+    // clears CRL and OCSP cached data
+    static void clearCertificateCache();
+
+  private:
+
+    static VerificationStatus intToVerificationStatus(int p);
+
+    CertificateCacheDAO()
+    {
+    }
+};
+
+} // namespace ValidationCore
+
+#endif /* _WRT_SRC_CONFIGURATION_CERTIFICATE_CACHE_DAO_H_ */
diff --git a/vcore/src/vcore/CertificateCollection.cpp b/vcore/src/vcore/CertificateCollection.cpp
new file mode 100644 (file)
index 0000000..27213c5
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * 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        CertificateCollection.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+#include <vcore/CertificateCollection.h>
+
+#include <algorithm>
+
+#include <dpl/binary_queue.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+#include <vcore/Base64.h>
+
+namespace {
+
+using namespace ValidationCore;
+
+inline std::string toBinaryString(int data)
+{
+    char buffer[sizeof(int)];
+    memcpy(buffer, &data, sizeof(int));
+    return std::string(buffer, buffer + sizeof(int));
+}
+
+} // namespace
+
+namespace ValidationCore {
+
+CertificateCollection::CertificateCollection()
+  : m_collectionStatus(COLLECTION_UNSORTED)
+{}
+
+void CertificateCollection::clear(void)
+{
+    m_collectionStatus = COLLECTION_UNSORTED;
+    m_certList.clear();
+}
+
+void CertificateCollection::load(const CertificateList &certList)
+{
+    m_collectionStatus = COLLECTION_UNSORTED;
+    std::copy(certList.begin(),
+              certList.end(),
+              std::back_inserter(m_certList));
+}
+
+bool CertificateCollection::load(const std::string &buffer)
+{
+    Base64Decoder base64;
+    base64.reset();
+    base64.append(buffer);
+    if (!base64.finalize()) {
+        LogWarning("Error during chain decoding");
+        return false;
+    }
+    std::string binaryData = base64.get();
+
+    DPL::BinaryQueue queue;
+    queue.AppendCopy(binaryData.c_str(), binaryData.size());
+
+    int certNum;
+    queue.FlattenConsume(&certNum, sizeof(int));
+
+    CertificateList list;
+
+    for (int i = 0; i < certNum; ++i) {
+        int certSize;
+        queue.FlattenConsume(&certSize, sizeof(int));
+        std::vector<char> rawDERCert;
+        rawDERCert.resize(certSize);
+        queue.FlattenConsume(&rawDERCert[0], certSize);
+        Try {
+            list.push_back(CertificatePtr(
+                               new Certificate(std::string(rawDERCert.begin(),
+                                                           rawDERCert.end()))));
+        } Catch(Certificate::Exception::Base) {
+            LogWarning("Error during certificate creation.");
+            return false;
+        }
+        LogDebug("Loading certificate. Certificate common name: " <<
+                 list.back()->getCommonName());
+    }
+    load(list);
+    return true;
+}
+
+std::string CertificateCollection::toBase64String() const
+{
+    std::ostringstream output;
+    int certNum = m_certList.size();
+    output << toBinaryString(certNum);
+    FOREACH(i, m_certList){
+        std::string derCert = (*i)->getDER();
+        output << toBinaryString(derCert.size());
+        output << derCert;
+    }
+    Base64Encoder base64;
+    base64.reset();
+    base64.append(output.str());
+    base64.finalize();
+    return base64.get();
+}
+
+CertificateList CertificateCollection::getCertificateList() const
+{
+    return m_certList;
+}
+
+bool CertificateCollection::isChain() const
+{
+    if (COLLECTION_SORTED != m_collectionStatus) {
+        LogError("You must sort certificates first");
+        ThrowMsg(Exception::WrongUsage,
+                 "You must sort certificates first");
+    }
+    return (COLLECTION_SORTED == m_collectionStatus) ? true : false;
+}
+
+bool CertificateCollection::sort()
+{
+    if (COLLECTION_UNSORTED == m_collectionStatus) {
+        sortCollection();
+    }
+    return (COLLECTION_SORTED == m_collectionStatus) ? true : false;
+}
+
+CertificateList CertificateCollection::getChain() const
+{
+    if (COLLECTION_SORTED != m_collectionStatus) {
+        LogError("You must sort certificates first");
+        ThrowMsg(Exception::WrongUsage,
+                 "You must sort certificates first");
+    }
+    return m_certList;
+}
+
+void CertificateCollection::sortCollection()
+{
+    // sorting is not necessary
+    if (m_certList.empty()) {
+        m_collectionStatus = COLLECTION_SORTED;
+        return;
+    }
+
+    CertificateList sorted;
+    std::map<std::string, CertificatePtr> subTransl;
+    std::map<std::string, CertificatePtr> issTransl;
+
+    // Sort all certificate by subject
+    for (auto it = m_certList.begin(); it != m_certList.end(); ++it) {
+        subTransl.insert(std::make_pair(DPL::ToUTF8String((*it)->getOneLine()),(*it)));
+    }
+    // We need one start certificate
+    sorted.push_back(subTransl.begin()->second);
+    subTransl.erase(subTransl.begin());
+
+    // Get the issuer from front certificate and find certificate with this subject in subTransl.
+    // Add this certificate to the front.
+    while (!subTransl.empty()) {
+        std::string issuer = DPL::ToUTF8String(sorted.back()->getOneLine(Certificate::FIELD_ISSUER));
+        auto it = subTransl.find(issuer);
+        if (it == subTransl.end()) {
+            break;
+        }
+        sorted.push_back(it->second);
+        subTransl.erase(it);
+    }
+
+    // Sort all certificates by issuer
+    for (auto it = subTransl.begin(); it != subTransl.end(); ++it) {
+        issTransl.insert(std::make_pair(DPL::ToUTF8String((it->second->getOneLine(Certificate::FIELD_ISSUER))),it->second));
+    }
+
+    // Get the subject from last certificate and find certificate with such issuer in issTransl.
+    // Add this certificate at end.
+    while (!issTransl.empty()) {
+        std::string sub = DPL::ToUTF8String(sorted.front()->getOneLine());
+        auto it = issTransl.find(sub);
+        if (it == issTransl.end()) {
+            break;
+        }
+        sorted.push_front(it->second);
+        issTransl.erase(it);
+    }
+
+    if (!issTransl.empty()) {
+        LogWarning("Certificates don't form a valid chain.");
+        m_collectionStatus = COLLECTION_CHAIN_BROKEN;
+        return;
+    }
+
+    m_collectionStatus = COLLECTION_SORTED;
+    m_certList = sorted;
+}
+
+size_t CertificateCollection::size() const {
+    return m_certList.size();
+}
+
+bool CertificateCollection::empty() const {
+    return m_certList.empty();
+}
+
+CertificateCollection::const_iterator CertificateCollection::begin() const {
+    return m_certList.begin();
+}
+
+CertificateCollection::const_iterator CertificateCollection::end() const {
+    return m_certList.end();
+}
+
+CertificatePtr CertificateCollection::back() const {
+    return m_certList.back();
+}
+
+} // namespace ValidationCore
+
diff --git a/vcore/src/vcore/CertificateCollection.h b/vcore/src/vcore/CertificateCollection.h
new file mode 100644 (file)
index 0000000..953bbfb
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * 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        CertificateCollection.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+#ifndef _VALIDATION_CORE_CERTIFICATECOLLECTION_H_
+#define _VALIDATION_CORE_CERTIFICATECOLLECTION_H_
+
+#include <list>
+#include <string>
+
+#include <dpl/exception.h>
+
+#include <vcore/Certificate.h>
+
+namespace ValidationCore {
+/*
+ * This class is used to store Certificate Chain.
+ * It could serialize chain to std::string in base64 form.
+ * It could read chain written in base64 form.
+ * It could check if collection creates certificate chain.
+ */
+
+class CertificateCollection
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, WrongUsage)
+    };
+
+    CertificateCollection();
+
+    typedef CertificateList::const_iterator const_iterator;
+
+    /*
+     * Remove all certificates from collection.
+     */
+    void clear();
+
+    /*
+     * In current implemenation this function MUST success.
+     *
+     * This function will add new certificate to collection.
+     * This function DOES NOT clean collection.
+     */
+    void load(const CertificateList &certList);
+
+    /*
+     * This function will return false if base64 string is broken
+     * (is not encoded in base64 format) or one from certificate
+     * is broken (is not encoded in der format).
+     *
+     * This function will add new certificate to collection.
+     * This function DOES NOT clean collection.
+     */
+    bool load(const std::string &base64);
+
+    /*
+     * This function will return all certificates from
+     * collection encoded in base64 format.
+     */
+    std::string toBase64String() const;
+
+    /*
+     * This will return all certificate from collection.
+     */
+    CertificateList getCertificateList() const;
+
+    /*
+     * This function will return true if certificates
+     * in in this structure were sorted and create
+     * certificate chain.
+
+     * Note: You MUST sort certificates first.
+     */
+    bool isChain() const;
+
+    /*
+     * This function will return true if all certificate are
+     * able to create certificate chain.
+     *
+     * This function will sort certificates if collection
+     * is not sorted.
+     *
+     * Note: This function will make all iterators invalid.
+     */
+    bool sort();
+
+    /*
+     * This function will return Certificate chain.
+     *
+     * First certificate on the list is EndEntity certificate.
+     *
+     * Last certificate on the list is RootCA certificate or
+     * CA certificate if RootCA is not present.
+     *
+     * Note: You MUST sort certificates first and
+     * check if certificates creates proper chain.
+     */
+    CertificateList getChain() const;
+
+    /*
+     * It returns size of certificate collection.
+     */
+    size_t size() const;
+
+    /*
+     * Return true if collection is empty.
+     */
+    bool empty() const;
+
+    /*
+     * This will return end iterator to internal collection.
+     *
+     * Note: this iterator will lose validity if you call non const
+     * method on CertificateCollection class.
+     */
+    const_iterator begin() const;
+
+    /*
+     * This will return end iterator to internal collection.
+     *
+     * Note: this iterator will lose validity if you call non const
+     * method on CertificateCollection class.
+     */
+    const_iterator end() const;
+
+    /*
+     * This function will return the last certificate from collection.
+     *
+     * Note: There is no point to call this function if certificate
+     * collection is not sorted!
+     */
+    CertificatePtr back() const;
+
+  protected:
+    void sortCollection(void);
+
+    enum CollectionStatus
+    {
+        // Certificate collection are not sorted in any way
+        COLLECTION_UNSORTED,
+        // Certificate collection creates certificate chain
+        COLLECTION_SORTED,
+        // Cerfificate collection is not able to create certificate chain
+        COLLECTION_CHAIN_BROKEN,
+    };
+
+    CollectionStatus m_collectionStatus;
+    CertificateList m_certList;
+};
+
+typedef std::list<CertificateCollection> CertificateCollectionList;
+
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_CERTIFICATECHAIN_H_
diff --git a/vcore/src/vcore/CertificateConfigReader.cpp b/vcore/src/vcore/CertificateConfigReader.cpp
new file mode 100644 (file)
index 0000000..608dda2
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * 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
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include "CertificateConfigReader.h"
+
+#include <cstdlib>
+
+#include <dpl/assert.h>
+
+namespace {
+const std::string XML_EMPTY_NAMESPACE = "";
+
+const std::string TOKEN_CERTIFICATE_SET = "CertificateSet";
+const std::string TOKEN_CERTIFICATE_DOMAIN = "CertificateDomain";
+const std::string TOKEN_FINGERPRINT_SHA1 = "FingerprintSHA1";
+
+const std::string TOKEN_ATTR_NAME = "name";
+const std::string TOKEN_VALUE_WAC_ROOT = "wacroot";
+const std::string TOKEN_VALUE_WAC_PUBLISHER = "wacpublisher";
+const std::string TOKEN_VALUE_WAC_MEMBER = "wacmember";
+const std::string TOKEN_VALUE_DEVELOPER = "developer";
+const std::string TOKEN_VALUE_TIZEN_MEMBER = "tizenmember";
+const std::string TOKEN_VALUE_ORANGE_LEGACY = "orangelegacy";
+
+int hexCharToInt(char c)
+{
+    if (c >= 'a' && c <= 'f') {
+        return 10 + static_cast<int>(c) - 'a';
+    }
+    if (c >= 'A' && c <= 'F') {
+        return 10 + static_cast<int>(c) - 'A';
+    }
+    if (c >= '0' && c <= '9') {
+        return static_cast<int>(c) - '0';
+    }
+    return c;
+}
+} // anonymous namespace
+
+namespace ValidationCore {
+CertificateConfigReader::CertificateConfigReader() :
+    m_certificateDomain(0),
+    m_parserSchema(this)
+{
+    m_parserSchema.addBeginTagCallback(
+        TOKEN_CERTIFICATE_SET,
+        XML_EMPTY_NAMESPACE,
+        &CertificateConfigReader::blankFunction);
+
+    m_parserSchema.addBeginTagCallback(
+        TOKEN_CERTIFICATE_DOMAIN,
+        XML_EMPTY_NAMESPACE,
+        &CertificateConfigReader::tokenCertificateDomain);
+
+    m_parserSchema.addBeginTagCallback(
+        TOKEN_FINGERPRINT_SHA1,
+        XML_EMPTY_NAMESPACE,
+        &CertificateConfigReader::blankFunction);
+
+    m_parserSchema.addEndTagCallback(
+        TOKEN_CERTIFICATE_SET,
+        XML_EMPTY_NAMESPACE,
+        &CertificateConfigReader::blankFunction);
+
+    m_parserSchema.addEndTagCallback(
+        TOKEN_CERTIFICATE_DOMAIN,
+        XML_EMPTY_NAMESPACE,
+        &CertificateConfigReader::blankFunction);
+
+    m_parserSchema.addEndTagCallback(
+        TOKEN_FINGERPRINT_SHA1,
+        XML_EMPTY_NAMESPACE,
+        &CertificateConfigReader::tokenEndFingerprintSHA1);
+}
+
+void CertificateConfigReader::tokenCertificateDomain(CertificateIdentifier &)
+{
+    std::string name = m_parserSchema.getReader().
+            attribute(TOKEN_ATTR_NAME, SaxReader::THROW_DISABLE);
+
+    if (name.empty()) {
+        LogWarning("Invalid fingerprint file. Domain name is mandatory");
+        ThrowMsg(Exception::InvalidFile,
+                 "Invalid fingerprint file. Domain name is mandatory");
+    } else if (name == TOKEN_VALUE_DEVELOPER) {
+        m_certificateDomain = CertStoreId::DEVELOPER;
+    } else if (name == TOKEN_VALUE_WAC_ROOT) {
+        m_certificateDomain = CertStoreId::WAC_ROOT;
+    } else if (name == TOKEN_VALUE_WAC_PUBLISHER) {
+        m_certificateDomain = CertStoreId::WAC_PUBLISHER;
+    } else if (name == TOKEN_VALUE_WAC_MEMBER) {
+        m_certificateDomain = CertStoreId::WAC_MEMBER;
+    } else if (name == TOKEN_VALUE_TIZEN_MEMBER) {
+        m_certificateDomain = CertStoreId::TIZEN_MEMBER;
+    } else if (name == TOKEN_VALUE_ORANGE_LEGACY) {
+        m_certificateDomain = CertStoreId::ORANGE_LEGACY;
+    } else {
+        LogWarning("This domain will be ignored: " << name);
+        m_certificateDomain = 0;
+    }
+}
+
+void CertificateConfigReader::tokenEndFingerprintSHA1(
+        CertificateIdentifier &identificator)
+{
+    std::string text = m_parserSchema.getText();
+    text += ":"; // add guard at the end of fingerprint
+    Certificate::Fingerprint fingerprint;
+    int s = 0;
+    int byteDescLen = 0;
+    for (size_t i = 0; i < text.size(); ++i) {
+        if (isxdigit(text[i])) {
+            s <<= 4;
+            s += hexCharToInt(text[i]);
+            byteDescLen++;
+            if (byteDescLen > 2) {
+                Assert(0 && "Unsupported fingerprint format in xml file.");
+            }
+        } else if (text[i] == ':') {
+            fingerprint.push_back(static_cast<unsigned char>(s));
+            s = 0;
+            byteDescLen = 0;
+        } else {
+            Assert(0 && "Unussported fingerprint format in xml file.");
+        }
+    }
+    identificator.add(fingerprint, m_certificateDomain);
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CertificateConfigReader.h b/vcore/src/vcore/CertificateConfigReader.h
new file mode 100644 (file)
index 0000000..4ca7d8e
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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        CertificateConfigReader.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef _VALIDATION_CORE_CERTIFICATE_CONFIG_READER_H_
+#define _VALIDATION_CORE_CERTIFICATE_CONFIG_READER_H_
+
+#include <string>
+#include <dpl/exception.h>
+
+#include <vcore/CertificateIdentifier.h>
+#include <vcore/CertStoreType.h>
+#include <vcore/ParserSchema.h>
+
+namespace ValidationCore {
+class CertificateConfigReader
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, InvalidFile)
+    };
+    CertificateConfigReader();
+
+    void initialize(const std::string &file,
+            const std::string &scheme)
+    {
+        m_parserSchema.initialize(file, true, SaxReader::VALIDATION_XMLSCHEME,
+                                  scheme);
+    }
+
+    void read(CertificateIdentifier &identificator)
+    {
+        m_parserSchema.read(identificator);
+    }
+
+  private:
+    void blankFunction(CertificateIdentifier &)
+    {
+    }
+    void tokenCertificateDomain(CertificateIdentifier &identificator);
+    void tokenEndFingerprintSHA1(CertificateIdentifier &identificator);
+
+    CertStoreId::Type m_certificateDomain;
+    ParserSchema<CertificateConfigReader, CertificateIdentifier>
+    m_parserSchema;
+};
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_CERTIFICATE_CONFIG_READER_H_
diff --git a/vcore/src/vcore/CertificateIdentifier.h b/vcore/src/vcore/CertificateIdentifier.h
new file mode 100644 (file)
index 0000000..f9ed48c
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef \
+    _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATEIDENTIFICATOR_H_
+#define \
+    _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATEIDENTIFICATOR_H_
+
+#include <map>
+
+#include <dpl/noncopyable.h>
+
+#include "Certificate.h"
+#include "CertStoreType.h"
+
+namespace ValidationCore {
+class CertificateIdentifier : public DPL::Noncopyable
+{
+  public:
+    typedef std::map<Certificate::Fingerprint, CertStoreId::Set> FingerPrintMap;
+
+    CertificateIdentifier()
+    {
+    }
+    ~CertificateIdentifier()
+    {
+    }
+
+    void add(const Certificate::Fingerprint &fingerprint,
+            CertStoreId::Type domain)
+    {
+        fingerPrintMap[fingerprint].add(domain);
+    }
+
+    CertStoreId::Set find(const Certificate::Fingerprint &fingerprint) const
+    {
+        FingerPrintMap::const_iterator iter = fingerPrintMap.find(fingerprint);
+        if (iter == fingerPrintMap.end()) {
+            return CertStoreId::Set();
+        }
+        return iter->second;
+    }
+
+    CertStoreId::Set find(const CertificatePtr &certificate) const
+    {
+        return
+            find(certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
+    }
+
+  private:
+    FingerPrintMap fingerPrintMap;
+};
+} // namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_CERTIFICATEIDENTIFICATOR_H_
diff --git a/vcore/src/vcore/CertificateLoader.cpp b/vcore/src/vcore/CertificateLoader.cpp
new file mode 100644 (file)
index 0000000..5aac8bb
--- /dev/null
@@ -0,0 +1,718 @@
+/*
+ * 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.
+ */
+#include <dpl/assert.h>
+#include <openssl/x509v3.h>
+#include <dpl/log/log.h>
+#include <dpl/noncopyable.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+
+#include <vcore/Base64.h>
+#include <vcore/CertificateLoader.h>
+#include <vcore/SSLContainers.h>
+
+namespace {
+const int MIN_RSA_KEY_LENGTH = 1024;
+//const char *OID_CURVE_SECP256R1 = "urn:oid:1.2.840.10045.3.1.7";
+} // namespace anonymous
+
+namespace ValidationCore {
+//// COMPARATOR CLASS START ////
+
+//class CertificateLoaderECDSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
+//public:
+//    CertificateLoaderECDSA(const std::string &publicKey)
+//      : m_ecPublicKey(NULL)
+//      , m_searchKey(NULL)
+//    {
+//        m_bnCtx = BN_CTX_new(); // if fails we can continue anyway
+//        m_tmpPoint = BN_new();  // if fails we can continue anyway
+//        m_initialized = CertificateLoader::convertBase64NodeToBigNum(publicKey, &m_searchKey);
+//
+//        if(!m_initialized)
+//            LogError("Init failed!");
+//    }
+//
+//    virtual bool compare(X509 *x509cert){
+//        if(!m_initialized)
+//            return false;
+//
+//        EVP_PKEY_free(m_ecPublicKey);
+//
+//        m_ecPublicKey = X509_get_pubkey(x509cert);
+//
+//        if(m_ecPublicKey == NULL)
+//            return false;
+//
+//        if(m_ecPublicKey->type != EVP_PKEY_EC){
+//            LogError("ecPublicKey has wrong type!");
+//            return false;
+//        }
+//
+//        // Pointer to internal data of ecPublicKey. Do not free!
+//        EC_KEY *eckey = m_ecPublicKey->pkey.ec;
+//
+//        const EC_POINT *ecpoint = EC_KEY_get0_public_key(eckey);
+//        const EC_GROUP *ecgroup = EC_KEY_get0_group(eckey);
+//
+//        m_tmpPoint = EC_POINT_point2bn(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, m_tmpPoint, m_bnCtx);
+//
+//        if(BN_cmp(m_tmpPoint, m_searchKey) == 0)
+//            return true;
+//
+//        return false;
+//    }
+//
+//    ~CertificateLoaderECDSA(){
+//        BN_CTX_free(m_bnCtx);
+//        EVP_PKEY_free(m_ecPublicKey);
+//        BN_free(m_searchKey);
+//        BN_free(m_tmpPoint);
+//    }
+//
+//private:
+//    bool        m_initialized;
+//    EVP_PKEY   *m_ecPublicKey;
+//    BN_CTX     *m_bnCtx;
+//    BIGNUM     *m_searchKey;
+//    BIGNUM     *m_tmpPoint;
+//};
+
+///// COMPARETORS CLASS END /////
+
+//// COMPARATOR RSA CLASS START ////
+
+//class CertificateLoaderRSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
+//public:
+//    CertificateLoaderRSA(const std::string &m_modulus,const std::string &m_exponent )
+//      : m_rsaPublicKey(NULL)
+//      , m_modulus_bn(NULL)
+//      , m_exponent_bn(NULL)
+//    {
+//
+//        m_initialized_modulus = CertificateLoader::convertBase64NodeToBigNum(m_modulus, &m_modulus_bn);
+//        m_initialized_exponent = CertificateLoader::convertBase64NodeToBigNum(m_exponent, &m_exponent_bn);
+//
+//        if(!m_initialized_modulus || !m_initialized_exponent)
+//            LogError("Init failed!");
+//    }
+//
+//    virtual bool compare(X509 *x509cert){
+//
+//        if(!m_initialized_modulus || !m_initialized_exponent)
+//            return false;
+//
+//        EVP_PKEY_free(m_rsaPublicKey);
+//        m_rsaPublicKey = X509_get_pubkey(x509cert);
+//
+//        if(m_rsaPublicKey == NULL)
+//            return false;
+//
+//        if(m_rsaPublicKey->type != EVP_PKEY_RSA){
+//            LogInfo("rsaPublicKey has wrong type!");
+//            return false;
+//        }
+//
+//        RSA *rsa = NULL;
+//        rsa = m_rsaPublicKey->pkey.rsa;
+//
+//        if (BN_cmp(m_modulus_bn, rsa->n) == 0 &&
+//            BN_cmp(m_exponent_bn, rsa->e) == 0 ){
+//            LogError ("Compare TRUE");
+//            return true;
+//        }
+//        return false;
+//    }
+//
+//    ~CertificateLoaderRSA(){
+//        EVP_PKEY_free(m_rsaPublicKey);
+//        BN_free(m_modulus_bn);
+//        BN_free(m_exponent_bn);
+//
+//    }
+//
+//private:
+//    bool        m_initialized_modulus;
+//    bool        m_initialized_exponent;
+//    EVP_PKEY   *m_rsaPublicKey;
+//    BIGNUM     *m_modulus_bn;
+//    BIGNUM     *m_exponent_bn;
+//};
+
+///// COMPARETORS RSA CLASS END /////
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+    loadCertificateBasedOnExponentAndModulus(const std::string &m_modulus,
+        const std::string &m_exponent)
+{
+    (void) m_modulus;
+    (void) m_exponent;
+    LogError("Not implemented.");
+    return UNKNOWN_ERROR;
+    //    if (m_exponent.empty() || m_modulus.empty())
+    //        return WRONG_ARGUMENTS;
+    //
+    //    CertificateLoaderRSA comparator(m_modulus,m_exponent);
+    //
+    //    CertificateLoaderResult result = NO_ERROR;
+    //    for(int i=0; storeId[i]; ++i){
+    //        result = loadCertificate(std::string(storeId[i]), &comparator);
+    //
+    //        if(result == ERR_NO_MORE_CERTIFICATES)
+    //            continue;
+    //
+    //        return result;
+    //    }
+    //
+    //    return result;
+}
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificate(
+        const std::string &storageName,
+        CertificateLoader::CertificateLoaderComparator *cmp)
+{
+    (void) storageName;
+    (void) cmp;
+    LogError("Not Implemented");
+    return UNKNOWN_ERROR;
+    //    long int result = OPERATION_SUCCESS;
+    //
+    //    char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+    //    char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+    //    certmgr_cert_id certId;
+    //    certmgr_ctx context;
+    //    certmgr_mem_buff certRetrieved;
+    //    unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+    //
+    //    certmgr_cert_descriptor descriptor;
+    //
+    //    certRetrieved.data = buffer;
+    //    certRetrieved.firstFree = 0;
+    //    certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+    //    certId.storeId = storeId;
+    //    certId.type = type;
+    //
+    //    CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+    //
+    //    strncpy(context.storeId, storageName.c_str(), storageName.size());
+    //
+    //    for(certRetrieved.firstFree = 0;
+    //        OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+    //        certRetrieved.firstFree = 0)
+    //    {
+    //
+    //        if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
+    //            LogError("Extracting Certificate Data failed \n");
+    //            continue;
+    //        }
+    //
+    //        const unsigned char *ptr = certRetrieved.data;
+    //
+    //        X509 *x509cert = d2i_X509(NULL, &ptr, certRetrieved.size);
+    //        if(x509cert == NULL){
+    //            certmgr_release_certificate_data(&descriptor);
+    //            LogError("Error extracting certificate (d2i_X509).");
+    //            return UNKNOWN_ERROR;
+    //        }
+    //
+    //        LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
+    //        if(cmp->compare(x509cert)){
+    //            LogDebug("Found match. Coping bytes: " << certRetrieved.size);
+    //            m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
+    //            certmgr_release_certificate_data(&descriptor);
+    //            X509_free(x509cert);
+    //            break;
+    //        }
+    //
+    //        LogDebug("Release");
+    //        X509_free(x509cert);
+    //        certmgr_release_certificate_data(&descriptor);
+    //    }
+    //
+    //    if(ERR_NO_MORE_CERTIFICATES == result){
+    //        LogError("Certificates for given DN not found\n");
+    //        return CERTIFICATE_NOT_FOUND;
+    //    }
+    //
+    //    if(result!= OPERATION_SUCCESS){
+    //        LogError("Certificate Manager Error\n");
+    //        return UNKNOWN_ERROR;
+    //    }
+    //
+    //    LogDebug("Exit");
+    //    return NO_ERROR;
+}
+
+// TODO
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+    loadCertificateBasedOnSubjectName(const std::string &subjectName)
+{
+    (void) subjectName;
+    LogError("Not implemented.");
+    return UNKNOWN_ERROR;
+    //    if(subjectName.empty())
+    //    {
+    //        return WRONG_ARGUMENTS;
+    //    }
+    //
+    //    long int result = OPERATION_SUCCESS;
+    //
+    //    char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+    //    char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+    //    certmgr_cert_id certId;
+    //    certmgr_ctx context;
+    //    certmgr_mem_buff certRetrieved;
+    //    unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+    //
+    //    certmgr_cert_descriptor descriptor;
+    //
+    //    certRetrieved.data = buffer;
+    //    certRetrieved.firstFree = 0;
+    //    certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+    //    certId.storeId = storeId;
+    //    certId.type = type;
+    //
+    //    CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+    //
+    //    for(certRetrieved.firstFree = 0;
+    //        OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+    //        certRetrieved.firstFree = 0)
+    //    {
+    //
+    //        if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
+    //            LogError("Extracting Certificate Data failed \n");
+    //            continue;
+    //        }
+    //
+    //        if(!strcmp(subjectName.c_str(), descriptor.mandatory.subject)){
+    //            LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
+    //            m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
+    //            certmgr_release_certificate_data(&descriptor);
+    //            break;
+    //        }
+    //        LogDebug("Release");
+    //        certmgr_release_certificate_data(&descriptor);
+    //    }
+    //
+    //    if(ERR_NO_MORE_CERTIFICATES == result) {
+    //        LogError("Certificates for given DN not found\n");
+    //        return CERTIFICATE_NOT_FOUND;
+    //    }
+    //    if(result!= OPERATION_SUCCESS){
+    //        LogError("Certificate Manager Error\n");
+    //        return UNKNOWN_ERROR;
+    //    }
+    //    LogDebug("Exit");
+    //    return NO_ERROR;
+}
+
+// KW CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificateBasedOnIssuerName(const std::string &issuerName, const std::string &serialNumber)
+// KW {
+// KW     if(issuerName.empty() || serialNumber.empty())
+// KW     {
+// KW         return WRONG_ARGUMENTS;
+// KW     }
+// KW
+// KW     if(m_cmBuff.data){
+// KW         delete[] m_cmBuff.data;
+// KW         memset(&m_cmBuff, 0, sizeof(certmgr_mem_buff));
+// KW     }
+// KW
+// KW     LogDebug("IssuerName: " << issuerName << " serialNumber: " << serialNumber);
+// KW
+// KW     //used to check status of retrieved certificate
+// KW     long int result = OPERATION_SUCCESS;
+// KW     char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+// KW     char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+// KW     certmgr_cert_id certId;
+// KW     certmgr_ctx context;
+// KW     certmgr_mem_buff certRetrieved;
+// KW     unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+// KW
+// KW     certmgr_cert_descriptor descriptor;
+// KW
+// KW     certRetrieved.data = buffer;
+// KW     certRetrieved.firstFree = 0;
+// KW     certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+// KW     certId.storeId = storeId;
+// KW     certId.type = type;
+// KW
+// KW     CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+// KW
+// KW     for(certRetrieved.firstFree = 0;
+// KW         OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+// KW         certRetrieved.firstFree = 0)
+// KW     {
+// KW
+// KW         LogDebug("Extracting certificate from CertMgr");
+// KW
+// KW         if( OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor) ){
+// KW             LogError("Extracting Certificate Data failed \n");
+// KW             continue;
+// KW         }
+// KW
+// KW         LogDebug("Issuer: " << descriptor.mandatory.issuer);
+// KW
+// KW         const unsigned char *ptr = certRetrieved.data;
+// KW         char *tmp;
+// KW
+// KW         X509 *x509cert = d2i_X509(NULL, &ptr, certRetrieved.size);
+// KW         std::string serialNO = std::string(tmp = i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(x509cert)));
+// KW         OPENSSL_free(tmp);
+// KW         X509_free(x509cert);
+// KW
+// KW         LogInfo("Certificate number found: " << serialNO);
+// KW         LogInfo("Certificate number looking for: " << serialNumber);
+// KW
+// KW         if(!strcmp(issuerName.c_str(), descriptor.mandatory.issuer)
+// KW               && serialNumber == serialNO)
+// KW         {
+// KW             LogError("The issuer of this certificate is " << descriptor.mandatory.issuer);
+// KW
+// KW             m_cmBuff.data = new unsigned char[certRetrieved.size];
+// KW             m_cmBuff.firstFree = m_cmBuff.size = certRetrieved.size;
+// KW             memcpy(m_cmBuff.data, certRetrieved.data, certRetrieved.size);
+// KW             certmgr_release_certificate_data(&descriptor);
+// KW             break;
+// KW         }
+// KW         certmgr_release_certificate_data(&descriptor);
+// KW     }
+// KW
+// KW     if(ERR_NO_MORE_CERTIFICATES == result) {
+// KW         LogError("Certificates not found");
+// KW         return CERTIFICATE_NOT_FOUND;
+// KW     }
+// KW     if(result != OPERATION_SUCCESS){
+// KW         LogError("Certificate Manager Error");
+// KW         return UNKNOWN_ERROR;
+// KW     }
+// KW     return NO_ERROR;
+// KW }
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+    loadCertificateWithECKEY(const std::string &curveName,
+        const std::string &publicKey)
+{
+    (void) curveName;
+    (void) publicKey;
+    LogError("Not implemented.");
+    return UNKNOWN_ERROR;
+    //    if(curveName != OID_CURVE_SECP256R1){
+    //        LogError("Found field id: " << curveName << " Expected: " << OID_CURVE_SECP256R1);
+    //        return UNSUPPORTED_CERTIFICATE_FIELD;
+    //    }
+    //
+    //    CertificateLoaderECDSA comparator(publicKey);
+    //
+    //    CertificateLoaderResult result = NO_ERROR;
+    //    for(int i=0; storeId[i]; ++i){
+    //        result = loadCertificate(std::string(storeId[i]), &comparator);
+    //
+    //        if(result == ERR_NO_MORE_CERTIFICATES)
+    //            continue;
+    //
+    //        return result;
+    //    }
+    //
+    //    return result;
+}
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+    loadCertificateFromRawData(const std::string &rawData)
+{
+    Try {
+        m_certificatePtr =
+            CertificatePtr(new Certificate(rawData, Certificate::FORM_BASE64));
+    } Catch(Certificate::Exception::Base) {
+        LogWarning("Error reading certificate by openssl.");
+        return UNKNOWN_ERROR;
+    }
+
+    // Check the key length if sig algorithm is RSA
+    EVP_PKEY *pKey = X509_get_pubkey(m_certificatePtr->getX509());
+
+    if (pKey->type == EVP_PKEY_RSA) {
+        RSA* pRSA = pKey->pkey.rsa;
+
+        if (pRSA) {
+            int keyLength = RSA_size(pRSA);
+
+            // key Length (modulus) is in bytes
+            keyLength <<= 3;
+            LogDebug("RSA key length: " << keyLength << " bits");
+
+            if (keyLength < MIN_RSA_KEY_LENGTH) {
+                LogError(
+                    "RSA key too short!" << "Has only " << keyLength << " bits");
+                return CERTIFICATE_SECURITY_ERROR;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+// DEPRACETED FUNCTION
+//CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificateFromRawData(const std::string &rawData)
+//{
+//    certmgr_mem_buff cmBuff = {0,0,0};
+//
+//    long int size;
+//    cmBuff.data = certmgr_util_base64_decode(const_cast<void*>(static_cast<const void*>(rawData.c_str())), rawData.size(), &size);
+//
+//    cmBuff.firstFree = cmBuff.size = size;
+//
+//    certmgr_cert_descriptor descriptor;
+//
+//    long int result = certmgr_extract_certificate_data(&cmBuff, &descriptor);
+//
+//    if (result != OPERATION_SUCCESS)
+//    {
+//        LogError("Unable to load certificate");
+//        return UNKNOWN_ERROR;
+//    }
+//
+//    certmgr_release_certificate_data(&descriptor);
+//
+//    m_certificatePtr = CertificatePtr(new Certificate(cmBuff));
+//
+//    // we have to use temp pointer cause d2i_x509 modifies its input
+//    const unsigned char* tmpPtr = cmBuff.data;
+//    X509* pCertificate = d2i_X509(NULL, &tmpPtr, cmBuff.size);
+//
+//    if (pCertificate)
+//    {
+//        SSLSmartContainer<X509> pX509(pCertificate);
+//
+//        // Check the key length if sig algorithm is RSA
+//        EVP_PKEY *pKey = X509_get_pubkey(pX509);
+//
+//        if (pKey->type == EVP_PKEY_RSA)
+//        {
+//            RSA* pRSA = pKey->pkey.rsa;
+//
+//            if (pRSA)
+//            {
+//                int keyLength = RSA_size(pRSA);
+//
+//                // key Length (modulus) is in bytes
+//                keyLength <<= 3;
+//                LogDebug("RSA key length: " << keyLength << " bits");
+//
+//                if (keyLength < MIN_RSA_KEY_LENGTH)
+//                {
+//                    LogError("RSA key too short!" << "Has only " << keyLength << " bits");
+//                    return CERTIFICATE_SECURITY_ERROR;
+//                }
+//            }
+//        }
+//    }
+//
+//    return NO_ERROR;
+//}
+
+CertificateLoader::CertificateLoaderResult CertificateLoader::
+    loadCertificateBasedOnDSAComponents(const std::string& strP,
+        const std::string& strQ,
+        const std::string& strG,
+        const std::string& strY,
+        const std::string& strJ,
+        const std::string& strSeed,
+        const std::string& strPGenCounter)
+{
+    (void) strP;
+    (void) strQ;
+    (void) strG;
+    (void) strY;
+    (void) strJ;
+    (void) strSeed;
+    (void) strPGenCounter;
+    LogError("Not implemented.");
+    return UNKNOWN_ERROR;
+    //    (void)strY;
+    //    (void)strJ;
+    //    (void)strSeed;
+    //    (void)strPGenCounter;
+    //
+    //    long int result = UNKNOWN_ERROR;
+    //
+    //    char storeId[CERTMGR_MAX_PLUGIN_ID_SIZE];
+    //    char type[CERTMGR_MAX_CERT_TYPE_SIZE];
+    //    certmgr_cert_id certId;
+    //    certmgr_ctx context;
+    //    certmgr_mem_buff certRetrieved;
+    //
+    //    unsigned char buffer[CERTMGR_MAX_BUFFER_SIZE];
+    //
+    //    certmgr_cert_descriptor descriptor;
+    //
+    //    certRetrieved.data = buffer;
+    //    certRetrieved.firstFree = 0;
+    //    certRetrieved.size = CERTMGR_MAX_BUFFER_SIZE;
+    //    certId.storeId = storeId;
+    //    certId.type = type;
+    //
+    //    CERTMGR_INIT_CONTEXT((&context), (sizeof(context)))
+    //    std::string strStoreType("Operator");
+    //    strncpy(context.storeId, strStoreType.c_str(),  strStoreType.length());
+    //
+    //    for (certRetrieved.firstFree = 0;
+    //      OPERATION_SUCCESS == (result = certmgr_retrieve_certificate_from_store(&context, &certRetrieved, &certId));
+    //      certRetrieved.firstFree = 0)
+    //    {
+    //
+    //        if (OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor))
+    //        {
+    //            LogDebug("unable to retrieve cert from storage");
+    //            continue;
+    //        }
+    //
+    //        X509* pCertificate = d2i_X509(NULL, (const unsigned char**) &(certRetrieved.data), certRetrieved.size);
+    //
+    //        if (pCertificate)
+    //        {
+    //            EVP_PKEY *pKey = X509_get_pubkey(pCertificate);
+    //
+    //            if (pKey->type == EVP_PKEY_DSA)
+    //            {
+    //                DSA* pDSA = pKey->pkey.dsa;
+    //
+    //                if (pDSA)
+    //                {
+    //                    BIGNUM *pDSApBigNum = NULL, *pDSAqBigNum = NULL, *pDSAgBigNum = NULL;
+    //
+    //                    convertBase64NodeToBigNum(strP, &pDSApBigNum);
+    //                    convertBase64NodeToBigNum(strQ, &pDSAqBigNum);
+    //                    convertBase64NodeToBigNum(strG, &pDSAgBigNum);
+    //
+    //                    if (pDSApBigNum && pDSAqBigNum && pDSAgBigNum &&
+    //                      BN_cmp(pDSApBigNum, pDSA->p) == 0 &&
+    //                      BN_cmp(pDSAqBigNum, pDSA->q) == 0 &&
+    //                      BN_cmp(pDSAgBigNum, pDSA->g) == 0)
+    //                    {
+    //                        LogInfo("DSA Certificate found");
+    //                        /* TODO load this certificate to m_cmBuff value */
+    //                        LogError("Not implemented!");
+    //
+    //                        EVP_PKEY_free(pKey);
+    //                        X509_free(pCertificate);
+    //
+    //                        BN_free(pDSApBigNum);
+    //                        BN_free(pDSAqBigNum);
+    //                        BN_free(pDSAgBigNum);
+    //
+    //                        certmgr_release_certificate_data(&descriptor);
+    //                        return NO_ERROR;
+    //                    }
+    //
+    //                    if (pDSApBigNum)
+    //                    {
+    //                        BN_free(pDSApBigNum);
+    //                    }
+    //                    if (pDSAqBigNum)
+    //                    {
+    //                        BN_free(pDSAqBigNum);
+    //                    }
+    //                    if (pDSAgBigNum)
+    //                    {
+    //                        BN_free(pDSAgBigNum);
+    //                    }
+    //
+    //                }
+    //                EVP_PKEY_free(pKey);
+    //            }
+    //            X509_free(pCertificate);
+    //        }
+    //        else
+    //            LogError("Unable to load certificate");
+    //
+    //        certmgr_release_certificate_data(&descriptor);
+    //    }
+    //
+    //    LogError("No DSA certificate with given parameters");
+    //
+    //    return CERTIFICATE_NOT_FOUND;
+}
+
+bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
+        BIGNUM** ppBigNum)
+{
+    (void) strNode;
+    (void) ppBigNum;
+    LogError("Not implemented.");
+    return false;
+    //    if (!ppBigNum || *ppBigNum != NULL)
+    //    {
+    //        LogError("Ptr variable not initialized properly!");
+    //        return false;
+    //    }
+    //
+    //    // decode base64 to binary
+    //    long int binBuffLength = 0;
+    //    unsigned char* binBuff = NULL;
+    //
+    //    binBuff = certmgr_util_base64_decode(const_cast<char*> (strNode.c_str()), strNode.length(), &binBuffLength);
+    //
+    //    if (!binBuff)
+    //    {
+    //        LogError("base64 decode failed");
+    //        return false;
+    //    }
+    //
+    //    // convert binary to bignum
+    //    *ppBigNum = BN_bin2bn(binBuff, binBuffLength, *ppBigNum);
+    //
+    //    free(binBuff);
+    //
+    //    if (!(*ppBigNum))
+    //    {
+    //        LogError("Conversion from node to bignum failed");
+    //        return false;
+    //    }
+    //
+    //    return true;
+}
+
+// KW bool CertificateLoader::convertBigNumToBase64Node(const BIGNUM* pBigNum, std::string& strNode)
+// KW {
+// KW     if (!pBigNum)
+// KW     {
+// KW         LogError("null ptr");
+// KW         return false;
+// KW     }
+// KW
+// KW     int nNumLength = BN_num_bytes(pBigNum);
+// KW     unsigned char* buffer = new unsigned char[nNumLength + 1];
+// KW
+// KW     // convert bignum to binary format
+// KW     if (BN_bn2bin(pBigNum, buffer) < 0)
+// KW     {
+// KW         LogError("Conversion from bignum to binary failed");
+// KW         delete []buffer;
+// KW         return false;
+// KW     }
+// KW
+// KW     char* pBase64Node = NULL;
+// KW     unsigned long int buffLen = 0;
+// KW     certmgr_util_base64_encode(buffer, (unsigned long int) nNumLength, &pBase64Node, &buffLen);
+// KW
+// KW     strNode.assign(pBase64Node, buffLen);
+// KW
+// KW     delete []buffer;
+// KW     return true;
+// KW }
+} // namespace ValidationCore
+
diff --git a/vcore/src/vcore/CertificateLoader.h b/vcore/src/vcore/CertificateLoader.h
new file mode 100644 (file)
index 0000000..de92764
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+#ifndef _CERTIFICATELOADER_H_
+#define _CERTIFICATELOADER_H_
+
+#include <string>
+#include <string.h>
+
+#include <dpl/noncopyable.h>
+#include <openssl/ssl.h>
+
+#include <cert-service.h>
+
+#include <vcore/Certificate.h>
+
+namespace ValidationCore {
+class CertificateLoader : public DPL::Noncopyable
+{
+  public:
+    class CertificateLoaderComparator
+    {
+      public:
+        virtual bool compare(X509 *x509cert) = 0;
+        virtual ~CertificateLoaderComparator()
+        {
+        }
+    };
+
+    enum CertificateLoaderResult
+    {
+        NO_ERROR,
+        CERTIFICATE_NOT_FOUND,
+        UNSUPPORTED_CERTIFICATE_FIELD,
+        WRONG_ARGUMENTS,
+        CERTIFICATE_SECURITY_ERROR,                  //!< there are some issues with certificate security (i.e. key too short)
+        UNKNOWN_ERROR
+    };
+
+    CertificateLoader()
+    {
+    }
+
+    virtual ~CertificateLoader()
+    {
+    }
+
+    CertificateLoaderResult loadCertificate(const std::string& storage,
+            CertificateLoaderComparator *cmp);
+
+    CertificateLoaderResult loadCertificateBasedOnSubjectName(
+            const std::string &subjectName);
+    CertificateLoaderResult loadCertificateBasedOnExponentAndModulus(
+            const std::string &m_modulus,
+            const std::string  &m_exponent);
+    // KW     CertificateLoaderResult loadCertificateBasedOnIssuerName(const std::string &isserName,
+    // KW       const std::string &serialNumber);
+
+    CertificateLoaderResult loadCertificateFromRawData(
+            const std::string &rawData);
+
+    CertificateLoaderResult loadCertificateBasedOnDSAComponents(
+            const std::string& strP,
+            const std::string& strQ,
+            const std::string& strG,
+            const std::string& strY,
+            const std::string& strJ,
+            const std::string& strSeed,
+            const std::string& strPGenCounter);
+
+    CertificateLoaderResult loadCertificateWithECKEY(
+            const std::string &curveName,
+            const std::string &publicKey);
+
+    /**
+     * converts base64 encoded node to SSL bignum
+     * allocates mem on *ppBigNum, don't forget to free it later with BN_free!
+     * returns conversion status
+     */
+    static bool convertBase64NodeToBigNum(const std::string& strNode,
+            BIGNUM** ppBigNum);
+
+    /*
+     * encodes SSL bignum into base64 octstring
+     * returns conversion status
+     */
+    // KW     static bool convertBigNumToBase64Node(const BIGNUM* pBigNum, std::string& strNode);
+
+    CertificatePtr getCertificatePtr() const
+    {
+        return m_certificatePtr;
+    }
+  private:
+    CertificatePtr m_certificatePtr;
+};
+} // namespace ValidationCore
+
+#endif // _CERTIFICATELOADER_H_
diff --git a/vcore/src/vcore/CertificateStorage.h b/vcore/src/vcore/CertificateStorage.h
new file mode 100644 (file)
index 0000000..7fbcb6b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+#ifndef VCORE_SRC_VCORE_CERTIFICATESTORAGE_H
+#define VCORE_SRC_VCORE_CERTIFICATESTORAGE_H
+
+#include <list>
+#include <openssl/x509.h>
+
+namespace ValidationCore {
+typedef std::list < X509* > X509CertificatesList;
+}
+
+#endif // VCORE_SRC_VCORE_CERTIFICATESTORAGE_H
diff --git a/vcore/src/vcore/CertificateVerifier.cpp b/vcore/src/vcore/CertificateVerifier.cpp
new file mode 100644 (file)
index 0000000..ffc0dcc
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@gmail.com)
+ * @version     0.1
+ * @file        CertificateVerifier.cpp
+ * @brief       This class integrates OCSP and CRL.
+ */
+#include <vcore/CertificateVerifier.h>
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+namespace ValidationCore {
+
+CertificateVerifier::CertificateVerifier(bool enableOcsp, bool enableCrl)
+: m_enableOcsp(enableOcsp)
+, m_enableCrl(enableCrl)
+{}
+
+VerificationStatus CertificateVerifier::check(
+        CertificateCollection &certCollection) const
+{
+    LogDebug("== Certificate collection validation start ==");
+    Assert(certCollection.isChain() && "Collection must form chain.");
+
+    VerificationStatus statusOcsp;
+    VerificationStatus statusCrl;
+
+    if (m_enableOcsp) {
+        statusOcsp = obtainOcspStatus(certCollection);
+    } else {
+        statusOcsp = VERIFICATION_STATUS_GOOD;
+    }
+
+    if (m_enableCrl) {
+        statusCrl = obtainCrlStatus(certCollection);
+    } else {
+        statusCrl = VERIFICATION_STATUS_GOOD;
+    }
+    LogDebug("== Certificate collection validation end ==");
+    return getStatus(statusOcsp, statusCrl);
+}
+
+VerificationStatus CertificateVerifier::obtainOcspStatus(
+        const CertificateCollection &chain) const
+{
+    LogDebug("== Obtain ocsp status ==");
+    CachedOCSP ocsp;
+    return ocsp.check(chain);
+}
+
+VerificationStatus CertificateVerifier::obtainCrlStatus(
+        const CertificateCollection &chain) const
+{
+    LogDebug("== Obtain crl status ==");
+    CachedCRL crl;
+    return crl.check(chain);
+}
+
+VerificationStatus CertificateVerifier::getStatus(
+        VerificationStatus ocsp,
+        VerificationStatus crl) const
+{
+    if (ocsp == VERIFICATION_STATUS_REVOKED ||
+        crl == VERIFICATION_STATUS_REVOKED)
+    {
+        LogDebug("Return status: REVOKED");
+        return VERIFICATION_STATUS_REVOKED;
+    }
+
+    if (ocsp == VERIFICATION_STATUS_GOOD) {
+        LogDebug("Return status: GOOD");
+        return VERIFICATION_STATUS_GOOD;
+    }
+
+    if (ocsp == VERIFICATION_STATUS_UNKNOWN) {
+        LogDebug("Return status: UNKNOWN");
+        return VERIFICATION_STATUS_UNKNOWN;
+    }
+
+    if (ocsp == VERIFICATION_STATUS_NOT_SUPPORT) {
+        LogDebug("Return status: NOT_SUPPORT");
+        return VERIFICATION_STATUS_GOOD;
+    }
+
+    LogDebug("Return status: ERROR");
+    return VERIFICATION_STATUS_ERROR;
+}
+
+VerificationStatus CertificateVerifier::checkEndEntity(
+        CertificateCollectionList &collectionList) const
+{
+    VerificationStatusSet statusOcsp;
+    VerificationStatusSet statusCrl;
+
+    if (m_enableOcsp) {
+        CachedOCSP ocsp;
+        FOREACH(it, collectionList){
+            statusOcsp.add(ocsp.checkEndEntity(*it));
+        }
+    } else {
+        statusOcsp.add(VERIFICATION_STATUS_GOOD);
+    }
+
+    if (m_enableCrl) {
+        CachedCRL crl;
+        FOREACH(it, collectionList){
+            statusCrl.add(crl.checkEndEntity(*it));
+        }
+    } else {
+        statusCrl.add(VERIFICATION_STATUS_GOOD);
+    }
+    LogDebug("== Certificate collection validateion end ==");
+    return getStatus(statusOcsp.convertToStatus(), statusCrl.convertToStatus());
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CertificateVerifier.h b/vcore/src/vcore/CertificateVerifier.h
new file mode 100644 (file)
index 0000000..656bd2b
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@gmail.com)
+ * @version     0.1
+ * @file        CertificateVerifier.h
+ * @brief       This class integrates OCSP and CRL into one module.
+ */
+#ifndef _VALIDATION_CORE_CERTIFICATE_VERIFIER_H_
+#define _VALIDATION_CORE_CERTIFICATE_VERIFIER_H_
+
+#include <vcore/Certificate.h>
+#include <vcore/CertificateCollection.h>
+#include <vcore/CachedCRL.h>
+#include <vcore/CachedOCSP.h>
+#include <vcore/VerificationStatus.h>
+
+namespace ValidationCore {
+
+class CertificateVerifier {
+  public:
+    explicit CertificateVerifier(bool enableOcsp, bool enableCrl);
+    ~CertificateVerifier(){}
+
+    /*
+     * Run OCSP and CRL for all certificates in collection.
+     * Collection must represent chain.
+     *
+     * Evaluate status. This function converts ocsp status set
+     * into one status - the most restricted. This one ocsp status
+     * and status from crl is evaluated to end result.
+     *
+     * Algorithm to evaluate result is represented in table:
+     *
+     * +--------------+-------+-------+-------+------------+---------+
+     * |      OCSP    |Good   |Revoked|Unknown|Undetermined|Not      |
+     * |              |       |       |       |            |supported|
+     * | CRL          |       |       |       |            |         |
+     * +--------------+-------+-------+-------+------------+---------+
+     * | GOOD         |GOOD   |Revoked|Unknown|Undetermined|Good     |
+     * +--------------+-------+-------+-------+------------+---------+
+     * | REVOKED      |Revoked|Revoked|Revoked|Revoked     |Revoked  |
+     * +--------------+-------+-------+-------+------------+---------+
+     * | UNDETERMINED |Good   |Revoked|Unknown|Undetermined|Good     |
+     * +--------------+-------+-------+-------+------------+---------+
+     * | Not supported|Good   |Revoked|Unknown|Undetermined|Good     |
+     * +--------------+-------+-------+-------+------------+---------+
+     *
+     * As Undetermind function returns VERIFICATION_STATUS_ERROR.
+     */
+
+    VerificationStatus check(CertificateCollection &certCollection) const;
+
+    VerificationStatus checkEndEntity(
+            CertificateCollectionList &certCollectionList) const;
+
+  private:
+    VerificationStatus obtainOcspStatus(
+            const CertificateCollection &chain) const;
+    VerificationStatus obtainCrlStatus(
+            const CertificateCollection &chain) const;
+    VerificationStatus getStatus(VerificationStatus ocsp,
+                                 VerificationStatus crl) const;
+
+    bool m_enableOcsp;
+    bool m_enableCrl;
+};
+
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_CERTIFICATE_VERIFIER_H_
+
diff --git a/vcore/src/vcore/Config.cpp b/vcore/src/vcore/Config.cpp
new file mode 100644 (file)
index 0000000..2a4cf83
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+#include <vcore/Config.h>
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(ValidationCore::Config)
diff --git a/vcore/src/vcore/Config.h b/vcore/src/vcore/Config.h
new file mode 100644 (file)
index 0000000..a810414
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_
+#define _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_
+
+#include <string>
+
+#include <dpl/singleton.h>
+
+namespace ValidationCore {
+class Config {
+public:
+    /*
+     * Set path to config file with certificate description.
+     */
+    bool setXMLConfigPath(const std::string& path) {
+        if (!m_certificateXMLConfigPath.empty()) {
+            return false;
+        }
+        m_certificateXMLConfigPath = path;
+        return true;
+    }
+
+    /*
+     * Set path to schema of config file.
+     */
+    bool setXMLSchemaPath(const std::string& path) {
+        if (!m_certificateXMLSchemaPath.empty()) {
+            return false;
+        }
+        m_certificateXMLSchemaPath = path;
+        return true;
+    }
+
+    /*
+     * Get path to config file with certificate description.
+     */
+    std::string getXMLConfigPath() {
+        return m_certificateXMLConfigPath;
+    }
+
+    /*
+     * Get path to schema of config file.
+     */
+    std::string getXMLSchemaPath() {
+        return m_certificateXMLSchemaPath;
+    }
+
+private:
+    std::string m_certificateXMLConfigPath;
+    std::string m_certificateXMLSchemaPath;
+};
+
+typedef DPL::Singleton<Config> ConfigSingleton;
+
+} // namespace ValidationCore
+
+#endif // _SRC_VALIDATION_CORE_VALIDATION_CORE_CONFIG_H_
+
diff --git a/vcore/src/vcore/CryptoHash.cpp b/vcore/src/vcore/CryptoHash.cpp
new file mode 100644 (file)
index 0000000..2827b16
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * 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        wrt_crypto_hash.cpp
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of cryptographic hasing algorithms
+ */
+#include <vcore/CryptoHash.h>
+
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <stdexcept>
+
+#include <vcore/Base64.h>
+
+namespace ValidationCore
+{
+namespace Crypto
+{
+namespace Hash
+{
+namespace // anonymous
+{
+const size_t HASH_DIGEST_STREAM_FEED_SIZE = 1024;
+
+std::string Raw2Base64(const void *buffer, size_t bufferSize)
+{
+    BIO *bio64, *biomem;
+
+    if ((bio64 = BIO_new(BIO_f_base64())) == NULL)
+        ThrowMsg(AppendFailed, "BIO_new(BIO_f_base64()) failed!");
+
+    if ((biomem = BIO_new(BIO_s_mem())) == NULL)
+    {
+        BIO_free_all(bio64);
+        ThrowMsg(AppendFailed, "BIO_new(BIO_s_mem()) failed!");
+    }
+
+    bio64 = BIO_push(bio64, biomem);
+
+    if (BIO_write(bio64, buffer, static_cast<int>(bufferSize)) <= 0)
+    {
+        BIO_free_all(bio64);
+        ThrowMsg(AppendFailed, "BIO_write failed!");
+    }
+
+    if (BIO_flush(bio64) <= 0)
+    {
+        BIO_free_all(bio64);
+        ThrowMsg(AppendFailed, "BIO_flush failed!");
+    }
+
+    BUF_MEM *bioptr;
+    BIO_get_mem_ptr(bio64, &bioptr);
+
+    std::string base64 = std::string(static_cast<const char *>(bioptr->data), static_cast<const char *>(bioptr->data + bioptr->length));
+
+    BIO_free_all(bio64);
+    return base64;
+}
+} // namespace anonymous
+
+Base::Base()
+    : m_hasFinal(false)
+{
+}
+
+Base::~Base()
+{
+}
+
+void Base::Append(const char *buffer)
+{
+    if (m_hasFinal)
+        ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+
+    HashUpdate(buffer, strlen(buffer));
+}
+
+void Base::Append(const char *buffer, size_t bufferSize)
+{
+    if (m_hasFinal)
+        ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+
+    HashUpdate(buffer, bufferSize);
+}
+
+void Base::Append(const std::string &buffer)
+{
+    if (m_hasFinal)
+        ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+
+    HashUpdate(buffer.c_str(), buffer.size());
+}
+
+void Base::Append(std::istream &stream)
+{
+    if (m_hasFinal)
+        ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+
+    char buffer[HASH_DIGEST_STREAM_FEED_SIZE];
+
+    do
+    {
+        stream.read(buffer, HASH_DIGEST_STREAM_FEED_SIZE);
+
+        if (stream.gcount() > 0)
+            Append(static_cast<void *>(buffer), static_cast<size_t>(stream.gcount()));
+
+    } while (stream.gcount() > 0);
+}
+
+void Base::Append(const void *data, size_t dataSize)
+{
+    if (m_hasFinal)
+        ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+
+    HashUpdate(data, dataSize);
+}
+
+void Base::Finish()
+{
+    if (m_hasFinal)
+        return;
+
+    // Finalize hashing algorithm
+    m_raw = HashFinal();
+
+    // Convert to base 64 string
+    Base64Encoder encoder;
+    encoder.reset();
+    encoder.append(std::string(m_raw.begin(), m_raw.end()));
+    encoder.finalize();
+    m_base64StringHash = encoder.get();
+
+    m_hasFinal = true;
+}
+
+std::string Base::ToBase64String() const
+{
+    return m_base64StringHash;
+}
+
+Raw Base::GetHash() const
+{
+    return m_raw;
+}
+
+OpenSSL::OpenSSL(const EVP_MD *evpMd)
+    : m_finalized(false)
+{
+    EVP_MD_CTX_init(&m_context);
+
+    if (EVP_DigestInit(&m_context, evpMd) != 1)
+        ThrowMsg(AppendFailed, "EVP_DigestInit failed!");
+}
+
+OpenSSL::~OpenSSL()
+{
+    if (!m_finalized)
+    {
+        // Just clean context
+        EVP_MD_CTX_cleanup(&m_context);
+        m_finalized = true;
+    }
+}
+
+void OpenSSL::HashUpdate(const void *data, size_t dataSize)
+{
+    if (m_finalized)
+        ThrowMsg(AppendFailed, "OpenSSLHash hash already finalized!");
+
+    if (EVP_DigestUpdate(&m_context, data, dataSize) != 1)
+        ThrowMsg(AppendFailed, "EVP_DigestUpdate failed!");
+}
+
+Hash::Raw OpenSSL::HashFinal()
+{
+    if (m_finalized)
+        ThrowMsg(AppendFailed, "OpenSSLHash hash already finalized!");
+
+    unsigned char hash[EVP_MAX_MD_SIZE] = {};
+    unsigned int hashLength;
+
+    // Also cleans context
+    if (EVP_DigestFinal(&m_context, hash, &hashLength) != 1)
+        ThrowMsg(AppendFailed, "EVP_DigestFinal failed!");
+
+    m_finalized = true;
+    return Raw(hash, hash + hashLength);
+}
+
+} // namespace Hash
+} // namespace Crypto
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/CryptoHash.h b/vcore/src/vcore/CryptoHash.h
new file mode 100644 (file)
index 0000000..aaed9e0
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * 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        crypto_hash.h
+ * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of cryptographic hasing algorithms
+ */
+#ifndef _CRYPTO_HASH_H_
+#define _CRYPTO_HASH_H_
+
+#include <dpl/exception.h>
+#include <openssl/evp.h>
+#include <istream>
+#include <string>
+#include <vector>
+
+namespace ValidationCore
+{
+namespace Crypto
+{
+namespace Hash
+{
+/**
+ * Raw hash buffer
+ */
+typedef std::vector<unsigned char> Raw;
+
+/**
+ * Append called out of sequence
+ */
+DECLARE_EXCEPTION_TYPE(DPL::Exception, OutOfSequence)
+
+/**
+ * Append failed internally
+ */
+DECLARE_EXCEPTION_TYPE(DPL::Exception, AppendFailed)
+
+class Base
+{
+private:
+    Raw m_raw;
+    std::string m_base64StringHash;
+    bool m_hasFinal;
+
+protected:
+    virtual void HashUpdate(const void *data, size_t dataSize) = 0;
+    virtual Raw HashFinal() = 0;
+
+public:
+    Base();
+    virtual ~Base();
+
+    virtual void Append(const char *buffer);
+    virtual void Append(const char *buffer, size_t bufferSize);
+    virtual void Append(const std::string &buffer);
+    virtual void Append(std::istream &stream);
+    virtual void Append(const void *data, size_t dataSize);
+
+    virtual void Finish();
+
+    virtual std::string ToBase64String() const;
+    virtual Raw GetHash() const;
+};
+
+/**
+ * OpenSSL hashing algorithm base
+ */
+class OpenSSL
+    : public Base
+{
+private:
+    EVP_MD_CTX m_context;
+    bool m_finalized;
+
+protected:
+    virtual void HashUpdate(const void *data, size_t dataSize);
+    virtual Raw HashFinal();
+
+public:
+    OpenSSL(const EVP_MD *evpMd);
+    virtual ~OpenSSL();
+};
+
+#define DECLARE_OPENSSL_HASH_ALGORITHM(ClassName, EvpMd) \
+    class ClassName                                      \
+        : public OpenSSL                                 \
+    {                                                    \
+    public:                                              \
+        ClassName() : OpenSSL(EvpMd()) {}                \
+        virtual ~ClassName() {}                          \
+    };
+
+DECLARE_OPENSSL_HASH_ALGORITHM(MD2, EVP_md2)
+DECLARE_OPENSSL_HASH_ALGORITHM(MD4, EVP_md4)
+DECLARE_OPENSSL_HASH_ALGORITHM(MD5, EVP_md5)
+DECLARE_OPENSSL_HASH_ALGORITHM(SHA, EVP_sha)
+DECLARE_OPENSSL_HASH_ALGORITHM(SHA1, EVP_sha1)
+DECLARE_OPENSSL_HASH_ALGORITHM(DSS, EVP_dss)
+DECLARE_OPENSSL_HASH_ALGORITHM(DSS1, EVP_dss1)
+DECLARE_OPENSSL_HASH_ALGORITHM(ECDSA, EVP_ecdsa)
+DECLARE_OPENSSL_HASH_ALGORITHM(SHA224, EVP_sha224)
+DECLARE_OPENSSL_HASH_ALGORITHM(SHA256, EVP_sha256)
+DECLARE_OPENSSL_HASH_ALGORITHM(SHA384, EVP_sha384)
+DECLARE_OPENSSL_HASH_ALGORITHM(SHA512, EVP_sha512)
+
+#undef DECLARE_OPENSSL_HASH_ALGORITHM
+
+} // namespace Hash
+} // namespace Crypto
+} // namespace ValidationCore
+
+#endif // DPL_CRYPTO_HASH_H
diff --git a/vcore/src/vcore/Database.cpp b/vcore/src/vcore/Database.cpp
new file mode 100644 (file)
index 0000000..5f03e45
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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    webruntime_database.cpp
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   This file contains the definition of webruntime database
+ */
+#include <vcore/Database.h>
+
+DPL::Mutex g_vcoreDbQueriesMutex;
diff --git a/vcore/src/vcore/Database.h b/vcore/src/vcore/Database.h
new file mode 100644 (file)
index 0000000..ca6efa2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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    webruntime_database.h
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   This file contains the declaration of webruntime database
+ */
+#ifndef VCORE_SRC_VCORE_DATABASE_H
+#define VCORE_SRC_VCORE_DATABASE_H
+
+#include <dpl/db/thread_database_support.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/mutex.h>
+#include <dpl/thread.h>
+
+extern DPL::Mutex g_vcoreDbQueriesMutex;
+
+#define VCORE_DB_INTERNAL(tlsCommand, InternalType, interface)               \
+    static DPL::ThreadLocalVariable<InternalType> *tlsCommand ## Ptr = NULL; \
+    {                                                                        \
+        DPL::Mutex::ScopedLock lock(&g_vcoreDbQueriesMutex);                 \
+        if (!tlsCommand ## Ptr) {                                            \
+            static DPL::ThreadLocalVariable<InternalType> tmp;               \
+            tlsCommand ## Ptr = &tmp;                                        \
+        }                                                                    \
+    }                                                                        \
+    DPL::ThreadLocalVariable<InternalType> &tlsCommand = *tlsCommand ## Ptr; \
+    if (tlsCommand.IsNull()) { tlsCommand = InternalType(interface); }
+
+#define VCORE_DB_SELECT(name, type, interface) \
+    VCORE_DB_INTERNAL(name, type::Select, interface)
+
+#define VCORE_DB_INSERT(name, type, interface) \
+    VCORE_DB_INTERNAL(name, type::Insert, interface)
+
+#define VCORE_DB_UPDATE(name, type, interface) \
+    VCORE_DB_INTERNAL(name, type::Update, interface)
+
+#define VCORE_DB_DELETE(name, type, interface) \
+    VCORE_DB_INTERNAL(name, type::Delete, interface)
+
+#endif // define VCORE_SRC_VCORE_DATABASE_H
diff --git a/vcore/src/vcore/DeveloperModeValidator.cpp b/vcore/src/vcore/DeveloperModeValidator.cpp
new file mode 100644 (file)
index 0000000..a861728
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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        DeveloperModeValidator.cpp
+ * @author      Bartosz Janiak (b.janiak@samsung.com)
+ * @version     1.0
+ * @brief       DeveloperModeValidatorValidator - implementing WAC 2.0 spec, including TargetRestriction
+ */
+
+#include <vcore/DeveloperModeValidator.h>
+
+#include <algorithm>
+#include <vconf.h>
+#include <dpl/log/log.h>
+#include <dpl/scoped_free.h>
+
+namespace ValidationCore {
+
+DeveloperModeValidator::DeveloperModeValidator(bool complianceMode,
+                                               const std::string& fakeIMEI,
+                                               const std::string& fakeMEID) :
+    m_complianceModeEnabled(complianceMode),
+    m_developerModeEnabled(true),
+    m_fakeIMEI(fakeIMEI),
+    m_fakeMEID(fakeMEID)
+{
+}
+
+DeveloperModeValidator::DeveloperModeValidator(bool complianceMode,
+                                               bool developerMode,
+                                               const std::string& fakeIMEI,
+                                               const std::string& fakeMEID,
+                                               const std::string& realMEID) :
+    m_complianceModeEnabled(complianceMode),
+    m_developerModeEnabled(developerMode),
+    m_fakeIMEI(fakeIMEI),
+    m_fakeMEID(fakeMEID),
+    m_realMEID(realMEID)
+{
+}
+
+void DeveloperModeValidator::check(const SignatureData &data)
+{
+    LogDebug("entered");
+    const SignatureData::IMEIList& IMEIList = data.getIMEIList();
+    const SignatureData::MEIDList& MEIDList = data.getMEIDList();
+
+    if (IMEIList.empty() && MEIDList.empty()) {
+        LogDebug("No TargetRestriction in signature.");
+        return;
+    }
+
+    if (!m_developerModeEnabled) {
+        Throw(Exception::NoTargetRestrictionSatisfied);
+    }
+
+    if (!IMEIList.empty()) {
+        std::string phoneIMEIString = m_fakeIMEI;
+        if (!m_complianceModeEnabled) {
+            LogDebug("Compilance Mode is not enabled");
+            DPL::ScopedFree<char> phoneIMEI(
+                vconf_get_str(VCONFKEY_TELEPHONY_IMEI));
+            if (!phoneIMEI.Get()) {
+                ThrowMsg(Exception::NoTargetRestrictionSatisfied,
+                         "Unable to get phone IMEI from vconf.");
+            }
+            phoneIMEIString = phoneIMEI.Get();
+        }
+
+        LogDebug("Phone IMEI: " << phoneIMEIString);
+        if (IMEIList.end() ==
+            std::find(IMEIList.begin(), IMEIList.end(), phoneIMEIString))
+        {
+            Throw(Exception::NoTargetRestrictionSatisfied);
+        }
+    }
+
+    if (!MEIDList.empty()) {
+        std::string phoneMEIDString = m_fakeMEID;
+        if (!m_complianceModeEnabled)
+        {
+            if (m_realMEID.empty())
+            {
+                ThrowMsg(Exception::NoTargetRestrictionSatisfied,
+                         "Unable to get phone MEID from Tapi service.");
+            }
+            phoneMEIDString = m_realMEID;
+        }
+
+        LogDebug("Phone MEID: " << phoneMEIDString);
+        if (MEIDList.end() ==
+            std::find(MEIDList.begin(), MEIDList.end(), phoneMEIDString))
+        {
+            Throw(Exception::NoTargetRestrictionSatisfied);
+        }
+    }
+    LogDebug("exit: ok");
+}
+
+} //ValidationCore
diff --git a/vcore/src/vcore/DeveloperModeValidator.h b/vcore/src/vcore/DeveloperModeValidator.h
new file mode 100644 (file)
index 0000000..a0c37ba
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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        DeveloperModeValidator.h
+ * @author      Bartosz Janiak (b.janiak@samsung.com)
+ * @version     1.0
+ * @brief       DeveloperModeValidatorValidator - implementing WAC 2.0 spec, including TargetRestriction
+ */
+#ifndef _VALIDATION_CORE_DEVELOPER_MODE_VALIDATOR_H_
+#define _VALIDATION_CORE_DEVELOPER_MODE_VALIDATOR_H_
+
+#include <string>
+#include <dpl/exception.h>
+#include <vcore/SignatureData.h>
+
+namespace ValidationCore {
+
+class DeveloperModeValidator
+{
+  public:
+    explicit DeveloperModeValidator(
+        bool complianceMode = false,
+        const std::string &fakeIMEI = "",
+        const std::string &fakeMEID = "")  __attribute__((deprecated));
+
+    explicit DeveloperModeValidator(bool complianceMode = false,
+                                    bool developerMode = false,
+                                    const std::string &fakeIMEI = "",
+                                    const std::string &fakeMEID = "",
+                                    const std::string &realMEID = "");
+
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, UnableToLoadTestCertificate)
+        DECLARE_EXCEPTION_TYPE(Base, NoTargetRestrictionSatisfied)
+    };
+
+    void check(const SignatureData &data);
+  private:
+    bool m_complianceModeEnabled;
+    bool m_developerModeEnabled;
+    std::string m_fakeIMEI;
+    std::string m_fakeMEID;
+    std::string m_realMEID;
+};
+
+}
+#endif /* _VALIDATION_CORE_DEVELOPER_MODE_VALIDATOR_H_ */
+
diff --git a/vcore/src/vcore/IAbstractResponseCache.h b/vcore/src/vcore/IAbstractResponseCache.h
new file mode 100644 (file)
index 0000000..2495d27
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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       AbstractResponseCache.h
+ * @author     Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version    0.1
+ * @brief      Common interface for OCSP/CRL caches
+ */
+
+#ifndef _VALIDATION_CORE_IABSTRACT_RESPONSE_CACHE_H_
+#define _VALIDATION_CORE_IABSTRACT_RESPONSE_CACHE_H_
+
+#include <vcore/VerificationStatus.h>
+
+namespace ValidationCore {
+
+class CertificateCollection;
+
+class IAbstractResponseCache {
+  public:
+    virtual VerificationStatus check(const CertificateCollection &certs) = 0;
+    virtual VerificationStatus checkEndEntity(CertificateCollection &certs) = 0;
+    virtual void updateCache() = 0;
+
+    virtual ~IAbstractResponseCache()
+    {
+    }
+};
+
+} // namespace ValidationCore
+
+#endif /* _VALIDATION_CORE_IABSTRACT_RESPONSE_CACHE_H_ */
diff --git a/vcore/src/vcore/OCSP.cpp b/vcore/src/vcore/OCSP.cpp
new file mode 100644 (file)
index 0000000..26f81c3
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski(b.grzelewski@samsung.com)
+ * @version     0.5
+ * @file        OCPS.cpp
+ * @brief       This class is used for hide OCSP implementation.
+ */
+
+#include <vcore/OCSPImpl.h>
+
+namespace ValidationCore {
+
+OCSP::OCSP() :
+    m_impl(new OCSPImpl())
+{}
+
+OCSP::~OCSP(){
+    delete m_impl;
+}
+
+ValidationCore::VerificationStatusSet OCSP::validateCertificateList(
+    const CertificateList &certs)
+{
+    return m_impl->validateCertificateList(certs);
+}
+
+VerificationStatus OCSP::checkEndEntity(
+        const CertificateCollection &chain)
+{
+    return m_impl->checkEndEntity(chain);
+}
+
+VerificationStatus OCSP::validateCertificate(CertificatePtr argCert,
+                                             CertificatePtr argIssuer)
+{
+    return m_impl->validateCertificate(argCert, argIssuer);
+}
+
+void OCSP::setDigestAlgorithmForCertId(DigestAlgorithm alg) {
+    return m_impl->setDigestAlgorithmForCertId(alg);
+}
+
+void OCSP::setDigestAlgorithmForRequest(DigestAlgorithm alg) {
+    return m_impl->setDigestAlgorithmForRequest(alg);
+}
+
+void OCSP::setTrustedStore(const CertificateList& certs) {
+    m_impl->setTrustedStore(certs);
+}
+
+void OCSP::setDefaultResponder(const char *uri) {
+    m_impl->setDefaultResponder(uri);
+}
+
+void OCSP::setUseDefaultResponder(bool value) {
+    m_impl->setUseDefaultResponder(value);
+}
+
+time_t OCSP::getResponseValidity() {
+    return m_impl->getResponseValidity();
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/OCSP.h b/vcore/src/vcore/OCSP.h
new file mode 100644 (file)
index 0000000..59c6969
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.5
+ * @file        OCPS.h
+ * @brief       This class is used to hide OCSP implementation.
+ */
+
+#ifndef _VALIDATION_CORE_OCSP_H_
+#define _VALIDATION_CORE_OCSP_H_
+
+#include <ctime>
+
+#include <dpl/noncopyable.h>
+
+#include <vcore/Certificate.h>
+#include <vcore/CertificateCollection.h>
+#include <vcore/VerificationStatus.h>
+
+namespace ValidationCore {
+
+class OCSPImpl;
+
+class OCSP : DPL::Noncopyable
+{
+public:
+    OCSP();
+
+    VerificationStatus checkEndEntity(const CertificateCollection &certList);
+
+    enum DigestAlgorithm
+    {
+        SHA1,
+        SHA224,
+        SHA256,
+        SHA384,
+        SHA512
+    };
+
+    /**
+     * Sets digest algorithm for certid in ocsp request
+     */
+    void setDigestAlgorithmForCertId(DigestAlgorithm alg);
+
+    /**
+     * Sets digest algorithm for certid in ocsp request
+     */
+    void setDigestAlgorithmForRequest(DigestAlgorithm alg);
+
+    void setTrustedStore(const CertificateList& certs);
+
+    VerificationStatusSet validateCertificateList(const CertificateList &certs);
+
+    VerificationStatus validateCertificate(CertificatePtr argCert,
+                                           CertificatePtr argIssuer);
+
+    void setDefaultResponder(const char* uri);
+
+    void setUseDefaultResponder(bool value);
+
+    /**
+     * @return time when response will become invalid - for list of
+     * certificates, this is the minimum of all validities; value is
+     * valid only for not-revoked certificates (non error validation result)
+     */
+    time_t getResponseValidity();
+
+    virtual ~OCSP();
+private:
+    OCSPImpl *m_impl;
+};
+
+} // namespace ValidationCore
+
+#endif //ifndef _VALIDATION_CORE_OCSP_H_
diff --git a/vcore/src/vcore/OCSPCertMgrUtil.cpp b/vcore/src/vcore/OCSPCertMgrUtil.cpp
new file mode 100644 (file)
index 0000000..f463d00
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Michal Ciepielski(m.ciepielski@samsung.com)
+ * @version     0.3
+ * @brief
+ */
+
+#include <vcore/OCSPCertMgrUtil.h>
+#include <vcore/SSLContainers.h>
+
+#include <openssl/pem.h>
+#include <openssl/ocsp.h>
+#include <openssl/x509.h>
+#include <dpl/log/log.h>
+#include <dpl/scoped_resource.h>
+#include <string.h>
+#include <iostream>
+#include <string>
+
+#include <cert-service.h>
+
+namespace {
+const int MAX_BUF = 1024;
+
+struct ContextDeleter
+{
+    typedef CERT_CONTEXT* Type;
+    static Type NullValue()
+    {
+        return NULL;
+    }
+    static void Destroy(Type context)
+    {
+        if (context) {
+            cert_svc_cert_context_final(context);
+        }
+    }
+};
+}
+
+namespace ValidationCore {
+namespace OCSPCertMgrUtil {
+/*
+ * TODO This API function should be changed to:
+ * CertifiatePtr getCertFromStore(const std::string &subject);
+ *
+ * All of cert_svc function could return error because input
+ * data are corruped. That's why I dont want to throw exceptions
+ * in this function.
+ */
+void getCertFromStore(X509_NAME *subject,
+        X509 **xcert)
+{
+    if (!xcert || *xcert || !subject) {
+        LogError("Invalid input!");
+        return;
+    }
+
+    typedef DPL::ScopedResource<ContextDeleter> ScopedContext;
+
+    int result;
+    char buffer[MAX_BUF];
+    const unsigned char* ptr = NULL;
+    X509 *pCertificate = NULL;
+    cert_svc_filename_list *fileList = NULL;
+
+    X509_NAME_oneline(subject, buffer, MAX_BUF);
+
+    ScopedContext ctx(cert_svc_cert_context_init());
+    if (ctx.Get() == NULL) {
+        LogWarning("Error in cert_svc_cert_context_init.");
+        return;
+    }
+
+    LogDebug("Search certificate with subject: " << buffer);
+    result = cert_svc_search_certificate(ctx.Get(), SUBJECT_STR, buffer);
+    LogDebug("Search finished!");
+
+    if (CERT_SVC_ERR_NO_ERROR != result) {
+        LogWarning("Error during certificate search");
+        return;
+    }
+
+    fileList = ctx.Get()->fileNames;
+
+    if (fileList == NULL) {
+        LogDebug("No certificate found");
+        return;
+    }
+
+    if (fileList->filename == NULL) {
+        LogWarning("Empty filename");
+        return;
+    }
+
+    LogDebug("Found cert file: " << fileList->filename);
+    ScopedContext ctx2(cert_svc_cert_context_init());
+
+    if (ctx2.Get() == NULL) {
+        LogWarning("Error in cert_svc_cert_context_init.");
+        return;
+    }
+
+    // TODO add read_certifcate_from_file function to Certificate.h
+    if (CERT_SVC_ERR_NO_ERROR !=
+        cert_svc_load_file_to_context(ctx2.Get(), fileList->filename)) {
+        LogWarning("Error in cert_svc_load_file_to_context");
+        return;
+    }
+
+    ptr = ctx2.Get()->certBuf->data;
+    // create a certificate from mem buff
+    pCertificate = d2i_X509(NULL, &ptr, ctx2.Get()->certBuf->size);
+
+    if (pCertificate == NULL) {
+        LogWarning("Error during certificate conversion in d2i_X509");
+        return;
+    }
+
+    *xcert = pCertificate;
+    if (fileList->next != NULL) {
+        LogError("There is more then one certificate with same subject :/");
+        // TODO Implement me.
+        for (fileList = fileList->next;
+             fileList != NULL;
+             fileList = fileList->next) {
+            LogError(
+                "Additional certificate with same subject: " <<
+                fileList->filename);
+        }
+    }
+}
+
+CertificatePtr getParentFromStore(const CertificatePtr &certificate)
+{
+    Assert(certificate.Get());
+    X509* rawPtr = certificate->getX509();
+
+    /* TODO Add getIssuerName function to Certificate.h */
+    X509_NAME *name = X509_get_issuer_name(rawPtr);
+
+    X509* rawTemp = NULL;
+    getCertFromStore(name, &rawTemp);
+
+    if (rawTemp == NULL) {
+        return CertificatePtr();
+    }
+
+    SSLSmartContainer<X509> scope(rawTemp);
+    return CertificatePtr(new Certificate(rawTemp));
+}
+
+CertificateList completeCertificateChain(const CertificateList &certificateList)
+{
+    CertificateList result = certificateList;
+    CertificatePtr last = result.back();
+    if (last->isSignedBy(last)) {
+        return result;
+    }
+    CertificatePtr parent = getParentFromStore(last);
+    if (parent.Get()) {
+        result.push_back(parent);
+    }
+    return result;
+}
+} // namespace OCSPCertMgrUtil
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/OCSPCertMgrUtil.h b/vcore/src/vcore/OCSPCertMgrUtil.h
new file mode 100644 (file)
index 0000000..5c0e2eb
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Tomasz Morawski(t.morawski@samsung.com)
+ * @author      Michal Ciepielski(m.ciepielski@samsung.com)
+ * @version     0.2
+ * @brief
+ */
+
+#ifndef _OCSP_CERT_MGR_UTIL_H_
+#define _OCSP_CERT_MGR_UTIL_H_
+
+#include <vcore/Certificate.h>
+
+namespace ValidationCore {
+namespace OCSPCertMgrUtil {
+void getCertFromStore(X509_NAME *subject,
+        X509 **xcert);
+CertificatePtr getParentFromStore(const CertificatePtr &certificate);
+/*
+ * Look for "parent" certificate from store.
+ * It returns new certificate chain.
+ */
+CertificateList completeCertificateChain(const CertificateList &certList);
+} // namespace OCSPCertMgrUtil
+} // namespace ValidationCore
+#endif
+
diff --git a/vcore/src/vcore/OCSPImpl.cpp b/vcore/src/vcore/OCSPImpl.cpp
new file mode 100644 (file)
index 0000000..fb5bb18
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Tomasz Morawski(t.morawski@samsung.com)
+ * @author      Michal Ciepielski(m.ciepielski@samsung.com)
+ * @author      Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version     0.4
+ * @file        OCPS.cpp
+ * @brief       Routines for certificate validation over OCSP
+ */
+
+#include <vcore/OCSP.h>
+#include <vcore/OCSPImpl.h>
+
+#include <string.h>
+#include <algorithm>
+
+#include <openssl/ssl.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/scoped_array.h>
+#include <dpl/scoped_free.h>
+
+#include <libsoup/soup.h>
+
+#include <vcore/Certificate.h>
+#include <vcore/SoupMessageSendSync.h>
+
+extern "C" {
+// This function is needed to fix "Invalid conversion from void*
+// to unsigned char*" C++ compiler error during calling
+// i2d_OCSP_REQUEST_bio macro
+    extern bool convertToBuffer(OCSP_REQUEST* req,
+                                char** buf,
+                                int* size);
+}
+
+namespace {
+const int ConnectionTimeoutInSeconds = 6;
+const int ConnectionRetryCount = 3;
+
+//! Maximum leeway in validity period in seconds: default 1 day
+//! (@see checkRevocationStatus function code)
+
+//! Maximum validity time for revocation status (1 day)
+const int MaxValidatyPeriodInSeconds = 24 * 60 * 60;
+
+//! Max age (@see checkRevocationStatus function code)
+const int MaxAge = -1;
+} // anonymous namespace
+
+namespace ValidationCore {
+
+const char* OCSPImpl::DEFAULT_RESPONDER_URI_ENV = "OCSP_DEFAULT_RESPONDER_URI";
+
+static const EVP_MD* getDigestAlg(OCSP::DigestAlgorithm alg)
+{
+    switch (alg) {
+    case OCSP::SHA1:
+           return EVP_sha1();
+    case OCSP::SHA224:
+           return EVP_sha224();
+    case OCSP::SHA256:
+           return EVP_sha256();
+    case OCSP::SHA384:
+           return EVP_sha384();
+    case OCSP::SHA512:
+           return EVP_sha512();
+    default:
+        return NULL;
+    }
+}
+
+OCSPImpl::OCSPImpl() :
+    /* Upgrade of openssl is required to support sha256 */
+    //    m_pCertIdDigestAlg(EVP_sha256()),
+    //    m_pRequestDigestAlg(EVP_sha256()),
+    m_pCertIdDigestAlg(EVP_sha1()),
+    m_pRequestDigestAlg(EVP_sha1()),
+    m_bUseNonce(false),
+    m_bUseDefResponder(false),
+    m_bSignRequest(false),
+    m_pSignKey(0)
+{
+}
+
+SoupWrapper::SoupMessageSendBase::RequestStatus OCSPImpl::sendOcspRequest(
+        OCSP_REQUEST* argRequest,
+        const DPL::OptionalString& argUri)
+{
+    using namespace SoupWrapper;
+    // convert OCSP_REQUEST to memory buffer
+    std::string url = DPL::ToUTF8String(*argUri);
+    char* requestBuffer;
+    int requestSizeInt;
+    if (!convertToBuffer(argRequest, &requestBuffer, &requestSizeInt)) {
+        ThrowMsg(Exception::VerificationError,
+                 "OCSP: failed to convert OCSP_REQUEST to mem buffer");
+    }
+
+    Assert(requestSizeInt >= 0);
+
+    SoupMessageSendBase::MessageBuffer buffer;
+    buffer.resize(requestSizeInt);
+    memcpy(&buffer[0], requestBuffer, requestSizeInt);
+    free(requestBuffer);
+
+    char *cport = 0,*chost = 0,*cpath = 0;
+    int use_ssl = 0;
+
+    if (!OCSP_parse_url(const_cast<char*>(url.c_str()),
+                        &chost,
+                        &cport,
+                        &cpath,
+                        &use_ssl))
+    {
+        LogWarning("Error in OCSP_parse_url");
+        return SoupMessageSendBase::REQUEST_STATUS_CONNECTION_ERROR;
+    }
+
+    std::string host = chost;
+
+    if (cport) {
+        host += ":";
+        host += cport;
+    }
+
+    free(cport);
+    free(chost);
+    free(cpath);
+
+    m_soupMessage.setHost(url);
+    m_soupMessage.setHeader("Host", host);
+    m_soupMessage.setRequest(std::string("application/ocsp-request"),
+                             buffer);
+
+    return m_soupMessage.sendSync();
+}
+
+ValidationCore::VerificationStatusSet OCSPImpl::validateCertificateList(
+        const CertificateList &certs)
+{
+    VerificationStatusSet statusSet;
+
+    if (certs.size() < 2) {
+        // no certificates to verify, just return a error
+        LogWarning("No validation will be proceed. OCSP require at"
+                   " least 2 certificates in chain. Found only " <<
+                   certs.size());
+        statusSet.add(VERIFICATION_STATUS_ERROR);
+        return statusSet;
+    }
+
+    CertificateList::const_iterator iter = certs.begin();
+    CertificateList::const_iterator parent = iter;
+
+    time_t minValidity = 0;
+    for (++parent; parent != certs.end(); ++iter, ++parent) {
+        LogDebug("Certificate validation (CN:" <<
+                 (*iter)->getOneLine() << ")");
+        LogDebug("Parent certificate     (CN:" <<
+                 (*parent)->getOneLine() << ")");
+        statusSet.add(validateCertificate(*iter, *parent));
+        if ((0 == minValidity || minValidity > m_responseValidity) &&
+                m_responseValidity > 0)
+        {
+            minValidity = m_responseValidity;
+        }
+    }
+    m_responseValidity = minValidity;
+
+    return statusSet;
+}
+
+VerificationStatus OCSPImpl::checkEndEntity(
+        const CertificateCollection &chain)
+{
+    const char *defResponderURI = getenv(OCSPImpl::DEFAULT_RESPONDER_URI_ENV);
+
+    VerificationStatusSet verSet;
+    if (defResponderURI) {
+        setUseDefaultResponder(true);
+        setDefaultResponder(defResponderURI);
+    }
+
+    // this is temporary fix. it must be rewriten
+    CertificateList clst;
+    if (chain.isChain() && chain.size() >= 2) {
+        CertificateList::const_iterator icert = chain.begin();
+        clst.push_back(*icert);
+        ++icert;
+        clst.push_back(*icert);
+    }
+    verSet += validateCertificateList(clst);
+
+    return verSet.convertToStatus();
+}
+
+VerificationStatus OCSPImpl::validateCertificate(CertificatePtr argCert,
+                                             CertificatePtr argIssuer)
+{
+    using namespace SoupWrapper;
+
+    Assert(!!argCert);
+    Assert(!!argIssuer);
+
+    Try {
+        DPL::OptionalString uri;
+
+        if (!m_bUseDefResponder) {
+            uri = argCert->getOCSPURL();
+            if (!uri) {
+                return VERIFICATION_STATUS_NOT_SUPPORT;
+            }
+        } else {
+            if (m_strResponderURI.empty()) {
+                ThrowMsg(Exception::VerificationError,
+                         "Default responder is not set");
+            }
+            LogWarning("Default responder will be used");
+
+            uri = m_strResponderURI;
+        }
+
+        // creates a request
+        CreateRequestResult newRequest = createRequest(argCert, argIssuer);
+        if (!newRequest.success) {
+            ThrowMsg(Exception::VerificationError, "Request creation failed");
+        }
+
+        // SSLSmartContainer <OCSP_CERTID> certIdCont(certId);
+        // this smart ptr is commented out in purpose. request
+        // manages certIdmemory (which was done in createRequest above)
+        SSLSmartContainer <OCSP_REQUEST> requestCont(newRequest.ocspRequest);
+
+        SoupMessageSendBase::RequestStatus requestStatus;
+        requestStatus = sendOcspRequest(requestCont, uri);
+
+        if (requestStatus != SoupMessageSendBase::REQUEST_STATUS_OK) {
+            return VERIFICATION_STATUS_CONNECTION_FAILED;
+        }
+
+        // Response is m_soupMessage, convert it to OCSP_RESPONSE
+        OcspResponse response  = convertToResponse();
+
+        if (!response.first) {
+            ThrowMsg(OCSPImpl::Exception::VerificationError,
+                     "OCSP: failed to convert mem buffer to OCSP_RESPONSE");
+        }
+
+        SSLSmartContainer <OCSP_RESPONSE> responseCont(response.second);
+        // verify response eg. check response status,
+        // validate responder certificate
+        validateResponse(requestCont,
+                         responseCont,
+                         newRequest.ocspCertId);
+    } Catch(Exception::ConnectionError) {
+        LogWarning("OCSP: ConnectionError");
+        return VERIFICATION_STATUS_CONNECTION_FAILED;
+    } Catch(Exception::CertificateRevoked) {
+        LogWarning("OCSP: Revoked");
+        return VERIFICATION_STATUS_REVOKED;
+    } Catch(Exception::CertificateUnknown) {
+        LogWarning("OCSP: Unknown");
+        return VERIFICATION_STATUS_UNKNOWN;
+    } Catch(Exception::VerificationError) {
+        LogWarning("OCSP: Verification error");
+        return VERIFICATION_STATUS_VERIFICATION_ERROR;
+    } Catch(Exception::Base) {
+        LogWarning("OCSP: Error");
+        return VERIFICATION_STATUS_ERROR;
+    }
+    LogWarning("OCSP: Good");
+    return VERIFICATION_STATUS_GOOD;
+}
+
+OCSPImpl::CreateRequestResult OCSPImpl::createRequest(CertificatePtr argCert,
+                                              CertificatePtr argIssuer)
+{
+    OCSP_REQUEST* newRequest = OCSP_REQUEST_new();
+
+    if (!newRequest) {
+        LogWarning("OCSP: Failed to create a request");
+        return CreateRequestResult();
+    }
+
+    SSLSmartContainer <OCSP_REQUEST> requestCont(newRequest);
+
+    OCSP_CERTID* certId = addSerial(argCert, argIssuer);
+
+    if (!certId) {
+        LogWarning("OCSP: Unable to create a serial id");
+        return CreateRequestResult();
+    }
+    SSLSmartContainer <OCSP_CERTID> certIdCont(certId);
+
+    // Inserting certificate ID to request
+    if (!OCSP_request_add0_id(requestCont, certIdCont)) {
+        LogWarning("OCSP: Unable to create a certificate id");
+        return CreateRequestResult();
+    }
+
+    if (m_bUseNonce) {
+        OCSP_request_add1_nonce(requestCont, 0, -1);
+    }
+
+    if (m_bSignRequest) {
+        if (!m_pSignCert || !m_pSignKey) {
+            LogWarning("OCSP: Unable to sign request if "
+                       "SignCert or SignKey was not set");
+            return CreateRequestResult();
+        }
+
+        if (!OCSP_request_sign(requestCont,
+                               m_pSignCert->getX509(),
+                               m_pSignKey,
+                               m_pRequestDigestAlg,
+                               0,
+                               0))
+        {
+            LogWarning("OCSP: Unable to sign request");
+            return CreateRequestResult();
+        }
+    }
+    return CreateRequestResult(true,
+                               requestCont.DetachPtr(),
+                               certIdCont.DetachPtr());
+}
+
+OCSP_CERTID* OCSPImpl::addSerial(CertificatePtr argCert,
+                             CertificatePtr argIssuer)
+{
+    X509_NAME* iname = X509_get_subject_name(argIssuer->getX509());
+    ASN1_BIT_STRING* ikey = X509_get0_pubkey_bitstr(argIssuer->getX509());
+    ASN1_INTEGER* serial = X509_get_serialNumber(argCert->getX509());
+
+    return OCSP_cert_id_new(m_pCertIdDigestAlg, iname, ikey, serial);
+}
+
+void OCSPImpl::setDigestAlgorithmForCertId(OCSP::DigestAlgorithm alg)
+{
+    const EVP_MD* foundAlg = getDigestAlg(alg);
+
+    if (NULL != foundAlg) {
+        m_pCertIdDigestAlg = foundAlg;
+    } else {
+        LogDebug("Request for unsupported CertId digest algorithm"
+                 "ignored!");
+    }
+}
+
+void OCSPImpl::setDigestAlgorithmForRequest(OCSP::DigestAlgorithm alg)
+{
+    const EVP_MD* foundAlg = getDigestAlg(alg);
+
+    if (NULL != foundAlg) {
+        m_pRequestDigestAlg = foundAlg;
+    } else {
+        LogDebug("Request for unsupported OCSP request digest algorithm"
+                 "ignored!");
+    }
+}
+
+void OCSPImpl::setTrustedStore(const CertificateList& certs)
+{
+    X509_STORE *store = X509_STORE_new();
+    m_pTrustedStore = store;
+    // create a trusted store basing on certificate chain from a signature
+    FOREACH(iter, certs) {
+        X509_STORE_add_cert(store, (*iter)->getX509());
+    }
+}
+
+void OCSPImpl::validateResponse(OCSP_REQUEST* argRequest,
+                            OCSP_RESPONSE* argResponse,
+                            OCSP_CERTID* argCertId)
+{
+    int result = OCSP_response_status(argResponse);
+
+    if (result != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+        handleInvalidResponse(result);
+        ThrowMsg(Exception::VerificationError, "OCSP_response_status failed");
+    }
+
+    // get response object
+    OCSP_BASICRESP* basic = OCSP_response_get1_basic(argResponse);
+    if (!basic) {
+        ThrowMsg(Exception::VerificationError,
+                 "OCSP: Unable to get a BASICRESP object.");
+    }
+
+    SSLSmartContainer <OCSP_BASICRESP> basicRespCont(basic);
+    if (m_bUseNonce && OCSP_check_nonce(argRequest, basicRespCont) <= 0) {
+        ThrowMsg(Exception::VerificationError, "OCSP: Invalid nonce");
+    }
+
+    if (!verifyResponse(basic)) {
+        ThrowMsg(Exception::VerificationError,
+                 "Unable to verify the OCSP responder's certificate");
+    }
+
+    checkRevocationStatus(basicRespCont, argCertId);
+}
+
+bool OCSPImpl::verifyResponse(OCSP_BASICRESP* basic)
+{
+    Assert(m_pTrustedStore);
+    // verify ocsp response
+    int response = OCSP_basic_verify(basic, NULL, m_pTrustedStore, 0);
+    if (response <= 0) {
+        LogWarning("OCSP verification failed");
+    }
+
+    return response > 0;
+}
+
+void OCSPImpl::checkRevocationStatus(OCSP_BASICRESP* basic,
+                                 OCSP_CERTID* id)
+{
+    ASN1_GENERALIZEDTIME* producedAt;
+    ASN1_GENERALIZEDTIME* thisUpdate;
+    ASN1_GENERALIZEDTIME* nextUpdate;
+    int reason;
+    int status;
+
+    m_responseValidity = 0;
+
+    if (!OCSP_resp_find_status(basic,
+                               id,
+                               &status,
+                               &reason,
+                               &producedAt,
+                               &thisUpdate,
+                               &nextUpdate))
+    {
+        ThrowMsg(Exception::VerificationError,
+                 "OCSP: Failed to find certificate status.");
+    }
+
+    if (!OCSP_check_validity(thisUpdate,
+                             nextUpdate,
+                             MaxValidatyPeriodInSeconds,
+                             MaxAge))
+    {
+        ThrowMsg(Exception::VerificationError,
+                 "OCSP: Failed to check certificate validate.");
+    }
+
+    if (nextUpdate) {
+        asn1GeneralizedTimeToTimeT(nextUpdate,&m_responseValidity);
+        time_t now;
+        time(&now);
+        LogDebug("Time of next OCSP update got from server: " <<
+                 m_responseValidity);
+        LogDebug("Expires in: " << (m_responseValidity - now));
+        LogDebug("Original: " << nextUpdate->data);
+    }
+
+    switch (status) {
+    case V_OCSP_CERTSTATUS_GOOD:
+        return;
+    case V_OCSP_CERTSTATUS_REVOKED:
+        ThrowMsg(Exception::CertificateRevoked, "Certificate is Revoked");
+    case V_OCSP_CERTSTATUS_UNKNOWN:
+        ThrowMsg(Exception::CertificateUnknown, "Certificate is Unknown");
+    default:
+        Assert(false && "Invalid status");
+    }
+}
+
+OCSPImpl::OcspResponse OCSPImpl::convertToResponse()
+{
+    using namespace SoupWrapper;
+
+    // convert memory buffer to ocsp response object
+    BUF_MEM res_bmem;
+    OCSP_RESPONSE* response;
+
+    SoupMessageSendBase::MessageBuffer buffer = m_soupMessage.getResponse();
+
+    res_bmem.length = buffer.size();
+    res_bmem.data = &buffer[0];
+    res_bmem.max = buffer.size();
+
+    BIO* res_mem_bio = BIO_new(BIO_s_mem());
+    BIO_set_mem_buf(res_mem_bio, &res_bmem, BIO_NOCLOSE);
+
+    response = d2i_OCSP_RESPONSE_bio(res_mem_bio, NULL);
+    BIO_free_all(res_mem_bio);
+
+    if (!response) {
+        LogWarning("OCSP: Failed to convert OCSP Response to DER format");
+        return std::make_pair(false, static_cast<OCSP_RESPONSE*>(NULL));
+    }
+
+    return std::make_pair(true, response);
+}
+
+void OCSPImpl::handleInvalidResponse(int result)
+{
+    switch (result) {
+    case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
+        LogWarning("OCSP: Server returns "
+                   "OCSP_RESPONSE_STATUS_MALFORMEDREQUEST status");
+        break;
+    case OCSP_RESPONSE_STATUS_INTERNALERROR:
+        LogWarning("OCSP: Server returns "
+                   "OCSP_RESPONSE_STATUS_INTERNALERROR status");
+        break;
+    case OCSP_RESPONSE_STATUS_TRYLATER:
+        LogWarning("OCSP: Server returns "
+                   "OCSP_RESPONSE_STATUS_TRYLATER status");
+        break;
+    case OCSP_RESPONSE_STATUS_SIGREQUIRED:
+        LogWarning("OCSP: Server returns "
+                   "OCSP_RESPONSE_STATUS_SIGREQUIRED status");
+        break;
+    case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
+        LogWarning("OCSP: Server returns "
+                   "OCSP_RESPONSE_STATUS_UNAUTHORIZED status");
+        break;
+    default:
+        Assert(false && "Invalid result value");
+    }
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/OCSPImpl.h b/vcore/src/vcore/OCSPImpl.h
new file mode 100644 (file)
index 0000000..21e244f
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Tomasz Morawski(t.morawski@samsung.com)
+ * @author      Michal Ciepielski(m.ciepielski@samsung.com)
+ * @author      Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @author      Bartlomiej Grzelewski(b.grzelewski@samsung.com)
+ * @version     0.4
+ * @file        OCPS.h
+ * @brief       Routines for certificate validation over OCSP
+ */
+
+#ifndef _VALIDATION_CORE_OCSPIMPL_H_
+#define _VALIDATION_CORE_OCSPIMPL_H_
+
+#include <vcore/OCSP.h>
+
+#include <string>
+#include <vector>
+#include <list>
+
+#include <openssl/pem.h>
+#include <openssl/ocsp.h>
+#include <libsoup/soup.h>
+
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/optional_typedefs.h>
+
+#include <vcore/scoped_gpointer.h>
+#include <vcore/OCSPCertMgrUtil.h>
+#include <vcore/CertificateCollection.h>
+#include <vcore/CertificateStorage.h>
+#include <vcore/VerificationStatus.h>
+#include <vcore/SSLContainers.h>
+#include <vcore/SoupMessageSendBase.h>
+#include <vcore/SoupMessageSendSync.h>
+#include <vcore/TimeConversion.h>
+/*
+ * The WRT MUST NOT allow installation of widgets with revoked signatures.
+ *
+ * The WRT MUST NOT allow use of widgets with revoked signatures.
+ *
+ * The WRT MUST support checking for revocation of widget signatures via
+ * OCSP [RFC 2560] at widget installation time, according to the following:
+ *
+ * At widget installation time, the WRT shall make several attempts
+ * (5 attempts at 6 seconds apart recommended) to establish contact with
+ * the OCSP server.
+ *
+ * If connectivity is successful and the application is validated, the
+ * installation process shall continue.
+ *
+ * If connectivity is successful and if the widget signature is
+ * determined to be revoked, the WRT shall issue a suitable error message
+ * and cancel installation.
+ *
+ * If connectivity is successful and revocation status is unknown or if
+ * connectivity is unsuccessful, the user must be notified that the
+ * widget was unable to be installed as trusted - the certification of
+ * the widget signature has not been validated -, and prompt the user to allow
+ * the user to install the widget as an untrusted application, or reject
+ * the installation.
+ *
+ * The WRT MUST support checking for revocation of widget signatures via OCSP
+ * [RFC 2560] at widget runtime.
+ *
+ * The WRT MUST support OCSP access policy.
+ */
+
+namespace ValidationCore {
+
+class OCSPImpl
+{
+  public:
+    static const char* DEFAULT_RESPONDER_URI_ENV;
+
+    VerificationStatus checkEndEntity(const CertificateCollection &certList);
+    OCSPImpl();
+
+    /**
+     * Sets digest algorithm for certid in ocsp request
+     */
+    void setDigestAlgorithmForCertId(OCSP::DigestAlgorithm alg);
+
+    /**
+     * Sets digest algorithm for certid in ocsp request
+     */
+    void setDigestAlgorithmForRequest(OCSP::DigestAlgorithm alg);
+
+    void setTrustedStore(const CertificateList& certs);
+
+    VerificationStatusSet validateCertificateList(const CertificateList &certs);
+
+    VerificationStatus validateCertificate(CertificatePtr argCert,
+                                           CertificatePtr argIssuer);
+
+    void setDefaultResponder(const char* uri)
+    {
+        Assert(uri);
+        m_strResponderURI = DPL::FromUTF8String(uri);
+    }
+
+    void setUseDefaultResponder(bool value)
+    {
+        m_bUseDefResponder = value;
+    }
+
+    /**
+     * @return time when response will become invalid - for list of
+     * certificates, this is the minimum of all validities; value is
+     * valid only for not-revoked certificates (non error validation result)
+     */
+    time_t getResponseValidity()
+    {
+        return m_responseValidity;
+    }
+
+  private:
+    typedef WRT::ScopedGPointer<SoupSession> ScopedSoupSession;
+    typedef WRT::ScopedGPointer<SoupMessage> ScopedSoupMessage;
+
+    void handleInvalidResponse(int result);
+    void sendHTTPRequest(ScopedSoupSession& session,
+                         ScopedSoupMessage& msg,
+                         const char* host,
+                         const char* port,
+                         const char* path,
+                         char* requestBuffer,
+                         size_t reqestSize);
+    void sendRequest(const std::string& uri,
+                     char* requestBuffer,
+                     size_t requestSize,
+                     char** responseBuffer,
+                     size_t* responseSize);
+
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, ConnectionError)
+        DECLARE_EXCEPTION_TYPE(Base, CertificateRevoked)
+        DECLARE_EXCEPTION_TYPE(Base, CertificateUnknown)
+        DECLARE_EXCEPTION_TYPE(Base, VerificationError)
+        DECLARE_EXCEPTION_TYPE(Base, RetrieveCertFromStoreError)
+        DECLARE_EXCEPTION_TYPE(Base, VerificationNotSupport)
+    };
+
+    const EVP_MD* m_pCertIdDigestAlg;
+    const EVP_MD* m_pRequestDigestAlg;
+
+    typedef std::pair<char*, size_t> HttpResponseBuffer;
+
+    SoupWrapper::SoupMessageSendBase::RequestStatus sendOcspRequest(
+            OCSP_REQUEST* argRequest,
+            const DPL::OptionalString& argUri);
+
+    //! Validates a single certificate
+    /*!
+     * @param cert The certificate to check
+     * @param issuer A certificate used to sign the certificate to check.
+     */
+
+    struct CreateRequestResult
+    {
+        bool success;
+        OCSP_REQUEST* ocspRequest;
+        OCSP_CERTID* ocspCertId;
+        CreateRequestResult(bool argSuccess = false,
+                            OCSP_REQUEST* argOcspRequest = NULL,
+                            OCSP_CERTID* argOcspCertId = NULL) :
+            success(argSuccess),
+            ocspRequest(argOcspRequest),
+            ocspCertId(argOcspCertId)
+        {
+        }
+    };
+
+    //! Creates a OCSP request
+    /*!
+     * @param request Returns created OCSP_REQUEST
+     * @param id Returns CertId that is used to find proper OCSP result in
+     * the OCSP response (@see checkRevocationStatus for more details).
+     *
+     */
+    CreateRequestResult createRequest(CertificatePtr argCert,
+                                      CertificatePtr argIssuer);
+
+    OCSP_CERTID* addSerial(CertificatePtr argCert,
+                           CertificatePtr argIssuer);
+
+    void validateResponse(OCSP_REQUEST* argRequest,
+                          OCSP_RESPONSE* argResponse,
+                          OCSP_CERTID* argCertId);
+
+    //! Create a X509 store
+    bool verifyResponse(OCSP_BASICRESP* argResponse);
+
+    void  checkRevocationStatus(OCSP_BASICRESP* argBasicResponse,
+                                OCSP_CERTID* argCertId);
+
+    typedef std::pair<bool, OCSP_RESPONSE*> OcspResponse;
+
+    OcspResponse convertToResponse();
+
+    time_t m_responseValidity;
+    bool m_bUseNonce;
+    bool m_bUseDefResponder;
+    DPL::String m_strResponderURI;
+    bool m_bSignRequest;
+    EVP_PKEY*                       m_pSignKey;
+    CertificatePtr m_pSignCert;
+    SSLSmartContainer <X509_STORE>  m_pTrustedStore;
+    SoupWrapper::SoupMessageSendSync m_soupMessage;
+};
+
+} // ValidationCore
+
+#endif // _VALIDATION_CORE_OCSPIMPL_H_
diff --git a/vcore/src/vcore/OCSPUtil.c b/vcore/src/vcore/OCSPUtil.c
new file mode 100644 (file)
index 0000000..451884a
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Tomasz Morawski(t.morawski@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+
+#include <openssl/ocsp.h>
+
+/*
+ * This function is needed to fix "Invalid conversion from void* to unsigned char*"
+ * C++ compiler error during calling i2d_OCSP_REQUEST_bio macro
+ */
+int convertToBuffer(OCSP_REQUEST *req, char **buf, int *size) {
+    BIO *req_mem_bio;
+    BUF_MEM req_bmem;
+
+    /*
+     * size and membuffer for request
+     */
+    *size = i2d_OCSP_REQUEST(req, NULL);
+    *buf = (char*) malloc(*size);
+
+    if (!*buf)
+        return 0;
+
+    /* copy request into buffer */
+    req_bmem.length = 0;
+    req_bmem.data = *buf;
+    req_bmem.max = *size;
+
+    /*
+     * create a new buffer using openssl
+     */
+    req_mem_bio = BIO_new(BIO_s_mem());
+
+    if (!req_mem_bio) {
+        /*
+         * creation failed, return
+         */
+        free(*buf);
+        *buf = NULL;
+        return 0;
+    }
+
+    BIO_set_mem_buf(req_mem_bio, &req_bmem, BIO_NOCLOSE);
+
+    /*
+     * prepare request
+     */
+    if (i2d_OCSP_REQUEST_bio(req_mem_bio, req) <= 0) {
+        free(*buf);
+        *buf = NULL;
+        BIO_free_all(req_mem_bio);
+        return 0;
+    }
+
+    /*
+     *  check consistency
+     */
+    if (*size != ((int)req_bmem.length) || req_bmem.length != req_bmem.max)
+    {
+        free(*buf);
+        *buf = NULL;
+        BIO_free_all(req_mem_bio);
+        return 0;
+    }
+
+    /*
+     * free all reserved memory
+     */
+    BIO_free_all(req_mem_bio);
+
+    /*
+     * and return success
+     */
+    return 1;
+}
diff --git a/vcore/src/vcore/ParserSchema.h b/vcore/src/vcore/ParserSchema.h
new file mode 100644 (file)
index 0000000..ed9eb68
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * 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        ParserSchema.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef _PARSERSCHEMA_H_
+#define _PARSERSCHEMA_H_
+
+#include <map>
+#include <string>
+
+#include <dpl/log/log.h>
+
+#include <vcore/SaxReader.h>
+
+namespace ValidationCore {
+namespace ParserSchemaException {
+DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+DECLARE_EXCEPTION_TYPE(Base, XmlReaderError)
+DECLARE_EXCEPTION_TYPE(Base, CertificateLoaderError)
+DECLARE_EXCEPTION_TYPE(Base, UnsupportedAlgorithm)
+DECLARE_EXCEPTION_TYPE(Base, UnsupportedValue)
+}
+
+template<typename ParserType, typename DataType>
+class ParserSchema
+{
+  public:
+    struct TagDescription
+    {
+        TagDescription(const std::string &tag,
+                const std::string & xmlNamespace) :
+            tagName(tag),
+            namespaceUri(xmlNamespace)
+        {
+        }
+
+        std::string tagName;
+        std::string namespaceUri;
+
+        bool operator<(const TagDescription &second) const
+        {
+            if (tagName < second.tagName) {
+                return true;
+            }
+            if (tagName > second.tagName) {
+                return false;
+            }
+            if (namespaceUri < second.namespaceUri) {
+                return true;
+            }
+            return false;
+        }
+    };
+
+    ParserSchema(ParserType * parser) :
+        m_functions(parser)
+    {
+    }
+
+    virtual ~ParserSchema()
+    {
+    }
+
+    void initialize(const std::string &filename,
+            bool defaultArgs,
+            SaxReader::ValidationType valType,
+            const std::string &xmlschema)
+    {
+        Try
+        {
+            m_reader.initialize(filename, defaultArgs, valType, xmlschema);
+        }
+        Catch(SaxReader::Exception::Base)
+        {
+            ReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
+        }
+    }
+
+    void deinitialize()
+    {
+        m_reader.deinitialize();
+    }
+
+    void read(DataType &dataContainer)
+    {
+        Try {
+            while (m_reader.next()) {
+                switch (m_reader.type()) {
+                case SaxReader::NODE_BEGIN:
+                    beginNode(dataContainer);
+                    break;
+                case SaxReader::NODE_END:
+                    endNode(dataContainer);
+                    break;
+                case SaxReader::NODE_TEXT:
+                    textNode(dataContainer);
+                    break;
+                default:
+                    //              LogInfo("Unknown Type Node");
+                    break;
+                }
+            }
+        }
+        Catch(SaxReader::Exception::Base)
+        {
+            ReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
+        }
+    }
+
+    typedef void (ParserType::*FunctionPtr)(DataType &data);
+    typedef std::map<TagDescription, FunctionPtr> FunctionMap;
+
+    void addBeginTagCallback(const std::string &tag,
+            const std::string &namespaceUri,
+            FunctionPtr function)
+    {
+        TagDescription desc(tag, namespaceUri);
+        m_beginFunctionMap[desc] = function;
+    }
+
+    void addEndTagCallback(const std::string &tag,
+            const std::string &namespaceUri,
+            FunctionPtr function)
+    {
+        TagDescription desc(tag, namespaceUri);
+        m_endFunctionMap[desc] = function;
+    }
+
+    SaxReader& getReader(void)
+    {
+        return m_reader;
+    }
+
+    std::string& getText(void)
+    {
+        return m_textNode;
+    }
+
+  protected:
+    void beginNode(DataType &dataContainer)
+    {
+        TagDescription desc(m_reader.name(), m_reader.namespaceURI());
+        FunctionPtr fun = m_beginFunctionMap[desc];
+
+        if (fun == 0) {
+            LogDebug("No function found for xml tag: " << m_reader.name());
+            return;
+        }
+
+        (m_functions->*fun)(dataContainer);
+    }
+
+    void endNode(DataType &dataContainer)
+    {
+        TagDescription desc(m_reader.name(), m_reader.namespaceURI());
+        FunctionPtr fun = m_endFunctionMap[desc];
+
+        if (fun == 0) {
+            LogDebug("No function found for xml tag: " << m_reader.name());
+            return;
+        }
+
+        (m_functions->*fun)(dataContainer);
+    }
+
+    void textNode(DataType &dataContainer)
+    {
+        (void)dataContainer;
+        m_textNode = m_reader.value();
+    }
+
+    ParserType *m_functions;
+
+    SaxReader m_reader;
+    FunctionMap m_beginFunctionMap;
+    FunctionMap m_endFunctionMap;
+
+    // temporary values require due parsing textNode
+    std::string m_textNode;
+};
+} // namespace ValidationCore
+#endif
diff --git a/vcore/src/vcore/ReferenceValidator.cpp b/vcore/src/vcore/ReferenceValidator.cpp
new file mode 100644 (file)
index 0000000..e983c69
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @file        ReferenceValidator.cpp
+ * @version     1.0
+ * @brief       Compare signature reference list and list of widget file.
+ */
+#include <vcore/ReferenceValidator.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <fstream>
+#include <memory>
+
+#include <pcrecpp.h>
+
+#include <dpl/errno_string.h>
+#include <dpl/log/log.h>
+
+namespace {
+
+const char *SPECIAL_SYMBOL_CURRENT_DIR = ".";
+const char *SPECIAL_SYMBOL_UPPER_DIR = "..";
+const char *SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE = "author-signature.xml";
+const char *REGEXP_DISTRIBUTOR_SIGNATURE = "^signature[1-9][0-9]*\\.xml";
+
+const char MARK_ENCODED_CHAR = '%';
+
+} // namespace anonymous
+
+namespace ValidationCore {
+
+class ReferenceValidator::Impl
+{
+  public:
+    Impl(const std::string &dirpath)
+      : m_dirpath(dirpath)
+      , m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
+    {}
+
+    virtual ~Impl(){}
+
+    Result checkReferences(const SignatureData &signatureData){
+        const ReferenceSet &refSet = signatureData.getReferenceSet();
+        ReferenceSet refDecoded;
+
+        try {
+            for (auto it = refSet.begin(); it != refSet.end(); ++it) {
+                if (std::string::npos != it->find(MARK_ENCODED_CHAR))
+                    refDecoded.insert(decodeProcent(*it));
+                else
+                    refDecoded.insert(*it);
+            }
+        } catch (Result &) {
+            return ERROR_DECODING_URL;
+        }
+        return dfsCheckDirectories(
+            refDecoded,
+            std::string(),
+            signatureData.isAuthorSignature());
+    }
+
+  private:
+    int hexToInt(char hex);
+    std::string decodeProcent(const std::string &path);
+
+    Result dfsCheckDirectories(
+        const ReferenceSet &referenceSet,
+        const std::string &directory,
+        bool isAuthorSignature);
+
+    inline bool isDistributorSignature(const char *cstring) const
+    {
+        return m_signatureRegexp.FullMatch(cstring);
+    }
+
+    std::string m_dirpath;
+    std::string m_errorDescription;
+    pcrecpp::RE m_signatureRegexp;
+};
+
+int ReferenceValidator::Impl::hexToInt(char a) {
+    if (a >= '0' && a <= '9') return a-'0';
+    if (a >= 'A' && a <= 'F') return a-'A' + 10;
+    if (a >= 'a' && a <= 'f') return a-'a' + 10;
+    LogError("Symbol '" << a << "' is out of scope.");
+    throw ERROR_DECODING_URL;
+}
+
+std::string ReferenceValidator::Impl::decodeProcent(const std::string &path) {
+    std::vector<int> input(path.begin(), path.end());
+    std::vector<char> output;
+    try {
+        size_t i = 0;
+        while(i<input.size()) {
+            if (MARK_ENCODED_CHAR == input[i]) {
+                if (i+2 >= input.size())
+                    throw ERROR_DECODING_URL;
+
+                int result = hexToInt(input[i+1])*16 + hexToInt(input[i+2]);
+
+                // RFC 1738 - octets 80 to FF are not allowed
+                if (result >= 128)
+                    throw ERROR_DECODING_URL;
+
+                output.push_back(static_cast<char>(result));
+                i+=3;
+            } else {
+                output.push_back(static_cast<char>(input[i]));
+                ++i;
+            }
+        }
+    } catch (Result &) {
+        LogError("Error while decoding url path: " << path);
+        throw ERROR_DECODING_URL;
+    }
+    return std::string(output.begin(), output.end());
+}
+
+ReferenceValidator::Result ReferenceValidator::Impl::dfsCheckDirectories(
+    const ReferenceSet &referenceSet,
+    const std::string &directory,
+    bool isAuthorSignature)
+{
+    DIR *dp;
+    struct dirent *dirp;
+    std::string currentDir = m_dirpath + directory;
+
+    if ((dp = opendir(currentDir.c_str())) == NULL) {
+        LogError("Error opening directory: " << currentDir.c_str());
+        m_errorDescription = currentDir;
+        return ERROR_OPENING_DIR;
+    }
+
+    for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
+        if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_CURRENT_DIR)) {
+            continue;
+        }
+
+        if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_UPPER_DIR)) {
+            continue;
+        }
+
+        if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
+            !strcmp(dirp->d_name, SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE) &&
+            isAuthorSignature)
+        {
+            continue;
+        }
+
+        if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
+            isDistributorSignature(dirp->d_name)) {
+            continue;
+        }
+
+        if (dirp->d_type == DT_DIR) {
+            LogDebug("Open directory: " << (directory + dirp->d_name));
+            std::string tmp_directory = directory + dirp->d_name + "/";
+            Result result = dfsCheckDirectories(referenceSet,
+                                                tmp_directory,
+                                                isAuthorSignature);
+            if (result != NO_ERROR) {
+                closedir(dp);
+                return result;
+            }
+        } else if (dirp->d_type == DT_REG) {
+            LogDebug("Found     file: " << (directory + dirp->d_name));
+
+            if (referenceSet.end() ==
+                referenceSet.find(directory + dirp->d_name))
+            {
+                closedir(dp);
+                m_errorDescription = directory + dirp->d_name;
+                return ERROR_REFERENCE_NOT_FOUND;
+            }
+        } else {
+            LogError("Unknown file type.");
+            closedir(dp);
+            m_errorDescription = directory + dirp->d_name;
+            return ERROR_UNSUPPORTED_FILE_TYPE;
+        }
+    }
+
+    if (errno != 0) {
+        m_errorDescription = DPL::GetErrnoString();
+        LogError("readdir failed. Errno code: " << errno <<
+                 " Description: " << m_errorDescription);
+        closedir(dp);
+        return ERROR_READING_DIR;
+    }
+
+    closedir(dp);
+
+    return NO_ERROR;
+}
+
+ReferenceValidator::ReferenceValidator(const std::string &dirpath)
+  : m_impl(new Impl(dirpath))
+{}
+
+ReferenceValidator::~ReferenceValidator(){
+    delete m_impl;
+}
+
+ReferenceValidator::Result ReferenceValidator::checkReferences(
+    const SignatureData &signatureData)
+{
+    return m_impl->checkReferences(signatureData);
+}
+
+} // ValidationCore
diff --git a/vcore/src/vcore/ReferenceValidator.h b/vcore/src/vcore/ReferenceValidator.h
new file mode 100644 (file)
index 0000000..d7d964f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @file        ReferenceValidator.h
+ * @version     1.0
+ * @brief       Compare signature reference list with widget package.
+ */
+#ifndef _VALIDATION_CORE_REFERENCEVALIDATOR_H_
+#define _VALIDATION_CORE_REFERENCEVALIDATOR_H_
+
+#include <dpl/noncopyable.h>
+
+#include <vcore/SignatureData.h>
+
+namespace ValidationCore {
+
+class ReferenceValidator : DPL::Noncopyable
+{
+  public:
+    enum Result
+    {
+        NO_ERROR = 0,
+        ERROR_OPENING_DIR,
+        ERROR_READING_DIR,
+        ERROR_UNSUPPORTED_FILE_TYPE,
+        ERROR_REFERENCE_NOT_FOUND,
+        ERROR_DECODING_URL
+    };
+
+    ReferenceValidator(const std::string &dirpath);
+
+    virtual ~ReferenceValidator();
+
+    Result checkReferences(const SignatureData &signatureData);
+
+  private:
+    class Impl;
+    Impl *m_impl;
+};
+}
+
+#endif // _VALIDATION_CORE_REFERENCEVALIDATOR_H_
diff --git a/vcore/src/vcore/RevocationCheckerBase.cpp b/vcore/src/vcore/RevocationCheckerBase.cpp
new file mode 100644 (file)
index 0000000..f0e43e7
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version     0.4
+ * @file        CommonCertValidator.cpp
+ * @brief       Common routines for certificate validation over OCSP and CRL
+ */
+
+#include "RevocationCheckerBase.h"
+
+#include <cstdlib>
+
+#include <openssl/pem.h>
+
+#include <dpl/scoped_fclose.h>
+
+#include "Certificate.h"
+#include "CertificateCollection.h"
+
+namespace {
+const char DefaultBundlePatch[] = "/opt/etc/ssl/certs/ca-certificates.crt";
+} //Anonymous name space
+
+namespace ValidationCore {
+CertificatePtr RevocationCheckerBase::loadPEMFile(const char* fileName)
+{
+    DPL::ScopedFClose fd(fopen(fileName, "rb"));
+
+    // no such file, return NULL
+    if (!fd.Get()) {
+        return CertificatePtr();
+    }
+
+    // create a new X509 certificate basing on file
+    CertificatePtr cert(new Certificate(PEM_read_X509(fd.Get(),
+                                                      NULL,
+                                                      NULL,
+                                                      NULL)));
+    return cert;
+}
+
+bool RevocationCheckerBase::sortCertList(CertificateList &lCertificates)
+{
+    CertificateCollection collection;
+    collection.load(lCertificates);
+
+    if (collection.sort()) {
+        lCertificates = collection.getChain();
+        return true;
+    }
+    return false;
+}
+
+} // ValidationCore
diff --git a/vcore/src/vcore/RevocationCheckerBase.h b/vcore/src/vcore/RevocationCheckerBase.h
new file mode 100644 (file)
index 0000000..3ce934d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
+ * @version     0.4
+ * @file        CommonCertValidator.h
+ * @brief       Common routines for certificate validation over OCSP and CRL
+ */
+
+#ifndef WRT_ENGINE_SRC_VALIDATION_CORE_REVOCATIONCHECKERBASE_H_
+#define WRT_ENGINE_SRC_VALIDATION_CORE_REVOCATIONCHECKERBASE_H_
+
+#include <string>
+
+#include "Certificate.h"
+
+namespace ValidationCore {
+class RevocationCheckerBase
+{
+  public:
+    //! Loads a PEM file and returns X509 certificate object.
+    static CertificatePtr loadPEMFile(const char* path);
+
+    //! Sorts a list of certficates and verifies them if they form
+    //! a valid chain
+    static bool sortCertList(CertificateList &cert) __attribute__((deprecated));
+};
+} // ValidationCore
+
+#endif //ifndef WRT_ENGINE_SRC_VALIDATION_CORE_REVOCATIONCHECKERBASE_H_
+
diff --git a/vcore/src/vcore/SSLContainers.h b/vcore/src/vcore/SSLContainers.h
new file mode 100644 (file)
index 0000000..e18cb00
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+#ifndef _SSLCONTAINERS_H
+#define _SSLCONTAINERS_H
+
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+
+/*
+ * default deleter functor with no overloaded operator()
+ */
+template <typename T>
+struct MySSLFree {};
+
+/*
+ * macro for defining custom deleters for openssl structs
+ * usage DECLARE_DELETER(OpenSSLType)
+ */
+#define DECLARE_DELETER(Type) template<> \
+    struct MySSLFree <Type>                  \
+    {                                        \
+        void operator() (Type* p)            \
+        {                                    \
+            Type ## _free(p);                  \
+        }                                    \
+                                         \
+    };
+
+/*
+ * declare custom deleter for X509 structs
+ */
+DECLARE_DELETER(X509)
+/*
+ * declare custom deleter for OCSP_REQUEST structs
+ */
+DECLARE_DELETER(OCSP_REQUEST)
+/*
+ * declare custom deleter for OCSP_RESPONSE structs
+ */
+DECLARE_DELETER(OCSP_RESPONSE)
+/*
+ * declare custom deleter for OCSP_CERTID structs
+ */
+DECLARE_DELETER(OCSP_CERTID)
+/*
+ * declare custom deleter for OCSP_BASICRESP structs
+ */
+DECLARE_DELETER(OCSP_BASICRESP)
+/*
+ * declare custom deleter for X509_STORE structs
+ */
+DECLARE_DELETER(X509_STORE)
+
+/*
+ * undef it, so anyone could use that macro name
+ */
+#undef DECLARE_DELETER
+
+/*
+ * OpenSSL smart container
+ * usage SSLSmartContainer <OpenSSLType> smartptr = ptrToOpenSSLType
+ * remember to add OpenSSLType to macro list few lines above
+ */
+template <typename T, typename deleter = MySSLFree<T> >
+class SSLSmartContainer
+{
+  public:
+    SSLSmartContainer() : m_pData(NULL)
+    {
+    }
+
+    /*
+     * explicit constructor, we don't want any auto casting
+     */
+    explicit SSLSmartContainer(T* pData)
+    {
+        m_pData = pData;
+    }
+
+    /*
+     * overloaded assignment operator
+     */
+    SSLSmartContainer & operator=(SSLSmartContainer& pContainer)
+    {
+        /*
+         * check if no assignment was done before
+         */
+        if (this != &pContainer) {
+            // if so, free internal data
+            deleter ssl_free;
+            ssl_free(m_pData);
+
+            // and assign new
+            m_pData = pContainer.m_pData;
+
+            pContainer.m_pData = NULL;
+        }
+
+        return *this;
+    }
+
+    SSLSmartContainer & operator=(T* pData)
+    {
+        /*
+         * check if no assignment was done before
+         */
+        if (m_pData != pData) {
+            // if so, free internal data
+            deleter ssl_free;
+            ssl_free(m_pData);
+
+            // and assign new
+            m_pData = pData;
+        }
+
+        return *this;
+    }
+
+    ~SSLSmartContainer()
+    {
+        deleter ssl_free;
+        ssl_free(m_pData);
+    }
+
+    /*
+     * overloaded operators for standardptr - like usage
+     */
+    SSLSmartContainer & operator*()
+    {
+        return *m_pData;
+    }
+    SSLSmartContainer* operator->()
+    {
+        return m_pData;
+    }
+
+    /*
+     * auto cast to T operator
+     */
+    operator T *() const { return m_pData;
+    }
+
+    /*
+     * detachs internal pointer from smart pointer
+     */
+    T* DetachPtr()
+    {
+        T* pData = m_pData;
+        m_pData = NULL;
+        return pData;
+    }
+
+  private:
+    /*
+     * blocked assignment from another types operator
+     */
+    template <typename S>
+    T & operator = (S& pContainer)
+    {
+        return *this;
+    }
+
+    /*
+     * internal data
+     */
+    T* m_pData;
+};
+
+#endif /* _SSLCONTAINERS_H */
+
diff --git a/vcore/src/vcore/SaxReader.cpp b/vcore/src/vcore/SaxReader.cpp
new file mode 100644 (file)
index 0000000..1a0261b
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * 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        SaxReader.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Simple c++ interface for libxml2.
+ */
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+
+#include <vcore/SaxReader.h>
+
+namespace ValidationCore {
+SaxReader::SaxReader() :
+    m_reader(0)
+{
+}
+
+SaxReader::~SaxReader()
+{
+    if (m_reader) {
+        deinitialize();
+    }
+}
+
+void SaxReader::initialize(const std::string &filename,
+        bool defaultArgs,
+        ValidationType validate,
+        const std::string &schema)
+{
+    Assert(m_reader == 0 && "Double initialization of SaxReader");
+
+    LogDebug("SaxReader opening file: " << filename);
+
+    /*
+     * create a new xml text reader
+     */
+    m_reader = xmlNewTextReaderFilename(filename.c_str());
+
+    if (m_reader == NULL) {
+        /*
+         * no such file, return
+         */
+        LogWarning("Error during opening file " << filename);
+        Throw(Exception::FileOpeningError);
+    }
+    if (validate == VALIDATION_XMLSCHEME &&
+        xmlTextReaderSchemaValidate(m_reader, schema.c_str())) {
+        /*
+         * unable to turn on schema validation
+         */
+        LogError("Turn on Schema validation failed.");
+        ThrowMsg(Exception::ParserInternalError,
+                 "Turn on Scheme validation failed!");
+    }
+    // Path to DTD schema is taken from xml file.
+    if (validate == VALIDATION_DTD &&
+        xmlTextReaderSetParserProp(m_reader, XML_PARSER_VALIDATE, 1)) {
+        /*
+         * unable to turn on DTD validation
+         */
+        LogError("Turn on DTD validation failed!");
+        ThrowMsg(Exception::ParserInternalError,
+                 "Turn on DTD validation failed!");
+    }
+    if (defaultArgs &&
+        xmlTextReaderSetParserProp(m_reader, XML_PARSER_DEFAULTATTRS, 1)) {
+        /*
+         * unable to turn on default arguments
+         */
+        LogError("Turn on default arguments failed");
+        ThrowMsg(Exception::ParserInternalError,
+                 "Turn on Default Arguments failed!");
+    }
+}
+
+void SaxReader::deinitialize()
+{
+    xmlFreeTextReader(m_reader);
+    m_reader = 0;
+}
+
+bool SaxReader::next()
+{
+    int res = xmlTextReaderRead(m_reader);
+
+    if (0 == xmlTextReaderIsValid(m_reader)) {
+        LogWarning("Throw exception file not valid!");
+        Throw(Exception::FileNotValid);
+    }
+
+    if (res == 1) {
+        return true;
+    }
+
+    if (res == 0) {
+        return false;
+    }
+    LogError("ParserInternalError");
+    Throw(Exception::ParserInternalError);
+}
+
+void SaxReader::next(const std::string &token)
+{
+    xmlTextReaderRead(m_reader);
+    if (0 == xmlTextReaderIsValid(m_reader)) {
+        /*
+         * invalid file
+         */
+        LogWarning("Throw exception file not valid!");
+        Throw(Exception::FileNotValid);
+    }
+
+    xmlChar *name = xmlTextReaderName(m_reader);
+
+    if (name == NULL) {
+        /*
+         * invalid file
+         */
+        LogWarning("File not Valid");
+        Throw(Exception::FileNotValid);
+    }
+
+    if (token == reinterpret_cast<const char*>(name)) {
+        xmlFree(name);
+    } else {
+        /*
+         * we encountered wrong token
+         */
+        xmlFree(name);
+        LogWarning("Wrong Token");
+        Throw(Exception::WrongToken);
+    }
+}
+
+bool SaxReader::isEmpty(void)
+{
+    int ret = xmlTextReaderIsEmptyElement(m_reader);
+    if (-1 == ret) {
+        LogError("Parser Internal Error");
+        Throw(Exception::ParserInternalErrorInEmptyQuery);
+    }
+    return ret;
+}
+
+std::string SaxReader::attribute(const std::string &token,
+        ThrowType throwStatus)
+{
+    std::string value;
+    xmlChar *attr = xmlTextReaderGetAttribute(m_reader, BAD_CAST(token.c_str()));
+    if ((NULL == attr) && (throwStatus == THROW_DISABLE)) {
+        /*
+         * return empty string
+         */
+        //TODO why not DPL::Optional?
+        return std::string();
+    }
+    if (NULL == attr) {
+        /*
+         * error during read attribute
+         */
+        LogError("Error in reading attribute.");
+        Throw(Exception::ParserInternalErrorInReadingAttribute);
+    }
+
+    /*
+     * cast it to val and return it
+     */
+    value = reinterpret_cast<const char *>(attr);
+    xmlFree(attr);
+    return value;
+}
+
+// KW std::string SaxReader::fullName(){
+// KW     std::string value;
+// KW     xmlChar *name = xmlTextReaderName(m_reader);
+// KW     if(NULL == name) {
+// KW         LogError("Error in reading name.");
+// KW         Throw(Exception::ErrorReadingName);
+// KW     }
+// KW     value = reinterpret_cast<const char *>(name);
+// KW     xmlFree(name);
+// KW     return value;
+// KW }
+
+std::string SaxReader::name()
+{
+    std::string value;
+    xmlChar *name = xmlTextReaderName(m_reader);
+    if (NULL == name) {
+        LogError("Error in reading name.");
+        Throw(Exception::ErrorReadingName);
+    }
+    value = reinterpret_cast<const char *>(name);
+    xmlFree(name);
+    size_t pos = value.find_last_of(":");
+    if (pos != std::string::npos) {
+        value.erase(0, pos + 1);
+    }
+    return value;
+}
+
+std::string SaxReader::namespaceURI()
+{
+    std::string value;
+    xmlChar *name = xmlTextReaderNamespaceUri(m_reader);
+    if (NULL != name) {
+        value = reinterpret_cast<const char *>(name);
+        xmlFree(name);
+    }
+    return value;
+}
+
+std::string SaxReader::value()
+{
+    std::string value;
+    /*
+     * get value of node
+     */
+    xmlChar *text = xmlTextReaderValue(m_reader);
+    if (NULL == text) {
+        LogError("Error in reading value");
+        Throw(Exception::ErrorReadingValue);
+    }
+    value = reinterpret_cast<const char*>(text);
+    /*
+     * free text and return the val
+     */
+    xmlFree(text);
+    return value;
+}
+
+SaxReader::NodeType SaxReader::type()
+{
+    xmlReaderTypes type =
+        static_cast<xmlReaderTypes>(xmlTextReaderNodeType(m_reader));
+    switch (type) {
+    case XML_READER_TYPE_ELEMENT:
+        return NODE_BEGIN;
+    case XML_READER_TYPE_END_ELEMENT:
+        return NODE_END;
+    case XML_READER_TYPE_TEXT:
+        return NODE_TEXT;
+    case XML_READER_TYPE_NONE:
+    case XML_READER_TYPE_ATTRIBUTE:
+    case XML_READER_TYPE_CDATA:
+    case XML_READER_TYPE_ENTITY_REFERENCE:
+    case XML_READER_TYPE_ENTITY:
+    case XML_READER_TYPE_PROCESSING_INSTRUCTION:
+    case XML_READER_TYPE_COMMENT:
+    case XML_READER_TYPE_DOCUMENT:
+    case XML_READER_TYPE_DOCUMENT_TYPE:
+    case XML_READER_TYPE_DOCUMENT_FRAGMENT:
+    case XML_READER_TYPE_NOTATION:
+    case XML_READER_TYPE_WHITESPACE:
+    case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
+    case XML_READER_TYPE_END_ENTITY:
+    case XML_READER_TYPE_XML_DECLARATION:
+    default:
+        return NODE_UNSUPPORTED;
+    }
+}
+
+void SaxReader::dumpNode(std::string &buffer)
+{
+    /*
+     * size of buffer
+     */
+    int size;
+    /*
+     * pointer to buffer
+     */
+    xmlBufferPtr buff = xmlBufferCreate();
+
+    xmlNodePtr node = xmlTextReaderExpand(m_reader);
+
+    if (node == NULL) {
+        /*
+         * internal parser error
+         */
+        xmlBufferFree(buff);
+        LogError("Parser Internal Error");
+        Throw(Exception::ParserInternalError);
+    }
+
+    /*
+     * get a size and fill in a buffer
+     */
+    size = xmlNodeDump(buff, node->doc, node, 0, 0);
+    buffer.insert(0, reinterpret_cast<char*>(buff->content), size);
+    xmlBufferFree(buff);
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/SaxReader.h b/vcore/src/vcore/SaxReader.h
new file mode 100644 (file)
index 0000000..3fd4efc
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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        SaxReader.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Simple c++ interface for libxml2.
+ *              Its used in wrt-installer only and should be removed
+ *              from cert-svc.
+ */
+#ifndef _SAXREADER_H_
+#define _SAXREADER_H_
+
+#include <string>
+#include <libxml/xmlreader.h>
+#include <dpl/exception.h>
+
+namespace ValidationCore {
+class SaxReader
+{
+  public:
+    SaxReader();
+    ~SaxReader();
+
+    /*
+     * custom exceptions
+     */
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, FileOpeningError)
+        DECLARE_EXCEPTION_TYPE(Base, FileNotValid)
+        DECLARE_EXCEPTION_TYPE(Base, ParserInternalError)
+        DECLARE_EXCEPTION_TYPE(Base, WrongToken)
+        DECLARE_EXCEPTION_TYPE(Base, ParserInternalErrorInReadingAttribute)
+        DECLARE_EXCEPTION_TYPE(Base, ParserInternalErrorInEmptyQuery)
+        DECLARE_EXCEPTION_TYPE(Base, ErrorReadingValue)
+        DECLARE_EXCEPTION_TYPE(Base, ErrorReadingName)
+        DECLARE_EXCEPTION_TYPE(Base, UnsupportedType)
+    };
+
+    enum NodeType
+    {
+        NODE_UNSUPPORTED,
+        NODE_BEGIN,
+        NODE_END,
+        NODE_TEXT
+    };
+
+    enum ThrowType
+    {
+        THROW_ENABLE = 0,
+        THROW_DISABLE
+    };
+
+    /*
+     * xml validation modes
+     */
+    enum ValidationType
+    {
+        VALIDATION_DISABLE,
+        VALIDATION_XMLSCHEME,
+        VALIDATION_DTD
+    };
+
+    /*
+     * initializes parser
+     */
+    void initialize(const std::string &filename,
+            bool defaultArgs = false,
+            ValidationType validation = VALIDATION_DISABLE,
+            const std::string &schema = std::string());
+    /*
+     * deinitializes parser
+     */
+    void deinitialize();
+
+    /**
+     * Move to next xml node.
+     */
+    bool next();
+
+    /**
+     * Move to next xml node. If next node name is differ from token the exception will
+     * be thrown.
+     */
+    void next(const std::string &token);
+
+    /**
+     * Check if xml tag is empty.
+     */
+    bool isEmpty(void);
+
+    /**
+     * Read attribute tag.
+     */
+    std::string attribute(const std::string &token,
+            ThrowType throwStatus = THROW_ENABLE);
+
+    /**
+     * Read xml tag name with namespace.
+     */
+    // KW    std::string fullName();
+
+    /**
+     * Read xml tag name without namespace.
+     */
+    std::string name();
+
+    /**
+     * Read xml tag namespace URI
+     */
+    std::string namespaceURI();
+
+    /**
+     * Read xml tag value.
+     */
+    std::string value();
+
+    /**
+     * Return information about node type.
+     */
+    NodeType type();
+
+    /**
+     * Save all contonet of xml file which is between current tag and
+     * it's close tag into buffer.
+     */
+    void dumpNode(std::string &buffer);
+
+  private:
+    /*
+     * internal libxml text reader
+     */
+    xmlTextReaderPtr m_reader;
+};
+}
+
+#endif // _SAXREADER_H_
diff --git a/vcore/src/vcore/SignatureData.h b/vcore/src/vcore/SignatureData.h
new file mode 100644 (file)
index 0000000..bfb5e1f
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * 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        SignatureData.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       SignatureData is used to storage data parsed from digsig file.
+ */
+#ifndef _SIGNATUREDATA_H_
+#define _SIGNATUREDATA_H_
+
+#include <list>
+#include <set>
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/noncopyable.h>
+#include <dpl/string.h>
+
+#include <vcore/Certificate.h>
+#include <vcore/CertStoreType.h>
+
+namespace ValidationCore {
+
+typedef std::set<std::string> ReferenceSet;
+typedef std::list<std::string> ObjectList;
+
+class SignatureData
+{
+  public:
+
+    SignatureData() :
+        m_signatureNumber(-1),
+        m_certificateSorted(false)
+    {
+    }
+
+    SignatureData(std::string fileName, int fileNumber)
+      : m_signatureNumber(fileNumber)
+      , m_fileName(fileName)
+      , m_certificateSorted(false)
+    {}
+
+    virtual ~SignatureData()
+    {}
+
+    typedef std::list<std::string> IMEIList;
+    typedef std::list<std::string> MEIDList;
+
+    const ReferenceSet& getReferenceSet() const
+    {
+        return m_referenceSet;
+    }
+
+    void setReference(const ReferenceSet &referenceSet)
+    {
+        m_referenceSet = referenceSet;
+    }
+
+    CertificateList getCertList(void) const
+    {
+        return m_certList;
+    }
+
+    void setSortedCertificateList(const CertificateList &list)
+    {
+        m_certList = list;
+        m_certificateSorted = true;
+    }
+
+    bool isAuthorSignature(void) const
+    {
+        return m_signatureNumber == -1;
+    }
+
+    std::string getSignatureFileName(void) const
+    {
+        return m_fileName;
+    }
+
+    int getSignatureNumber() const
+    {
+        return m_signatureNumber;
+    }
+
+    std::string getRoleURI() const
+    {
+        return m_roleURI;
+    }
+
+    std::string getProfileURI() const
+    {
+        return m_profileURI;
+    }
+
+    bool containObjectReference(const std::string &ref) const
+    {
+        std::string rName = "#";
+        rName += ref;
+        return m_referenceSet.end() != m_referenceSet.find(rName);
+    }
+
+    ObjectList getObjectList() const
+    {
+        return m_objectList;
+    }
+
+    void setStorageType(const CertStoreId::Set &storeIdSet)
+    {
+        m_storeIdSet = storeIdSet;
+    }
+
+    const CertStoreId::Set& getStorageType(void) const
+    {
+        return m_storeIdSet;
+    }
+
+    const IMEIList& getIMEIList() const
+    {
+        return m_imeiList;
+    }
+
+    const MEIDList& getMEIDList() const
+    {
+        return m_meidList;
+    }
+
+    CertificatePtr getEndEntityCertificatePtr() const
+    {
+        if (m_certificateSorted) {
+            return m_certList.front();
+        }
+        return CertificatePtr();
+    }
+
+    CertificatePtr getRootCaCertificatePtr() const
+    {
+        if (m_certificateSorted) {
+            return m_certList.back();
+        }
+        return CertificatePtr();
+    }
+
+    friend class SignatureReader;
+  private:
+    ReferenceSet m_referenceSet;
+    CertificateList m_certList;
+
+    //TargetRestriction
+    IMEIList m_imeiList;
+    MEIDList m_meidList;
+
+    /*
+     * This number is taken from distributor signature file name.
+     * Author signature do not contain any number on the file name.
+     * Author signature should have signature number equal to -1.
+     */
+    int m_signatureNumber;
+    std::string m_fileName;
+    std::string m_roleURI;
+    std::string m_profileURI;
+    std::string m_identifier;
+    ObjectList m_objectList;
+    CertStoreId::Set m_storeIdSet;
+    bool m_certificateSorted;
+};
+
+typedef std::set<SignatureData> SignatureDataSet;
+
+} // ValidationCore
+
+#endif
diff --git a/vcore/src/vcore/SignatureFinder.cpp b/vcore/src/vcore/SignatureFinder.cpp
new file mode 100644 (file)
index 0000000..cc0a408
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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        SignatureFinder.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Search for author-signature.xml and signatureN.xml files.
+ */
+#include <vcore/SignatureFinder.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <istream>
+
+#include <pcrecpp.h>
+
+#include <dpl/log/log.h>
+
+namespace ValidationCore {
+static const char *SIGNATURE_AUTHOR = "author-signature.xml";
+static const char *REGEXP_DISTRIBUTOR_SIGNATURE =
+    "^(signature)([1-9][0-9]*)(\\.xml)";
+
+class SignatureFinder::Impl {
+  public:
+    Impl(const std::string& dir)
+      : m_dir(dir)
+      , m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
+    {}
+
+    virtual ~Impl(){}
+
+    Result find(SignatureFileInfoSet &set);
+
+  private:
+    std::string m_dir;
+    pcrecpp::RE m_signatureRegexp;
+};
+
+SignatureFinder::Result SignatureFinder::Impl::find(SignatureFileInfoSet &set)
+{
+    DIR *dp;
+    struct dirent *dirp;
+
+    /*
+     * find a dir
+     */
+    if ((dp = opendir(m_dir.c_str())) == NULL) {
+        LogError("Error opening directory:" << m_dir);
+        return ERROR_OPENING_DIR;
+    }
+
+    for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
+        /**
+         * check if it's author signature
+         */
+        if (!strcmp(dirp->d_name, SIGNATURE_AUTHOR)) {
+            set.insert(SignatureFileInfo(std::string(dirp->d_name), -1));
+            continue;
+        }
+
+        std::string sig, num, xml;
+        if (m_signatureRegexp.FullMatch(dirp->d_name, &sig, &num, &xml)) {
+            std::istringstream stream(num);
+            int number;
+            stream >> number;
+
+            if (stream.fail()) {
+                closedir(dp);
+                return ERROR_ISTREAM;
+            }
+
+            set.insert(SignatureFileInfo(std::string(dirp->d_name), number));
+        }
+    }
+
+    if (errno != 0) {
+        LogError("Error in readdir");
+        closedir(dp);
+        return ERROR_READING_DIR;
+    }
+
+    closedir(dp);
+    return NO_ERROR;
+}
+
+SignatureFinder::SignatureFinder(const std::string& dir)
+  : m_impl(new Impl(dir))
+{}
+
+SignatureFinder::~SignatureFinder(){
+    delete m_impl;
+}
+
+SignatureFinder::Result SignatureFinder::find(SignatureFileInfoSet &set) {
+    return m_impl->find(set);
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/SignatureFinder.h b/vcore/src/vcore/SignatureFinder.h
new file mode 100644 (file)
index 0000000..c1545cc
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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        SignatureFinder.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Search for author-signature.xml and signatureN.xml files.
+ *              This class is WAC 2.0 specific and shuld be moved to
+ *              wrt-installer.
+ */
+#ifndef _VALIDATION_CORE_SIGNATUREFINDER_H_
+#define _VALIDATION_CORE_SIGNATUREFINDER_H_
+
+#include <set>
+#include <string>
+
+#include <dpl/noncopyable.h>
+
+namespace ValidationCore {
+class SignatureFileInfo
+{
+  public:
+    SignatureFileInfo(const std::string &fileName, int num)
+      : m_fileName(fileName)
+      , m_fileNumber(num)
+    {}
+
+    std::string getFileName() const
+    {
+        return m_fileName;
+    }
+
+    int getFileNumber() const
+    {
+        return m_fileNumber;
+    }
+
+    bool operator<(const SignatureFileInfo &second) const
+    {
+        return m_fileNumber < second.m_fileNumber;
+    }
+  private:
+    std::string m_fileName;
+    int m_fileNumber;
+};
+
+typedef std::set<SignatureFileInfo> SignatureFileInfoSet;
+
+class SignatureFinder : DPL::Noncopyable {
+  public:
+    enum Result
+    {
+        NO_ERROR,
+        ERROR_OPENING_DIR,
+        ERROR_READING_DIR,
+        ERROR_ISTREAM
+    };
+
+    SignatureFinder(const std::string& dir);
+
+    virtual ~SignatureFinder();
+
+    Result find(SignatureFileInfoSet &set);
+
+  private:
+    class Impl;
+    Impl *m_impl;
+};
+
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_SIGNATUREFINDER_H_
diff --git a/vcore/src/vcore/SignatureReader.cpp b/vcore/src/vcore/SignatureReader.cpp
new file mode 100644 (file)
index 0000000..1d2071b
--- /dev/null
@@ -0,0 +1,582 @@
+/*
+ * 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        SignatureReader.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       SignatureReader is used to parse widget digital signature.
+ */
+#include <vcore/SignatureReader.h>
+
+#include <vcore/CertificateLoader.h>
+
+namespace ValidationCore {
+static const std::string XML_NAMESPACE =
+    "http://www.w3.org/2000/09/xmldsig#";
+static const std::string XML_NAMESPACE_DIGITALSIG =
+    "http://wacapps.net/ns/digsig";
+static const std::string XML_OBJ_NS =
+    "http://www.w3.org/2009/xmldsig-properties";
+
+// TAG TOKENS
+static const std::string TOKEN_SIGNATURE = "Signature";
+static const std::string TOKEN_SIGNED_INFO = "SignedInfo";
+static const std::string TOKEN_CANONICALIZATION_METHOD =
+    "CanonicalizationMethod";
+static const std::string TOKEN_SIGNATURE_METHOD = "SignatureMethod";
+static const std::string TOKEN_REFERENCE = "Reference";
+static const std::string TOKEN_TRANSFORMS = "Transforms";
+static const std::string TOKEN_TRANSFORM = "Transform";
+static const std::string TOKEN_DIGEST_METHOD = "DigestMethod";
+static const std::string TOKEN_DIGEST_VALUE = "DigestValue";
+static const std::string TOKEN_SIGNATURE_VALUE = "SignatureValue";
+static const std::string TOKEN_KEY_INFO = "KeyInfo";
+static const std::string TOKEN_X509DATA = "X509Data";
+static const std::string TOKEN_X509CERTIFICATE = "X509Certificate";
+static const std::string TOKEN_KEY_VALUE = "KeyValue";
+static const std::string TOKEN_RSA_KEY_VALUE = "RSAKeyValue";
+static const std::string TOKEN_MODULUS_COMPONENT = "Modulus";
+static const std::string TOKEN_EXPONENT_COMPONENT = "Exponent";
+static const std::string TOKEN_ECKEY_VALUE = "ECKeyValue";
+static const std::string TOKEN_NAMED_CURVE = "NamedCurve";
+static const std::string TOKEN_PUBLIC_KEY = "PublicKey";
+static const std::string TOKEN_OBJECT = "Object";
+static const std::string TOKEN_SIGNATURE_PROPERTIES = "SignatureProperties";
+static const std::string TOKEN_SIGNATURE_PROPERTY = "SignatureProperty";
+static const std::string TOKEN_PROFILE = "Profile";
+static const std::string TOKEN_ROLE = "Role";
+static const std::string TOKEN_IDENTIFIER = "Identifier";
+static const std::string TOKEN_DSAKEYVALUE = "DSAKeyValue";
+static const std::string TOKEN_DSA_P_COMPONENT = "P";
+static const std::string TOKEN_DSA_Q_COMPONENT = "Q";
+static const std::string TOKEN_DSA_G_COMPONENT = "G";
+static const std::string TOKEN_DSA_Y_COMPONENT = "Y";
+static const std::string TOKEN_DSA_J_COMPONENT = "J";
+static const std::string TOKEN_DSA_SEED_COMPONENT = "Seed";
+static const std::string TOKEN_DSA_PGENCOUNTER_COMPONENT = "PgenCounter";
+static const std::string TOKEN_TARGET_RESTRICTION = "TargetRestriction";
+
+// ATTRIBUTTE TOKENS
+
+static const std::string TOKEN_ALGORITHM = "Algorithm";
+static const std::string TOKEN_URI = "URI";
+static const std::string TOKEN_ID = "Id";
+static const std::string TOKEN_TARGET = "Target";
+static const std::string TOKEN_IMEI = "IMEI";
+static const std::string TOKEN_MEID = "MEID";
+
+// ATTIRUBTE VALUES
+
+static const std::string TOKEN_ATTR_PROFILE = "profile";
+static const std::string TOKEN_ATTR_ROLE = "role";
+static const std::string TOKEN_ATTR_IDENTIFIER = "identifier";
+
+// ALGORITHMS
+
+//static const std::string TOKEN_ALGORITHM_XML_EXC_CAN   =
+//            "http://www.w3.org/2001/10/xml-exc-c14n#";
+//static const std::string TOKEN_ALGORITHM_RSA_SHA256    =
+//            "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
+//static const std::string TOKEN_ALGORITHM_DSA_SHA1      =
+//            "http://www.w3.org/2000/09/xmldsig#dsa-sha1";
+//static const std::string TOKEN_ALGORITHM_ECDSA_SHA256  =
+//            "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";
+//static const std::string TOKEN_ALGORITHM_SHA1          =
+//            "http://www.w3.org/2000/09/xmldsig#sha1";
+//static const std::string TOKEN_ALGORITHM_SHA256        =
+//            "http://www.w3.org/2001/04/xmlenc#sha256";
+//static const std::string TOKEN_ALGORITHM_SHA384        =
+//            "http://www.w3.org/2001/04/xmldsig-more#sha384";
+//static const std::string TOKEN_ALGORITHM_SHA512        =
+//            "http://www.w3.org/2001/04/xmlenc#sha512";
+
+SignatureReader::SignatureReader() :
+    m_signaturePropertiesCounter(0),
+    m_targetRestrictionObjectFound(false),
+    m_parserSchema(this)
+{
+    /**
+     * member func pointers map
+     */
+    m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_SIGNED_INFO,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_CANONICALIZATION_METHOD,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_METHOD,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_REFERENCE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_TRANSFORMS,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_TRANSFORM,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DIGEST_METHOD,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DIGEST_VALUE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_VALUE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_KEY_INFO,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::tokenKeyInfo);
+    m_parserSchema.addBeginTagCallback(TOKEN_X509DATA,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::tokenX509Data);
+    m_parserSchema.addBeginTagCallback(TOKEN_X509CERTIFICATE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::tokenX509Certificate);
+    m_parserSchema.addBeginTagCallback(TOKEN_ECKEY_VALUE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_NAMED_CURVE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::tokenNamedCurve);
+    m_parserSchema.addBeginTagCallback(TOKEN_PUBLIC_KEY,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::tokenPublicKey);
+    m_parserSchema.addBeginTagCallback(TOKEN_OBJECT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::tokenObject);
+    m_parserSchema.addBeginTagCallback(
+        TOKEN_SIGNATURE_PROPERTIES,
+        XML_NAMESPACE,
+        &SignatureReader::
+            tokenSignatureProperties);
+    m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_PROPERTY,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_PROFILE,
+                                       XML_OBJ_NS,
+                                       &SignatureReader::tokenProfile);
+    m_parserSchema.addBeginTagCallback(TOKEN_ROLE,
+                                       XML_OBJ_NS,
+                                       &SignatureReader::tokenRole);
+    m_parserSchema.addBeginTagCallback(TOKEN_IDENTIFIER,
+                                       XML_OBJ_NS,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_KEY_VALUE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSAKEYVALUE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSA_P_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSA_Q_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSA_G_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSA_Y_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSA_J_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSA_SEED_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_DSA_PGENCOUNTER_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_RSA_KEY_VALUE,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_MODULUS_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_EXPONENT_COMPONENT,
+                                       XML_NAMESPACE,
+                                       &SignatureReader::blankFunction);
+    m_parserSchema.addBeginTagCallback(TOKEN_TARGET_RESTRICTION,
+                                       XML_NAMESPACE_DIGITALSIG,
+                                       &SignatureReader::tokenTargetRestriction);
+
+    m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_SIGNED_INFO,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_CANONICALIZATION_METHOD,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_METHOD,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_REFERENCE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_TRANSFORMS,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_TRANSFORM,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_DIGEST_METHOD,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_DIGEST_VALUE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_VALUE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_KEY_INFO,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndKeyInfo);
+    m_parserSchema.addEndTagCallback(TOKEN_X509DATA,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndX509Data);
+    m_parserSchema.addEndTagCallback(TOKEN_X509CERTIFICATE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndX509Certificate);
+    m_parserSchema.addEndTagCallback(TOKEN_ECKEY_VALUE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndECKeyValue);
+    m_parserSchema.addEndTagCallback(TOKEN_PUBLIC_KEY,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndPublicKey);
+    m_parserSchema.addEndTagCallback(TOKEN_OBJECT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndObject);
+    m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_PROPERTIES,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_SIGNATURE_PROPERTY,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_PROFILE,
+                                     XML_OBJ_NS,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_ROLE,
+                                     XML_OBJ_NS,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_IDENTIFIER,
+                                     XML_OBJ_NS,
+                                     &SignatureReader::tokenEndIdentifier);
+    m_parserSchema.addEndTagCallback(TOKEN_KEY_VALUE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+    m_parserSchema.addEndTagCallback(TOKEN_DSAKEYVALUE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndDSAKeyValue);
+    m_parserSchema.addEndTagCallback(TOKEN_DSA_P_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndDSAPComponent);
+    m_parserSchema.addEndTagCallback(TOKEN_DSA_Q_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndDSAQComponent);
+    m_parserSchema.addEndTagCallback(TOKEN_DSA_G_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndDSAGComponent);
+    m_parserSchema.addEndTagCallback(TOKEN_DSA_Y_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndDSAYComponent);
+    m_parserSchema.addEndTagCallback(TOKEN_DSA_J_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndDSAJComponent);
+    m_parserSchema.addEndTagCallback(TOKEN_DSA_SEED_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndDSASeedComponent);
+    m_parserSchema.addEndTagCallback(
+        TOKEN_DSA_PGENCOUNTER_COMPONENT,
+        XML_NAMESPACE,
+        &SignatureReader::
+            tokenEndDSAPGenCounterComponent);
+    m_parserSchema.addEndTagCallback(TOKEN_RSA_KEY_VALUE,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndRSAKeyValue);
+    m_parserSchema.addEndTagCallback(TOKEN_MODULUS_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndKeyModulus);
+    m_parserSchema.addEndTagCallback(TOKEN_EXPONENT_COMPONENT,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::tokenEndKeyExponent);
+    m_parserSchema.addEndTagCallback(TOKEN_TARGET_RESTRICTION,
+                                     XML_NAMESPACE,
+                                     &SignatureReader::blankFunction);
+}
+
+void SignatureReader::tokenKeyInfo(SignatureData &signatureData)
+{
+    (void)signatureData;
+}
+void SignatureReader::tokenX509Data(SignatureData &signatureData)
+{
+    (void)signatureData;
+}
+void SignatureReader::tokenX509Certificate(SignatureData &signatureData)
+{
+    (void)signatureData;
+}
+void SignatureReader::tokenPublicKey(SignatureData &signatureData)
+{
+    (void)signatureData;
+}
+
+void SignatureReader::tokenNamedCurve(SignatureData &signatureData)
+{
+    (void)signatureData;
+    m_nameCurveURI = m_parserSchema.getReader().attribute(TOKEN_URI);
+}
+
+void SignatureReader::tokenTargetRestriction(SignatureData &signatureData)
+{
+    std::string IMEI = m_parserSchema.getReader().attribute(
+            TOKEN_IMEI,
+            SaxReader::
+                THROW_DISABLE);
+    std::string MEID = m_parserSchema.getReader().attribute(
+            TOKEN_MEID,
+            SaxReader::
+                THROW_DISABLE);
+
+    //less verbose way to say (IMEI && MEID) || (!IMEI && !MEID)
+    if (IMEI.empty() == MEID.empty()) {
+        //WAC 2.0 WR-4650 point 4
+        ThrowMsg(Exception::TargetRestrictionException,
+                 "TargetRestriction should contain exactly one attribute.");
+        return;
+    }
+
+    if (!IMEI.empty()) {
+        signatureData.m_imeiList.push_back(IMEI);
+    }
+    if (!MEID.empty()) {
+        signatureData.m_meidList.push_back(MEID);
+    }
+}
+
+void SignatureReader::tokenEndKeyInfo(SignatureData &signatureData)
+{
+    (void)signatureData;
+}
+
+void SignatureReader::tokenEndX509Data(SignatureData &signatureData)
+{
+    (void)signatureData;
+}
+
+void SignatureReader::tokenEndX509Certificate(SignatureData &signatureData)
+{
+    CertificateLoader loader;
+    if (CertificateLoader::NO_ERROR !=
+        loader.loadCertificateFromRawData(m_parserSchema.getText())) {
+        LogWarning("Certificate could not be loaded!");
+        ThrowMsg(ParserSchemaException::CertificateLoaderError,
+                 "Certificate could not be loaded.");
+    }
+    signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+// KW void SignatureReader::tokenEndKeyName(SignatureData &signatureData){
+// KW     CertificateLoader loader;
+// KW     if(CertificateLoader::NO_ERROR != loader.loadCertificateBasedOnSubjectName(m_parserSchema.getText())){
+// KW         LogError("Certificate could not be loaded!");
+// KW         ThrowMsg(ParserSchemaException::CertificateLoaderError, "Certificate could not be loaded.");
+// KW     }
+// KW     signatureData.m_certList.push_back(loader);
+// KW }
+
+void SignatureReader::tokenEndRSAKeyValue(SignatureData &signatureData)
+{
+    CertificateLoader loader;
+    if (CertificateLoader::NO_ERROR !=
+        loader.loadCertificateBasedOnExponentAndModulus(m_modulus,
+                                                        m_exponent)) {
+        LogWarning("Certificate could not be loaded!");
+        ThrowMsg(ParserSchemaException::CertificateLoaderError,
+                 "Certificate could not be loaded.");
+    }
+    signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+
+void SignatureReader::tokenEndKeyModulus(SignatureData &signatureData)
+{
+    (void)signatureData;
+    m_modulus = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndKeyExponent(SignatureData &signatureData)
+{
+    (void)signatureData;
+    m_exponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndPublicKey(SignatureData &signatureData)
+{
+    (void)signatureData;
+    m_publicKey = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndECKeyValue(SignatureData &signatureData)
+{
+    CertificateLoader loader;
+    if (CertificateLoader::NO_ERROR !=
+        loader.loadCertificateWithECKEY(m_nameCurveURI, m_publicKey)) {
+        ThrowMsg(ParserSchemaException::CertificateLoaderError,
+                 "Certificate could not be loaded.");
+    }
+    signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+
+void SignatureReader::tokenEndObject(SignatureData &signatureData)
+{
+    m_signaturePropertiesCounter = 0;
+
+    if (((!signatureData.m_imeiList.empty()) ||
+         (!signatureData.m_meidList.empty())) &&
+        m_targetRestrictionObjectFound) {
+        //WAC 2.0 WR-4650 point 1
+        ThrowMsg(
+            Exception::TargetRestrictionException,
+            "TargetRestriction should contain exactly one ds:Object containing zero or more wac:TargetRestriction children.");
+        return;
+    }
+    if ((!signatureData.m_imeiList.empty()) ||
+        (!signatureData.m_meidList.empty())) {
+        m_targetRestrictionObjectFound = true;
+    }
+}
+void SignatureReader::tokenEndDSAPComponent(SignatureData& signatureData)
+{
+    (void)signatureData;
+    m_dsaKeyPComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAQComponent(SignatureData& signatureData)
+{
+    (void)signatureData;
+    m_dsaKeyQComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAGComponent(SignatureData& signatureData)
+{
+    (void)signatureData;
+    m_dsaKeyGComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAYComponent(SignatureData& signatureData)
+{
+    (void)signatureData;
+    m_dsaKeyYComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAJComponent(SignatureData& signatureData)
+{
+    (void)signatureData;
+    m_dsaKeyJComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSASeedComponent(SignatureData& signatureData)
+{
+    (void)signatureData;
+    m_dsaKeySeedComponent = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAPGenCounterComponent(
+        SignatureData& signatureData)
+{
+    (void)signatureData;
+    m_dsaKeyPGenCounter = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenEndDSAKeyValue(SignatureData& signatureData)
+{
+    CertificateLoader loader;
+
+    if (CertificateLoader::NO_ERROR !=
+        loader.loadCertificateBasedOnDSAComponents(m_dsaKeyPComponent,
+                                                   m_dsaKeyQComponent,
+                                                   m_dsaKeyGComponent,
+                                                   m_dsaKeyYComponent,
+                                                   m_dsaKeyJComponent,
+                                                   m_dsaKeySeedComponent,
+                                                   m_dsaKeyPGenCounter)) {
+        LogWarning("Certificate could not be loaded.");
+        ThrowMsg(ParserSchemaException::CertificateLoaderError,
+                 "Certificate could not be loaded.");
+    }
+    signatureData.m_certList.push_back(loader.getCertificatePtr());
+}
+
+void SignatureReader::tokenRole(SignatureData &signatureData)
+{
+    if (!signatureData.m_roleURI.empty()) {
+        LogWarning("Multiple definition of Role is not allowed.");
+        ThrowMsg(ParserSchemaException::UnsupportedValue,
+                 "Multiple definition of Role is not allowed.");
+    }
+    signatureData.m_roleURI = m_parserSchema.getReader().attribute(TOKEN_URI);
+}
+
+void SignatureReader::tokenProfile(SignatureData &signatureData)
+{
+    if (!signatureData.m_profileURI.empty()) {
+        LogWarning("Multiple definition of Profile is not allowed.");
+        ThrowMsg(ParserSchemaException::UnsupportedValue,
+                 "Multiple definition of Profile is not allowed.");
+    }
+    signatureData.m_profileURI = m_parserSchema.getReader().attribute(TOKEN_URI);
+}
+
+void SignatureReader::tokenEndIdentifier(SignatureData &signatureData)
+{
+    if (!signatureData.m_identifier.empty()) {
+        LogWarning("Multiple definition of Identifier is not allowed.");
+        ThrowMsg(ParserSchemaException::UnsupportedValue,
+                 "Multiple definition of Identifier is not allowed.");
+    }
+    signatureData.m_identifier = m_parserSchema.getText();
+}
+
+void SignatureReader::tokenObject(SignatureData &signatureData)
+{
+    std::string id = m_parserSchema.getReader().attribute(TOKEN_ID);
+
+    if (id.empty()) {
+        LogWarning("Unsupported value of Attribute Id in Object tag.");
+        ThrowMsg(ParserSchemaException::UnsupportedValue,
+                 "Unsupported value of Attribute Id in Object tag.");
+    }
+
+    signatureData.m_objectList.push_back(id);
+}
+
+void SignatureReader::tokenSignatureProperties(SignatureData &signatureData)
+{
+    (void)signatureData;
+    if (++m_signaturePropertiesCounter > 1) {
+        LogWarning("Only one SignatureProperties tag is allowed in Object");
+        ThrowMsg(ParserSchemaException::UnsupportedValue,
+                 "Only one SignatureProperties tag is allowed in Object");
+    }
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/SignatureReader.h b/vcore/src/vcore/SignatureReader.h
new file mode 100644 (file)
index 0000000..2f2f9a8
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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        SignatureReader.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       SignatureReader is used to parse widget digital signature.
+ */
+#ifndef _VALIDATION_CORE_SIGNATUREREADER_H_
+#define _VALIDATION_CORE_SIGNATUREREADER_H_
+
+#include <map>
+#include <dpl/log/log.h>
+
+#include <vcore/SignatureData.h>
+#include <vcore/ParserSchema.h>
+
+namespace ValidationCore {
+class SignatureReader
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, TargetRestrictionException)
+    };
+
+    SignatureReader();
+
+    void initialize(SignatureData &data,
+            const std::string &xmlscheme)
+    {
+        m_parserSchema.initialize(
+            data.getSignatureFileName(), true, SaxReader::VALIDATION_XMLSCHEME,
+            xmlscheme);
+    }
+
+    void read(SignatureData &data)
+    {
+        m_parserSchema.read(data);
+    }
+
+  private:
+    void blankFunction(SignatureData &)
+    {
+    }
+
+    void tokenKeyInfo(SignatureData &signatureData);
+    void tokenKeyModulus(SignatureData &signatureData);
+    void tokenKeyExponent(SignatureData &signatureData);
+    void tokenX509Data(SignatureData &signatureData);
+    void tokenX509Certificate(SignatureData &signatureData);
+    void tokenPublicKey(SignatureData &signatureData);
+    void tokenNamedCurve(SignatureData &signatureData);
+    void tokenRole(SignatureData &signatureData);
+    void tokenProfile(SignatureData &signatureData);
+    void tokenObject(SignatureData &signatureData);
+    void tokenSignatureProperties(SignatureData &signatureData);
+    void tokenTargetRestriction(SignatureData &signatureData);
+
+    void tokenEndKeyInfo(SignatureData &signatureData);
+    // KW     void tokenEndKeyName(SignatureData &signatureData);
+    void tokenEndRSAKeyValue(SignatureData &signatureData);
+    void tokenEndKeyModulus(SignatureData &signatureData);
+    void tokenEndKeyExponent(SignatureData &signatureData);
+    void tokenEndX509Data(SignatureData &signatureData);
+    void tokenEndX509Certificate(SignatureData &signatureData);
+    void tokenEndPublicKey(SignatureData &signatureData);
+    void tokenEndECKeyValue(SignatureData &signatureData);
+    void tokenEndIdentifier(SignatureData &signatureData);
+    void tokenEndObject(SignatureData &signatureData);
+
+    // DSA key components
+    void tokenEndDSAPComponent(SignatureData& signatureData);
+    void tokenEndDSAQComponent(SignatureData& signatureData);
+    void tokenEndDSAGComponent(SignatureData& signatureData);
+    void tokenEndDSAYComponent(SignatureData& signatureData);
+    void tokenEndDSAJComponent(SignatureData& signatureData);
+
+    void tokenEndDSAKeyValue(SignatureData& signatureData);
+
+    void tokenEndDSASeedComponent(SignatureData& signatureData);
+    void tokenEndDSAPGenCounterComponent(SignatureData& signatureData);
+
+    // temporary values required due reference parsing process
+    // optional parameters for dsa
+    std::string m_dsaKeyPComponent;
+    std::string m_dsaKeyQComponent;
+    std::string m_dsaKeyGComponent;
+    std::string m_dsaKeyYComponent;
+    std::string m_dsaKeyJComponent;
+    std::string m_dsaKeySeedComponent;
+    std::string m_dsaKeyPGenCounter;
+    // temporary values of ecdsa key
+    std::string m_publicKey;
+    std::string m_nameCurveURI;
+    std::string m_modulus;
+    std::string m_exponent;
+
+    // temporary values required due Object parsing
+    int m_signaturePropertiesCounter;
+    bool m_targetRestrictionObjectFound;
+
+    ParserSchema<SignatureReader, SignatureData> m_parserSchema;
+};
+}
+
+#endif // _VALIDATION_CORE_SIGNATUREREADER_H_
diff --git a/vcore/src/vcore/SoupMessageSendAsync.cpp b/vcore/src/vcore/SoupMessageSendAsync.cpp
new file mode 100644 (file)
index 0000000..d8bb132
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * 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.
+ */
diff --git a/vcore/src/vcore/SoupMessageSendAsync.h b/vcore/src/vcore/SoupMessageSendAsync.h
new file mode 100644 (file)
index 0000000..07fcad5
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        SoupMessageSendAsync.h
+ * @brief       Routines for certificate validation over OCSP
+ */
+#ifndef _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_ASYNC_H_
+#define _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_ASYNC_H_
+
+#include <map>
+#include <vector>
+
+#include <dpl/assert.h>
+
+#include <dpl/event/inter_context_delegate.h>
+
+#include <vcore/SoupMessageSendBase.h>
+
+namespace SoupWrapper {
+
+class SoupMessageSendAsync
+  : public SoupMessageSendBase
+  , public DPL::Event::ICDelegateSupport<SoupMessageSendAsync>
+{
+    typedef DPL::Event::ICDelegate<SoupSession*, SoupMessage*, void*> SoupDelegate;
+  public:
+    void sendAsync() {
+        Assert(m_status == STATUS_IDLE);
+        Assert(!m_soupSession);
+        Assert(!m_soupMessage);
+
+        m_status = STATUS_SEND_ASYNC;
+        m_tryLeft = m_tryCount;
+        m_mainContext = g_main_context_new();
+
+        if (!m_mainContext){
+            m_status = STATUS_IDLE;
+
+            // call the delegate to outside with error!
+            return;
+        }
+
+        m_soupSession = soup_session_async_new_with_options(
+            SOUP_SESSION_ASYNC_CONTEXT,
+            m_mainContext,
+            SOUP_SESSION_TIMEOUT,
+            m_timeout,
+            NULL);
+
+        if (!m_soupSession){
+            m_status = STATUS_IDLE;
+            g_object_unref(m_mainContext);
+            m_mainContext = 0;
+
+            // call the deletage to outside with error!
+            return;
+        }
+
+        m_soupMessage = createRequest();
+
+        if (!m_soupMessage){
+            m_status = STATUS_IDLE;
+            g_object_unref(m_soupSession);
+            m_soupSession = 0;
+            g_object_unref(m_mainContext);
+            m_mainContext = 0;
+
+            // call the delegate to outsize with error!
+            return;
+        }
+
+        sendAsyncIterationStart();
+    }
+
+  protected:
+
+    struct SoupDelegateOpaque {
+        SoupDelegate dlg;
+    };
+
+    void sendAsyncIterationStart(){
+        // ICDelegate could be called only once.
+        // We can set user data only once.
+        // We need nasty hack because we will call ICDelegate m_tryCount times.
+        SoupDelegateOpaque *opaq = new SoupDelegateOpaque;
+        opaq->dlg = makeICDelegate(&SoupMessageSendAsync::requestReceiver);
+
+        soup_session_queue_message(m_soupSession,
+                                   m_soupMessage,
+                                   soupSessionCallback,
+                                   reinterpret_cast<gpointer>(opaq));
+    }
+
+    void sendAsyncIteration(SoupDelegateOpaque *opaq){
+        // Replace used ICDelegate with new one without changing
+        // userdata ;-)
+        opaq->dlg = makeICDelegate(&SoupMessageSendAsync::requestReceiver);
+        soup_session_requeue_message(m_soupSession,
+                                     m_soupMessage);
+    }
+
+    void requestReceiver(SoupSession *session, SoupMessage *msg, void *opaque){
+        // We are in thread which called sendAsync function.
+        Assert(session == m_soupSession);
+        Assert(msg == m_soupMessage);
+        Assert(opaque != 0);
+        Assert(m_status == STATUS_SEND_ASYNC);
+
+        m_tryLeft--;
+
+        if (msg->status_code == SOUP_STATUS_OK) {
+            m_responseBuffer.resize(msg->response_body->length);
+            memcpy(&m_responseBuffer[0],
+              msg->response_body->data,
+              msg->response_body->length);
+            // We are done.
+            m_status = STATUS_IDLE;
+            delete static_cast<SoupDelegateOpaque*>(opaque);
+
+            // call the delegate to outside!
+            return;
+        }
+
+        // Error protocol //
+        if (m_tryLeft <= 0) {
+            m_status = STATUS_IDLE;
+            delete static_cast<SoupDelegateOpaque*>(opaque);
+
+            // call the delegate to outside with error!
+            return;
+        }
+
+        // create delegate and send the request once again.
+        sendAsyncIteration(reinterpret_cast<SoupDelegateOpaque*>(opaque));
+    }
+
+    static void soupSessionCallback(SoupSession *session,
+                                    SoupMessage *msg,
+                                    gpointer userdata)
+    {
+        // We are in main thread. We need to switch context.
+        // This delegate can switch context to dpl thread or main thread.
+        SoupDelegateOpaque *opaque;
+        opaque = reinterpret_cast<SoupDelegateOpaque*>(userdata);
+        opaque->dlg(session, msg, userdata);
+    }
+
+    int m_tryLeft;
+
+    GMainContext *m_mainContext;
+    SoupSession *m_soupSession;
+    SoupMessage *m_soupMessage;
+};
+
+} // namespace ValidationCore
+
+#endif
diff --git a/vcore/src/vcore/SoupMessageSendBase.cpp b/vcore/src/vcore/SoupMessageSendBase.cpp
new file mode 100644 (file)
index 0000000..e7f4742
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        SoupMessageSendBase.cpp
+ * @brief       Simple wrapper for soup.
+ */
+#include <vcore/SoupMessageSendBase.h>
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+namespace SoupWrapper {
+
+SoupMessageSendBase::SoupMessageSendBase()
+  : m_status(STATUS_IDLE)
+  , m_timeout(30)
+  , m_tryCount(5)
+{}
+
+SoupMessageSendBase::~SoupMessageSendBase(){
+    Assert(m_status == STATUS_IDLE);
+}
+
+void SoupMessageSendBase::setHeader(const std::string &property, const std::string &value){
+    Assert(m_status == STATUS_IDLE);
+    m_headerMap[property] = value;
+}
+
+void SoupMessageSendBase::setHost(const std::string &host){
+    Assert(m_status == STATUS_IDLE);
+    m_host = host;
+}
+
+void SoupMessageSendBase::setRequest(const std::string &contentType, const MessageBuffer &message){
+    Assert(m_status == STATUS_IDLE);
+    m_requestType = contentType;
+    m_requestBuffer = message;
+}
+
+SoupMessageSendBase::MessageBuffer SoupMessageSendBase::getResponse() const {
+    Assert(m_status == STATUS_IDLE);
+    return m_responseBuffer;
+}
+
+void SoupMessageSendBase::setTimeout(int seconds) {
+    Assert(m_status == STATUS_IDLE);
+    Assert(seconds >= 0);
+    m_timeout = seconds;
+}
+
+void SoupMessageSendBase::setRetry(int retry) {
+    Assert(m_status == STATUS_IDLE);
+    Assert(retry >= 0);
+    m_tryCount = retry + 1;
+}
+
+
+SoupMessage* SoupMessageSendBase::createRequest(){
+    SoupMessage *message;
+
+    LogInfo("Soup message will be send to: " << m_host.c_str());
+
+    if (!m_requestBuffer.empty()) {
+        message = soup_message_new("POST", m_host.c_str());
+    } else {
+        message = soup_message_new("GET", m_host.c_str());
+    }
+
+    if (!message) {
+        LogError("Error creating request!");
+        return 0;
+    }
+
+    FOREACH(it, m_headerMap){
+        soup_message_headers_append(message->request_headers,
+                                    it->first.c_str(),
+                                    it->second.c_str());
+    }
+
+    if (!m_requestBuffer.empty()) {
+        soup_message_set_http_version(message, SOUP_HTTP_1_0);
+        soup_message_set_request(message,
+          m_requestType.c_str(),
+          SOUP_MEMORY_COPY,
+          &m_requestBuffer[0],
+          m_requestBuffer.size());
+    }
+//    soup_message_set_flags(message, SOUP_MESSAGE_NO_REDIRECT);
+    return message;
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/SoupMessageSendBase.h b/vcore/src/vcore/SoupMessageSendBase.h
new file mode 100644 (file)
index 0000000..aaa5fb4
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        SoupMessageSendBase.h
+ * @brief       Simple wrapper for soup.
+ */
+#ifndef _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_BASE_H_
+#define _SRC_VALIDATION_CORE_SOUP_MESSAGE_SEND_BASE_H_
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include <libsoup/soup.h>
+
+namespace SoupWrapper {
+
+class SoupMessageSendBase {
+  public:
+
+    typedef std::vector<char> MessageBuffer;
+    typedef std::map<std::string,std::string> HeaderMap;
+
+    enum RequestStatus {
+        REQUEST_STATUS_OK,
+        REQUEST_STATUS_CONNECTION_ERROR
+    };
+
+    SoupMessageSendBase();
+
+    virtual ~SoupMessageSendBase();
+
+    /**
+     * Add specific information to request header.
+     *
+     * @param[in] property property name (for example "Host")
+     * @param[in] value property value (for example "onet.pl:80")
+     */
+    void setHeader(const std::string &property,
+                const std::string &value);
+
+    /**
+     * Set request destination.
+     *
+     * @param[in] host - full path to source (http://onet.pl/index.html)
+     */
+    void setHost(const std::string &host);
+
+    /**
+     * Set body of request.
+     *
+     * @param[in] contentType (for example: "application/ocsp-request")
+     * @param[in] message body of reqeust
+     */
+    void setRequest(const std::string &contentType,
+                const MessageBuffer &message);
+
+    /**
+     * Set network timeout. Default is 30 seconds.
+     *
+     * @param[in] seconds timeout in seconds
+     */
+    void setTimeout(int seconds);
+
+    /**
+     * How many erros soup will accept before he will terminate connection.
+     * Default is 5.
+     *
+     * @param[in] retry number
+     */
+    void setRetry(int retry);
+
+    /**
+     * Get response from serwer.
+     */
+    MessageBuffer getResponse() const;
+
+  protected:
+
+    SoupMessage* createRequest();
+
+    enum Status {
+        STATUS_IDLE,
+        STATUS_SEND_SYNC,
+        STATUS_SEND_ASYNC
+    };
+
+    Status m_status;
+
+    int m_timeout;
+    int m_tryCount;
+
+    std::string m_host;
+    std::string m_requestType;
+    MessageBuffer m_requestBuffer;
+    MessageBuffer m_responseBuffer;
+    HeaderMap m_headerMap;
+};
+
+} // namespace ValidationCore
+
+#endif
diff --git a/vcore/src/vcore/SoupMessageSendSync.cpp b/vcore/src/vcore/SoupMessageSendSync.cpp
new file mode 100644 (file)
index 0000000..e3f3ee4
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        SoupMessageSendSync.cpp
+ * @brief       Implementation of soup synchronous interface.
+ */
+#include <vcore/SoupMessageSendSync.h>
+
+#include <memory>
+#include <functional>
+
+#include <vconf.h>
+
+#include <dpl/log/log.h>
+
+namespace SoupWrapper {
+
+SoupMessageSendBase::RequestStatus SoupMessageSendSync::sendSync()
+{
+    Assert(m_status == STATUS_IDLE);
+    m_status = STATUS_SEND_SYNC;
+
+    ScopedGMainContext context(g_main_context_new());
+
+    std::unique_ptr<char,std::function<void(void*)> >
+            proxy(vconf_get_str(VCONFKEY_NETWORK_PROXY), free);
+
+    std::unique_ptr <SoupURI, std::function<void(SoupURI*)> >
+                   proxyURI(soup_uri_new (proxy.get()), soup_uri_free);
+
+    LogDebug("Proxy ptr:" << (void*)proxy.get() <<
+             " Proxy addr: " << proxy.get());
+
+    for(int tryCount = 0; tryCount < m_tryCount; ++ tryCount){
+        LogDebug("Try(" << tryCount << ") to download " << m_host);
+
+        ScopedSoupSession session(soup_session_async_new_with_options(
+              SOUP_SESSION_ASYNC_CONTEXT,
+              &*context,
+              SOUP_SESSION_TIMEOUT,
+              m_timeout,
+              SOUP_SESSION_PROXY_URI,
+              proxyURI.get(),
+              NULL));
+
+        ScopedSoupMessage msg;
+
+        msg.Reset(createRequest());
+
+        if (!msg) {
+            LogError("Unable to send HTTP request.");
+            m_status = STATUS_IDLE;
+            return REQUEST_STATUS_CONNECTION_ERROR;
+        }
+        soup_session_send_message(&*session, &*msg);
+
+        // if (SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
+
+        if (msg->status_code == SOUP_STATUS_OK) {
+            m_responseBuffer.resize(msg->response_body->length);
+            memcpy(&m_responseBuffer[0],
+              msg->response_body->data,
+              msg->response_body->length);
+            // We are done.
+            m_status = STATUS_IDLE;
+            return REQUEST_STATUS_OK;
+        } else {
+            LogWarning("Soup failed with code " << msg->status_code
+              << " message \n------------\n"
+              << msg->response_body->data
+              << "\n--------------\n");
+        }
+    }
+
+    m_status = STATUS_IDLE;
+    return REQUEST_STATUS_CONNECTION_ERROR;
+}
+
+} // namespave ValidationCore
diff --git a/vcore/src/vcore/SoupMessageSendSync.h b/vcore/src/vcore/SoupMessageSendSync.h
new file mode 100644 (file)
index 0000000..e022f0b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @file        SoupMessageSendSync.h
+ * @brief       Wrapper for soup synchronous interface.
+ */
+#ifndef _VALIDATION_CORE_SOUP_MESSAGE_SEND_SYNC_H_
+#define _VALIDATION_CORE_SOUP_MESSAGE_SEND_SYNC_H_
+
+#include <vcore/SoupMessageSendBase.h>
+
+#include <vcore/scoped_gpointer.h>
+
+namespace SoupWrapper {
+
+class SoupMessageSendSync : public SoupMessageSendBase {
+  public:
+    RequestStatus sendSync();
+  protected:
+    typedef WRT::ScopedGPointer<SoupMessage> ScopedSoupMessage;
+    typedef WRT::ScopedGPointer<SoupSession> ScopedSoupSession;
+    typedef WRT::ScopedGPointer<GMainContext> ScopedGMainContext;
+};
+
+} // namespace ValidationCore
+
+#endif
diff --git a/vcore/src/vcore/TimeConversion.cpp b/vcore/src/vcore/TimeConversion.cpp
new file mode 100644 (file)
index 0000000..98c80f3
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+#include <vcore/TimeConversion.h>
+
+#include <string.h>
+
+#include <dpl/log/log.h>
+#include <dpl/assert.h>
+
+namespace ValidationCore {
+
+int asn1TimeToTimeT(ASN1_TIME *t, time_t *res)
+{
+    struct tm tm;
+    int offset;
+
+    (*res) = 0;
+    if (!ASN1_TIME_check(t)) {
+        return -1;
+    }
+
+    memset(&tm, 0, sizeof(tm));
+
+#define g2(p) (((p)[0] - '0') * 10 + (p)[1] - '0')
+    if (t->type == V_ASN1_UTCTIME) {
+        Assert(t->length > 12);
+
+        /*   this code is copied from OpenSSL asn1/a_utctm.c file */
+        tm.tm_year = g2(t->data);
+        if (tm.tm_year < 50) {
+            tm.tm_year += 100;
+        }
+        tm.tm_mon = g2(t->data + 2) - 1;
+        tm.tm_mday = g2(t->data + 4);
+        tm.tm_hour = g2(t->data + 6);
+        tm.tm_min = g2(t->data + 8);
+        tm.tm_sec = g2(t->data + 10);
+        if (t->data[12] == 'Z') {
+            offset = 0;
+        } else {
+            Assert(t->length > 16);
+
+            offset = g2(t->data + 13) * 60 + g2(t->data + 15);
+            if (t->data[12] == '-') {
+                offset = -offset;
+            }
+        }
+        tm.tm_isdst = -1;
+    } else {
+        Assert(t->length > 14);
+
+        tm.tm_year = g2(t->data) * 100 + g2(t->data + 2);
+        tm.tm_mon = g2(t->data + 4) - 1;
+        tm.tm_mday = g2(t->data + 6);
+        tm.tm_hour = g2(t->data + 8);
+        tm.tm_min = g2(t->data + 10);
+        tm.tm_sec = g2(t->data + 12);
+        if (t->data[14] == 'Z') {
+            offset = 0;
+        } else {
+            Assert(t->length > 18);
+
+            offset = g2(t->data + 15) * 60 + g2(t->data + 17);
+            if (t->data[14] == '-') {
+                offset = -offset;
+            }
+        }
+        tm.tm_isdst = -1;
+    }
+#undef g2
+    (*res) = timegm(&tm) - offset * 60;
+    return 0;
+}
+
+int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm, time_t *res)
+{
+    /*
+     * This code is based on following assumption:
+     * from openssl/a_gentm.c:
+     * GENERALIZEDTIME is similar to UTCTIME except the year is
+     * represented as YYYY. This stuff treats everything as a two digit
+     * field so make first two fields 00 to 99
+     */
+    const int DATE_BUFFER_LENGTH = 15; // YYYYMMDDHHMMSSZ
+
+    if (NULL == res || NULL == tm) {
+        LogError("NULL pointer");
+        return -1;
+    }
+
+    if (DATE_BUFFER_LENGTH != tm->length || NULL == tm->data) {
+        LogError("Invalid ASN1_GENERALIZEDTIME");
+        return -1;
+    }
+
+    struct tm time_s;
+    if (sscanf ((char*)tm->data,
+                "%4d%2d%2d%2d%2d%2d",
+                &time_s.tm_year,
+                &time_s.tm_mon,
+                &time_s.tm_mday,
+                &time_s.tm_hour,
+                &time_s.tm_min,
+                &time_s.tm_sec) < 6)
+    {
+        LogError("Could not extract time data from ASN1_GENERALIZEDTIME");
+        return -1;
+    }
+
+    time_s.tm_year -= 1900;
+    time_s.tm_mon -= 1;
+    time_s.tm_isdst = 0;   // UTC
+    time_s.tm_gmtoff = 0;  // UTC
+    time_s.tm_zone = NULL; // UTC
+
+    *res = mktime(&time_s);
+
+    return 0;
+}
+
+} // namespace ValidationCore
+
diff --git a/vcore/src/vcore/TimeConversion.h b/vcore/src/vcore/TimeConversion.h
new file mode 100644 (file)
index 0000000..6b50503
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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        TimeConversion.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+#ifndef _VALIDATION_CORE_TIMECONVERSION_H_
+#define _VALIDATION_CORE_TIMECONVERSION_H_
+
+#include <ctime>
+
+#include <openssl/x509.h>
+
+namespace ValidationCore {
+// from OpenSSL asn1/a_utctm.c code
+int asn1TimeToTimeT(ASN1_TIME *t, time_t *res);
+
+int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm,
+                               time_t *res);
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_TIMECONVERSION_H_
+
diff --git a/vcore/src/vcore/VCore.cpp b/vcore/src/vcore/VCore.cpp
new file mode 100644 (file)
index 0000000..a3bbfee
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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        VCore.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @brief
+ */
+
+#include <vcore/VCorePrivate.h>
+#include <vcore/Config.h>
+#include <vcore/Database.h>
+#include <openssl/ssl.h>
+#include <database_checksum_vcore.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+
+namespace {
+DPL::DB::ThreadDatabaseSupport *threadInterface = NULL;
+} // namespace anonymous
+
+namespace ValidationCore {
+
+void AttachToThreadRO(void)
+{
+    Assert(threadInterface);
+    static bool check = true;
+    threadInterface->AttachToThread(
+        DPL::DB::SqlConnection::Flag::RO);
+    // We can have race condition here but CheckTableExist
+    // is thread safe and nothing bad will happend.
+    if (check) {
+        check = false;
+        Assert(ThreadInterface().CheckTableExist(DB_CHECKSUM_STR) &&
+               "Not a valid vcore database version");
+    }
+}
+
+void AttachToThreadRW(void)
+{
+    Assert(threadInterface);
+    static bool check = true;
+    threadInterface->AttachToThread(
+        DPL::DB::SqlConnection::Flag::RW);
+    // We can have race condition here but CheckTableExist
+    // is thread safe and nothing bad will happend.
+    if (check) {
+        check = false;
+        Assert(ThreadInterface().CheckTableExist(DB_CHECKSUM_STR) &&
+               "Not a valid vcore database version");
+    }
+}
+
+void DetachFromThread(void){
+    Assert(threadInterface);
+    threadInterface->DetachFromThread();
+}
+
+DPL::DB::ThreadDatabaseSupport& ThreadInterface(void) {
+    Assert(threadInterface);
+    return *threadInterface;
+}
+
+bool VCoreInit(const std::string& configFilePath,
+               const std::string& configSchemaPath,
+               const std::string& databasePath)
+{
+    if(threadInterface) {
+        LogDebug("Already Initialized");
+        return false;
+    }
+
+    threadInterface = new DPL::DB::ThreadDatabaseSupport(
+        databasePath.c_str(),
+        DPL::DB::SqlConnection::Flag::UseLucene);
+
+    SSL_library_init();
+//    g_thread_init(NULL);
+    g_type_init();
+
+    LogDebug("Initializing VCore");
+    Config &globalConfig = ConfigSingleton::Instance();
+    bool returnValue = globalConfig.setXMLConfigPath(configFilePath) &&
+        globalConfig.setXMLSchemaPath(configSchemaPath);
+
+    return returnValue;
+}
+
+void VCoreDeinit()
+{
+    Assert(threadInterface && "Not initialized or already deinitialized");
+    delete threadInterface;
+    threadInterface = NULL;
+}
+
+} // namespace ValidationCore
+
diff --git a/vcore/src/vcore/VCore.h b/vcore/src/vcore/VCore.h
new file mode 100644 (file)
index 0000000..d293563
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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        VCore.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef _VCORE_SRC_VCORE_VCORE_H_
+#define _VCORE_SRC_VCORE_VCORE_H_
+
+#include <string>
+
+namespace ValidationCore {
+/*
+ * configFilePath - path to XML config file with certificates configuration
+ *
+ * configSchemaPath - XMLschema of config file
+ *
+ * databasePath - path to database with OCSP/CRL cache.
+ *
+ * This function could be run only once. If you call it twice it will
+ * return false and non data will be set.
+ *
+ * This function must be call before AttachToThread function.
+ */
+bool VCoreInit(const std::string& configFilePath,
+               const std::string& configSchemaPath,
+               const std::string& databasePath);
+
+/*
+ * This function will free internal structures responsible for db connection.
+ */
+void VCoreDeinit(void);
+
+/*
+ * All thread with are using OCSP/CRL must call AttachToThread function before
+ * it can call OCSP/CRL. More than one thread could be Attach with OCPS/CRL.
+ *
+ * You mast attach thread to OCSP/CRL because OCSP/CRL is using database
+ * CertificateCachedDAO. For each thread that will be using this database
+ * vcore  must create internal structure (with connection info).
+ *
+ */
+void AttachToThreadRO(void);
+void AttachToThreadRW(void);
+void DetachFromThread(void);
+
+} // namespace ValidationCore
+
+#endif // _VCORE_SRC_VCORE_VCORE_H_
+
diff --git a/vcore/src/vcore/VCorePrivate.h b/vcore/src/vcore/VCorePrivate.h
new file mode 100644 (file)
index 0000000..ed85958
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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        VCore.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef _VCORE_SRC_VCORE_VCOREPRIVATE_H_
+#define _VCORE_SRC_VCORE_VCOREPRIVATE_H_
+
+#include <string>
+#include <VCore.h>
+#include <database_checksum_vcore.h>
+#include <dpl/db/thread_database_support.h>
+
+namespace ValidationCore {
+DPL::DB::ThreadDatabaseSupport& ThreadInterface(void);
+} // namespace ValidationCore
+
+#endif // _VCORE_SRC_VCORE_VCORE_H_
+
diff --git a/vcore/src/vcore/ValidatorCommon.h b/vcore/src/vcore/ValidatorCommon.h
new file mode 100644 (file)
index 0000000..05f2b7c
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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        ValidatorCommon.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This file contais definictions of common types used in ValidationCore.
+ */
+#ifndef _VALIDATORCOMMON_H_
+#define _VALIDATORCOMMON_H_
+
+#include <list>
+#include <set>
+#include <string>
+
+namespace ValidationCore {
+
+/*
+ * base deleter func
+ */
+template <typename T>
+struct ValidatorCoreUniversalFree {};
+
+// Template Specialization
+#define VC_DECLARE_DELETER(type, function)           \
+    template <> \
+    struct ValidatorCoreUniversalFree <type> {           \
+        void universal_free(type *ptr){                  \
+            if (ptr) {                                      \
+                function(ptr); }                           \
+        }                                                \
+    };
+
+template <typename T>
+class AutoPtr
+{
+  public:
+    AutoPtr(T *ptr) :
+        m_data(ptr)
+    {
+    }
+
+    AutoPtr(const AutoPtr<T> &second)
+    {
+        m_data = second.m_data;
+        second.m_data = 0;
+    }
+
+    AutoPtr & operator=(const AutoPtr &second)
+    {
+        if (this != &second) {
+            ValidatorCoreUniversalFree<T> deleter;
+            deleter.universal_free(m_data);
+            m_data = second.m_data;
+            second.m_data = 0;
+        }
+        return *this;
+    }
+
+    /**
+     * overloaded -> operator, so smart ptr could act as ordinary ptr
+     */
+    T* operator->()
+    {
+        return m_data;
+    }
+
+    ~AutoPtr()
+    {
+        ValidatorCoreUniversalFree<T> deleter;
+        deleter.universal_free(m_data);
+    }
+
+    /**
+     * get internal pointer
+     */
+    T* get(void)
+    {
+        return m_data;
+    }
+
+  private:
+    mutable T *m_data;
+};
+} // namespace ValidationCore
+
+#endif // _VALIDATORCOMMON_H_
diff --git a/vcore/src/vcore/ValidatorFactories.cpp b/vcore/src/vcore/ValidatorFactories.cpp
new file mode 100644 (file)
index 0000000..c068df7
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include <vcore/ValidatorFactories.h>
+
+#include <string>
+#include <dpl/log/log.h>
+
+#include <vcore/Certificate.h>
+#include <vcore/CertificateConfigReader.h>
+#include <vcore/Config.h>
+
+namespace ValidationCore {
+
+const CertificateIdentifier& createCertificateIdentifier()
+{
+    static CertificateIdentifier certificateIdentifier;
+    static bool initialized = false;
+    if (!initialized) {
+        CertificateConfigReader reader;
+        std::string file =
+            ConfigSingleton::Instance().getXMLConfigPath();
+        LogDebug("File with fingerprint list is: " << file);
+        std::string schema =
+            ConfigSingleton::Instance().getXMLSchemaPath();
+        LogDebug("File with fingerprint list schema is: " << schema);
+        reader.initialize(file, schema);
+        reader.read(certificateIdentifier);
+        initialized = true;
+    }
+    return certificateIdentifier;
+}
+
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/ValidatorFactories.h b/vcore/src/vcore/ValidatorFactories.h
new file mode 100644 (file)
index 0000000..075eef1
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_VALIDATORFACTORY_H_
+#define _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_VALIDATORFACTORY_H_
+
+#include <CertificateIdentifier.h>
+
+namespace ValidationCore {
+// First use of CertificateIdentificator should initialized it.
+// We do not want to create cyclic dependencies between
+// CertificateConfigReader and CertificateIdentificator so
+// we are using factory method to create CertificateIdentificator.
+
+const CertificateIdentifier& createCertificateIdentifier();
+} // namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_VALIDATORFACTORY_H_
diff --git a/vcore/src/vcore/VerificationStatus.cpp b/vcore/src/vcore/VerificationStatus.cpp
new file mode 100644 (file)
index 0000000..8007c0c
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.2
+ * @file        VerficationStatus.cpp
+ * @brief       OCSP/CRL status.
+ */
+#include <vcore/VerificationStatus.h>
+
+namespace ValidationCore {
+
+VerificationStatusSet::VerificationStatusSet()
+    : m_verdictMap(0)
+{}
+
+void VerificationStatusSet::add(VerificationStatus status) {
+    m_verdictMap |= status;
+}
+
+bool VerificationStatusSet::contains(VerificationStatus status) const {
+    return m_verdictMap & status;
+}
+
+bool VerificationStatusSet::isEmpty() const {
+    return 0 == m_verdictMap;
+}
+
+void VerificationStatusSet::operator+=(const VerificationStatusSet &second) {
+    m_verdictMap |= second.m_verdictMap;
+}
+
+void VerificationStatusSet::reset() {
+    m_verdictMap = 0;
+}
+
+VerificationStatus VerificationStatusSet::convertToStatus() const
+{
+    if (m_verdictMap & VERIFICATION_STATUS_REVOKED) {
+        return VERIFICATION_STATUS_REVOKED;
+    }
+
+    if (m_verdictMap & VERIFICATION_STATUS_VERIFICATION_ERROR) {
+        return VERIFICATION_STATUS_VERIFICATION_ERROR;
+    }
+
+    if (m_verdictMap & VERIFICATION_STATUS_ERROR) {
+        return VERIFICATION_STATUS_ERROR;
+    }
+
+    if (m_verdictMap & VERIFICATION_STATUS_UNKNOWN) {
+        return VERIFICATION_STATUS_UNKNOWN;
+    }
+
+    if (m_verdictMap & VERIFICATION_STATUS_CONNECTION_FAILED) {
+        return VERIFICATION_STATUS_CONNECTION_FAILED;
+    }
+
+    if (m_verdictMap & VERIFICATION_STATUS_NOT_SUPPORT) {
+        return VERIFICATION_STATUS_NOT_SUPPORT;
+    }
+
+    if (m_verdictMap & VERIFICATION_STATUS_GOOD) {
+        return VERIFICATION_STATUS_GOOD;
+    }
+
+    return VERIFICATION_STATUS_ERROR;
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/VerificationStatus.h b/vcore/src/vcore/VerificationStatus.h
new file mode 100644 (file)
index 0000000..c43981c
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+/*!
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     0.2
+ * @file        VerificationStatus.h
+ * @brief       OCSP/CRL status.
+ */
+#ifndef _VALIDATION_CORE_VERIFICATION_STATUS_H_
+#define _VALIDATION_CORE_VERIFICATION_STATUS_H_
+
+namespace ValidationCore {
+enum VerificationStatus
+{
+    //! The certificate has not been revoked.
+    /*! Connection to OCSP responder was successful and the certificate
+     *  has not been revoked.
+     */
+    VERIFICATION_STATUS_GOOD = 1,
+
+    //! The certificate has been revoked.
+    /*! Connection to OCSP responder was successful and the certificate
+     *  has been revoked.
+     *  RFC2560: "The "revoked" state indicates that the certificate has
+     *  been revoked (either permanantly or temporarily
+     *  (on hold))."
+     */
+    VERIFICATION_STATUS_REVOKED = 1 << 1,
+
+    //! The certificate status is unknown.
+    /*! Connection to OCSP responder was successful and the certificate
+     *  has unknown status.
+     *
+     *  RFC2560: "The "unknown" state indicates that the responder
+     *  doesn't know about the certificate being requested."
+     */
+    VERIFICATION_STATUS_UNKNOWN = 1 << 2,
+
+    //! The certificate status was not figure out.
+    /*! The response from ocsp/crl server contains broken signature. */
+    VERIFICATION_STATUS_VERIFICATION_ERROR = 1 << 3,
+
+    //! The certificate status was not figure out.
+    /*! The certificate does not contain ocsp/crl extension. */
+    VERIFICATION_STATUS_NOT_SUPPORT = 1 << 4,
+
+    //! The certificate status was not figure out.
+    /*! The CertMgr could not connect to OCSP responder. */
+    VERIFICATION_STATUS_CONNECTION_FAILED = 1 << 5,
+
+    //! The certificate status is unknown due to internal error inside OCSP
+    VERIFICATION_STATUS_ERROR = 1 << 6
+};
+
+class VerificationStatusSet
+{
+  public:
+    VerificationStatusSet();
+
+    void add(VerificationStatus status);
+
+    bool contains(VerificationStatus status) const;
+
+    bool isEmpty() const;
+
+    void operator+=(const VerificationStatusSet &second);
+
+    void reset();
+
+    VerificationStatus convertToStatus() const;
+
+  private:
+    unsigned int m_verdictMap;
+};
+
+/* TODO this status should be defined in wrt-engine sources */
+enum WidgetVerificationStatus
+{
+    // All certificate has been veficated and all certificates are good.
+    // Widget is able to be installed.
+    WIDGET_VERIFICATION_STATUS_GOOD,
+    // Some certificate has been revoked. Widget is not able to be installed.
+    WIDGET_VERIFICATION_STATUS_REVOKED,
+};
+
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_VERIFICATION_STATUS_H_
diff --git a/vcore/src/vcore/WacOrigin.cpp b/vcore/src/vcore/WacOrigin.cpp
new file mode 100644 (file)
index 0000000..7ca0174
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * 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
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include "WacOrigin.h"
+
+#include <algorithm>
+#include <ctype.h>
+#include <idna.h>
+
+#include <<dpl/log/log.h>>
+
+#include <iri.h>
+#include "ValidatorCommon.h"
+
+namespace {
+const std::string SCHEME_HTTP = "http";
+const std::string SCHEME_HTTPS = "https";
+const int PORT_HTTP = 80;
+const int PORT_HTTPS = 443;
+}
+
+namespace ValidationCore {
+VC_DECLARE_DELETER(iri_struct, iri_destroy)
+
+WacOrigin::WacOrigin(const std::string &url) :
+    m_port(0),
+    m_parseFailed(false)
+{
+    parse(url.c_str());
+}
+
+WacOrigin::WacOrigin(const char *url) :
+    m_port(0),
+    m_parseFailed(false)
+{
+    parse(url);
+}
+
+bool WacOrigin::operator==(const WacOrigin &second) const
+{
+    if (m_parseFailed || second.m_parseFailed) {
+        return false;
+    }
+
+    return (m_scheme == second.m_scheme) &&
+           (m_host == second.m_host) &&
+           (m_port == second.m_port);
+}
+
+void WacOrigin::parse(const char *url)
+{
+    // Step are taken from algorihtm:
+    // http://www.w3.org/TR/html5/origin-0.html#origin-0
+
+    // Step 1
+    // Step 2
+    AutoPtr<iri_struct> iri(iri_parse(url));
+    if (!iri.get()) {
+        m_parseFailed = true;
+        return;
+    }
+
+    if (iri->scheme) {
+        m_scheme = iri->scheme;
+    } else {
+        m_parseFailed = true;
+        return;
+    }
+
+    // Step 3 - Skip this point.
+    // WAC 2.0 PRV - we are suport only "http" and "https" schemas.
+
+    // Step 4 - Todo
+
+    // Step 5
+    std::transform(m_scheme.begin(), m_scheme.end(), m_scheme.begin(), tolower);
+
+    // Step 6 - we only support "http" and "https" schemas
+    if ((m_scheme != SCHEME_HTTP) && (m_scheme != SCHEME_HTTPS)) {
+        m_parseFailed = true;
+        return;
+    }
+
+    // Step 7 - Skip. We do not support "file" schema.
+
+    // Step 8
+    if (iri->host) {
+        m_host = iri->host;
+    } else {
+        m_parseFailed = true;
+        return;
+    }
+
+    // Step 9
+    char *output = NULL;
+    if (IDNA_SUCCESS !=
+        idna_to_ascii_lz(m_host.c_str(), &output, IDNA_USE_STD3_ASCII_RULES)) {
+        LogError("libidn error");
+        m_parseFailed = true;
+        free(output);
+        return;
+    }
+    m_host = output;
+    free(output);
+
+    // Step 10
+    std::transform(m_host.begin(), m_host.end(), m_host.begin(), ::tolower);
+
+    // Step 11
+    if (iri->port) {
+        m_port = iri->port;
+    } else {
+        setPort();
+    }
+
+    // Step 12 - Skip it. We do not return anything.
+    // User should create geters if he need access to schema/host/port.
+}
+
+void WacOrigin::setPort()
+{
+    if (SCHEME_HTTP == m_scheme) {
+        m_port = PORT_HTTP;
+        return;
+    } else if (SCHEME_HTTPS == m_scheme) {
+        m_port = PORT_HTTPS;
+        return;
+    } else {
+        LogDebug("Scheme " << m_scheme << " is not support by WAC2.0");
+        m_parseFailed = true;
+    }
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/WacOrigin.h b/vcore/src/vcore/WacOrigin.h
new file mode 100644 (file)
index 0000000..d706fe3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       This is stub for HTML5Origin implementation.
+ *              This implementation is compatible with WAC 2.0 PRV requirements
+ *              and is _not_ full compatible with ORIGIN algorithm requirements
+ *              defined in http://www.w3.org/TR/html5/origin-0.html#origin-0
+ */
+#ifndef _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_HTML5ORIGIN_H_
+#define _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_HTML5ORIGIN_H_
+
+#include <string>
+
+namespace ValidationCore {
+class WacOrigin
+{
+  public:
+
+    WacOrigin(const std::string &url);
+    WacOrigin(const char *url);
+
+    bool operator!=(const WacOrigin &second) const
+    {
+        return !(operator==(second));
+    }
+
+    bool operator==(const WacOrigin &second) const;
+
+  private:
+    void parse(const char *url);
+    void setPort();
+
+    std::string m_scheme;
+    std::string m_host;
+    int m_port;
+    bool m_parseFailed; // if parsing failed we should return unique identifier
+};
+} //namespace ValidationCore
+
+#endif // _WRT_ENGINE_SRC_INSTALLER_CORE_VALIDATION_CORE_HTML5ORIGIN_H_
diff --git a/vcore/src/vcore/WrtSignatureValidator.cpp b/vcore/src/vcore/WrtSignatureValidator.cpp
new file mode 100644 (file)
index 0000000..7138e8a
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * 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        WrtSignatureValidator.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementatin of tizen signature validation protocol.
+ */
+#include <vcore/WrtSignatureValidator.h>
+
+#include <dpl/log/log.h>
+
+#include <vcore/CertificateVerifier.h>
+#include <vcore/Certificate.h>
+#include <vcore/OCSPCertMgrUtil.h>
+#include <vcore/ReferenceValidator.h>
+#include <vcore/ValidatorFactories.h>
+#include <vcore/XmlsecAdapter.h>
+
+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 WrtSignatureValidator::Impl {
+public:
+    virtual WrtSignatureValidator::Result check(
+        SignatureData &data,
+        const std::string &widgetContentPath) = 0;
+
+    explicit Impl(bool ocspEnable,
+                  bool crlEnable,
+                  bool complianceMode)
+      : m_ocspEnable(ocspEnable)
+      , m_crlEnable(crlEnable)
+      , m_complianceModeEnabled(complianceMode)
+    {}
+
+    virtual ~Impl(){}
+
+    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 ImplTizen : public WrtSignatureValidator::Impl
+{
+  public:
+    WrtSignatureValidator::Result check(SignatureData &data,
+            const std::string &widgetContentPath);
+
+    explicit ImplTizen(bool ocspEnable,
+                       bool crlEnable,
+                       bool complianceMode)
+      : Impl(ocspEnable, crlEnable, complianceMode)
+    {}
+
+    virtual ~ImplTizen() {}
+};
+
+WrtSignatureValidator::Result ImplTizen::check(
+        SignatureData &data,
+        const std::string &widgetContentPath)
+{
+    bool disregard = false;
+
+    if (!checkRoleURI(data)) {
+        return WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    if (!checkProfileURI(data)) {
+        return WrtSignatureValidator::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 WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    // Check for error
+    if (collection.empty()) {
+        LogWarning("Certificate list in signature is empty.");
+        return WrtSignatureValidator::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));
+
+    // 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 WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    data.setReference(context.referenceSet);
+
+    if (!checkObjectReferences(data)) {
+        return WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    ReferenceValidator fileValidator(widgetContentPath);
+    if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
+        LogWarning("Invalid package - file references broken");
+        return WrtSignatureValidator::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 WrtSignatureValidator::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 WrtSignatureValidator::SIGNATURE_REVOKED;
+        }
+
+        if (result == VERIFICATION_STATUS_UNKNOWN ||
+            result == VERIFICATION_STATUS_ERROR)
+        {
+            disregard = true;
+        }
+    }
+
+    if (disregard) {
+        LogWarning("Signature is disregard.");
+        return WrtSignatureValidator::SIGNATURE_DISREGARD;
+    }
+    return WrtSignatureValidator::SIGNATURE_VERIFIED;
+}
+
+class ImplWac : public WrtSignatureValidator::Impl
+{
+  public:
+    WrtSignatureValidator::Result check(SignatureData &data,
+            const std::string &widgetContentPath);
+
+    explicit ImplWac(bool ocspEnable,
+                     bool crlEnable,
+                     bool complianceMode)
+      : Impl(ocspEnable, crlEnable, complianceMode)
+    {}
+
+    virtual ~ImplWac() {}
+};
+
+WrtSignatureValidator::Result ImplWac::check(
+    SignatureData &data,
+    const std::string &widgetContentPath)
+{
+    bool disregard = false;
+
+    if (!checkRoleURI(data)) {
+        return WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    if (!checkProfileURI(data)) {
+        return WrtSignatureValidator::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 WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    // Check for error
+    if (collection.empty()) {
+        LogWarning("Certificate list in signature is empty.");
+        return WrtSignatureValidator::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));
+
+    // 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 WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    data.setReference(context.referenceSet);
+
+    if (!checkObjectReferences(data)) {
+        return WrtSignatureValidator::SIGNATURE_INVALID;
+    }
+
+    ReferenceValidator fileValidator(widgetContentPath);
+    if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
+        LogWarning("Invalid package - file references broken");
+        return WrtSignatureValidator::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 WrtSignatureValidator::SIGNATURE_INVALID;
+        }
+
+        CertificateVerifier verificator(m_ocspEnable, m_crlEnable);
+        VerificationStatus result = verificator.check(coll);
+
+        if (result == VERIFICATION_STATUS_REVOKED) {
+            return WrtSignatureValidator::SIGNATURE_REVOKED;
+        }
+
+        if (result == VERIFICATION_STATUS_UNKNOWN ||
+            result == VERIFICATION_STATUS_ERROR)
+        {
+            disregard = true;
+        }
+    }
+
+    if (disregard) {
+        LogWarning("Signature is disregard.");
+        return WrtSignatureValidator::SIGNATURE_DISREGARD;
+    }
+    return WrtSignatureValidator::SIGNATURE_VERIFIED;
+}
+
+// Implementation of WrtSignatureValidator
+
+WrtSignatureValidator::WrtSignatureValidator(
+    AppType appType,
+    bool ocspEnable,
+    bool crlEnable,
+    bool complianceMode)
+  : m_impl(0)
+{
+    if (appType == TIZEN)
+        m_impl = new ImplTizen(ocspEnable,crlEnable,complianceMode);
+    else
+        m_impl = new ImplWac(ocspEnable,crlEnable,complianceMode);
+}
+
+WrtSignatureValidator::~WrtSignatureValidator() {
+    delete m_impl;
+}
+
+WrtSignatureValidator::Result WrtSignatureValidator::check(
+    SignatureData &data,
+    const std::string &widgetContentPath)
+{
+    return m_impl->check(data, widgetContentPath);
+}
+
+} // namespace ValidationCore
+
diff --git a/vcore/src/vcore/WrtSignatureValidator.h b/vcore/src/vcore/WrtSignatureValidator.h
new file mode 100644 (file)
index 0000000..5ff8752
--- /dev/null
@@ -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        WrtSignatureValidator.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementatin of tizen signature validation protocol.
+ */
+#ifndef _VALIDATION_CORE_TIZENSIGNATUREVALIDATOR_H_
+#define _VALIDATION_CORE_TIZENSIGNATUREVALIDATOR_H_
+
+#include <string>
+
+#include <dpl/noncopyable.h>
+
+#include <vcore/SignatureData.h>
+
+namespace ValidationCore {
+
+class WrtSignatureValidator : public DPL::Noncopyable {
+public:
+    class Impl;
+
+    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 WrtSignatureValidator(
+        AppType appType,
+        bool ocspEnable,
+        bool crlEnable,
+        bool complianceMode);
+
+    virtual ~WrtSignatureValidator();
+
+    Result check(
+        SignatureData &data,
+        const std::string &widgetContentPath);
+
+private:
+    Impl *m_impl;
+};
+
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_TIZENSIGNATUREVALIDATOR_H_
+
diff --git a/vcore/src/vcore/XmlsecAdapter.cpp b/vcore/src/vcore/XmlsecAdapter.cpp
new file mode 100644 (file)
index 0000000..6bc978e
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * 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        XmlsecAdapter.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include <cstdlib>
+#include <cstring>
+
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+
+#ifndef XMLSEC_NO_XSLT
+#include <libxslt/xslt.h>
+#endif /*   XMLSEC_NO_XSLT */
+
+#include <xmlsec/xmlsec.h>
+#include <xmlsec/xmltree.h>
+#include <xmlsec/xmldsig.h>
+#include <xmlsec/crypto.h>
+#include <xmlsec/io.h>
+#include <xmlsec/keyinfo.h>
+
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+
+#include <vcore/XmlsecAdapter.h>
+
+#include <vcore/ValidatorCommon.h>
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(ValidationCore::XmlSec)
+
+namespace {
+
+struct FileWrapper {
+    FileWrapper(void *argFile, bool argReleased)
+      : file(argFile)
+      , released(argReleased)
+    {}
+    void *file;
+    bool released;
+};
+
+} // anonymous namespace
+
+namespace ValidationCore {
+VC_DECLARE_DELETER(xmlSecKeysMngr, xmlSecKeysMngrDestroy)
+
+static const char* DIGEST_MD5 = "md5";
+
+std::string XmlSec::s_prefixPath;
+
+int XmlSec::fileMatchCallback(const char *filename)
+{
+    std::string path = s_prefixPath + filename;
+    return xmlFileMatch(path.c_str());
+}
+
+void* XmlSec::fileOpenCallback(const char *filename)
+{
+    std::string path = s_prefixPath + filename;
+    LogDebug("Xmlsec opening: " << path);
+    return new FileWrapper(xmlFileOpen(path.c_str()),false);
+}
+
+int XmlSec::fileReadCallback(void *context,
+        char *buffer,
+        int len)
+{
+    FileWrapper *fw = static_cast<FileWrapper*>(context);
+    if (fw->released) {
+        return 0;
+    }
+    int output = xmlFileRead(fw->file, buffer, len);
+    if (output == 0) {
+        fw->released = true;
+        xmlFileClose(fw->file);
+    }
+    return output;
+}
+
+int XmlSec::fileCloseCallback(void *context)
+{
+    FileWrapper *fw = static_cast<FileWrapper*>(context);
+    int output = 0;
+    if (!(fw->released)) {
+        output = xmlFileClose(fw->file);
+    }
+    delete fw;
+    return output;
+}
+
+void XmlSec::fileExtractPrefix(XmlSecContext *context)
+{
+    if (!(context->workingDirectory.empty())) {
+        s_prefixPath = context->workingDirectory;
+        return;
+    }
+
+    s_prefixPath = context->signatureFile;
+    size_t pos = s_prefixPath.rfind('/');
+    if (pos == std::string::npos) {
+        s_prefixPath.clear();
+    } else {
+        s_prefixPath.erase(pos + 1, std::string::npos);
+    }
+}
+
+XmlSec::XmlSec() :
+    m_initialized(false)
+{
+    LIBXML_TEST_VERSION
+        xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+    xmlSubstituteEntitiesDefault(1);
+#ifndef XMLSEC_NO_XSLT
+    xmlIndentTreeOutput = 1;
+#endif
+
+    if (xmlSecInit() < 0) {
+        LogError("Xmlsec initialization failed.");
+        ThrowMsg(Exception::InternalError, "Xmlsec initialization failed.");
+    }
+
+    if (xmlSecCheckVersion() != 1) {
+        xmlSecShutdown();
+        LogError("Loaded xmlsec library version is not compatible.");
+        ThrowMsg(Exception::InternalError,
+                 "Loaded xmlsec library version is not compatible.");
+    }
+
+#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
+    if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
+        xmlSecShutdown();
+        LogError(
+            "Error: unable to load default xmlsec-crypto library. Make sure "
+            "that you have it installed and check shared libraries path "
+            "(LD_LIBRARY_PATH) envornment variable.");
+        ThrowMsg(Exception::InternalError,
+                 "Unable to load default xmlsec-crypto library.");
+    }
+#endif
+
+    if (xmlSecCryptoAppInit(NULL) < 0) {
+        xmlSecShutdown();
+        LogError("Crypto initialization failed.");
+        ThrowMsg(Exception::InternalError, "Crypto initialization failed.");
+    }
+
+    if (xmlSecCryptoInit() < 0) {
+        xmlSecCryptoAppShutdown();
+        xmlSecShutdown();
+        LogError("Xmlsec-crypto initialization failed.");
+        ThrowMsg(Exception::InternalError,
+                 "Xmlsec-crypto initialization failed.");
+    }
+
+    m_initialized = true;
+}
+
+void XmlSec::deinitialize(void)
+{
+    Assert(m_initialized);
+
+    /*   Shutdown xmlsec-crypto library */
+    xmlSecCryptoShutdown();
+
+    /*   Shutdown crypto library */
+    xmlSecCryptoAppShutdown();
+
+    /*   Shutdown xmlsec library */
+    xmlSecShutdown();
+
+    /*   Shutdown libxslt/libxml */
+#ifndef XMLSEC_NO_XSLT
+    xsltCleanupGlobals();
+#endif /*   XMLSEC_NO_XSLT */
+
+    s_prefixPath.clear();
+    m_initialized = false;
+}
+
+XmlSec::~XmlSec()
+{
+    if (m_initialized) {
+        deinitialize();
+    }
+}
+
+XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
+        xmlSecKeysMngrPtr mngr)
+{
+    xmlDocPtr doc = NULL;
+    xmlNodePtr node = NULL;
+    xmlSecDSigCtxPtr dsigCtx = NULL;
+    int size, res = -1;
+
+    fileExtractPrefix(context);
+    LogDebug("Prefix path: " << s_prefixPath);
+
+    xmlSecIOCleanupCallbacks();
+
+    xmlSecIORegisterCallbacks(
+        fileMatchCallback,
+        fileOpenCallback,
+        fileReadCallback,
+        fileCloseCallback);
+
+    /*   load file */
+    doc = xmlParseFile(context->signatureFile.c_str());
+    if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)) {
+        LogWarning("Unable to parse file " << context->signatureFile);
+        goto done;
+    }
+
+    /*   find start node */
+    node = xmlSecFindNode(xmlDocGetRootElement(
+                              doc), xmlSecNodeSignature, xmlSecDSigNs);
+    if (node == NULL) {
+        LogWarning("Start node not found in " << context->signatureFile);
+        goto done;
+    }
+
+    /*   create signature context */
+    dsigCtx = xmlSecDSigCtxCreate(mngr);
+    if (dsigCtx == NULL) {
+        LogError("Failed to create signature context.");
+        goto done;
+    }
+
+    if (context->allowBrokenChain) {
+        dsigCtx->keyInfoReadCtx.flags |=
+            XMLSEC_KEYINFO_FLAGS_ALLOW_BROKEN_CHAIN;
+    }
+
+    if (context->validationTime) {
+        LogDebug("Setting validation time.");
+        dsigCtx->keyInfoReadCtx.certsVerificationTime = context->validationTime;
+    }
+
+    /*   Verify signature */
+    if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
+        LogWarning("Signature verify error.");
+        goto done;
+    }
+
+    if (dsigCtx->keyInfoReadCtx.flags2 &
+        XMLSEC_KEYINFO_ERROR_FLAGS_BROKEN_CHAIN) {
+        LogWarning("XMLSEC_KEYINFO_FLAGS_ALLOW_BROKEN_CHAIN was set to true!");
+        LogWarning("Signature contains broken chain!");
+        context->errorBrokenChain = true;
+    }
+
+    /*   print verification result to stdout */
+    if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
+        LogDebug("Signature is OK");
+        res = 0;
+    } else {
+        LogDebug("Signature is INVALID");
+        goto done;
+    }
+
+    if (dsigCtx->c14nMethod && dsigCtx->c14nMethod->id &&
+        dsigCtx->c14nMethod->id->name) {
+        LogInfo("Canonicalization method: " <<
+                reinterpret_cast<const char *>(dsigCtx->c14nMethod->id->name));
+    }
+
+    size = xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences));
+    for (int i = 0; i < size; ++i) {
+        xmlSecDSigReferenceCtxPtr dsigRefCtx =
+            (xmlSecDSigReferenceCtxPtr)xmlSecPtrListGetItem(&(dsigCtx->
+                                                                  signedInfoReferences),
+                                                            i);
+        if (dsigRefCtx && dsigRefCtx->uri) {
+            if (dsigRefCtx->digestMethod && dsigRefCtx->digestMethod->id &&
+                dsigRefCtx->digestMethod->id->name) {
+                const char* pDigest =
+                    reinterpret_cast<const char *>(dsigRefCtx->digestMethod->id
+                                                       ->name);
+                std::string strDigest(pDigest);
+                LogInfo("reference digest method: " <<
+                        reinterpret_cast<const char *>(dsigRefCtx->digestMethod
+                                                           ->id
+                                                           ->name));
+                if (strDigest == DIGEST_MD5) {
+                    LogWarning("MD5 digest method used! Please use sha");
+                    res = -1;
+                    break;
+                }
+            }
+            context->referenceSet.insert(std::string(reinterpret_cast<char *>(
+                                                         dsigRefCtx->uri)));
+        }
+    }
+
+done:
+    /*   cleanup */
+    if (dsigCtx != NULL) {
+        xmlSecDSigCtxDestroy(dsigCtx);
+    }
+
+    if (doc != NULL) {
+        xmlFreeDoc(doc);
+    }
+
+    if (res) {
+        return ERROR_INVALID_SIGNATURE;
+    }
+    return NO_ERROR;
+}
+
+void XmlSec::loadDERCertificateMemory(XmlSecContext *context,
+        xmlSecKeysMngrPtr mngr)
+{
+    unsigned char *derCertificate = NULL;
+    int size = i2d_X509(context->certificatePtr->getX509(), &derCertificate);
+
+    if (!derCertificate) {
+        LogError("Failed during x509 conversion to der format.");
+        ThrowMsg(Exception::InternalError,
+                 "Failed during x509 conversion to der format.");
+    }
+
+    if (xmlSecCryptoAppKeysMngrCertLoadMemory(mngr,
+                                              derCertificate,
+                                              size,
+                                              xmlSecKeyDataFormatDer,
+                                              xmlSecKeyDataTypeTrusted) < 0) {
+        OPENSSL_free(derCertificate);
+        LogError("Failed to load der certificate from memory.");
+        ThrowMsg(Exception::InternalError,
+                 "Failed to load der certificate from memory.");
+    }
+
+    OPENSSL_free(derCertificate);
+}
+
+void XmlSec::loadPEMCertificateFile(XmlSecContext *context,
+        xmlSecKeysMngrPtr mngr)
+{
+    if (xmlSecCryptoAppKeysMngrCertLoad(mngr,
+                                        context->certificatePath.c_str(),
+                                        xmlSecKeyDataFormatPem,
+                                        xmlSecKeyDataTypeTrusted) < 0) {
+        LogError("Failed to load PEM certificate from file.");
+        ThrowMsg(Exception::InternalError,
+                 "Failed to load PEM certificate from file.");
+    }
+}
+
+XmlSec::Result XmlSec::validate(XmlSecContext *context)
+{
+    Assert(context);
+    Assert(!(context->signatureFile.empty()));
+    Assert(context->certificatePtr.Get() || !(context->certificatePath.empty()));
+
+    if (!m_initialized) {
+        LogError("XmlSec is not initialized.");
+        ThrowMsg(Exception::InternalError, "XmlSec is not initialized");
+    }
+
+    AutoPtr<xmlSecKeysMngr> mngr(xmlSecKeysMngrCreate());
+
+    if (!mngr.get()) {
+        LogError("Failed to create keys manager.");
+        ThrowMsg(Exception::InternalError, "Failed to create keys manager.");
+    }
+
+    if (xmlSecCryptoAppDefaultKeysMngrInit(mngr.get()) < 0) {
+        LogError("Failed to initialize keys manager.");
+        ThrowMsg(Exception::InternalError, "Failed to initialize keys manager.");
+    }
+    context->referenceSet.clear();
+
+    if (context->certificatePtr.Get()) {
+        loadDERCertificateMemory(context, mngr.get());
+    }
+
+    if (!context->certificatePath.empty()) {
+        loadPEMCertificateFile(context, mngr.get());
+    }
+
+    return validateFile(context, mngr.get());
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/XmlsecAdapter.h b/vcore/src/vcore/XmlsecAdapter.h
new file mode 100644 (file)
index 0000000..4f36636
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * 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        XmlSecAdapter.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef _VALIDATION_CORE_XMLSECADAPTER_H_
+#define _VALIDATION_CORE_XMLSECADAPTER_H_
+
+#include <xmlsec/keysmngr.h>
+
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <dpl/singleton.h>
+
+#include <vcore/Certificate.h>
+#include <vcore/SignatureData.h>
+
+namespace ValidationCore {
+class XmlSec : public DPL::Noncopyable
+{
+  public:
+
+    struct XmlSecContext
+    {
+        /* You _must_ set one of the value: certificatePath or certificate. */
+        XmlSecContext() :
+            validationTime(0),
+            allowBrokenChain(false),
+            errorBrokenChain(false)
+        {
+        }
+
+        /*
+         * Absolute path to signature file.
+         */
+        std::string signatureFile;
+        /*
+         * Direcotory with signed data.
+         * If you leave it empty xmlsec will use directory extracted
+         * from signatureFile.
+         */
+        std::string workingDirectory;
+        /*
+         * Path to trusted certificate.
+         */
+        std::string certificatePath;
+        /*
+         * Trusted certificate. In most cases it should be Root CA certificate.
+         */
+        CertificatePtr certificatePtr;
+        /*
+         * Validation date.
+         * 0 - uses current time.
+         */
+        time_t validationTime;
+        /*
+         * Input parameter.
+         * If true, signature validation will not be interrupted by chain error.
+         * If true and chain is broken then the value errorBrokenChain will be
+         * set to true.
+         */
+        bool allowBrokenChain;
+        /*
+         * Output parameter.
+         * This will be set if chain is incomplete or broken.
+         */
+        bool errorBrokenChain;
+        /*
+         * Output parameter.
+         * Reference checked by xmlsec
+         */
+        ReferenceSet referenceSet;
+    };
+
+    enum Result
+    {
+        NO_ERROR,
+        ERROR_INVALID_SIGNATURE
+    };
+
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, InternalError)
+    };
+
+    /*
+     * Context - input/output param.
+     */
+    Result validate(XmlSecContext *context);
+  protected:
+    XmlSec();
+    ~XmlSec();
+  private:
+    void deinitialize(void);
+
+    void loadDERCertificateMemory(XmlSecContext *context,
+            xmlSecKeysMngrPtr mngr);
+    void loadPEMCertificateFile(XmlSecContext *context,
+            xmlSecKeysMngrPtr mngr);
+    Result validateFile(XmlSecContext *context,
+            xmlSecKeysMngrPtr mngr);
+
+    bool m_initialized;
+
+    static std::string s_prefixPath;
+    static int fileMatchCallback(const char *filename);
+    static void* fileOpenCallback(const char *filename);
+    static int fileReadCallback(void *context,
+            char *buffer,
+            int len);
+    static int fileCloseCallback(void *context);
+    static void fileExtractPrefix(XmlSecContext *context);
+};
+
+typedef DPL::Singleton<XmlSec> XmlSecSingleton;
+
+} // namespace ValidationCore
+
+#endif // _VALIDATION_CORE_XMLSECVERIFICATOR_H_
diff --git a/vcore/src/vcore/api.cpp b/vcore/src/vcore/api.cpp
new file mode 100644 (file)
index 0000000..a9843f4
--- /dev/null
@@ -0,0 +1,1583 @@
+/**
+ * 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        api.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @author      Jacek Migacz (j.migacz@samsung.com)
+ * @version     1.0
+ * @brief       This is part of C-api proposition for cert-svc.
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <algorithm>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <glib-object.h>
+
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+
+#include <dlog.h>
+
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+#include <cert-svc/cinstance.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc/cocsp.h>
+#include <cert-svc/cpkcs12.h>
+#include <cert-svc/ccrl.h>
+#include <cert-svc/cpkcs12.h>
+#include <cert-svc/cprimitives.h>
+
+#include <vcore/Base64.h>
+#include <vcore/Certificate.h>
+#include <vcore/CertificateCollection.h>
+#include <vcore/OCSP.h>
+#include <vcore/CRL.h>
+#include <vcore/CRLCacheInterface.h>
+#include <vcore/pkcs12.h>
+
+using namespace ValidationCore;
+
+namespace {
+
+typedef std::unique_ptr<CERT_CONTEXT, std::function<int(CERT_CONTEXT*)> > ScopedCertCtx;
+
+class CRLCacheCAPI : public CRLCacheInterface {
+public:
+    CRLCacheCAPI(
+        CertSvcCrlCacheWrite crlWrite,
+        CertSvcCrlCacheRead crlRead,
+        CertSvcCrlFree crlFree,
+        void *userParam)
+      : m_crlWrite(crlWrite)
+      , m_crlRead(crlRead)
+      , m_crlFree(crlFree)
+      , m_userParam(userParam)
+    {}
+
+    bool getCRLResponse(CRLCachedData *ptr){
+        if (!m_crlRead || !m_crlFree)
+            return false;
+
+        char *buffer;
+        int size;
+
+        bool result = m_crlRead(
+            ptr->distribution_point.c_str(),
+            &buffer,
+            &size,
+            &(ptr->next_update_time),
+            m_userParam);
+
+        if (result) {
+            ptr->crl_body.clear();
+            ptr->crl_body.append(buffer, size);
+            m_crlFree(buffer, m_userParam);
+        }
+
+        return result;
+    }
+    void setCRLResponse(CRLCachedData *ptr){
+        if (m_crlWrite) {
+            m_crlWrite(
+                ptr->distribution_point.c_str(),
+                ptr->crl_body.c_str(),
+                ptr->crl_body.size(),
+                ptr->next_update_time,
+                m_userParam);
+        }
+    }
+
+private:
+    CertSvcCrlCacheWrite m_crlWrite;
+    CertSvcCrlCacheRead m_crlRead;
+    CertSvcCrlFree m_crlFree;
+    void *m_userParam;
+};
+
+class CertSvcInstanceImpl {
+public:
+    CertSvcInstanceImpl()
+      : m_certificateCounter(0)
+      , m_idListCounter(0)
+      , m_stringListCounter(0)
+      , m_crlWrite(NULL)
+      , m_crlRead(NULL)
+      , m_crlFree(NULL)
+    {}
+
+    ~CertSvcInstanceImpl(){
+        FOREACH(it, m_allocatedStringSet) {
+            delete[] *it;
+        }
+    }
+
+    inline void reset(){
+        m_certificateCounter = 0;
+        m_certificateMap.clear();
+        m_idListCounter = 0;
+        m_idListMap.clear();
+        m_stringListCounter = 0;
+        m_stringListMap.clear();
+
+        FOREACH(it, m_allocatedStringSet) {
+            delete[] *it;
+        }
+
+        m_allocatedStringSet.clear();
+    }
+
+    inline int addCert(const CertificatePtr &cert) {
+        m_certificateMap[m_certificateCounter] = cert;
+        return m_certificateCounter++;
+    }
+
+    inline void removeCert(const CertSvcCertificate &cert) {
+        auto iter = m_certificateMap.find(cert.privateHandler);
+        if (iter != m_certificateMap.end()) {
+            m_certificateMap.erase(iter);
+        }
+    }
+
+    inline int getCertFromList(
+        const CertSvcCertificateList &handler,
+        int position,
+        CertSvcCertificate *certificate)
+    {
+        auto iter = m_idListMap.find(handler.privateHandler);
+        if (iter == m_idListMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        if (position >= static_cast<int>(iter->second.size())) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        certificate->privateInstance = handler.privateInstance;
+        certificate->privateHandler = (iter->second)[position];
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getCertListLen(const CertSvcCertificateList &handler, int *len) {
+        auto iter = m_idListMap.find(handler.privateHandler);
+        if (iter == m_idListMap.end() || !len) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        *len = (iter->second).size();
+        return CERTSVC_SUCCESS;
+    }
+
+    inline void removeCertList(const CertSvcCertificateList &handler) {
+        auto iter = m_idListMap.find(handler.privateHandler);
+        if (iter != m_idListMap.end())
+            m_idListMap.erase(iter);
+    }
+
+    inline int isSignedBy(const CertSvcCertificate &child,
+                          const CertSvcCertificate &parent,
+                          int *status)
+    {
+        auto citer = m_certificateMap.find(child.privateHandler);
+        if (citer == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        auto piter = m_certificateMap.find(parent.privateHandler);
+        if (piter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        if (citer->second->isSignedBy(piter->second)) {
+            *status = CERTSVC_TRUE;
+        } else {
+            *status = CERTSVC_FALSE;
+        }
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getField(const CertSvcCertificate &cert,
+                        CertSvcCertificateField field,
+                        CertSvcString *buffer)
+    {
+        auto iter = m_certificateMap.find(cert.privateHandler);
+        if (iter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        auto certPtr = iter->second;
+        DPL::OptionalString result;
+        switch(field) {
+            case CERTSVC_SUBJECT:
+                result = DPL::OptionalString(certPtr->getOneLine());
+                break;
+            case CERTSVC_ISSUER:
+                result = DPL::OptionalString(certPtr->getOneLine(Certificate::FIELD_ISSUER));
+                break;
+            case CERTSVC_SUBJECT_COMMON_NAME:
+                result = certPtr->getCommonName();
+                break;
+            case CERTSVC_SUBJECT_COUNTRY_NAME:
+                result = certPtr->getCountryName();
+                break;
+            case CERTSVC_SUBJECT_STATE_NAME:
+                result = certPtr->getStateOrProvinceName();
+                break;
+            case CERTSVC_SUBJECT_ORGANIZATION_NAME:
+                result = certPtr->getOrganizationName();
+                break;
+            case CERTSVC_SUBJECT_ORGANIZATION_UNIT_NAME:
+                result = certPtr->getOrganizationalUnitName();
+                break;
+            case CERTSVC_SUBJECT_EMAIL_ADDRESS:
+                result = certPtr->getEmailAddres();
+                break;
+            case CERTSVC_ISSUER_COMMON_NAME:
+                result = certPtr->getCommonName(Certificate::FIELD_ISSUER);
+                break;
+            case CERTSVC_ISSUER_STATE_NAME:
+                result = certPtr->getStateOrProvinceName(Certificate::FIELD_ISSUER);
+                break;
+            case CERTSVC_ISSUER_ORGANIZATION_NAME:
+                result = certPtr->getOrganizationName(Certificate::FIELD_ISSUER);
+                break;
+            case CERTSVC_ISSUER_ORGANIZATION_UNIT_NAME:
+                result = certPtr->getOrganizationalUnitName(Certificate::FIELD_ISSUER);
+                break;
+            case CERTSVC_VERSION:
+                {
+                    std::stringstream stream;
+                    stream << (certPtr->getVersion()+1);
+                    result = DPL::OptionalString(DPL::FromUTF8String(stream.str()));
+                    break;
+                }
+            case CERTSVC_SERIAL_NUMBER:
+                result = DPL::OptionalString(certPtr->getSerialNumberString());
+                break;
+            case CERTSVC_KEY_USAGE:
+                result = DPL::OptionalString(certPtr->getKeyUsageString());
+                break;
+            case CERTSVC_KEY:
+                result = DPL::OptionalString(certPtr->getPublicKeyString());
+                break;
+            case CERTSVC_SIGNATURE_ALGORITHM:
+                result = DPL::OptionalString(certPtr->getSignatureAlgorithmString());
+                break;
+            default:
+                break;
+        }
+
+        if (result.IsNull()) {
+            buffer->privateHandler = NULL;
+            buffer->privateLength = 0;
+            buffer->privateInstance = cert.privateInstance;
+            return CERTSVC_SUCCESS;
+        }
+        std::string output = DPL::ToUTF8String(*result);
+
+        char *cstring = new char[output.size()+1];
+        strncpy(cstring, output.c_str(), output.size()+1);
+
+        buffer->privateHandler = cstring;
+        buffer->privateLength = output.size();
+        buffer->privateInstance = cert.privateInstance;
+
+        m_allocatedStringSet.insert(cstring);
+
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getNotAfter(const CertSvcCertificate &cert,
+                           time_t *time)
+    {
+        auto iter = m_certificateMap.find(cert.privateHandler);
+        if (iter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        *time = iter->second->getNotAfter();
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getNotBefore(const CertSvcCertificate &cert,
+                            time_t *time)
+    {
+        auto iter = m_certificateMap.find(cert.privateHandler);
+        if (iter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        *time = iter->second->getNotBefore();
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int isRootCA(const CertSvcCertificate &cert, int *status){
+        auto iter = m_certificateMap.find(cert.privateHandler);
+        if (iter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        if (iter->second->isRootCert()) {
+            *status = CERTSVC_TRUE;
+        } else {
+            *status = CERTSVC_FALSE;
+        }
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getCrl(const CertSvcCertificate &cert, CertSvcStringList *handler){
+        auto iter = m_certificateMap.find(cert.privateHandler);
+        if (iter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        int position = m_stringListCounter++;
+
+        std::list<std::string> temp = iter->second->getCrlUris();
+        std::copy(temp.begin(),
+                  temp.end(),
+                  back_inserter(m_stringListMap[position]));
+
+        handler->privateHandler = position;
+        handler->privateInstance = cert.privateInstance;
+
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getStringFromList(
+        const CertSvcStringList &handler,
+        int position,
+        CertSvcString *buffer)
+    {
+        buffer->privateHandler = NULL;
+        buffer->privateLength = 0;
+
+        auto iter = m_stringListMap.find(handler.privateHandler);
+        if (iter == m_stringListMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        if (position >= (int)iter->second.size()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        const std::string &data = iter->second.at(position);
+        int size = data.size();
+        char *cstring = new char[size+1];
+        if (!cstring) {
+            return CERTSVC_FAIL;
+        }
+
+        strncpy(cstring, data.c_str(), data.size()+1);
+
+        buffer->privateHandler = cstring;
+        buffer->privateLength = data.size();
+        buffer->privateInstance = handler.privateInstance;
+
+        m_allocatedStringSet.insert(cstring);
+
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getStringListLen(
+        const CertSvcStringList &handler,
+        int *size)
+    {
+        auto iter = m_stringListMap.find(handler.privateHandler);
+        if (iter == m_stringListMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        *size = (int) iter->second.size();
+        return CERTSVC_SUCCESS;
+    }
+
+    inline void removeStringList(const CertSvcStringList &handler)
+    {
+        m_stringListMap.erase(m_stringListMap.find(handler.privateHandler));
+    }
+
+    inline void removeString(const CertSvcString &handler)
+    {
+        auto iter = m_allocatedStringSet.find(handler.privateHandler);
+        if (iter != m_allocatedStringSet.end()) {
+            delete[] *iter;
+            m_allocatedStringSet.erase(iter);
+        }
+    }
+
+    inline int certificateSearch(
+        CertSvcInstance instance,
+        CertSvcCertificateField field,
+        const char *value,
+        CertSvcCertificateList *handler)
+    {
+        int result;
+        search_field fieldId = SEARCH_FIELD_END;
+
+        switch(field){
+        case CERTSVC_SUBJECT:
+            fieldId = SUBJECT_STR;
+            break;
+        case CERTSVC_ISSUER:
+            fieldId = ISSUER_STR;
+            break;
+        case CERTSVC_SUBJECT_COMMON_NAME:
+            fieldId = SUBJECT_COMMONNAME;
+            break;
+        default:
+            LogError("Not implemented!");
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        ScopedCertCtx ctx(cert_svc_cert_context_init(),
+                          cert_svc_cert_context_final);
+
+        if (ctx.get() == NULL) {
+            LogWarning("Error in cert_svc_cert_context_init.");
+            return CERTSVC_FAIL;
+        }
+
+        LogDebug("Match string: " << value);
+        result = cert_svc_search_certificate(ctx.get(), fieldId, const_cast<char*>(value));
+        LogDebug("Search finished!");
+
+        if (CERT_SVC_ERR_NO_ERROR != result) {
+            LogWarning("Error during certificate search");
+            return CERTSVC_FAIL;
+        }
+
+        cert_svc_filename_list *fileList = ctx.get()->fileNames;
+
+        int listId = m_idListCounter++;
+        std::vector<int> &list = m_idListMap[listId];
+        handler->privateHandler = listId;
+        handler->privateInstance = instance;
+
+        for(;fileList != NULL; fileList = fileList->next) {
+            ScopedCertCtx ctx2(cert_svc_cert_context_init(),
+                               cert_svc_cert_context_final);
+            if (ctx2.get() == NULL) {
+                LogWarning("Error in cert_svc_cert_context_init.");
+                return CERTSVC_FAIL;
+            }
+
+            // TODO add read_certifcate_from_file function to Certificate.h
+            if (CERT_SVC_ERR_NO_ERROR !=
+                cert_svc_load_file_to_context(ctx2.get(), fileList->filename))
+            {
+                LogWarning("Error in cert_svc_load_file_to_context");
+                return CERTSVC_FAIL;
+            }
+            int certId = addCert(CertificatePtr(new Certificate(*(ctx2.get()->certBuf))));
+            list.push_back(certId);
+        }
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int sortCollection(CertSvcCertificate *certificate_array, int size) {
+        if (size < 2) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        for(int i=1; i<size; ++i) {
+            if (certificate_array[i-1].privateInstance.privatePtr
+                != certificate_array[i].privateInstance.privatePtr)
+            {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+        }
+
+        CertificateList certList;
+        std::map<Certificate*,int> translator;
+
+        for(int i=0; i<size; ++i) {
+            int pos = certificate_array[i].privateHandler;
+            auto cert = m_certificateMap.find(pos);
+            if (cert == m_certificateMap.end()) {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+            translator[cert->second.Get()] = pos;
+            certList.push_back(cert->second);
+        }
+
+        CertificateCollection collection;
+        collection.load(certList);
+
+        if (!collection.sort()) {
+            return CERTSVC_FAIL;
+        }
+
+        auto chain = collection.getChain();
+
+        int i=0;
+        for (auto iter = chain.begin(); iter != chain.end() && i<size; ++iter, ++i) {
+            certificate_array[i].privateHandler = translator[iter->Get()];
+        }
+
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int getX509Copy(const CertSvcCertificate &certificate, X509** cert)
+    {
+        auto it = m_certificateMap.find(certificate.privateHandler);
+        if (it == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        *cert = X509_dup(it->second->getX509());
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int saveToFile(const CertSvcCertificate &certificate,
+                          const char *location)
+    {
+        auto it = m_certificateMap.find(certificate.privateHandler);
+        if (it == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        FILE *out;
+        if (NULL == (out = fopen(location, "w"))) {
+            return CERTSVC_FAIL;
+        }
+        if (0 == i2d_X509_fp(out, it->second->getX509())) {
+            fclose(out);
+            return CERTSVC_FAIL;
+        }
+        fclose(out);
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int ocspCheck(const CertSvcCertificate *chain,
+                         int chain_size,
+                         const CertSvcCertificate *trusted,
+                         int trusted_size,
+                         const char *url,
+                         int *status)
+    {
+        auto instance = chain[0].privateInstance.privatePtr;
+
+        for(int i=1; i<chain_size; ++i) {
+            if (instance != chain[i].privateInstance.privatePtr)
+            {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+        }
+        CertificateList chainList, trustedList;
+
+        for(int i=0; i<chain_size; ++i) {
+            auto cert = m_certificateMap.find(chain[i].privateHandler);
+            if (cert == m_certificateMap.end()) {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+            chainList.push_back(cert->second);
+        }
+
+        for(int i=0; i<trusted_size; ++i) {
+            if (instance != trusted[i].privateInstance.privatePtr)
+            {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+        }
+
+        for(int i=0; i<trusted_size; ++i) {
+            auto cert = m_certificateMap.find(trusted[i].privateHandler);
+            if (cert == m_certificateMap.end()) {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+            trustedList.push_back(cert->second);
+        }
+
+        OCSP ocsp;
+//        ocsp.setDigestAlgorithmForCertId(OCSP::SHA1);
+//        ocsp.setDigestAlgorithmForRequest(OCSP::SHA1);
+        ocsp.setTrustedStore(trustedList);
+
+        if (url) {
+            ocsp.setUseDefaultResponder(true);
+            ocsp.setDefaultResponder(url);
+        }
+
+        CertificateCollection collection;
+        collection.load(chainList);
+        if (!collection.sort()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        chainList = collection.getChain();
+
+        VerificationStatusSet statusSet = ocsp.validateCertificateList(chainList);
+
+        int ret = 0;
+        if (statusSet.contains(VERIFICATION_STATUS_GOOD)) {
+            ret |= CERTSVC_OCSP_GOOD;
+        }
+        if (statusSet.contains(VERIFICATION_STATUS_REVOKED)) {
+            ret |= CERTSVC_OCSP_REVOKED;
+        }
+        if (statusSet.contains(VERIFICATION_STATUS_UNKNOWN)) {
+            ret |= CERTSVC_OCSP_UNKNOWN;
+        }
+        if (statusSet.contains(VERIFICATION_STATUS_VERIFICATION_ERROR)) {
+            ret |= CERTSVC_OCSP_VERIFICATION_ERROR;
+        }
+        if (statusSet.contains(VERIFICATION_STATUS_NOT_SUPPORT)) {
+            ret |= CERTSVC_OCSP_NO_SUPPORT;
+        }
+        if (statusSet.contains(VERIFICATION_STATUS_ERROR)) {
+            ret |= CERTSVC_OCSP_ERROR;
+        }
+
+        *status = ret;
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int verify(
+        CertSvcCertificate certificate,
+        CertSvcString &message,
+        CertSvcString &signature,
+        const char *algorithm,
+        int *status)
+    {
+        int result = CERTSVC_FAIL;
+
+        if (!status) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        auto it = m_certificateMap.find(certificate.privateHandler);
+        if (it == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        OpenSSL_add_all_digests();
+
+        int temp;
+        EVP_MD_CTX* mdctx = NULL;
+        const EVP_MD * md = NULL;
+        X509 *cert = it->second->getX509();
+        EVP_PKEY *pkey = NULL;
+
+        if (cert == NULL) {
+            goto err;
+        }
+
+        pkey = X509_get_pubkey(cert);
+
+        if (pkey == NULL) {
+            goto err;
+        }
+
+        if (algorithm == NULL) {
+            md = EVP_get_digestbyobj(cert->cert_info->signature->algorithm);
+        } else {
+            md = EVP_get_digestbyname(algorithm);
+        }
+
+        if (md == NULL) {
+            result = CERTSVC_INVALID_ALGORITHM;
+            goto err;
+        }
+
+        mdctx = EVP_MD_CTX_create();
+
+        if (mdctx == NULL) {
+            goto err;
+        }
+
+        if (EVP_VerifyInit_ex(mdctx, md, NULL) != 1) {
+            goto err;
+        }
+
+        if (EVP_VerifyUpdate(mdctx, message.privateHandler, message.privateLength) != 1) {
+            goto err;
+        }
+
+        temp = EVP_VerifyFinal(mdctx,
+            reinterpret_cast<unsigned char*>(signature.privateHandler),
+            signature.privateLength,
+            pkey);
+
+        if (temp == 0) {
+            *status = CERTSVC_INVALID_SIGNATURE;
+            result = CERTSVC_SUCCESS;
+        } else if (temp == 1) {
+            *status = CERTSVC_SUCCESS;
+            result = CERTSVC_SUCCESS;
+        }
+
+    err:
+        if (mdctx != NULL)
+            EVP_MD_CTX_destroy(mdctx);
+        if (pkey != NULL)
+            EVP_PKEY_free(pkey);
+        return result;
+    }
+
+    inline int base64Encode(
+        const CertSvcString &message,
+        CertSvcString *base64)
+    {
+        if (!base64) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        std::string info(message.privateHandler, message.privateLength);
+        Base64Encoder base;
+        base.reset();
+        base.append(info);
+        base.finalize();
+        info = base.get();
+        char *ptr = new char[info.size()+1];
+        memcpy(ptr, info.c_str(), info.size()+1);
+        m_allocatedStringSet.insert(ptr);
+        base64->privateHandler = ptr;
+        base64->privateLength = info.size();
+        base64->privateInstance = message.privateInstance;
+        return CERTSVC_SUCCESS;
+    }
+
+    int base64Decode(
+        const CertSvcString &base64,
+        CertSvcString *message)
+    {
+        if (!message) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        std::string info(base64.privateHandler, base64.privateLength);
+        Base64Decoder base;
+        base.reset();
+        base.append(info);
+        if (!base.finalize()) {
+            return CERTSVC_FAIL;
+        }
+        info = base.get();
+        char *ptr = new char[info.size()+1];
+        memcpy(ptr, info.c_str(), info.size()+1);
+        m_allocatedStringSet.insert(ptr);
+        message->privateHandler = ptr;
+        message->privateLength = info.size();
+        message->privateInstance = base64.privateInstance;
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int stringNew(
+        CertSvcInstance &instance,
+        const char *str,
+        int size,
+        CertSvcString *output)
+    {
+        if (!output || size < 0) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        int allocSize = size;
+
+        if (allocSize == 0 || str[allocSize-1] != 0)
+            allocSize++;
+
+        char *ptr = new char[allocSize];
+        memcpy(ptr, str, size);
+        ptr[allocSize-1] = 0;
+
+        output->privateHandler = ptr;
+        output->privateLength = size;
+        output->privateInstance = instance;
+
+        m_allocatedStringSet.insert(ptr);
+
+        return CERTSVC_SUCCESS;
+    }
+
+    inline void setCRLFunction(
+        CertSvcCrlCacheWrite writePtr,
+        CertSvcCrlCacheRead readPtr,
+        CertSvcCrlFree freePtr)
+    {
+        m_crlWrite = writePtr;
+        m_crlRead = readPtr;
+        m_crlFree = freePtr;
+    }
+
+    inline int crlCheck(
+        CertSvcCertificate certificate,
+        CertSvcCertificate *trustedStore,
+        int storeSize,
+        int force,
+        int *status,
+        void *userParam)
+    {
+        for(int i=1; i<storeSize; ++i) {
+            if (certificate.privateInstance.privatePtr
+                != trustedStore[i].privateInstance.privatePtr)
+            {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+        }
+
+        CRL crl(new CRLCacheCAPI(m_crlWrite, m_crlRead, m_crlFree, userParam));
+
+        for (int i=0; i<storeSize; ++i) {
+            auto iter = m_certificateMap.find(trustedStore[i].privateHandler);
+            if (iter == m_certificateMap.end()) {
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+            crl.addToStore(iter->second);
+        }
+
+        auto iter = m_certificateMap.find(certificate.privateHandler);
+        if (iter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        if (iter->second->getCrlUris().empty()) {
+            *status = CERTSVC_CRL_NO_SUPPORT;
+            return CERTSVC_SUCCESS;
+        }
+        crl.updateList(iter->second, force ? CRL::UPDATE_ON_DEMAND: CRL::UPDATE_ON_EXPIRED);
+        CRL::RevocationStatus st = crl.checkCertificate(iter->second);
+        *status = 0;
+
+        if (!st.isCRLValid) {
+            *status |= CERTSVC_CRL_VERIFICATION_ERROR;
+            return CERTSVC_SUCCESS;
+        }
+
+        if (st.isRevoked) {
+            *status |= CERTSVC_CRL_REVOKED;
+        } else {
+            *status |= CERTSVC_CRL_GOOD;
+        }
+
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int certificateVerify(
+        CertSvcCertificate certificate,
+        CertSvcCertificate *trusted,
+        int trustedSize,
+        CertSvcCertificate *untrusted,
+        int untrustedSize,
+        int *status)
+    {
+        if (!trusted || !status) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        auto iter = m_certificateMap.find(certificate.privateHandler);
+        if (iter == m_certificateMap.end()) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+
+        X509 *cert = iter->second->getX509();
+        X509_STORE *store = X509_STORE_new();
+        STACK_OF(X509) *ustore = sk_X509_new_null();
+
+        for (int i=0; i<trustedSize; ++i) {
+            auto iter = m_certificateMap.find(trusted[i].privateHandler);
+            if (iter == m_certificateMap.end()) {
+                X509_STORE_free(store);
+                sk_X509_free(ustore);
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+            X509_STORE_add_cert(store, iter->second->getX509());
+        }
+
+        for (int i=0; i<untrustedSize; ++i) {
+            auto iter = m_certificateMap.find(untrusted[i].privateHandler);
+            if (iter == m_certificateMap.end()) {
+                X509_STORE_free(store);
+                sk_X509_free(ustore);
+                return CERTSVC_WRONG_ARGUMENT;
+            }
+            sk_X509_push(ustore, iter->second->getX509());
+        }
+        X509_STORE_CTX context;
+        X509_STORE_CTX_init(&context, store, cert, ustore);
+        int result = X509_verify_cert(&context);
+        X509_STORE_CTX_cleanup(&context);
+        X509_STORE_free(store);
+        sk_X509_free(ustore);
+
+        if (result == 1) {
+            *status = CERTSVC_SUCCESS;
+        } else {
+            *status = CERTSVC_FAIL;
+        }
+        return CERTSVC_SUCCESS;
+    }
+
+    inline int pkcsNameIsUnique(
+        CertSvcString pfxIdString,
+        int *is_unique)
+    {
+      gboolean exists;
+      int result = c_certsvc_pkcs12_alias_exists(pfxIdString.privateHandler, &exists);
+      *is_unique = !exists;
+      return result;
+    }
+
+    inline int pkcsImport(
+        CertSvcString path,
+        CertSvcString pass,
+        CertSvcString pfxIdString)
+    {
+      return c_certsvc_pkcs12_import(path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
+    }
+
+    inline int getPkcsIdList(
+        CertSvcInstance &instance,
+        CertSvcStringList *handler)
+    {
+      gchar **aliases;
+      gsize i, naliases;
+      std::vector<std::string> output;
+      int result;
+
+      result = c_certsvc_pkcs12_aliases_load(&aliases, &naliases);
+      if(result != CERTSVC_SUCCESS)
+        return result;
+      for(i = 0; i < naliases; i++)
+        output.push_back(std::string(aliases[i]));
+      c_certsvc_pkcs12_aliases_free(aliases);
+
+      int position = m_stringListCounter++;
+      m_stringListMap[position] = output;
+
+      handler->privateHandler = position;
+      handler->privateInstance = instance;
+      return CERTSVC_SUCCESS;
+    }
+
+    inline int pkcsHasPassword(
+        CertSvcString filepath,
+        int *has_password)
+    {
+      return c_certsvc_pkcs12_has_password(filepath.privateHandler, has_password);
+    }
+
+    inline int getPkcsPrivateKey(
+        CertSvcString pfxIdString,
+        char **buffer,
+        size_t *size)
+    {
+        return c_certsvc_pkcs12_private_key_load(pfxIdString.privateHandler, buffer, size);
+    }
+
+    inline int getPkcsCertificateList(
+        CertSvcInstance &instance,
+        CertSvcString &pfxIdString,
+        CertSvcCertificateList *handler)
+    {
+      gchar **certs;
+      gsize i, ncerts;
+      std::vector<CertificatePtr> certPtrVector;
+      std::vector<int> listId;
+      int result;
+
+      result = c_certsvc_pkcs12_load_certificates(pfxIdString.privateHandler, &certs, &ncerts);
+      if(result != CERTSVC_SUCCESS)
+        return result;
+      for(i = 0; i < ncerts; i++) {
+        ScopedCertCtx context(cert_svc_cert_context_init(), cert_svc_cert_context_final);
+        if(cert_svc_load_file_to_context(context.get(), certs[i]) != CERT_SVC_ERR_NO_ERROR) {
+          c_certsvc_pkcs12_free_certificates(certs);
+          return CERTSVC_IO_ERROR;
+        }
+        else
+          certPtrVector.push_back(CertificatePtr(new Certificate(*(context->certBuf))));
+      }
+      if(ncerts > 0)
+          c_certsvc_pkcs12_free_certificates(certs);
+
+      FOREACH(it, certPtrVector) {
+        listId.push_back(addCert(*it));
+      }
+
+      int position = m_idListCounter++;
+      m_idListMap[position] = listId;
+
+      handler->privateInstance = instance;
+      handler->privateHandler = position;
+
+      return result;
+    }
+
+    inline int pkcsDelete(CertSvcString pfxIdString)
+    {
+      return c_certsvc_pkcs12_delete(pfxIdString.privateHandler);
+    }
+
+private:
+    int m_certificateCounter;
+    std::map<int, CertificatePtr> m_certificateMap;
+
+    int m_idListCounter;
+    std::map<int, std::vector<int> > m_idListMap;
+
+    int m_stringListCounter;
+    std::map<int, std::vector<std::string> > m_stringListMap;
+
+    std::set<char *> m_allocatedStringSet;
+
+    CertSvcCrlCacheWrite m_crlWrite;
+    CertSvcCrlCacheRead m_crlRead;
+    CertSvcCrlFree m_crlFree;
+};
+
+inline CertSvcInstanceImpl *impl(CertSvcInstance instance) {
+    return static_cast<CertSvcInstanceImpl*>(instance.privatePtr);
+}
+
+} // namespace anonymous
+
+int certsvc_instance_new(CertSvcInstance *instance) {
+    static int init = 1;
+    if (init) {
+        SSL_library_init();     // required by message verification
+        OpenSSL_add_all_digests();
+        g_type_init();          // required by libsoup/ocsp
+        init = 0;
+    }
+    try {
+        instance->privatePtr =
+            reinterpret_cast<void*>(new CertSvcInstanceImpl);
+        if (instance->privatePtr)
+            return CERTSVC_SUCCESS;
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+void certsvc_instance_reset(CertSvcInstance instance) {
+    impl(instance)->reset();
+}
+
+void certsvc_instance_free(CertSvcInstance instance) {
+    delete impl(instance);
+}
+
+int certsvc_certificate_new_from_file(
+        CertSvcInstance instance,
+        const char *location,
+        CertSvcCertificate *certificate)
+{
+    try {
+        ScopedCertCtx context(cert_svc_cert_context_init(),
+                              cert_svc_cert_context_final);
+
+        int result = cert_svc_load_file_to_context(context.get(), location);
+
+        switch(result) {
+            case CERT_SVC_ERR_INVALID_PARAMETER: return CERTSVC_WRONG_ARGUMENT;
+            case CERT_SVC_ERR_INVALID_OPERATION: return CERTSVC_FAIL;
+            case CERT_SVC_ERR_MEMORY_ALLOCATION: return CERTSVC_BAD_ALLOC;
+            default:;
+        }
+
+        CertificatePtr cert(new Certificate(*(context->certBuf)));
+
+        certificate->privateInstance = instance;
+        certificate->privateHandler = impl(instance)->addCert(cert);
+
+        return CERTSVC_SUCCESS;
+    // TODO support for std exceptions
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_certificate_new_from_memory(
+        CertSvcInstance instance,
+        const unsigned char *memory,
+        int len,
+        CertSvcCertificateForm form,
+        CertSvcCertificate *certificate)
+{
+    try {
+        Certificate::FormType formType;
+        std::string binary((char*)memory, len);
+
+        if (CERTSVC_FORM_DER == form) {
+            formType = Certificate::FORM_DER;
+        } else {
+            formType = Certificate::FORM_BASE64;
+        }
+
+        CertificatePtr cert(new Certificate(binary, formType));
+
+        certificate->privateInstance = instance;
+        certificate->privateHandler = impl(instance)->addCert(cert);
+        return CERTSVC_SUCCESS;
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+void certsvc_certificate_free(CertSvcCertificate certificate)
+{
+    impl(certificate.privateInstance)->removeCert(certificate);
+}
+
+int certsvc_certificate_save_file(
+        CertSvcCertificate certificate,
+        const char *location)
+{
+    return impl(certificate.privateInstance)->saveToFile(certificate, location);
+}
+
+int certsvc_certificate_search(
+        CertSvcInstance instance,
+        CertSvcCertificateField field,
+        const char *value,
+        CertSvcCertificateList *handler)
+{
+    try {
+        return impl(instance)->certificateSearch(instance, field, value, handler);
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_certificate_list_get_one(
+        CertSvcCertificateList handler,
+        int position,
+        CertSvcCertificate *certificate)
+{
+    return impl(handler.privateInstance)->
+        getCertFromList(handler,position, certificate);
+}
+
+int certsvc_certificate_list_get_length(
+        CertSvcCertificateList handler,
+        int *size)
+{
+    return impl(handler.privateInstance)->getCertListLen(handler, size);
+}
+
+void certsvc_certificate_list_free(CertSvcCertificateList handler)
+{
+    impl(handler.privateInstance)->removeCertList(handler);
+}
+
+int certsvc_certificate_is_signed_by(
+        CertSvcCertificate child,
+        CertSvcCertificate parent,
+        int *status)
+{
+    if (child.privateInstance.privatePtr == parent.privateInstance.privatePtr) {
+        return impl(child.privateInstance)->isSignedBy(child, parent, status);
+    }
+    return CERTSVC_WRONG_ARGUMENT;
+}
+
+int certsvc_certificate_get_string_field(
+        CertSvcCertificate certificate,
+        CertSvcCertificateField field,
+        CertSvcString *buffer)
+{
+    try {
+        return impl(certificate.privateInstance)->getField(certificate, field, buffer);
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_certificate_get_not_after(
+        CertSvcCertificate certificate,
+        time_t *result)
+{
+    try {
+        return impl(certificate.privateInstance)->getNotAfter(certificate, result);
+    } catch(...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_certificate_get_not_before(
+        CertSvcCertificate certificate,
+        time_t *result)
+{
+    try {
+        return impl(certificate.privateInstance)->getNotBefore(certificate, result);
+    } catch(...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_certificate_is_root_ca(CertSvcCertificate certificate, int *status)
+{
+    return impl(certificate.privateInstance)->isRootCA(certificate, status);
+}
+
+int certsvc_certificate_get_crl_distribution_points(
+        CertSvcCertificate certificate,
+        CertSvcStringList *handler)
+{
+    try {
+        return impl(certificate.privateInstance)->getCrl(certificate, handler);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_string_list_get_one(
+        CertSvcStringList handler,
+        int position,
+        CertSvcString *buffer)
+{
+    try {
+        return impl(handler.privateInstance)->getStringFromList(handler, position, buffer);
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_string_list_get_length(
+        CertSvcStringList handler,
+        int *size)
+{
+    return impl(handler.privateInstance)->getStringListLen(handler, size);
+}
+
+void certsvc_string_list_free(CertSvcStringList handler)
+{
+    impl(handler.privateInstance)->removeStringList(handler);
+}
+
+void certsvc_string_free(CertSvcString string)
+{
+    impl(string.privateInstance)->removeString(string);
+}
+
+void certsvc_string_to_cstring(
+        CertSvcString string,
+        const char **buffer,
+        int *len)
+{
+    if (buffer) {
+        *buffer = string.privateHandler;
+    }
+    if (len) {
+        *len = string.privateLength;
+    }
+}
+
+int certsvc_certificate_chain_sort(
+        CertSvcCertificate *certificate_array,
+        int size)
+{
+    try {
+        if (!certificate_array) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        return impl(certificate_array[0].privateInstance)->
+            sortCollection(certificate_array, size);
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_certificate_dup_x509(CertSvcCertificate certificate, X509 **cert)
+{
+    try {
+        return impl(certificate.privateInstance)->getX509Copy(certificate, cert);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+void certsvc_certificate_free_x509(X509 *x509)
+{
+    X509_free(x509);
+}
+
+int certsvc_pkcs12_dup_evp_pkey(
+    CertSvcInstance instance,
+    CertSvcString alias,
+    EVP_PKEY** pkey)
+{
+    char *buffer;
+    size_t size;
+
+    int result = certsvc_pkcs12_private_key_dup(
+        instance,
+        alias,
+        &buffer,
+        &size);
+
+    if (result != CERTSVC_SUCCESS) {
+        LogError("Error in certsvc_pkcs12_private_key_dup");
+        return result;
+    }
+
+    BIO *b = BIO_new(BIO_s_mem());
+
+    if ((int)size != BIO_write(b, buffer, size)) {
+        LogError("Error in BIO_write");
+        BIO_free_all(b);
+        certsvc_pkcs12_private_key_free(buffer);
+        return CERTSVC_FAIL;
+    }
+
+    certsvc_pkcs12_private_key_free(buffer);
+
+    *pkey = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL);
+
+    BIO_free_all(b);
+
+    if (*pkey) {
+        return CERTSVC_SUCCESS;
+    }
+
+    LogError("Result is null. Openssl REASON code is: "
+        << ERR_GET_REASON(ERR_peek_last_error()));
+
+    return CERTSVC_FAIL;
+}
+
+void certsvc_pkcs12_free_evp_pkey(EVP_PKEY* pkey)
+{
+    EVP_PKEY_free(pkey);
+}
+
+int certsvc_ocsp_check(
+    CertSvcCertificate *chain,
+    int chain_size,
+    CertSvcCertificate *trusted,
+    int trusted_size,
+    const char *url,
+    int *status)
+{
+    try {
+        if (!chain || !trusted) {
+            return CERTSVC_WRONG_ARGUMENT;
+        }
+        return impl(chain[0].privateInstance)->
+            ocspCheck(chain,
+                      chain_size,
+                      trusted,
+                      trusted_size,
+                      url,
+                      status);
+    } catch (std::bad_alloc &) {
+        return CERTSVC_BAD_ALLOC;
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_message_verify(
+    CertSvcCertificate certificate,
+    CertSvcString message,
+    CertSvcString signature,
+    const char *algorithm,
+    int *status)
+{
+    try {
+        return impl(certificate.privateInstance)->verify(
+            certificate,
+            message,
+            signature,
+            algorithm,
+            status);
+    } catch(...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_base64_encode(CertSvcString message, CertSvcString *base64)
+{
+    try {
+        return impl(message.privateInstance)->base64Encode(message, base64);
+    } catch(...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_base64_decode(CertSvcString base64, CertSvcString *message)
+{
+    try {
+        return impl(base64.privateInstance)->base64Decode(base64, message);
+    } catch(...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_string_new(
+    CertSvcInstance instance,
+    const char *url,
+    int size,
+    CertSvcString *output)
+{
+    try {
+        return impl(instance)->stringNew(instance, url, size, output);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_string_not_managed(
+    CertSvcInstance instance,
+    const char *url,
+    int size,
+    CertSvcString *output)
+{
+    if (!output) {
+        return CERTSVC_WRONG_ARGUMENT;
+    }
+    output->privateHandler = const_cast<char*>(url);
+    output->privateLength = size;
+    output->privateInstance = instance;
+    return CERTSVC_SUCCESS;
+}
+
+void certsvc_crl_cache_functions(
+    CertSvcInstance instance,
+    CertSvcCrlCacheWrite writePtr,
+    CertSvcCrlCacheRead readPtr,
+    CertSvcCrlFree freePtr)
+{
+    impl(instance)->setCRLFunction(writePtr, readPtr, freePtr);
+}
+
+int certsvc_crl_check(
+    CertSvcCertificate certificate,
+    CertSvcCertificate *trustedStore,
+    int storeSize,
+    int force,
+    int *status,
+    void *userParam)
+{
+    try {
+        return impl(certificate.privateInstance)->crlCheck(
+            certificate,
+            trustedStore,
+            storeSize,
+            force,
+            status,
+            userParam);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_certificate_verify(
+    CertSvcCertificate certificate,
+    CertSvcCertificate *trusted,
+    int trustedSize,
+    CertSvcCertificate *untrusted,
+    int untrustedSize,
+    int *status)
+{
+    try {
+        return impl(certificate.privateInstance)->certificateVerify(
+            certificate,
+            trusted,
+            trustedSize,
+            untrusted,
+            untrustedSize,
+            status);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_alias_exists(CertSvcInstance instance,
+    CertSvcString pfxIdString,
+    int *is_unique)
+{
+    try {
+      return impl(instance)->pkcsNameIsUnique(pfxIdString, is_unique);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_import_from_file(CertSvcInstance instance,
+    CertSvcString path,
+    CertSvcString password,
+    CertSvcString pfxIdString)
+{
+    try {
+      return impl(instance)->pkcsImport(path, password, pfxIdString);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_id_list(
+    CertSvcInstance instance,
+    CertSvcStringList *pfxIdStringList)
+{
+    try {
+        return impl(instance)->getPkcsIdList(
+            instance,
+            pfxIdStringList);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_has_password(
+    CertSvcInstance instance,
+    CertSvcString filepath,
+    int *has_password)
+{
+    try {
+        return impl(instance)->pkcsHasPassword(
+            filepath,
+            has_password);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_load_certificate_list(
+    CertSvcInstance instance,
+    CertSvcString pfxIdString,
+    CertSvcCertificateList *certificateList)
+{
+    try {
+        return impl(instance)->getPkcsCertificateList(
+            instance,
+            pfxIdString,
+            certificateList);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_private_key_dup(
+    CertSvcInstance instance,
+    CertSvcString pfxIdString,
+    char **buffer,
+    size_t *size)
+{
+    try {
+        return impl(instance)->getPkcsPrivateKey(pfxIdString, buffer, size);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
+
+void certsvc_pkcs12_private_key_free(
+    char *buffer)
+{
+    delete[] buffer;
+}
+
+int certsvc_pkcs12_delete(
+    CertSvcInstance instance,
+    CertSvcString pfxIdString)
+{
+    try {
+        return impl(instance)->pkcsDelete(pfxIdString);
+    } catch (...) {}
+    return CERTSVC_FAIL;
+}
diff --git a/vcore/src/vcore/pkcs12.c b/vcore/src/vcore/pkcs12.c
new file mode 100644 (file)
index 0000000..ffaaa6c
--- /dev/null
@@ -0,0 +1,493 @@
+/**
+ * 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        pkcs12.h
+ * @author      Jacek Migacz (j.migacz@samsung.com)
+ * @version     1.0
+ * @brief       PKCS#12 container manipulation routines.
+ */
+#define _GNU_SOURCE
+
+#include "pkcs12.h"
+#include <cert-svc/cerror.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+#include <openssl/sha.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <ss_manager.h>
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define CERTSVC_PKCS12_STORAGE_DIR  "/opt/share/cert-svc/pkcs12"
+#define CERTSVC_PKCS12_STORAGE_FILE "storage"
+#define CERTSVC_PKCS12_STORAGE_PATH CERTSVC_PKCS12_STORAGE_DIR "/" CERTSVC_PKCS12_STORAGE_FILE
+
+static const char  CERTSVC_PKCS12_STORAGE_KEY_PKEY[]  = "pkey";
+static const char  CERTSVC_PKCS12_STORAGE_KEY_CERTS[] = "certs";
+static const gchar CERTSVC_PKCS12_STORAGE_SEPARATOR  = ';';
+static const char  CERTSVC_PKCS12_UNIX_GROUP[] = "ss_privatekey";
+
+static gboolean keyfile_check(const char *pathname) {
+  int result;
+  if(access(pathname, F_OK | R_OK | W_OK) == 0)
+    return TRUE;
+  SYSCALL(result = creat(pathname, S_IRUSR | S_IWUSR));
+  if (result != -1) {
+      close(result);
+      return TRUE;
+  } else {
+      return FALSE;
+  }
+}
+
+static GKeyFile *keyfile_load(const char *pathname) {
+  GKeyFile *keyfile;
+  GError *error;
+
+  if(!keyfile_check(pathname))
+    return NULL;
+  keyfile = g_key_file_new();
+  error = NULL;
+  if(!g_key_file_load_from_file(keyfile, pathname, G_KEY_FILE_KEEP_COMMENTS, &error)) {
+    g_key_file_free(keyfile);
+    return NULL;
+  }
+  return keyfile;
+}
+
+static int generate_random_filepath(char **filepath) {
+  int generator;
+  int64_t random;
+  SHA_CTX ctx;
+  unsigned char d[SHA_DIGEST_LENGTH];
+  int result;
+
+  if(!filepath)
+    return CERTSVC_WRONG_ARGUMENT;
+
+  SYSCALL(generator = open("/dev/urandom", O_RDONLY));
+  if(generator == -1)
+    return CERTSVC_FAIL;
+  SYSCALL(result = read(generator, &random, sizeof(random)));
+  if(result == -1) {
+    SYSCALL(close(generator));
+    return CERTSVC_FAIL;
+  }
+  SYSCALL(result = close(generator));
+  if(result == -1)
+    return CERTSVC_FAIL;
+
+  SHA1_Init(&ctx);
+  SHA1_Update(&ctx, &random, sizeof(random));
+  SHA1_Final(d, &ctx);
+
+  result = asprintf(filepath, "%s/"                            \
+                    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
+                    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+                    CERTSVC_PKCS12_STORAGE_DIR,
+                    d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9],
+                    d[10], d[11], d[12], d[13], d[14], d[15], d[16], d[17], d[18], d[19]);
+  return (result != -1) ? CERTSVC_SUCCESS : CERTSVC_BAD_ALLOC;
+}
+
+static int unique_filename(char **filepath, gboolean with_secure_storage) {
+  const unsigned attempts = 0xFFU;
+  unsigned trial;
+  int result;
+  ssm_file_info_t sfi;
+  gboolean exists;
+
+  trial = 0U;
+ try_again:
+  ++trial;
+  result = generate_random_filepath(filepath);
+  if(result != CERTSVC_SUCCESS)
+    return result;
+  if(with_secure_storage)
+    exists = (access(*filepath, F_OK) == 0 || ssm_getinfo(*filepath, &sfi, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP) == 0);
+  else
+    exists = (access(*filepath, F_OK) == 0);
+  if(exists) {
+    free(*filepath);
+    if(trial + 1 > attempts)
+      return CERTSVC_FAIL;
+    else
+      goto try_again;
+  }
+  return CERTSVC_SUCCESS;
+}
+
+static char *bare_filename(char *filepath) {
+  char *needle;
+  if(!filepath)
+    return NULL;
+  needle = strrchr(filepath, '/');
+  if(!needle)
+    return NULL;
+  return *(++needle) ? needle : NULL;
+}
+
+int c_certsvc_pkcs12_alias_exists(const gchar *alias, gboolean *exists) {
+  GKeyFile *keyfile;
+
+  if(exists == NULL)
+    return CERTSVC_WRONG_ARGUMENT;
+  keyfile = keyfile_load(CERTSVC_PKCS12_STORAGE_PATH);
+  if(!keyfile)
+    return CERTSVC_IO_ERROR;
+  *exists = g_key_file_has_group(keyfile, alias);
+  g_key_file_free(keyfile);
+  return CERTSVC_SUCCESS;
+}
+
+int c_certsvc_pkcs12_import(const char *path, const char *password, const gchar *alias) {
+  int exists;
+  FILE *stream;
+  PKCS12 *container;
+  EVP_PKEY *key;
+  X509 *cert;
+  STACK_OF(X509) *certv;
+  int nicerts;
+  char *unique;
+  int result;
+  struct stat st;
+  int wr_res;
+  GKeyFile *keyfile;
+  gchar *bare;
+  gchar *pkvalue;
+  gchar **cvaluev;
+  gsize i, n;
+  gchar *data;
+  gsize length;
+
+  certv = NULL;
+  pkvalue = NULL;
+  if(!alias || strlen(alias) < 1)
+    return CERTSVC_WRONG_ARGUMENT;
+  result = c_certsvc_pkcs12_alias_exists(alias, &exists);
+  if(result != CERTSVC_SUCCESS)
+    return result;
+  if(exists == TRUE)
+    return CERTSVC_DUPLICATED_ALIAS;
+
+  keyfile = keyfile_load(CERTSVC_PKCS12_STORAGE_PATH);
+  if(!keyfile)
+    return CERTSVC_IO_ERROR;
+  if(stat(CERTSVC_PKCS12_STORAGE_PATH, &st) == -1) {
+    if(mkdir(CERTSVC_PKCS12_STORAGE_PATH, S_IRWXU | S_IRWXG | S_IRWXO) == -1) {
+      result = CERTSVC_FAIL;
+      goto free_keyfile;
+    }
+  }
+
+  if((stream = fopen(path, "rb")) == NULL) {
+    result = CERTSVC_IO_ERROR;
+    goto free_keyfile;
+  }
+  container = d2i_PKCS12_fp(stream, NULL);
+  fclose(stream);
+  if(container == NULL) {
+    result = CERTSVC_FAIL;
+    goto free_keyfile;
+  }
+  result = PKCS12_parse(container, password, &key, &cert, &certv);
+  PKCS12_free(container);
+  if(result == 0) {
+    result = CERTSVC_FAIL;
+    goto free_keyfile;
+  }
+  nicerts = certv ? sk_X509_num(certv) : 0;
+  cvaluev = (gchar **)calloc(1 + nicerts, sizeof(gchar *));
+  n = 0;
+
+  result = unique_filename(&unique, TRUE);
+  if(result != CERTSVC_SUCCESS)
+    goto clean_cert_chain_and_pkey;
+  if((stream = fopen(unique, "w")) == NULL) {
+    free(unique);
+    result = CERTSVC_IO_ERROR;
+    goto clean_cert_chain_and_pkey;
+  }
+  result = PEM_write_PrivateKey(stream, key, NULL, NULL, 0, NULL, NULL);
+  fclose(stream);
+  if(result == 0) {
+    result = CERTSVC_FAIL;
+    goto clean_cert_chain_and_pkey;
+  }
+  wr_res = ssm_write_file(unique, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP);
+  if(wr_res != 0) {
+    free(unique);
+    result = CERTSVC_FAIL;
+    goto clean_cert_chain_and_pkey;
+  }
+  bare = bare_filename(unique);
+  if(bare) {
+    pkvalue = g_strdup(bare);
+    g_key_file_set_string(keyfile, alias, CERTSVC_PKCS12_STORAGE_KEY_PKEY, pkvalue);
+  }
+  free(unique);
+  result = unique_filename(&unique, FALSE);
+  if(result != CERTSVC_SUCCESS)
+    goto clean_cert_chain_and_pkey;
+  if((stream = fopen(unique, "w")) == NULL) {
+    free(unique);
+    result = CERTSVC_IO_ERROR;
+    goto clean_cert_chain_and_pkey;
+  }
+  result = PEM_write_X509(stream, cert);
+  fclose(stream);
+  if(result == 0) {
+    result = CERTSVC_FAIL;
+    goto clean_cert_chain_and_pkey;
+  }
+  bare = bare_filename(unique);
+  if(bare)
+    cvaluev[n++] = g_strdup(bare);
+  free(unique);
+  for(i = 0; i < nicerts; i++) {
+    result = unique_filename(&unique, FALSE);
+    if(result != CERTSVC_SUCCESS)
+      goto clean_cert_chain_and_pkey;
+    if((stream = fopen(unique, "w")) == NULL) {
+      free(unique);
+      result = CERTSVC_IO_ERROR;
+      goto clean_cert_chain_and_pkey;
+    }
+    result = PEM_write_X509_AUX(stream, sk_X509_value(certv, i));
+    fclose(stream);
+    if(result == 0) {
+      result = CERTSVC_FAIL;
+      goto clean_cert_chain_and_pkey;
+    }
+    bare = bare_filename(unique);
+    if(bare)
+      cvaluev[n++] = g_strdup(bare);
+    free(unique);
+  }
+  g_key_file_set_list_separator(keyfile, CERTSVC_PKCS12_STORAGE_SEPARATOR);
+  g_key_file_set_string_list(keyfile, alias, CERTSVC_PKCS12_STORAGE_KEY_CERTS, (const gchar * const *)cvaluev, n);
+  data = g_key_file_to_data(keyfile, &length, NULL);
+  if(data == NULL) {
+    result = CERTSVC_BAD_ALLOC;
+    goto clean_cert_chain_and_pkey;
+  }
+  if(!g_file_set_contents(CERTSVC_PKCS12_STORAGE_PATH, data, length, NULL)) {
+    result = CERTSVC_IO_ERROR;
+    goto free_data;
+  }
+  result = CERTSVC_SUCCESS;
+ free_data:
+  g_free(data);
+ clean_cert_chain_and_pkey:
+  EVP_PKEY_free(key);
+  X509_free(cert);
+  sk_X509_free(certv);
+  free(pkvalue);
+ for(i = 0; i < n; i++) {
+    g_free(cvaluev[i]);
+ }
+  free(cvaluev);
+ free_keyfile:
+  g_key_file_free(keyfile);
+  return result;
+}
+
+int c_certsvc_pkcs12_aliases_load(gchar ***aliases, gsize *naliases) {
+  GKeyFile *keyfile;
+
+  keyfile = keyfile_load(CERTSVC_PKCS12_STORAGE_PATH);
+  if(!keyfile)
+    return CERTSVC_IO_ERROR;
+  *aliases = g_key_file_get_groups(keyfile, naliases);
+  g_key_file_free(keyfile);
+  return CERTSVC_SUCCESS;
+}
+
+void c_certsvc_pkcs12_aliases_free(gchar **aliases) {
+  g_strfreev(aliases);
+}
+
+int c_certsvc_pkcs12_has_password(const char *filepath, gboolean *passworded) {
+  FILE *stream;
+  EVP_PKEY *pkey;
+  X509 *cert;
+  PKCS12 *container;
+  int result;
+
+  if(passworded == NULL)
+    return CERTSVC_WRONG_ARGUMENT;
+  if((stream = fopen(filepath, "rb")) == NULL)
+    return CERTSVC_IO_ERROR;
+  container = d2i_PKCS12_fp(stream, NULL);
+  fclose(stream);
+  if(container == NULL)
+    return CERTSVC_FAIL;
+  result = PKCS12_parse(container, NULL, &pkey, &cert, NULL);
+  PKCS12_free(container);
+  if(result == 1) {
+    EVP_PKEY_free(pkey);
+    X509_free(cert);
+    *passworded = FALSE;
+    return CERTSVC_SUCCESS;
+  }
+  else {
+    if(ERR_GET_REASON(ERR_peek_last_error()) == PKCS12_R_MAC_VERIFY_FAILURE) {
+      *passworded = TRUE;
+      return CERTSVC_SUCCESS;
+    }
+    else
+      return CERTSVC_FAIL;
+  }
+}
+
+int c_certsvc_pkcs12_load_certificates(const gchar *alias, gchar ***certs, gsize *ncerts) {
+  GKeyFile *keyfile;
+  gchar **barev;
+  gsize i;
+  keyfile = keyfile_load(CERTSVC_PKCS12_STORAGE_PATH);
+  if(!keyfile)
+    return CERTSVC_IO_ERROR;
+  g_key_file_set_list_separator(keyfile, CERTSVC_PKCS12_STORAGE_SEPARATOR);
+  barev = g_key_file_get_string_list(keyfile, alias, CERTSVC_PKCS12_STORAGE_KEY_CERTS, ncerts, NULL);
+  if(barev == NULL) {
+      *ncerts = 0;
+      goto free_keyfile;
+  }
+  *certs = g_malloc((*ncerts + 1) * sizeof(gchar *));
+  for(i = 0; i < *ncerts; i++)
+      (*certs)[i] = g_strdup_printf("%s/%s", CERTSVC_PKCS12_STORAGE_DIR, barev[i]);
+  (*certs)[*ncerts] = NULL;
+  g_strfreev(barev);
+free_keyfile:
+  g_key_file_free(keyfile);
+  return CERTSVC_SUCCESS;
+}
+
+void c_certsvc_pkcs12_free_certificates(gchar **certs) {
+  gsize i = 0;
+  if(certs == NULL)
+    return;
+  while(certs[i])
+    g_free(certs[i++]);
+  g_free(certs);
+}
+
+int c_certsvc_pkcs12_private_key_load(const gchar *alias, char **buffer, gsize *count) {
+  GKeyFile *keyfile;
+  gchar *pkey;
+  GError *error;
+  ssm_file_info_t sfi;
+  char *spkp;
+  int result;
+
+  if(!buffer)
+    return CERTSVC_WRONG_ARGUMENT;
+  keyfile = keyfile_load(CERTSVC_PKCS12_STORAGE_PATH);
+  if(!keyfile)
+    return CERTSVC_IO_ERROR;
+  error = NULL;
+  result = CERTSVC_SUCCESS;
+  pkey = g_key_file_get_string(keyfile, alias, CERTSVC_PKCS12_STORAGE_KEY_PKEY, &error);
+  if(error && error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND) {
+    *count = 0;
+    result = CERTSVC_SUCCESS;
+  }
+  else if(error)
+    result = CERTSVC_FAIL;
+  else {
+    if(asprintf(&spkp, "%s/%s", CERTSVC_PKCS12_STORAGE_DIR, pkey) == -1) {
+      spkp = NULL;
+      result = CERTSVC_BAD_ALLOC;
+    }
+    else if(ssm_getinfo(spkp, &sfi, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP) == 0) {
+      if((*buffer = malloc(sfi.originSize))) {
+        if(ssm_read(spkp, *buffer, sfi.originSize, count, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP) != 0) {
+          c_certsvc_pkcs12_private_key_free(*buffer);
+          result = CERTSVC_FAIL;
+        }
+      }
+      else
+        result = CERTSVC_BAD_ALLOC;
+    }
+    free(spkp);
+    g_free(pkey);
+  }
+  g_key_file_free(keyfile);
+  return result;
+}
+
+void c_certsvc_pkcs12_private_key_free(char *buffer) {
+  free(buffer);
+}
+
+int c_certsvc_pkcs12_delete(const gchar *alias) {
+  gchar **certs;
+  gsize ncerts;
+  char *pkey;
+  char *spkp;
+  int result;
+  GKeyFile *keyfile;
+  gchar *data;
+  gsize i, length;
+
+  data = NULL;
+  result = c_certsvc_pkcs12_load_certificates(alias, &certs, &ncerts);
+  if(result != CERTSVC_SUCCESS)
+    goto load_certificates_failed;
+  keyfile = keyfile_load(CERTSVC_PKCS12_STORAGE_PATH);
+  if(!keyfile) {
+    result = CERTSVC_IO_ERROR;
+    goto keyfile_load_failed;
+  }
+  pkey = g_key_file_get_string(keyfile, alias, CERTSVC_PKCS12_STORAGE_KEY_PKEY, NULL);
+  if(g_key_file_remove_group(keyfile, alias, NULL)) {
+    data = g_key_file_to_data(keyfile, &length, NULL);
+    if(data == NULL) {
+      result = CERTSVC_BAD_ALLOC;
+      goto keyfile_free;
+    }
+    if(!g_file_set_contents(CERTSVC_PKCS12_STORAGE_PATH, data, length, NULL)) {
+      result = CERTSVC_IO_ERROR;
+      goto data_free;
+    }
+  }
+  for(i = 0; i < ncerts; i++)
+    unlink(certs[i]);
+  if(pkey != NULL) {
+      if(asprintf(&spkp, "%s/%s", CERTSVC_PKCS12_STORAGE_DIR, pkey) == -1) {
+          result = CERTSVC_BAD_ALLOC;
+          goto data_free;
+      }
+      ssm_delete_file(spkp, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP);
+      free(spkp);
+  }
+ data_free:
+  g_free(data);
+ keyfile_free:
+  g_key_file_free(keyfile);
+ keyfile_load_failed:
+  if(ncerts != 0)
+      c_certsvc_pkcs12_free_certificates(certs);
+ load_certificates_failed:
+  return result;
+}
diff --git a/vcore/src/vcore/pkcs12.h b/vcore/src/vcore/pkcs12.h
new file mode 100644 (file)
index 0000000..eca7a7a
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * 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        pkcs12.c
+ * @author      Jacek Migacz (j.migacz@samsung.com)
+ * @version     1.0
+ * @brief       PKCS#12 container manipulation routines.
+ */
+#ifndef _PKCS12_H_
+#define _PKCS12_H_
+
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int  c_certsvc_pkcs12_alias_exists(const gchar *alias, gboolean *exists);
+int  c_certsvc_pkcs12_import(const char *path, const char *password, const gchar *alias);
+int  c_certsvc_pkcs12_aliases_load(gchar ***aliases, gsize *naliases);
+void c_certsvc_pkcs12_aliases_free(gchar **aliases);
+int  c_certsvc_pkcs12_has_password(const char *filepath, gboolean *passworded);
+int  c_certsvc_pkcs12_load_certificates(const gchar *alias, gchar ***certificates, gsize *ncertificates);
+void c_certsvc_pkcs12_free_certificates(gchar **certs);
+int  c_certsvc_pkcs12_private_key_load(const gchar *alias, char **pkey, gsize *count);
+void c_certsvc_pkcs12_private_key_free(char *buffer);
+int  c_certsvc_pkcs12_delete(const gchar *alias);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/vcore/src/vcore/scoped_gpointer.h b/vcore/src/vcore/scoped_gpointer.h
new file mode 100644 (file)
index 0000000..78772df
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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        scoped_fclose.h
+ * @author      Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @version     1.0
+ * @brief       This file is the implementation file of scoped fclose RAII
+ */
+#ifndef WRT_ENGINE_SRC_COMMON_SCOPED_GPOINTER_H
+#define WRT_ENGINE_SRC_COMMON_SCOPED_GPOINTER_H
+
+#include <cstddef>
+#include <glib-object.h>
+
+#include <dpl/scoped_resource.h>
+#include <dpl/assert.h>
+
+namespace WRT {
+struct ScopedGPointerPolicy
+{
+    typedef gpointer Type;
+    static Type NullValue()
+    {
+        return NULL;
+    }
+    static void Destroy(Type pointer)
+    {
+        if (pointer != NULL) {
+            g_object_unref(pointer);
+        }
+    }
+};
+
+template <typename Class>
+class ScopedGPointer : public DPL::ScopedResource<ScopedGPointerPolicy>
+{
+    typedef ScopedGPointerPolicy Policy;
+    typedef DPL::ScopedResource<Policy> BaseType;
+
+  public:
+    explicit ScopedGPointer(typename Policy::Type pointer =
+                Policy::NullValue()) :
+        BaseType(pointer)
+    {
+    }
+
+    Class *operator->() const throw()
+    {
+        Assert(this->m_value != Policy::NullValue() &&
+               "Dereference of scoped NULL pointer!");
+        return static_cast<Class *>(this->m_value);
+    }
+
+    Class & operator *() const throw()
+    {
+        Assert(this->m_value != Policy::NullValue() &&
+               "Dereference of scoped NULL pointer!");
+        return *static_cast<Class *>(this->m_value);
+    }
+};
+} // namespace WRT
+
+#endif // WRT_ENGINE_SRC_COMMON_SCOPED_GPOINTER_H