summaryrefslogtreecommitdiff
path: root/vcore/src
diff options
context:
space:
mode:
Diffstat (limited to 'vcore/src')
-rw-r--r--vcore/src/CMakeLists.txt342
-rw-r--r--vcore/src/cert-svc/ccert.h49
-rw-r--r--vcore/src/cert-svc/cerror.h28
-rw-r--r--vcore/src/cert-svc/cpkcs12.h213
-rw-r--r--vcore/src/cert-svc/cprimitives.h16
-rw-r--r--vcore/src/dpl/core/include/dpl/abstract_input.h58
-rw-r--r--vcore/src/dpl/core/include/dpl/abstract_input_output.h38
-rw-r--r--vcore/src/dpl/core/include/dpl/abstract_output.h60
-rw-r--r--vcore/src/dpl/core/include/dpl/abstract_waitable_input.h39
-rw-r--r--vcore/src/dpl/core/include/dpl/assert.h51
-rw-r--r--vcore/src/dpl/core/include/dpl/availability.h30
-rw-r--r--vcore/src/dpl/core/include/dpl/binary_queue.h296
-rw-r--r--vcore/src/dpl/core/include/dpl/char_traits.h38
-rw-r--r--vcore/src/dpl/core/include/dpl/colors.h73
-rw-r--r--vcore/src/dpl/core/include/dpl/errno_string.h35
-rw-r--r--vcore/src/dpl/core/include/dpl/exception.h390
-rw-r--r--vcore/src/dpl/core/include/dpl/file_input.h62
-rw-r--r--vcore/src/dpl/core/include/dpl/foreach.h61
-rw-r--r--vcore/src/dpl/core/include/dpl/free_deleter.h33
-rw-r--r--vcore/src/dpl/core/include/dpl/lexical_cast.h43
-rw-r--r--vcore/src/dpl/core/include/dpl/noncopyable.h38
-rw-r--r--vcore/src/dpl/core/include/dpl/optional.h176
-rw-r--r--vcore/src/dpl/core/include/dpl/optional_typedefs.h33
-rw-r--r--vcore/src/dpl/core/include/dpl/preprocessor.h35
-rw-r--r--vcore/src/dpl/core/include/dpl/scoped_array.h68
-rw-r--r--vcore/src/dpl/core/include/dpl/scoped_fclose.h72
-rw-r--r--vcore/src/dpl/core/include/dpl/scoped_free.h57
-rw-r--r--vcore/src/dpl/core/include/dpl/scoped_resource.h80
-rw-r--r--vcore/src/dpl/core/include/dpl/singleton.h57
-rw-r--r--vcore/src/dpl/core/include/dpl/singleton_impl.h53
-rw-r--r--vcore/src/dpl/core/include/dpl/string.h157
-rw-r--r--vcore/src/dpl/core/include/dpl/thread.h394
-rw-r--r--vcore/src/dpl/core/include/dpl/type_list.h159
-rw-r--r--vcore/src/dpl/core/include/dpl/waitable_event.h59
-rw-r--r--vcore/src/dpl/core/include/dpl/waitable_handle.h115
-rw-r--r--vcore/src/dpl/core/include/dpl/waitable_handle_watch_support.h149
-rw-r--r--vcore/src/dpl/core/include/dpl/workaround.h43
-rw-r--r--vcore/src/dpl/core/src/assert.cpp61
-rw-r--r--vcore/src/dpl/core/src/binary_queue.cpp312
-rw-r--r--vcore/src/dpl/core/src/char_traits.cpp34
-rw-r--r--vcore/src/dpl/core/src/colors.cpp70
-rw-r--r--vcore/src/dpl/core/src/errno_string.cpp98
-rw-r--r--vcore/src/dpl/core/src/exception.cpp47
-rw-r--r--vcore/src/dpl/core/src/file_input.cpp142
-rw-r--r--vcore/src/dpl/core/src/noncopyable.cpp31
-rw-r--r--vcore/src/dpl/core/src/singleton.cpp31
-rw-r--r--vcore/src/dpl/core/src/string.cpp250
-rw-r--r--vcore/src/dpl/core/src/thread.cpp609
-rw-r--r--vcore/src/dpl/core/src/type_list.cpp31
-rw-r--r--vcore/src/dpl/core/src/waitable_event.cpp77
-rw-r--r--vcore/src/dpl/core/src/waitable_handle.cpp161
-rw-r--r--vcore/src/dpl/core/src/waitable_handle_watch_support.cpp376
-rw-r--r--vcore/src/dpl/db/include/dpl/db/naive_synchronization_object.h45
-rw-r--r--vcore/src/dpl/db/include/dpl/db/orm.h1117
-rw-r--r--vcore/src/dpl/db/include/dpl/db/orm_generator.h382
-rw-r--r--vcore/src/dpl/db/include/dpl/db/orm_interface.h48
-rw-r--r--vcore/src/dpl/db/include/dpl/db/orm_macros.h34
-rw-r--r--vcore/src/dpl/db/include/dpl/db/sql_connection.h519
-rw-r--r--vcore/src/dpl/db/include/dpl/db/thread_database_support.h300
-rw-r--r--vcore/src/dpl/db/src/naive_synchronization_object.cpp44
-rw-r--r--vcore/src/dpl/db/src/orm.cpp102
-rw-r--r--vcore/src/dpl/db/src/sql_connection.cpp896
-rw-r--r--vcore/src/dpl/db/src/thread_database_support.cpp (renamed from vcore/src/vcore/SoupMessageSendAsync.cpp)8
-rw-r--r--vcore/src/dpl/log/include/dpl/log/abstract_log_provider.h59
-rw-r--r--vcore/src/dpl/log/include/dpl/log/dlog_log_provider.h73
-rw-r--r--vcore/src/dpl/log/include/dpl/log/log.h171
-rw-r--r--vcore/src/dpl/log/include/dpl/log/old_style_log_provider.h84
-rw-r--r--vcore/src/dpl/log/include/dpl/log/vcore_log.h48
-rw-r--r--vcore/src/dpl/log/include/dpl/log/wrt_log.h48
-rw-r--r--vcore/src/dpl/log/src/abstract_log_provider.cpp34
-rw-r--r--vcore/src/dpl/log/src/dlog_log_provider.cpp117
-rw-r--r--vcore/src/dpl/log/src/log.cpp222
-rw-r--r--vcore/src/dpl/log/src/old_style_log_provider.cpp200
-rw-r--r--vcore/src/dpl/test/include/dpl/test/abstract_input_parser.h57
-rw-r--r--vcore/src/dpl/test/include/dpl/test/abstract_input_reader.h109
-rw-r--r--vcore/src/dpl/test/include/dpl/test/abstract_input_tokenizer.h85
-rw-r--r--vcore/src/dpl/test/include/dpl/test/process_pipe.h62
-rw-r--r--vcore/src/dpl/test/include/dpl/test/test_results_collector.h96
-rw-r--r--vcore/src/dpl/test/include/dpl/test/test_runner.h231
-rw-r--r--vcore/src/dpl/test/include/dpl/test/test_runner_child.h91
-rw-r--r--vcore/src/dpl/test/include/dpl/test/test_runner_multiprocess.h60
-rw-r--r--vcore/src/dpl/test/include/dpl/test/value_separated_parser.h94
-rw-r--r--vcore/src/dpl/test/include/dpl/test/value_separated_policies.h47
-rw-r--r--vcore/src/dpl/test/include/dpl/test/value_separated_reader.h63
-rw-r--r--vcore/src/dpl/test/include/dpl/test/value_separated_tokenizer.h149
-rw-r--r--vcore/src/dpl/test/include/dpl/test/value_separated_tokens.h44
-rw-r--r--vcore/src/dpl/test/src/process_pipe.cpp83
-rw-r--r--vcore/src/dpl/test/src/test_results_collector.cpp984
-rw-r--r--vcore/src/dpl/test/src/test_runner.cpp696
-rw-r--r--vcore/src/dpl/test/src/test_runner_child.cpp325
-rw-r--r--vcore/src/dpl/test/src/test_runner_multiprocess.cpp274
-rw-r--r--vcore/src/dpl/test/src/value_separated_policies.cpp65
-rw-r--r--vcore/src/dpl/test/src/value_separated_tokens.cpp44
-rw-r--r--vcore/src/server/include/cert-server-logic.h50
-rw-r--r--vcore/src/server/src/cert-server-logic.c1604
-rw-r--r--vcore/src/server/src/cert-server-main.c479
-rw-r--r--vcore/src/vcore/Base64.cpp61
-rw-r--r--vcore/src/vcore/Base64.h53
-rw-r--r--vcore/src/vcore/CRL.h23
-rw-r--r--vcore/src/vcore/CRLImpl.cpp146
-rw-r--r--vcore/src/vcore/CRLImpl.h24
-rw-r--r--vcore/src/vcore/CachedCRL.cpp26
-rw-r--r--vcore/src/vcore/CachedOCSP.cpp14
-rw-r--r--vcore/src/vcore/CertStoreType.cpp43
-rw-r--r--vcore/src/vcore/CertStoreType.h19
-rw-r--r--vcore/src/vcore/Certificate.cpp289
-rw-r--r--vcore/src/vcore/Certificate.h69
-rw-r--r--vcore/src/vcore/CertificateCacheDAO.cpp56
-rw-r--r--vcore/src/vcore/CertificateCacheDAO.h2
-rw-r--r--vcore/src/vcore/CertificateCollection.cpp55
-rw-r--r--vcore/src/vcore/CertificateCollection.h19
-rw-r--r--vcore/src/vcore/CertificateConfigReader.cpp51
-rw-r--r--vcore/src/vcore/CertificateConfigReader.h39
-rw-r--r--vcore/src/vcore/CertificateIdentifier.h19
-rw-r--r--vcore/src/vcore/CertificateLoader.cpp138
-rw-r--r--vcore/src/vcore/CertificateLoader.h2
-rw-r--r--vcore/src/vcore/CertificateVerifier.cpp22
-rw-r--r--vcore/src/vcore/Config.h2
-rw-r--r--vcore/src/vcore/CryptoHash.cpp66
-rw-r--r--vcore/src/vcore/CryptoHash.h17
-rw-r--r--vcore/src/vcore/Database.cpp3
-rw-r--r--vcore/src/vcore/Database.h12
-rw-r--r--vcore/src/vcore/DeveloperModeValidator.cpp113
-rw-r--r--vcore/src/vcore/DeveloperModeValidator.h64
-rw-r--r--vcore/src/vcore/OCSP.cpp7
-rw-r--r--vcore/src/vcore/OCSP.h10
-rw-r--r--vcore/src/vcore/OCSPCertMgrUtil.cpp33
-rw-r--r--vcore/src/vcore/OCSPImpl.cpp149
-rw-r--r--vcore/src/vcore/OCSPImpl.h58
-rw-r--r--vcore/src/vcore/ParserSchema.h66
-rw-r--r--vcore/src/vcore/ReferenceValidator.cpp27
-rw-r--r--vcore/src/vcore/ReferenceValidator.h2
-rw-r--r--vcore/src/vcore/RevocationCheckerBase.cpp6
-rw-r--r--vcore/src/vcore/SaxReader.cpp229
-rw-r--r--vcore/src/vcore/SaxReader.h51
-rw-r--r--vcore/src/vcore/SignatureData.cpp154
-rw-r--r--vcore/src/vcore/SignatureData.h160
-rw-r--r--vcore/src/vcore/SignatureFinder.cpp14
-rw-r--r--vcore/src/vcore/SignatureFinder.h23
-rw-r--r--vcore/src/vcore/SignatureReader.cpp173
-rw-r--r--vcore/src/vcore/SignatureReader.h45
-rw-r--r--vcore/src/vcore/SignatureValidator.cpp462
-rw-r--r--vcore/src/vcore/SignatureValidator.h24
-rw-r--r--vcore/src/vcore/SoupMessageSendAsync.h172
-rw-r--r--vcore/src/vcore/SoupMessageSendBase.cpp6
-rw-r--r--vcore/src/vcore/SoupMessageSendSync.cpp14
-rw-r--r--vcore/src/vcore/TimeConversion.cpp8
-rw-r--r--vcore/src/vcore/VCore.cpp46
-rw-r--r--vcore/src/vcore/VCorePrivate.h2
-rw-r--r--vcore/src/vcore/ValidatorFactories.cpp11
-rw-r--r--vcore/src/vcore/WacOrigin.cpp4
-rw-r--r--vcore/src/vcore/WrtSignatureValidator.cpp353
-rw-r--r--vcore/src/vcore/WrtSignatureValidator.h21
-rw-r--r--vcore/src/vcore/XmlsecAdapter.cpp80
-rw-r--r--vcore/src/vcore/XmlsecAdapter.h6
-rw-r--r--vcore/src/vcore/api.cpp663
-rw-r--r--vcore/src/vcore/cert-svc-client.c582
-rw-r--r--vcore/src/vcore/cert-svc-client.h116
-rw-r--r--vcore/src/vcore/exception.cpp48
-rw-r--r--vcore/src/vcore/exception.h390
-rwxr-xr-xvcore/src/vcore/pkcs12.c946
-rw-r--r--vcore/src/vcore/pkcs12.cpp1465
-rw-r--r--vcore/src/vcore/pkcs12.h240
-rw-r--r--vcore/src/vcore/scoped_gpointer.h4
-rw-r--r--vcore/src/vcore/utils.c156
-rw-r--r--vcore/src/vcore/utils.h14
166 files changed, 21566 insertions, 3294 deletions
diff --git a/vcore/src/CMakeLists.txt b/vcore/src/CMakeLists.txt
index 0772fc6..c982724 100644
--- a/vcore/src/CMakeLists.txt
+++ b/vcore/src/CMakeLists.txt
@@ -1,34 +1,44 @@
-INCLUDE(FindPkgConfig)
+# compiler warning flags
+ADD_DEFINITIONS("-Wall")
+ADD_DEFINITIONS("-Wextra")
+ADD_DEFINITIONS("-Werror")
+IF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
PKG_CHECK_MODULES(VCORE_DEPS
- dpl-efl
- dpl-db-efl
- ecore
- appcore-efl
+ REQUIRED
+ glib-2.0
libxml-2.0
- libsoup-2.4
- libpcre
libpcrecpp
openssl
xmlsec1
+ dlog
secure-storage
- REQUIRED)
+ icu-uc
+ libsoup-2.4
+ db-util
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
+ sqlite3
+ vconf
+ )
+ELSE(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
PKG_CHECK_MODULES(VCORE_DEPS
- dpl-db-efl
- )
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-
-IF(TIZEN_FEAT_OSP_DISABLE EQUAL 1)
-ADD_DEFINITIONS("-DTIZEN_FEATURE_OSP_DISABLE")
-ENDIF(TIZEN_FEAT_OSP_DISABLE EQUAL 1)
-
-SET(LIBCRYPTSVC_DIR
- ${PROJECT_SOURCE_DIR}/vcore
+ REQUIRED
+ glib-2.0
+ libxml-2.0
+ libpcrecpp
+ openssl
+ xmlsec1
+ dlog
+ secure-storage
+ icu-uc
+ libsoup-2.4
+ db-util
)
+ENDIF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
-INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
+ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS})
+ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS_OTHER})
+ADD_DEFINITIONS("-DSEPARATED_SINGLETON_IMPLEMENTATION")
SET(VCORE_DIR
${PROJECT_SOURCE_DIR}/vcore
@@ -38,6 +48,54 @@ SET(VCORE_SRC_DIR
${VCORE_DIR}/src/vcore
)
+########### DPL SOURCES ##########
+SET(VCORE_DPL_DIR
+ ${VCORE_DIR}/src/dpl
+ )
+SET(VCORE_DPL_CORE_SRC_DIR
+ ${VCORE_DPL_DIR}/core/src
+ )
+SET(VCORE_DPL_CORE_SOURCES
+ ${VCORE_DPL_CORE_SRC_DIR}/assert.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/binary_queue.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/char_traits.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/colors.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/errno_string.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/exception.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/file_input.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/noncopyable.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/singleton.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/string.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/type_list.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/thread.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/waitable_event.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/waitable_handle.cpp
+ ${VCORE_DPL_CORE_SRC_DIR}/waitable_handle_watch_support.cpp
+ )
+
+SET(VCORE_DPL_DB_SRC_DIR
+ ${VCORE_DPL_DIR}/db/src
+ )
+SET(VCORE_DPL_DB_SOURCES
+ ${VCORE_DPL_DB_SRC_DIR}/naive_synchronization_object.cpp
+ ${VCORE_DPL_DB_SRC_DIR}/orm.cpp
+ ${VCORE_DPL_DB_SRC_DIR}/sql_connection.cpp
+ ${VCORE_DPL_DB_SRC_DIR}/thread_database_support.cpp
+ )
+
+SET(VCORE_DPL_LOG_SRC_DIR
+ ${VCORE_DPL_DIR}/log/src
+ )
+SET(VCORE_DPL_LOG_SOURCES
+ ${VCORE_DPL_LOG_SRC_DIR}/abstract_log_provider.cpp
+ ${VCORE_DPL_LOG_SRC_DIR}/old_style_log_provider.cpp
+ ${VCORE_DPL_LOG_SRC_DIR}/dlog_log_provider.cpp
+ ${VCORE_DPL_LOG_SRC_DIR}/log.cpp
+ )
+########### DPL SOURCES ##########
+
+
+########### VCORE SOURCES ########
SET(VCORE_SOURCES
${VCORE_SRC_DIR}/api.cpp
${VCORE_SRC_DIR}/Base64.cpp
@@ -52,6 +110,7 @@ SET(VCORE_SOURCES
${VCORE_SRC_DIR}/ReferenceValidator.cpp
${VCORE_SRC_DIR}/RevocationCheckerBase.cpp
${VCORE_SRC_DIR}/SaxReader.cpp
+ ${VCORE_SRC_DIR}/SignatureData.cpp
${VCORE_SRC_DIR}/SignatureFinder.cpp
${VCORE_SRC_DIR}/SignatureReader.cpp
${VCORE_SRC_DIR}/TimeConversion.cpp
@@ -61,141 +120,158 @@ SET(VCORE_SOURCES
${VCORE_SRC_DIR}/WrtSignatureValidator.cpp
${VCORE_SRC_DIR}/SignatureValidator.cpp
${VCORE_SRC_DIR}/XmlsecAdapter.cpp
- ${VCORE_SRC_DIR}/pkcs12.c
- )
+ ${VCORE_SRC_DIR}/pkcs12.cpp
+ ${VCORE_SRC_DIR}/exception.cpp
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-SET(VCORE_SOURCES
- ${VCORE_SRC_DIR}/api.cpp
- ${VCORE_SRC_DIR}/Base64.cpp
- ${VCORE_SRC_DIR}/Certificate.cpp
- ${VCORE_SRC_DIR}/CertificateCollection.cpp
- ${VCORE_SRC_DIR}/CertificateConfigReader.cpp
- ${VCORE_SRC_DIR}/CertificateLoader.cpp
- ${VCORE_SRC_DIR}/CertStoreType.cpp
- ${VCORE_SRC_DIR}/Config.cpp
- ${VCORE_SRC_DIR}/CryptoHash.cpp
- ${VCORE_SRC_DIR}/OCSPCertMgrUtil.cpp
- ${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}/TimeConversion.cpp
- ${VCORE_SRC_DIR}/VerificationStatus.cpp
- ${VCORE_SRC_DIR}/ValidatorFactories.cpp
- ${VCORE_SRC_DIR}/VCore.cpp
- ${VCORE_SRC_DIR}/DUID.cpp
- ${VCORE_SRC_DIR}/WrtSignatureValidator.cpp
- ${VCORE_SRC_DIR}/SignatureValidator.cpp
- ${VCORE_SRC_DIR}/XmlsecAdapter.cpp
- ${VCORE_SRC_DIR}/pkcs12.c
- ${VCORE_SRC_DIR}/CachedCRL.cpp
+ ${VCORE_SRC_DIR}/utils.c
+ ${VCORE_SRC_DIR}/cert-svc-client.c
+ )
+
+SET(VCORE_OCSP_CRL_SOURCES
+ ${VCORE_SRC_DIR}/CachedCRL.cpp
${VCORE_SRC_DIR}/CachedOCSP.cpp
- ${VCORE_SRC_DIR}/CertificateCacheDAO.cpp
- ${VCORE_SRC_DIR}/CertificateVerifier.cpp
- ${VCORE_SRC_DIR}/CRL.cpp
+ ${VCORE_SRC_DIR}/CertificateCacheDAO.cpp
+ ${VCORE_SRC_DIR}/CertificateVerifier.cpp
+ ${VCORE_SRC_DIR}/CRL.cpp
${VCORE_SRC_DIR}/CRLImpl.cpp
${VCORE_SRC_DIR}/CRLCacheDAO.cpp
- ${VCORE_SRC_DIR}/Database.cpp
+ ${VCORE_SRC_DIR}/Database.cpp
${VCORE_SRC_DIR}/OCSP.cpp
${VCORE_SRC_DIR}/OCSPImpl.cpp
- ${VCORE_SRC_DIR}/SoupMessageSendBase.cpp
+ ${VCORE_SRC_DIR}/SoupMessageSendBase.cpp
${VCORE_SRC_DIR}/SoupMessageSendSync.cpp
- ${VCORE_SRC_DIR}/SoupMessageSendAsync.cpp
- ${VCORE_SRC_DIR}/OCSPUtil.c
+ ${VCORE_SRC_DIR}/OCSPUtil.c
)
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
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
)
-ELSE(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-SET(VCORE_INCLUDES
- ${VCORE_DEPS_INCLUDE_DIRS}
- ${VCORE_SRC_DIR}
- ${VCORE_DIR}/src
- ${VCORE_DIR}/src/legacy
- ${CMAKE_BINARY_DIR}/vcore/src
+
+SET(VCORE_INCLUDES_OCSP_CRL
+ ${VCORE_DIR}/src/orm
)
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
+########### VCORE SOURCES ########
-ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS})
-ADD_DEFINITIONS(${VCORE_DEPS_CFLAGS_OTHER})
-ADD_DEFINITIONS("-DSEPARATED_SINGLETON_IMPLEMENTATION")
-ADD_DEFINITIONS("-DDPL_LOGS_ENABLED")
-ADD_DEFINITIONS("-DCERT_SVC_LOG")
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-ADD_DEFINITIONS("-DTIZENUCT_FEATURE_CERT_SVC_OCSP_CRL")
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-
-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})
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
+IF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
+SET(VCORE_ALL_SOURCES
+ ${VCORE_SOURCES}
+ ${VCORE_DPL_CORE_SOURCES}
+ ${VCORE_DPL_DB_SOURCES}
+ ${VCORE_DPL_LOG_SOURCES}
+ ${VCORE_OCSP_CRL_SOURCES}
+ )
+SET(VCORE_ALL_INCLUDES
+ ${PROJECT_SOURCE_DIR}/include
+ ${VCORE_INCLUDES}
+ ${VCORE_DPL_DIR}/core/include
+ ${VCORE_DPL_DIR}/db/include
+ ${VCORE_DPL_DIR}/log/include
+ ${VCORE_INCLUDES_OCSP_CRL}
+ )
+ELSE(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
+SET(VCORE_ALL_SOURCES
+ ${VCORE_SOURCES}
+ ${VCORE_DPL_CORE_SOURCES}
+ ${VCORE_DPL_LOG_SOURCES}
+ )
+SET(VCORE_ALL_INCLUDES
+ ${PROJECT_SOURCE_DIR}/include
+ ${VCORE_INCLUDES}
+ ${VCORE_DPL_DIR}/core/include
+ ${VCORE_DPL_DIR}/log/include
+ )
+ENDIF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
+
+INCLUDE_DIRECTORIES(SYSTEM ${VCORE_ALL_INCLUDES})
+
+ADD_LIBRARY(${TARGET_VCORE_LIB} SHARED ${VCORE_ALL_SOURCES})
+
+# TODO: visibility needed to be hidden
+SET_TARGET_PROPERTIES(${TARGET_VCORE_LIB}
+ PROPERTIES
+ COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default"
+ SOVERSION ${SO_VERSION}
+ VERSION ${VERSION})
+
+IF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
ADD_DEPENDENCIES(${TARGET_VCORE_LIB} Sqlite3DbWTF)
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
+ENDIF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-TARGET_LINK_LIBRARIES(${TARGET_VCORE_LIB}
- ${VCORE_DEPS_LIBRARIES}
- ${TARGET_CERT_SVC_LIB}
- dpl-db-efl
- )
-ELSE(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
TARGET_LINK_LIBRARIES(${TARGET_VCORE_LIB}
${VCORE_DEPS_LIBRARIES}
${TARGET_CERT_SVC_LIB}
- )
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
+ )
+
+########## cert-server #############
+PKG_CHECK_MODULES(CERT_SERVER_DEP
+ REQUIRED
+ dlog
+ sqlite3
+ db-util
+ libsystemd-daemon
+ key-manager
+ )
+
+SET(CERT_SERVER_DIR
+ ${PROJECT_SOURCE_DIR}/vcore/src/server
+ )
+
+SET(CERT_SERVER_SRCS
+ ${CERT_SERVER_DIR}/src/cert-server-main.c
+ ${CERT_SERVER_DIR}/src/cert-server-logic.c
+ )
+
+INCLUDE_DIRECTORIES(
+ SYSTEM
+ ${CERT_SERVER_DEP_INCLUDE_DIRS}
+ ${PROJECT_SOURCE_DIR}/include
+ ${VCORE_DIR}/src
+ ${CERT_SERVER_DIR}/include
+ )
+
+SET_SOURCE_FILES_PROPERTIES(
+ ${CERT_SERVER_SRCS}
+ PROPERTIES
+ COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden -fPIE"
+ )
+
+ADD_EXECUTABLE(${TARGET_CERT_SERVER} ${CERT_SERVER_SRCS})
+
+TARGET_LINK_LIBRARIES(${TARGET_CERT_SERVER}
+ ${CERT_SERVER_DEP_LIBRARIES}
+ -pie
+ )
+
+INSTALL(TARGETS ${TARGET_CERT_SERVER} DESTINATION ${BINDIR})
+
+########################################################
INSTALL(TARGETS ${TARGET_VCORE_LIB}
- DESTINATION ${LIB_INSTALL_DIR}
+ DESTINATION ${LIBDIR}
)
INSTALL(FILES
- ${VCORE_SRC_DIR}/Base64.h
- ${VCORE_SRC_DIR}/Certificate.h
+ ${VCORE_SRC_DIR}/VCore.h
+ ${VCORE_SRC_DIR}/WrtSignatureValidator.h
+ ${VCORE_SRC_DIR}/SignatureValidator.h
+ ${VCORE_SRC_DIR}/SignatureFinder.h
+ ${VCORE_SRC_DIR}/SignatureReader.h
${VCORE_SRC_DIR}/CertificateCollection.h
- ${VCORE_SRC_DIR}/CertStoreType.h
${VCORE_SRC_DIR}/CryptoHash.h
- ${VCORE_SRC_DIR}/IAbstractResponseCache.h
+ ${VCORE_SRC_DIR}/Base64.h
+
${VCORE_SRC_DIR}/ParserSchema.h
- ${VCORE_SRC_DIR}/ReferenceValidator.h
${VCORE_SRC_DIR}/SaxReader.h
+
+ ${VCORE_SRC_DIR}/Certificate.h
${VCORE_SRC_DIR}/SignatureData.h
- ${VCORE_SRC_DIR}/SignatureFinder.h
- ${VCORE_SRC_DIR}/SignatureReader.h
- ${VCORE_SRC_DIR}/WrtSignatureValidator.h
- ${VCORE_SRC_DIR}/SignatureValidator.h
- ${VCORE_SRC_DIR}/VerificationStatus.h
- ${VCORE_SRC_DIR}/VCore.h
+ ${VCORE_SRC_DIR}/CertStoreType.h
+ ${VCORE_SRC_DIR}/exception.h
DESTINATION ${INCLUDEDIR}/cert-svc/vcore
)
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-INSTALL(FILES
- ${VCORE_SRC_DIR}/CachedCRL.h
- ${VCORE_SRC_DIR}/CachedOCSP.h
- ${VCORE_SRC_DIR}/CRL.h
- ${VCORE_SRC_DIR}/CRLCacheInterface.h
- ${VCORE_SRC_DIR}/OCSP.h
- ${VCORE_SRC_DIR}/OCSPCertMgrUtil.h
- DESTINATION ${INCLUDEDIR}/cert-svc/vcore
- )
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
-
INSTALL(FILES
${VCORE_DIR}/src/cert-svc/ccert.h
${VCORE_DIR}/src/cert-svc/cinstance.h
@@ -206,12 +282,22 @@ INSTALL(FILES
DESTINATION ${INCLUDEDIR}/cert-svc/cert-svc
)
-IF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
+IF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
INSTALL(FILES
- ${VCORE_DIR}/src/cert-svc/ccrl.h
- ${VCORE_DIR}/src/cert-svc/cocsp.h
- DESTINATION ${INCLUDEDIR}/cert-svc/cert-svc
- )
-ENDIF(TIZEN_FEAT_PROFILE_CERT_SVC_OCSP_CRL)
+ ${VCORE_SRC_DIR}/IAbstractResponseCache.h
+ ${VCORE_SRC_DIR}/VerificationStatus.h
+ ${VCORE_SRC_DIR}/CachedCRL.h
+ ${VCORE_SRC_DIR}/CachedOCSP.h
+ ${VCORE_SRC_DIR}/CRL.h
+ ${VCORE_SRC_DIR}/CRLCacheInterface.h
+ ${VCORE_SRC_DIR}/OCSP.h
+ ${VCORE_SRC_DIR}/OCSPCertMgrUtil.h
+ DESTINATION ${INCLUDEDIR}/cert-svc/vcore
+ )
-#FILE(MAKE_DIRECTORY %{TZ_SYS_SHARE}/cert-svc/pkcs12)
+INSTALL(FILES
+ ${VCORE_DIR}/src/cert-svc/ccrl.h
+ ${VCORE_DIR}/src/cert-svc/cocsp.h
+ DESTINATION ${INCLUDEDIR}/cert-svc/cert-svc
+ )
+ENDIF(DEFINED TIZEN_FEAT_CERTSVC_OCSP_CRL)
diff --git a/vcore/src/cert-svc/ccert.h b/vcore/src/cert-svc/ccert.h
index d26837e..798d520 100644
--- a/vcore/src/cert-svc/ccert.h
+++ b/vcore/src/cert-svc/ccert.h
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 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.
@@ -41,6 +41,38 @@ typedef struct CertSvcCertificateList_t {
CertSvcInstance privateInstance;
} CertSvcCertificateList;
+#define MAX_STORE_ENUMS 5
+typedef enum certImportType_t {
+ NONE_STORE = 0,
+ VPN_STORE = 1 << 0,
+ WIFI_STORE = 1 << 1,
+ EMAIL_STORE = 1 << 2,
+ SYSTEM_STORE = 1 << 3,
+ ALL_STORE = VPN_STORE | WIFI_STORE | EMAIL_STORE | SYSTEM_STORE
+} CertStoreType;
+
+typedef struct CertSvcStoreCertList_t{
+ char* gname; // keyfile group name
+ char* title; // common Name / Alias provided by the user
+ int status; // enabled / disabled
+ CertStoreType storeType; // Holds the storetype information
+ struct CertSvcStoreCertList_t *next;
+}CertSvcStoreCertList;
+
+typedef enum certType_t {
+ PEM_CRT = 1 << 0,
+ P12_END_USER = 1 << 1,
+ P12_INTERMEDIATE = 1 << 2,
+ P12_TRUSTED = 1 << 3,
+ P12_PKEY = 1 << 4,
+ INVALID_DATA = 1 << 5,
+} CertType;
+
+typedef enum certStatus_t {
+ DISABLED = 0,
+ ENABLED = 1,
+} CertStatus;
+
typedef enum CertSvcCertificateForm_t {
/* CERTSVC_FORM_PEM, */
CERTSVC_FORM_DER,
@@ -79,6 +111,20 @@ typedef enum CertSvcVisibility_t {
} CertSvcVisibility;
/**
+ * This function will return certificate for the unique name identifier passed (gname).
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to the store (WIFI_STORE, VPN_STORE, EMAIL_STORE, SSL_STORE).
+ * @oaran[in] gname Refers to the unique name identifier associated for the certificate.
+ * @param[out] certificate Certificate for the gname passed.
+ * @return CERTSVC_SUCCESS, CERTSVC_BAD_ALLOC, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_get_certificate(CertSvcInstance instance,
+ CertStoreType storeType,
+ char *gname,
+ CertSvcCertificate *certificate);
+
+/**
* Read certificate from file. Certificate must be in PEM/CER/DER format.
*
* @param[in] instance CertSvcInstance object.
@@ -365,6 +411,7 @@ int certsvc_certificate_verify_with_caflag(
*/
int certsvc_certificate_get_visibility(CertSvcCertificate certificate, int* visibility);
+
#ifdef __cplusplus
}
#endif
diff --git a/vcore/src/cert-svc/cerror.h b/vcore/src/cert-svc/cerror.h
index 0566152..b850b3c 100644
--- a/vcore/src/cert-svc/cerror.h
+++ b/vcore/src/cert-svc/cerror.h
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 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.
@@ -27,19 +27,21 @@
extern "C" {
#endif
-#define CERTSVC_TRUE (1)
-#define CERTSVC_FALSE (0)
+#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. */
+#define CERTSVC_SUCCESS (1)
+#define CERTSVC_FAIL (0) /* Openssl internal error. */
+#define CERTSVC_BAD_ALLOC (-2) /* Memmory allcation error. */
+#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. */
+#define CERTSVC_ALIAS_DOES_NOT_EXIST (-10) /* Alias no exist in store. */
+#define CERTSVC_INVALID_STORE_TYPE (-11) /* User-provided invalid import type for storing in system/email/wifi/vpn store. */
+#define CERTSVC_INVALID_STATUS (-12) /* User-provided invalid status while stetting the status for the store system/email/wifi/vpn store. */
#ifdef __cplusplus
}
diff --git a/vcore/src/cert-svc/cpkcs12.h b/vcore/src/cert-svc/cpkcs12.h
index 328afd9..d779fa2 100644
--- a/vcore/src/cert-svc/cpkcs12.h
+++ b/vcore/src/cert-svc/cpkcs12.h
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 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.
@@ -48,7 +48,7 @@ int certsvc_pkcs12_alias_exists(CertSvcInstance instance,
* @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).
+ * @param[in] alias Logical name for certificate bundle identification (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,
@@ -126,6 +126,215 @@ void certsvc_pkcs12_private_key_free(char *buffer);
int certsvc_pkcs12_delete(CertSvcInstance instance,
CertSvcString alias);
+/**
+ * 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] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Container bundle identifier.
+ * @param[out] certBuffer Poiner to newly-allocated memory with private key data.
+ * @param[out] certsize 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_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ char **certBuffer,
+ size_t *certsize);
+
+/**
+ * This function will set the status for the specified certificate in a particular
+ * store to enabled / disabled.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] is_root_app Set to ENABLED/DISABLED. Should be ENABLED if master application is changing the status, else DISABLED for other applications.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @param[in] status Allows to set the status of the certificate to enabled / disabled.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_set_certificate_status_to_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ int is_root_app,
+ CertSvcString gname,
+ CertStatus status);
+
+/**
+ * This function will get the status for the specified certificate in a particular
+ * store.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @param[out] status refers to weather the certificate is enabled/disabled.
+ * @return Disable=0, Enable=1, Fail=-1
+ */
+int certsvc_pkcs12_get_certificate_status_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ int *status);
+
+/**
+ * This function will get the Alias name, Path to certificate, Certificate status of all
+ * the certificates present in the specified certificate store.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[out] certList Linked-list having all the information about each certificate present in a store.
+ * @param[out] length Provides the length of the linked list.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_get_certificate_list_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ int is_root_app,
+ CertSvcStoreCertList** certList,
+ int* length);
+
+/**
+ * This function will get the Alias name, Path to certificate, Certificate status of all
+ * the end user certificates present in the specified certificate store.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[out] certList Linked-list having all the information about each certificate present in a store.
+ * @param[out] length Provides the length of the linked list.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_get_end_user_certificate_list_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcStoreCertList** certList,
+ int* length);
+
+/**
+ * This function will get the Alias name, Path to certificate, Certificate status of all
+ * the root/trusted certificates present in the specified certificate store.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[out] certList Linked-list having all the information about each certificate present in a store.
+ * @param[out] length Provides the length of the linked list.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_get_root_certificate_list_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcStoreCertList** certList,
+ int* length);
+
+/**
+ * This function will free all the linked list of data structure holding the information about
+ * all the certificates present in a store which was previously by calling the
+ * certsvc_get_certificate_list_from_store() function.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] certList The structure which need to be freed.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_free_certificate_list_loaded_from_store(CertSvcInstance instance,
+ CertSvcStoreCertList** certList);
+
+/**
+ * This function will provide the certificate back for the gname provided.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in[ gname Referred as group name, is the key for accessing the certificate.
+ * @param[out] certificate Certificate holding the information.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_BAD_ALLOC
+ */
+int certsvc_pkcs12_get_certificate_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ char *gname,
+ CertSvcCertificate *certificate);
+
+/**
+ * This function will give back the the encoded certificate buffer for the matching
+ * alias present in the specified store.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @param[out] certBuffer Buffer containing the encoded certificate.
+ * @param[out] certSize Size of the buffer.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_get_certificate_info_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ char** certBuffer,
+ size_t* certSize);
+
+/**
+ * This function will import a .pfx/.p12 file to specified store (WIFI, VPN, EMAIL).
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] path Path of the certificate which needs to be imported.
+ * @param[in] password Password to open the pfx/p12 file.
+ * @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString path,
+ CertSvcString password,
+ CertSvcString alias);
+
+/**
+ * This function will delete the certificate from the path specified present in the specified store.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE
+ */
+int certsvc_pkcs12_delete_certificate_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname);
+
+/**
+ * Query PKCS#12 storage to find out whenever new alias proposal is unique.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @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_check_alias_exists_in_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString alias,
+ int *is_unique);
+
+/**
+ * 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_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString pfxIdString,
+ CertSvcCertificateList *certificateList);
+
+/**
+ * Gets the alias name for the gname passed.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] gname Certificate identification of pfx/pkcs file.
+ * @param[out] alias Alias name for the given gname.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int certsvc_pkcs12_get_alias_name_for_certificate_in_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ char **alias);
+
#ifdef __cplusplus
}
#endif
diff --git a/vcore/src/cert-svc/cprimitives.h b/vcore/src/cert-svc/cprimitives.h
index da6fae6..d53b961 100644
--- a/vcore/src/cert-svc/cprimitives.h
+++ b/vcore/src/cert-svc/cprimitives.h
@@ -65,6 +65,22 @@ int certsvc_pkcs12_dup_evp_pkey(CertSvcInstance instance,
CertSvcString alias,
EVP_PKEY** pkey);
+/**
+ * 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] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Pkcs12 identificator.
+ * @param[out] pkey Duplicate of private key.
+ * @return CERTSVC_SUCCESS, CERT_FAIL
+ */
+
+int certsvc_pkcs12_dup_evp_pkey_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ EVP_PKEY** pkey);
+
void certsvc_pkcs12_free_evp_pkey(EVP_PKEY* pkey);
#ifdef __cplusplus
diff --git a/vcore/src/dpl/core/include/dpl/abstract_input.h b/vcore/src/dpl/core/include/dpl/abstract_input.h
new file mode 100644
index 0000000..08a2733
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/abstract_input.h
@@ -0,0 +1,58 @@
+/*
+ * 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 abstract_input.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of abstract input
+ */
+#ifndef DPL_ABSTRACT_INPUT_H
+#define DPL_ABSTRACT_INPUT_H
+
+#include <dpl/exception.h>
+#include <memory>
+
+namespace VcoreDPL {
+class BinaryQueue;
+typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr;
+
+class AbstractInput
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, ReadFailed)
+ };
+
+ public:
+ virtual ~AbstractInput() {}
+
+ /**
+ * Read binary data from input
+ * If no data is available method returns NULL buffer.
+ * In case connection was successfuly close, method returns empty buffer
+ *
+ * @param[in] size Maximum number of bytes to read from input
+ * @return Buffer containing read bytes
+ * @throw ReadFailed
+ */
+ virtual BinaryQueueAutoPtr Read(size_t size) = 0;
+};
+} // namespace VcoreDPL
+
+#endif // DPL_ABSTRACT_INPUT_H
diff --git a/vcore/src/dpl/core/include/dpl/abstract_input_output.h b/vcore/src/dpl/core/include/dpl/abstract_input_output.h
new file mode 100644
index 0000000..9d1f17c
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/abstract_input_output.h
@@ -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 abstract_output.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of abstract output
+ */
+#ifndef DPL_ABSTRACT_INPUT_OUTPUT_H
+#define DPL_ABSTRACT_INPUT_OUTPUT_H
+
+#include <dpl/abstract_input.h>
+#include <dpl/abstract_output.h>
+
+namespace VcoreDPL {
+class AbstractInputOutput :
+ public AbstractInput,
+ public AbstractOutput
+{
+ public:
+ virtual ~AbstractInputOutput() {}
+};
+} // namespace VcoreDPL
+
+#endif // DPL_ABSTRACT_INPUT_OUTPUT_H
diff --git a/vcore/src/dpl/core/include/dpl/abstract_output.h b/vcore/src/dpl/core/include/dpl/abstract_output.h
new file mode 100644
index 0000000..6b414eb
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/abstract_output.h
@@ -0,0 +1,60 @@
+/*
+ * 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 abstract_output.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of abstract output
+ */
+#ifndef DPL_ABSTRACT_OUTPUT_H
+#define DPL_ABSTRACT_OUTPUT_H
+
+#include <dpl/exception.h>
+#include <memory>
+
+namespace VcoreDPL {
+class BinaryQueue;
+typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr;
+
+class AbstractOutput
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, WriteFailed)
+ };
+
+ public:
+ virtual ~AbstractOutput() {}
+
+ /**
+ * Write binary data to output
+ * If output is blocked, Write returns zero, if instance is a type of
+ * WaitableAbstractOutput one can wait for writability then
+ *
+ * @param[in] buffer Input buffer with data to be written
+ * @param[in] bufferSize Maximum number of bytes to write from buffer
+ * @return Number of bytes success successfuly written or zero if output is
+ * blocked
+ * @throw WriteFailed
+ */
+ virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize) = 0;
+};
+} // namespace VcoreDPL
+
+#endif // DPL_ABSTRACT_OUTPUT_H
diff --git a/vcore/src/dpl/core/include/dpl/abstract_waitable_input.h b/vcore/src/dpl/core/include/dpl/abstract_waitable_input.h
new file mode 100644
index 0000000..6447690
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/abstract_waitable_input.h
@@ -0,0 +1,39 @@
+/*
+ * 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 abstract_waitable_input.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of abstract waitable input
+ */
+#ifndef DPL_ABSTRACT_WAITABLE_INPUT_H
+#define DPL_ABSTRACT_WAITABLE_INPUT_H
+
+#include <dpl/waitable_handle.h>
+#include <dpl/abstract_input.h>
+
+namespace VcoreDPL {
+class AbstractWaitableInput :
+ public AbstractInput
+{
+ public:
+ virtual ~AbstractWaitableInput() {}
+
+ virtual WaitableHandle WaitableReadHandle() const = 0;
+};
+} // namespace VcoreDPL
+
+#endif // DPL_ABSTRACT_WAITABLE_INPUT_H
diff --git a/vcore/src/dpl/core/include/dpl/assert.h b/vcore/src/dpl/core/include/dpl/assert.h
new file mode 100644
index 0000000..b2cb426
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/assert.h
@@ -0,0 +1,51 @@
+/*
+ * 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 assert.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of assert
+ */
+#ifndef DPL_ASSERT_H
+#define DPL_ASSERT_H
+
+namespace VcoreDPL {
+// Assertion handler procedure
+// Do not call directly
+// Always use Assert macro
+void AssertProc(const char *condition,
+ const char *file,
+ int line,
+ const char *function) __attribute__ ((__noreturn__));
+} // namespace VcoreDPL
+
+#define Assert(Condition) \
+do { \
+ if (!(Condition)) { \
+ VcoreDPL::AssertProc(#Condition, __FILE__, __LINE__, __FUNCTION__); \
+ } \
+} while (0)
+
+#define AssertMsg(Condition, Msg) \
+ do { \
+ if (!(Condition)) { \
+ VcoreDPL::AssertProc( \
+ (std::string(std::string(#Condition)+" ") + Msg).c_str(), \
+ __FILE__, __LINE__, __FUNCTION__); \
+ } \
+ } while (0)
+
+#endif // DPL_ASSERT_H
diff --git a/vcore/src/dpl/core/include/dpl/availability.h b/vcore/src/dpl/core/include/dpl/availability.h
new file mode 100644
index 0000000..0813892
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/availability.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 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 availability.h
+ * @author Jihoon Chung (jihoon.chung@samsung.com)
+ * @version 1.0
+ */
+#ifndef DPL_AVAILABILITY_H
+#define DPL_AVAILABILITY_H
+
+#define DPL_DEPRECATED __attribute__((deprecated))
+#define DPL_DEPRECATED_WITH_MESSAGE(msg) __attribute__((deprecated(msg)))
+
+#define DPL_UNUSED __attribute__((unused))
+#define DPL_UNUSED_PARAM(variable) (void)variable
+
+#endif // DPL_AVAILABILITY_H
diff --git a/vcore/src/dpl/core/include/dpl/binary_queue.h b/vcore/src/dpl/core/include/dpl/binary_queue.h
new file mode 100644
index 0000000..92d4e3f
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/binary_queue.h
@@ -0,0 +1,296 @@
+/*
+ * 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 binary_queue.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of binary queue
+ */
+#ifndef DPL_BINARY_QUEUE_H
+#define DPL_BINARY_QUEUE_H
+
+#include <dpl/abstract_input_output.h>
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <memory>
+#include <list>
+
+namespace VcoreDPL {
+/**
+ * Binary stream implemented as constant size bucket list
+ *
+ * @todo Add optimized implementation for FlattenConsume
+ */
+class BinaryQueue :
+ public AbstractInputOutput
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, OutOfData)
+ };
+
+ typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize,
+ void *userParam);
+ static void BufferDeleterFree(const void *buffer,
+ size_t bufferSize,
+ void *userParam);
+
+ class BucketVisitor
+ {
+ public:
+ /**
+ * Destructor
+ */
+ virtual ~BucketVisitor();
+
+ /**
+ * Visit bucket
+ *
+ * @return none
+ * @param[in] buffer Constant pointer to bucket data buffer
+ * @param[in] bufferSize Number of bytes in bucket
+ */
+ virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0;
+ };
+
+ private:
+ struct Bucket :
+ private Noncopyable
+ {
+ const void *buffer;
+ const void *ptr;
+ size_t size;
+ size_t left;
+
+ BufferDeleter deleter;
+ void *param;
+
+ Bucket(const void *buffer,
+ size_t bufferSize,
+ BufferDeleter deleter,
+ void *userParam);
+ virtual ~Bucket();
+ };
+
+ typedef std::list<Bucket *> BucketList;
+ BucketList m_buckets;
+ size_t m_size;
+
+ static void DeleteBucket(Bucket *bucket);
+
+ class BucketVisitorCall
+ {
+ private:
+ BucketVisitor *m_visitor;
+
+ public:
+ BucketVisitorCall(BucketVisitor *visitor);
+ virtual ~BucketVisitorCall();
+
+ void operator()(Bucket *bucket) const;
+ };
+
+ public:
+ /**
+ * Construct empty binary queue
+ */
+ BinaryQueue();
+
+ /**
+ * Construct binary queue via bare copy of other binary queue
+ *
+ * @param[in] other Other binary queue to copy from
+ * @warning One cannot assume that bucket structure is preserved during copy
+ */
+ BinaryQueue(const BinaryQueue &other);
+
+ /**
+ * Destructor
+ */
+ virtual ~BinaryQueue();
+
+ /**
+ * Construct binary queue via bare copy of other binary queue
+ *
+ * @param[in] other Other binary queue to copy from
+ * @warning One cannot assume that bucket structure is preserved during copy
+ */
+ BinaryQueue &operator=(const BinaryQueue &other);
+
+ /**
+ * Append copy of @a bufferSize bytes from memory pointed by @a buffer
+ * to the end of binary queue. Uses default deleter based on free.
+ *
+ * @return none
+ * @param[in] buffer Pointer to buffer to copy data from
+ * @param[in] bufferSize Number of bytes to copy
+ * @exception std::bad_alloc Cannot allocate memory to hold additional data
+ * @see BinaryQueue::BufferDeleterFree
+ */
+ void AppendCopy(const void *buffer, size_t bufferSize);
+
+ /**
+ * Append @a bufferSize bytes from memory pointed by @a buffer
+ * to the end of binary queue. Uses custom provided deleter.
+ * Responsibility for deleting provided buffer is transfered to BinaryQueue.
+ *
+ * @return none
+ * @param[in] buffer Pointer to data buffer
+ * @param[in] bufferSize Number of bytes available in buffer
+ * @param[in] deleter Pointer to deleter procedure used to free provided
+ * buffer
+ * @param[in] userParam User parameter passed to deleter routine
+ * @exception std::bad_alloc Cannot allocate memory to hold additional data
+ */
+ void AppendUnmanaged(
+ const void *buffer,
+ size_t bufferSize,
+ BufferDeleter deleter =
+ &BinaryQueue::BufferDeleterFree,
+ void *userParam = NULL);
+
+ /**
+ * Append copy of other binary queue to the end of this binary queue
+ *
+ * @return none
+ * @param[in] other Constant reference to other binary queue to copy data
+ * from
+ * @exception std::bad_alloc Cannot allocate memory to hold additional data
+ * @warning One cannot assume that bucket structure is preserved during copy
+ */
+ void AppendCopyFrom(const BinaryQueue &other);
+
+ /**
+ * Move bytes from other binary queue to the end of this binary queue.
+ * This also removes all bytes from other binary queue.
+ * This method is designed to be as fast as possible (only pointer swaps)
+ * and is suggested over making copies of binary queues.
+ * Bucket structure is preserved after operation.
+ *
+ * @return none
+ * @param[in] other Reference to other binary queue to move data from
+ * @exception std::bad_alloc Cannot allocate memory to hold additional data
+ */
+ void AppendMoveFrom(BinaryQueue &other);
+
+ /**
+ * Append copy of binary queue to the end of other binary queue
+ *
+ * @return none
+ * @param[in] other Constant reference to other binary queue to copy data to
+ * @exception std::bad_alloc Cannot allocate memory to hold additional data
+ * @warning One cannot assume that bucket structure is preserved during copy
+ */
+ void AppendCopyTo(BinaryQueue &other) const;
+
+ /**
+ * Move bytes from binary queue to the end of other binary queue.
+ * This also removes all bytes from binary queue.
+ * This method is designed to be as fast as possible (only pointer swaps)
+ * and is suggested over making copies of binary queues.
+ * Bucket structure is preserved after operation.
+ *
+ * @return none
+ * @param[in] other Reference to other binary queue to move data to
+ * @exception std::bad_alloc Cannot allocate memory to hold additional data
+ */
+ void AppendMoveTo(BinaryQueue &other);
+
+ /**
+ * Retrieve total size of all data contained in binary queue
+ *
+ * @return Number of bytes in binary queue
+ */
+ size_t Size() const;
+
+ /**
+ * Remove all data from binary queue
+ *
+ * @return none
+ */
+ void Clear();
+
+ /**
+ * Check if binary queue is empty
+ *
+ * @return true if binary queue is empty, false otherwise
+ */
+ bool Empty() const;
+
+ /**
+ * Remove @a size bytes from beginning of binary queue
+ *
+ * @return none
+ * @param[in] size Number of bytes to remove
+ * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger
+ * than available bytes in binary queue
+ */
+ void Consume(size_t size);
+
+ /**
+ * Retrieve @a bufferSize bytes from beginning of binary queue and copy them
+ * to user supplied buffer
+ *
+ * @return none
+ * @param[in] buffer Pointer to user buffer to receive bytes
+ * @param[in] bufferSize Size of user buffer pointed by @a buffer
+ * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten
+ * is larger than available bytes in binary queue
+ */
+ void Flatten(void *buffer, size_t bufferSize) const;
+
+ /**
+ * Retrieve @a bufferSize bytes from beginning of binary queue, copy them
+ * to user supplied buffer, and remove from binary queue
+ *
+ * @return none
+ * @param[in] buffer Pointer to user buffer to receive bytes
+ * @param[in] bufferSize Size of user buffer pointed by @a buffer
+ * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten
+ * is larger than available bytes in binary queue
+ */
+ void FlattenConsume(void *buffer, size_t bufferSize);
+
+ /**
+ * Visit each buffer with data using visitor object
+ *
+ * @return none
+ * @param[in] visitor Pointer to bucket visitor
+ * @see BinaryQueue::BucketVisitor
+ */
+ void VisitBuckets(BucketVisitor *visitor) const;
+
+ /**
+ * IAbstractInput interface
+ */
+ virtual BinaryQueueAutoPtr Read(size_t size);
+
+ /**
+ * IAbstractOutput interface
+ */
+ virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize);
+};
+
+/**
+ * Binary queue auto pointer
+ */
+typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr;
+} // namespace VcoreDPL
+
+#endif // DPL_BINARY_QUEUE_H
diff --git a/vcore/src/dpl/core/include/dpl/char_traits.h b/vcore/src/dpl/core/include/dpl/char_traits.h
new file mode 100644
index 0000000..a9d0bc0
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/char_traits.h
@@ -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 char_traits.h
+ * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @version 1.0
+ * @brief Char traits are used to create basic_string extended with
+ * additional features
+ * Current char traits could be extended in feature to boost
+ * performance
+ */
+#ifndef DPL_CHAR_TRAITS
+#define DPL_CHAR_TRAITS
+
+#include <cstring>
+#include <string>
+#include <ostream>
+#include <algorithm>
+#include <dpl/exception.h>
+
+namespace VcoreDPL {
+typedef std::char_traits<wchar_t> CharTraits;
+} // namespace VcoreDPL
+
+#endif // DPL_CHAR_TRAITS
diff --git a/vcore/src/dpl/core/include/dpl/colors.h b/vcore/src/dpl/core/include/dpl/colors.h
new file mode 100644
index 0000000..4c22139
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/colors.h
@@ -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 colors.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief Some constants with definition of colors for Console
+ * and html output
+ */
+
+#ifndef DPL_COLORS_H
+#define DPL_COLORS_H
+
+namespace VcoreDPL {
+namespace Colors {
+namespace Text {
+extern const char* BOLD_GREEN_BEGIN;
+extern const char* BOLD_GREEN_END;
+extern const char* PURPLE_BEGIN;
+extern const char* PURPLE_END;
+extern const char* RED_BEGIN;
+extern const char* RED_END;
+extern const char* GREEN_BEGIN;
+extern const char* GREEN_END;
+extern const char* CYAN_BEGIN;
+extern const char* CYAN_END;
+extern const char* BOLD_RED_BEGIN;
+extern const char* BOLD_RED_END;
+extern const char* BOLD_YELLOW_BEGIN;
+extern const char* BOLD_YELLOW_END;
+extern const char* BOLD_GOLD_BEGIN;
+extern const char* BOLD_GOLD_END;
+extern const char* BOLD_WHITE_BEGIN;
+extern const char* BOLD_WHITE_END;
+} //namespace Text
+
+namespace Html {
+extern const char* BOLD_GREEN_BEGIN;
+extern const char* BOLD_GREEN_END;
+extern const char* PURPLE_BEGIN;
+extern const char* PURPLE_END;
+extern const char* RED_BEGIN;
+extern const char* RED_END;
+extern const char* GREEN_BEGIN;
+extern const char* GREEN_END;
+extern const char* CYAN_BEGIN;
+extern const char* CYAN_END;
+extern const char* BOLD_RED_BEGIN;
+extern const char* BOLD_RED_END;
+extern const char* BOLD_YELLOW_BEGIN;
+extern const char* BOLD_YELLOW_END;
+extern const char* BOLD_GOLD_BEGIN;
+extern const char* BOLD_GOLD_END;
+extern const char* BOLD_WHITE_BEGIN;
+extern const char* BOLD_WHITE_END;
+} //namespace Html
+} //namespace Colors
+} //namespace VcoreDPL
+
+#endif /* DPL_COLORS_H */
diff --git a/vcore/src/dpl/core/include/dpl/errno_string.h b/vcore/src/dpl/core/include/dpl/errno_string.h
new file mode 100644
index 0000000..5ea55e5
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/errno_string.h
@@ -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 errno_string.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of errno string
+ */
+#ifndef DPL_ERRNO_STRING_H
+#define DPL_ERRNO_STRING_H
+
+#include <dpl/exception.h>
+#include <string>
+#include <cerrno>
+
+namespace VcoreDPL {
+DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, InvalidErrnoValue)
+
+std::string GetErrnoString(int error = errno);
+} // namespace VcoreDPL
+
+#endif // DPL_ERRNO_STRING_H
diff --git a/vcore/src/dpl/core/include/dpl/exception.h b/vcore/src/dpl/core/include/dpl/exception.h
new file mode 100644
index 0000000..95ea4ac
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/exception.h
@@ -0,0 +1,390 @@
+/*
+ * 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 exception.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief Header file for base exception
+ */
+#ifndef VcoreDPL_EXCEPTION_H
+#define VcoreDPL_EXCEPTION_H
+
+#include <string>
+#include <cstring>
+#include <cstdio>
+#include <exception>
+#include <cstdlib>
+#include <sstream>
+
+namespace VcoreDPL {
+void LogUnhandledException(const std::string &str);
+void LogUnhandledException(const std::string &str,
+ const char *filename,
+ int line,
+ const char *function);
+}
+
+namespace VcoreDPL {
+class Exception {
+private:
+ static unsigned int m_exceptionCount;
+ static Exception* m_lastException;
+ static void (*m_terminateHandler)();
+
+ static void AddRef(Exception* exception)
+ {
+ if (!m_exceptionCount) {
+ m_terminateHandler = std::set_terminate(&TerminateHandler);
+ }
+
+ ++m_exceptionCount;
+ m_lastException = exception;
+ }
+
+ static void UnRef(Exception* e)
+ {
+ if (m_lastException == e) {
+ m_lastException = NULL;
+ }
+
+ --m_exceptionCount;
+
+ if (!m_exceptionCount) {
+ std::set_terminate(m_terminateHandler);
+ m_terminateHandler = NULL;
+ }
+ }
+
+ static void TerminateHandler()
+ {
+ if (m_lastException != NULL) {
+ DisplayKnownException(*m_lastException);
+ abort();
+ } else {
+ DisplayUnknownException();
+ abort();
+ }
+ }
+
+ Exception *m_reason;
+ std::string m_path;
+ std::string m_function;
+ int m_line;
+
+protected:
+ std::string m_message;
+ std::string m_className;
+
+public:
+ static std::string KnownExceptionToString(const Exception &e)
+ {
+ std::ostringstream message;
+ message <<
+ "\033[1;5;31m\n=== Unhandled DPL exception occurred ===\033[m\n\n";
+ message << "\033[1;33mException trace:\033[m\n\n";
+ message << e.DumpToString();
+ message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+ return message.str();
+ }
+
+ static std::string UnknownExceptionToString()
+ {
+ std::ostringstream message;
+ message <<
+ "\033[1;5;31m\n=== Unhandled non-DPL exception occurred ===\033[m\n\n";
+ message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+ return message.str();
+ }
+
+ static void DisplayKnownException(const Exception& e)
+ {
+ LogUnhandledException(KnownExceptionToString(e).c_str());
+ }
+
+ static void DisplayUnknownException()
+ {
+ LogUnhandledException(UnknownExceptionToString().c_str());
+ }
+
+ Exception(const Exception &other)
+ {
+ // Deep copy
+ if (other.m_reason != NULL) {
+ m_reason = new Exception(*other.m_reason);
+ } else {
+ m_reason = NULL;
+ }
+
+ m_message = other.m_message;
+ m_path = other.m_path;
+ m_function = other.m_function;
+ m_line = other.m_line;
+
+ m_className = other.m_className;
+
+ AddRef(this);
+ }
+
+ const Exception &operator =(const Exception &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ // Deep copy
+ if (other.m_reason != NULL) {
+ m_reason = new Exception(*other.m_reason);
+ } else {
+ m_reason = NULL;
+ }
+
+ m_message = other.m_message;
+ m_path = other.m_path;
+ m_function = other.m_function;
+ m_line = other.m_line;
+
+ m_className = other.m_className;
+
+ AddRef(this);
+
+ return *this;
+ }
+
+ Exception(const char *path,
+ const char *function,
+ int line,
+ const std::string &message) :
+ m_reason(NULL),
+ m_path(path),
+ m_function(function),
+ m_line(line),
+ m_message(message)
+ {
+ AddRef(this);
+ }
+
+ Exception(const char *path,
+ const char *function,
+ int line,
+ const Exception &reason,
+ const std::string &message) :
+ m_reason(new Exception(reason)),
+ m_path(path),
+ m_function(function),
+ m_line(line),
+ m_message(message)
+ {
+ AddRef(this);
+ }
+
+ virtual ~Exception() throw()
+ {
+ if (m_reason != NULL) {
+ delete m_reason;
+ m_reason = NULL;
+ }
+
+ UnRef(this);
+ }
+
+ void Dump() const
+ {
+ // Show reason first
+ if (m_reason != NULL) {
+ m_reason->Dump();
+ }
+
+ // Afterward, dump exception
+ const char *file = strchr(m_path.c_str(), '/');
+
+ if (file == NULL) {
+ file = m_path.c_str();
+ } else {
+ ++file;
+ }
+
+ printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+ file, m_line,
+ m_function.c_str(),
+ m_className.c_str(),
+ m_message.empty() ? "<EMPTY>" : m_message.c_str());
+ }
+
+ std::string DumpToString() const
+ {
+ std::string ret;
+ if (m_reason != NULL) {
+ ret = m_reason->DumpToString();
+ }
+
+ const char *file = strchr(m_path.c_str(), '/');
+
+ if (file == NULL) {
+ file = m_path.c_str();
+ } else {
+ ++file;
+ }
+
+ char buf[1024];
+ snprintf(buf,
+ sizeof(buf),
+ "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+ file,
+ m_line,
+ m_function.c_str(),
+ m_className.c_str(),
+ m_message.empty() ? "<EMPTY>" : m_message.c_str());
+
+ buf[sizeof(buf) - 1] = '\n';
+ ret += buf;
+
+ return ret;
+ }
+
+ Exception *GetReason() const
+ {
+ return m_reason;
+ }
+
+ std::string GetPath() const
+ {
+ return m_path;
+ }
+
+ std::string GetFunction() const
+ {
+ return m_function;
+ }
+
+ int GetLine() const
+ {
+ return m_line;
+ }
+
+ std::string GetMessage() const
+ {
+ return m_message;
+ }
+
+ std::string GetClassName() const
+ {
+ return m_className;
+ }
+};
+} // namespace VcoreDPL
+
+#define Try try
+
+#define Throw(ClassName) \
+ throw ClassName(__FILE__, __FUNCTION__, __LINE__)
+
+#define ThrowMsg(ClassName, Message) \
+ do \
+ { \
+ std::ostringstream dplLoggingStream; \
+ dplLoggingStream << Message; \
+ throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \
+ } while (0)
+
+#define ReThrow(ClassName) \
+ throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception)
+
+#define ReThrowMsg(ClassName, Message) \
+ throw ClassName(__FILE__, \
+ __FUNCTION__, \
+ __LINE__, \
+ _rethrown_exception, \
+ Message)
+
+#define Catch(ClassName) \
+ catch (const ClassName &_rethrown_exception)
+
+#define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \
+ class Class : public BaseClass { \
+ public: \
+ Class(const char *path, \
+ const char *function, \
+ int line, \
+ const std::string & message = std::string()) \
+ : BaseClass(path, function, line, message) { \
+ \
+ BaseClass::m_className = #Class; \
+ } \
+ \
+ Class(const char *path, \
+ const char *function, \
+ int line, \
+ const VcoreDPL::Exception & reason, \
+ const std::string & message = std::string()) \
+ : BaseClass(path, function, line, reason, message) { \
+ BaseClass::m_className = #Class; \
+ } \
+ };
+
+#define UNHANDLED_EXCEPTION_HANDLER_BEGIN try
+
+#define UNHANDLED_EXCEPTION_HANDLER_END \
+ catch (const VcoreDPL::Exception &exception) \
+ { \
+ std::ostringstream msg; \
+ msg << VcoreDPL::Exception::KnownExceptionToString(exception); \
+ VcoreDPL::LogUnhandledException(msg.str(), \
+ __FILE__, \
+ __LINE__, \
+ __FUNCTION__); \
+ abort(); \
+ } \
+ catch (std::exception& e) \
+ { \
+ std::ostringstream msg; \
+ msg << e.what(); \
+ msg << "\n"; \
+ msg << VcoreDPL::Exception::UnknownExceptionToString(); \
+ VcoreDPL::LogUnhandledException(msg.str(), \
+ __FILE__, \
+ __LINE__, \
+ __FUNCTION__); \
+ abort(); \
+ } \
+ catch (...) \
+ { \
+ std::ostringstream msg; \
+ msg << VcoreDPL::Exception::UnknownExceptionToString(); \
+ VcoreDPL::LogUnhandledException(msg.str(), \
+ __FILE__, \
+ __LINE__, \
+ __FUNCTION__); \
+ abort(); \
+ }
+
+namespace VcoreDPL {
+namespace CommonException {
+/**
+ * Internal exception definitions
+ *
+ * These should normally not happen.
+ * Usually, exception trace with internal error includes
+ * important messages.
+ */
+DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from
+ // underlying libraries or
+ // kernel
+}
+}
+
+#endif // VcoreDPL_EXCEPTION_H
diff --git a/vcore/src/dpl/core/include/dpl/file_input.h b/vcore/src/dpl/core/include/dpl/file_input.h
new file mode 100644
index 0000000..d982957
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/file_input.h
@@ -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.
+ */
+/*
+ * @file file_input.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of file input
+ */
+#ifndef DPL_FILE_INPUT_H
+#define DPL_FILE_INPUT_H
+
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/abstract_waitable_input.h>
+
+namespace VcoreDPL {
+class FileInput :
+ private Noncopyable,
+ public AbstractWaitableInput
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, OpenFailed)
+ DECLARE_EXCEPTION_TYPE(Base, CloseFailed)
+ };
+
+ protected:
+ int m_fd;
+
+ public:
+ FileInput();
+ FileInput(const std::string &fileName);
+ virtual ~FileInput();
+
+ void Open(const std::string &fileName);
+ void Close();
+
+ // AbstractInput
+ virtual BinaryQueueAutoPtr Read(size_t size);
+
+ // AbstractWaitableInput
+ virtual WaitableHandle WaitableReadHandle() const;
+};
+} // namespace VcoreDPL
+
+#endif // DPL_FILE_INPUT_H
diff --git a/vcore/src/dpl/core/include/dpl/foreach.h b/vcore/src/dpl/core/include/dpl/foreach.h
new file mode 100644
index 0000000..0a4485d
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/foreach.h
@@ -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 foreach.h
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of foreach macro for stl
+ * containers
+ */
+#ifndef DPL_FOREACH_H
+#define DPL_FOREACH_H
+
+#include <dpl/preprocessor.h>
+
+namespace VcoreDPL {
+namespace Private {
+/*
+ * Used to detect type of valid reference to value object.
+ */
+template <typename T>
+T& ValueReference(T& t)
+{
+ return(t);
+}
+
+template <typename T>
+const T& ValueReference(const T& t)
+{
+ return(t);
+}
+} //Private
+} //DPL
+
+#define DPL_FOREACH_IMPL(temporaryName, iterator, container) \
+ __typeof__ (VcoreDPL::Private::ValueReference((container))) & \
+ temporaryName = (container); \
+ for (__typeof__ (temporaryName.begin())iterator = \
+ temporaryName.begin(); \
+ (iterator) != temporaryName.end(); ++iterator)
+
+#define FOREACH(iterator, container) \
+ DPL_FOREACH_IMPL( \
+ DPL_MACRO_CONCAT(foreachContainerReference, __COUNTER__), \
+ iterator, \
+ container)
+
+#endif // DPL_FOREACH_H
diff --git a/vcore/src/dpl/core/include/dpl/free_deleter.h b/vcore/src/dpl/core/include/dpl/free_deleter.h
new file mode 100644
index 0000000..f3494f2
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/free_deleter.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014 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 free_deleter.h
+ * @author Pawel Czajkowski (p.czajkowski@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file deleter with use std::free()
+ */
+#ifndef FREE_DELETER_H
+#define FREE_DELETER_H
+
+#include <cstdlib>
+namespace VcoreDPL
+{
+struct free_deleter
+{
+ void operator()(void *p) { std::free(p); }
+};
+}// DPL
+#endif // FREE_DELETER_H
diff --git a/vcore/src/dpl/core/include/dpl/lexical_cast.h b/vcore/src/dpl/core/include/dpl/lexical_cast.h
new file mode 100644
index 0000000..b08f513
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/lexical_cast.h
@@ -0,0 +1,43 @@
+/*
+ * 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 lexical_cast.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief Header file for lexical cast
+ */
+#ifndef DPL_LEXICAL_CAST_H
+#define DPL_LEXICAL_CAST_H
+
+#include <sstream>
+
+namespace VcoreDPL {
+template<typename TargetType, typename SourceType>
+TargetType lexical_cast(const SourceType &data)
+{
+ TargetType result;
+
+ std::ostringstream out;
+ out << data;
+
+ std::istringstream in(out.str());
+ in >> result;
+
+ return result;
+}
+} // namespace VcoreDPL
+
+#endif // DPL_LEXICAL_CAST_H
diff --git a/vcore/src/dpl/core/include/dpl/noncopyable.h b/vcore/src/dpl/core/include/dpl/noncopyable.h
new file mode 100644
index 0000000..89372d0
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/noncopyable.h
@@ -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 noncopyable
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of noncopyable
+ */
+#ifndef DPL_NONCOPYABLE_H
+#define DPL_NONCOPYABLE_H
+
+namespace VcoreDPL {
+class Noncopyable
+{
+ private:
+ Noncopyable(const Noncopyable &);
+ const Noncopyable &operator=(const Noncopyable &);
+
+ public:
+ Noncopyable();
+ virtual ~Noncopyable();
+};
+} // namespace VcoreDPL
+
+#endif // DPL_NONCOPYABLE_H
diff --git a/vcore/src/dpl/core/include/dpl/optional.h b/vcore/src/dpl/core/include/dpl/optional.h
new file mode 100644
index 0000000..2f37aa1
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/optional.h
@@ -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 optional_value.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ */
+
+#ifndef DPL_OPTIONAL_H
+#define DPL_OPTIONAL_H
+
+#include <dpl/exception.h>
+#include <dpl/availability.h>
+
+namespace VcoreDPL {
+template <typename Type>
+class Optional
+{
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, NullReference)
+ };
+
+ public:
+ Optional() :
+ m_null(true),
+ m_value()
+ {}
+
+ Optional(const Type& t) :
+ m_null(false),
+ m_value(t)
+ {}
+
+ bool IsNull() const
+ {
+ return m_null;
+ }
+
+ Type& operator*()
+ {
+ if (m_null) {
+ Throw(typename Exception::NullReference);
+ }
+ return m_value;
+ }
+
+ const Type& operator*() const
+ {
+ if (m_null) {
+ Throw(typename Exception::NullReference);
+ }
+ return m_value;
+ }
+
+ const Type* operator->() const
+ {
+ if (m_null) {
+ Throw(typename Exception::NullReference);
+ }
+ return &m_value;
+ }
+
+ Type* operator->()
+ {
+ if (m_null) {
+ Throw(typename Exception::NullReference);
+ }
+ return &m_value;
+ }
+
+ bool operator!() const
+ {
+ return m_null;
+ }
+
+ Optional<Type>& operator=(const Type& other)
+ {
+ m_null = false;
+ m_value = other;
+ return *this;
+ }
+
+ bool operator==(const Optional<Type>& aSecond) const
+ {
+ return LogicalOperator<true>(*this, aSecond,
+ std::equal_to<Type>(), std::equal_to<bool>());
+ }
+
+ bool operator==(const Type& aSecond) const
+ {
+ return Optional<Type>(aSecond) == *this;
+ }
+
+ bool operator!=(const Optional<Type>& aSecond) const
+ {
+ return !(*this == aSecond);
+ }
+
+ bool operator<(const Optional<Type>& aSecond) const
+ {
+ return LogicalOperator<false>(*this, aSecond,
+ std::less<Type>(), std::less<bool>());
+ }
+
+ bool operator>(const Optional<Type>& aSecond) const
+ {
+ return LogicalOperator<false>(*this, aSecond,
+ std::greater<Type>(), std::greater<bool>());
+ }
+
+ bool operator<=(const Optional<Type>& aSecond) const
+ {
+ return *this == aSecond || *this < aSecond;
+ }
+
+ bool operator>=(const Optional<Type>& aSecond) const
+ {
+ return *this == aSecond || *this > aSecond;
+ }
+
+ static Optional<Type> Null;
+
+ private:
+ bool m_null;
+ Type m_value;
+
+ template <bool taEquality, typename taComparator, typename taNullComparator>
+ static bool LogicalOperator(const Optional<Type>& aFirst,
+ const Optional<Type>& aSecond,
+ taComparator aComparator,
+ taNullComparator aNullComparator)
+ {
+ if (aFirst.m_null == aSecond.m_null) {
+ if (aFirst.m_null) {
+ return taEquality;
+ } else {
+ return aComparator(aFirst.m_value, aSecond.m_value);
+ }
+ } else {
+ return aNullComparator(aFirst.m_null, aSecond.m_null);
+ }
+ }
+} DPL_DEPRECATED_WITH_MESSAGE("Use boost::optional instead");
+
+template<typename Type>
+Optional<Type> Optional<Type>::Null = Optional<Type>();
+} //namespace VcoreDPL
+
+template<typename Type>
+std::ostream& operator<<(std::ostream& aStream,
+ const VcoreDPL::Optional<Type>& aOptional)
+{
+ if (aOptional.IsNull()) {
+ return aStream << "null optional";
+ } else {
+ return aStream << *aOptional;
+ }
+}
+
+#endif // DPL_OPTIONAL_VALUE_H
diff --git a/vcore/src/dpl/core/include/dpl/optional_typedefs.h b/vcore/src/dpl/core/include/dpl/optional_typedefs.h
new file mode 100644
index 0000000..bd411f2
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/optional_typedefs.h
@@ -0,0 +1,33 @@
+/*
+ * 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 DPL_OPTIONAL_TYPEDEFS_H
+#define DPL_OPTIONAL_TYPEDEFS_H
+
+#include <string>
+#include <dpl/string.h>
+#include <boost/optional.hpp>
+
+namespace VcoreDPL {
+typedef boost::optional<String> OptionalString;
+typedef boost::optional<int> OptionalInt;
+typedef boost::optional<unsigned int> OptionalUInt;
+typedef boost::optional<bool> OptionalBool;
+typedef boost::optional<float> OptionalFloat;
+typedef boost::optional<std::string> OptionalStdString;
+} //namespace VcoreDPL
+
+#endif /* DPL_OPTIONAL_TYPEDEFS_H */
+
diff --git a/vcore/src/dpl/core/include/dpl/preprocessor.h b/vcore/src/dpl/core/include/dpl/preprocessor.h
new file mode 100644
index 0000000..6fca34c
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/preprocessor.h
@@ -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 preprocessor.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This file contains some usefull macros.
+ */
+
+#ifndef DPL_PREPROCESSOR_H
+#define DPL_PREPROCESSOR_H
+
+#define DPL_MACRO_CONCAT_IMPL(x, y) x##y
+#define DPL_MACRO_CONCAT(x, y) DPL_MACRO_CONCAT_IMPL(x, y)
+
+#ifdef __COUNTER__
+#define DPL_ANONYMOUS_VARIABLE(name) DPL_MACRO_CONCAT(name, __COUNTER__)
+#else
+#define DPL_ANONYMOUS_VARIABLE(name) DPL_MACRO_CONCAT(name, __LINE__)
+#endif
+
+#endif //DPL_PREPROCESSOR_H
diff --git a/vcore/src/dpl/core/include/dpl/scoped_array.h b/vcore/src/dpl/core/include/dpl/scoped_array.h
new file mode 100644
index 0000000..e117f33
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/scoped_array.h
@@ -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.
+ */
+/*!
+ * @file scoped_ptr.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of scoped array RAII
+ *
+ * This module is deprecated, please use standard C++11 feature: std::unique_ptr<Type[]>
+ */
+#ifndef DPL_SCOPED_ARRAY_H
+#define DPL_SCOPED_ARRAY_H
+
+#include <cstddef>
+
+#include <dpl/assert.h>
+#include <dpl/scoped_resource.h>
+#include <dpl/availability.h>
+
+namespace VcoreDPL {
+template<typename Class>
+struct ScopedArrayPolicy
+{
+ typedef Class* Type;
+ static Type NullValue()
+ {
+ return NULL;
+ }
+ static void Destroy(Type ptr)
+ {
+ delete[] ptr;
+ }
+};
+
+template<typename Class>
+class ScopedArray : public ScopedResource<ScopedArrayPolicy<Class> >
+{
+ typedef ScopedArrayPolicy<Class> Policy;
+ typedef ScopedResource<Policy> BaseType;
+
+ public:
+ explicit ScopedArray(Class *ptr = Policy::NullValue()) : BaseType(ptr) { }
+
+ Class &operator [](std::ptrdiff_t k) const
+ {
+ Assert(this->m_value != Policy::NullValue() &&
+ "Dereference of scoped NULL array!");
+ Assert(k >= 0 && "Negative array index");
+
+ return this->m_value[k];
+ }
+} DPL_DEPRECATED_WITH_MESSAGE("use standard C++11 feature: std::unique_ptr<Type[]>");
+} // namespace VcoreDPL
+
+#endif // DPL_SCOPED_PTR_H
diff --git a/vcore/src/dpl/core/include/dpl/scoped_fclose.h b/vcore/src/dpl/core/include/dpl/scoped_fclose.h
new file mode 100644
index 0000000..8813497
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/scoped_fclose.h
@@ -0,0 +1,72 @@
+/*
+ * 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 DPL_SCOPED_FCLOSE_H
+#define DPL_SCOPED_FCLOSE_H
+
+#include <unistd.h>
+#include <cerrno>
+#include <cstdio>
+#include <string>
+#include <dpl/log/vcore_log.h>
+#include <dpl/scoped_resource.h>
+#include <dpl/errno_string.h>
+
+namespace VcoreDPL {
+struct ScopedFClosePolicy
+{
+ typedef FILE* Type;
+ static Type NullValue()
+ {
+ return NULL;
+ }
+ static void Destroy(Type file)
+ {
+ if (file != NULL) {
+ // Try to flush first
+ if (TEMP_FAILURE_RETRY(fflush(file)) != 0) {
+ std::string errString = GetErrnoString();
+ VcoreLogD("Failed to fflush scoped fclose error: %s",
+ errString.c_str());
+ }
+
+ // fclose cannot be retried, try to close once
+ if (fclose(file) != 0) {
+ std::string errString = GetErrnoString();
+ VcoreLogD("Failed scoped fclose error: %s", errString.c_str());
+ }
+ }
+ }
+};
+
+class ScopedFClose : public ScopedResource<ScopedFClosePolicy>
+{
+ typedef ScopedFClosePolicy Policy;
+ typedef ScopedResource<Policy> BaseType;
+
+ public:
+ explicit ScopedFClose(FILE* argFileStream = Policy::NullValue()) :
+ BaseType(argFileStream)
+ {}
+};
+} // namespace VcoreDPL
+
+#endif // DPL_SCOPED_FCLOSE_H
diff --git a/vcore/src/dpl/core/include/dpl/scoped_free.h b/vcore/src/dpl/core/include/dpl/scoped_free.h
new file mode 100644
index 0000000..7f9685b
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/scoped_free.h
@@ -0,0 +1,57 @@
+/*
+ * 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_free.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of scoped free RAII
+ */
+
+#ifndef DPL_SCOPED_FREE_H
+#define DPL_SCOPED_FREE_H
+
+#include <malloc.h>
+#include <cstddef>
+
+#include <dpl/scoped_resource.h>
+
+namespace VcoreDPL {
+template<typename Class>
+struct ScopedFreePolicy
+{
+ typedef Class* Type;
+ static Type NullValue()
+ {
+ return NULL;
+ }
+ static void Destroy(Type ptr)
+ {
+ free(ptr);
+ }
+};
+
+template<typename Memory>
+class ScopedFree : public ScopedResource<ScopedFreePolicy<Memory> >
+{
+ typedef ScopedFreePolicy<Memory> Policy;
+ typedef ScopedResource<Policy> BaseType;
+
+ public:
+ explicit ScopedFree(Memory *ptr = Policy::NullValue()) : BaseType(ptr) { }
+};
+} // namespace VcoreDPL
+
+#endif // DPL_SCOPED_FREE_H
diff --git a/vcore/src/dpl/core/include/dpl/scoped_resource.h b/vcore/src/dpl/core/include/dpl/scoped_resource.h
new file mode 100644
index 0000000..ed034dd
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/scoped_resource.h
@@ -0,0 +1,80 @@
+/*
+ * 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_resource.h
+ * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of scoped resource pattern
+ */
+#ifndef DPL_SCOPED_RESOURCE_H
+#define DPL_SCOPED_RESOURCE_H
+
+#include <dpl/noncopyable.h>
+
+namespace VcoreDPL {
+template<typename ClassPolicy>
+class ScopedResource :
+ private Noncopyable
+{
+ public:
+ typedef typename ClassPolicy::Type ValueType;
+ typedef ScopedResource<ClassPolicy> ThisType;
+
+ protected:
+ ValueType m_value;
+
+ public:
+ explicit ScopedResource(ValueType value) : m_value(value) { }
+
+ ~ScopedResource()
+ {
+ ClassPolicy::Destroy(m_value);
+ }
+
+ ValueType Get() const
+ {
+ return m_value;
+ }
+
+ void Reset(ValueType value = ClassPolicy::NullValue())
+ {
+ ClassPolicy::Destroy(m_value);
+ m_value = value;
+ }
+
+ ValueType Release()
+ {
+ ValueType value = m_value;
+ m_value = ClassPolicy::NullValue();
+ return value;
+ }
+ typedef ValueType ThisType::*UnknownBoolType;
+
+ operator UnknownBoolType() const
+ {
+ return m_value == ClassPolicy::NullValue() ?
+ 0 : //0 is valid here because it converts to false
+ &ThisType::m_value; //it converts to true
+ }
+
+ bool operator !() const
+ {
+ return m_value == ClassPolicy::NullValue();
+ }
+};
+} // namespace VcoreDPL
+
+#endif // DPL_SCOPED_RESOURCE_H
diff --git a/vcore/src/dpl/core/include/dpl/singleton.h b/vcore/src/dpl/core/include/dpl/singleton.h
new file mode 100644
index 0000000..4371f32
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/singleton.h
@@ -0,0 +1,57 @@
+/*
+ * 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 singleton.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of singleton
+ */
+#ifndef DPL_SINGLETON_H
+#define DPL_SINGLETON_H
+
+#include <boost/optional.hpp>
+#include <dpl/thread.h>
+#include <dpl/assert.h>
+
+namespace VcoreDPL {
+template<typename Class>
+class Singleton :
+ private Class
+{
+ //
+ // Note:
+ //
+ // To remove posibility of instantiating directly Class,
+ // make Class' default constructor protected
+ //
+
+ private:
+ Singleton()
+ {}
+
+ typedef boost::optional<Thread *> OptionalThreadPtr;
+
+ static Singleton &InternalInstance();
+
+ public:
+ virtual ~Singleton()
+ {}
+
+ static Class &Instance();
+};
+} // namespace VcoreDPL
+
+#endif // DPL_SINGLETON_H
diff --git a/vcore/src/dpl/core/include/dpl/singleton_impl.h b/vcore/src/dpl/core/include/dpl/singleton_impl.h
new file mode 100644
index 0000000..fd70741
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/singleton_impl.h
@@ -0,0 +1,53 @@
+/*
+ * 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 singleton_impl.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of singleton
+ */
+#ifndef DPL_SINGLETON_IMPL_H
+#define DPL_SINGLETON_IMPL_H
+
+/*
+ * WARNING!
+ *
+ * If some singleton's implementation uses another singletons implementation,
+ * those templates make the second singleton a dubleton. Be warned. Try to use
+ * singleton_safe_impl.h if possible.
+ */
+
+namespace VcoreDPL {
+template<typename Class>
+Singleton<Class>& Singleton<Class>::InternalInstance()
+{
+ static Singleton<Class> instance;
+ return instance;
+}
+
+template<typename Class>
+Class &Singleton<Class>::Instance()
+{
+ Singleton<Class>& instance = Singleton<Class>::InternalInstance();
+ return instance;
+}
+} // namespace VcoreDPL
+
+#define IMPLEMENT_SINGLETON(Type) \
+ template VcoreDPL::Singleton<Type>&VcoreDPL::Singleton<Type>::InternalInstance(); \
+ template Type & VcoreDPL::Singleton<Type>::Instance(); \
+
+#endif // DPL_SINGLETON_IMPL_H
diff --git a/vcore/src/dpl/core/include/dpl/string.h b/vcore/src/dpl/core/include/dpl/string.h
new file mode 100644
index 0000000..68d6a09
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/string.h
@@ -0,0 +1,157 @@
+/*
+ * 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 string.h
+ * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @version 1.0
+ */
+#ifndef DPL_STRING
+#define DPL_STRING
+
+#include <dpl/exception.h>
+#include <dpl/char_traits.h>
+#include <string>
+#include <ostream>
+#include <numeric>
+
+namespace VcoreDPL {
+// @brief DPL string
+typedef std::basic_string<wchar_t, CharTraits> String;
+
+// @brief String exception class
+class StringException
+{
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+
+ // @brief Invalid init for UTF8 to UTF32 converter
+ DECLARE_EXCEPTION_TYPE(Base, IconvInitErrorUTF8ToUTF32)
+
+ // @brief Invalid taStdContainerinit for UTF32 to UTF32 converter
+ DECLARE_EXCEPTION_TYPE(Base, IconvInitErrorUTF32ToUTF8)
+
+ // @brief Invalid conversion for UTF8 to UTF32 converter
+ DECLARE_EXCEPTION_TYPE(Base, IconvConvertErrorUTF8ToUTF32)
+
+ // @brief Invalid conversion for UTF8 to UTF32 converter
+ DECLARE_EXCEPTION_TYPE(Base, IconvConvertErrorUTF32ToUTF8)
+
+ // @brief Invalid ASCII character detected in FromASCII
+ DECLARE_EXCEPTION_TYPE(Base, InvalidASCIICharacter)
+
+ // @brief Invalid ASCII character detected in FromASCII
+ DECLARE_EXCEPTION_TYPE(Base, ICUInvalidCharacterFound)
+};
+
+//!\brief convert ASCII string to VcoreDPL::String
+String FromASCIIString(const std::string& aString);
+
+//!\brief convert UTF32 string to VcoreDPL::String
+String FromUTF32String(const std::wstring& aString);
+
+//@brief Returns String object created from UTF8 string
+//@param[in] aString input UTF-8 string
+String FromUTF8String(const std::string& aString);
+
+//@brief Returns String content as std::string
+std::string ToUTF8String(const String& aString);
+
+//@brief Compare two unicode strings
+int StringCompare(const String &left,
+ const String &right,
+ bool caseInsensitive = false);
+
+//@brief Splits the string into substrings.
+//@param[in] str Input string
+//@param[in] delimiters array or string containing a sequence of substring
+// delimiters. Can be also a single delimiter character.
+//@param[in] it InserterIterator that is used to save the generated substrings.
+template<typename StringType, typename Delimiters, typename InserterIterator>
+void Tokenize(const StringType& str,
+ const Delimiters& delimiters,
+ InserterIterator it,
+ bool ignoreEmpty = false)
+{
+ typename StringType::size_type nextSearchStart = 0;
+ typename StringType::size_type pos;
+ typename StringType::size_type length;
+
+ while (true) {
+ pos = str.find_first_of(delimiters, nextSearchStart);
+ length =
+ ((pos == StringType::npos) ? str.length() : pos) - nextSearchStart;
+
+ if (!ignoreEmpty || length > 0) {
+ *it = str.substr(nextSearchStart, length);
+ it++;
+ }
+
+ if (pos == StringType::npos) {
+ return;
+ }
+
+ nextSearchStart = pos + 1;
+ }
+}
+
+namespace Utils {
+
+template<typename T> class ConcatFunc : public std::binary_function<T, T, T>
+{
+public:
+ explicit ConcatFunc(const T & val) : m_delim(val) {}
+ T operator()(const T & arg1, const T & arg2) const
+ {
+ return arg1 + m_delim + arg2;
+ }
+private:
+ T m_delim;
+};
+
+}
+
+template<typename ForwardIterator>
+typename ForwardIterator::value_type Join(ForwardIterator begin, ForwardIterator end, typename ForwardIterator::value_type delim)
+{
+ typedef typename ForwardIterator::value_type value;
+ if(begin == end) return value();
+ Utils::ConcatFunc<value> func(delim);
+ ForwardIterator init = begin;
+ return std::accumulate(++begin, end, *init, func);
+}
+
+template<class StringType> void TrimLeft(StringType & obj, typename StringType::const_pointer separators)
+{
+ obj.erase(0, obj.find_first_not_of(separators));
+}
+
+template<class StringType> void TrimRight(StringType & obj, typename StringType::const_pointer separators)
+{
+ obj.erase(obj.find_last_not_of(separators)+1);
+}
+
+template<class StringType> void Trim(StringType & obj, typename StringType::const_pointer separators)
+{
+ TrimLeft(obj, separators);
+ TrimRight(obj, separators);
+}
+
+
+} //namespace VcoreDPL
+
+std::ostream& operator<<(std::ostream& aStream, const VcoreDPL::String& aString);
+
+#endif // DPL_STRING
diff --git a/vcore/src/dpl/core/include/dpl/thread.h b/vcore/src/dpl/core/include/dpl/thread.h
new file mode 100644
index 0000000..d13740b
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/thread.h
@@ -0,0 +1,394 @@
+/*
+ * 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 thread.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of thread
+ */
+#ifndef DPL_THREAD_H
+#define DPL_THREAD_H
+
+#include <dpl/waitable_handle_watch_support.h>
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/assert.h>
+#include <boost/optional.hpp>
+#include <stdint.h>
+#include <cstdlib>
+#include <pthread.h>
+#include <thread>
+#include <vector>
+#include <list>
+#include <mutex>
+
+namespace VcoreDPL {
+class Thread :
+ private Noncopyable,
+ public WaitableHandleWatchSupport
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, CreateFailed)
+ DECLARE_EXCEPTION_TYPE(Base, DestroyFailed)
+ DECLARE_EXCEPTION_TYPE(Base, RunFailed)
+ DECLARE_EXCEPTION_TYPE(Base, QuitFailed)
+ DECLARE_EXCEPTION_TYPE(Base, UnmanagedThread)
+ };
+
+ typedef void (*EventDeleteProc)(void *event, void *userParam);
+ typedef void (*EventDispatchProc)(void *event, void *userParam);
+
+ protected:
+ /**
+ * Main thread entry
+ * The method is intended to be overloaded with custom code.
+ * Default implementation just executes Exec method to process
+ * all thread exents
+ */
+ virtual int ThreadEntry();
+
+ /**
+ * Start processing of thread events
+ */
+ int Exec();
+
+ private:
+ struct InternalEvent
+ {
+ void *event;
+ void *userParam;
+ EventDispatchProc eventDispatchProc;
+ EventDeleteProc eventDeleteProc;
+
+ InternalEvent(void *eventArg,
+ void *userParamArg,
+ EventDispatchProc eventDispatchProcArg,
+ EventDeleteProc eventDeleteProcArg) :
+ event(eventArg),
+ userParam(userParamArg),
+ eventDispatchProc(eventDispatchProcArg),
+ eventDeleteProc(eventDeleteProcArg)
+ {}
+ };
+
+ struct InternalTimedEvent :
+ InternalEvent
+ {
+ unsigned long dueTimeMiliseconds;
+ unsigned long registerTimeMiliseconds;
+
+ InternalTimedEvent(void *eventArg,
+ void *userParamArg,
+ unsigned long dueTimeMilisecondsArg,
+ unsigned long registerTimeMilisecondsArg,
+ EventDispatchProc eventDispatchProcArg,
+ EventDeleteProc eventDeleteProcArg) :
+ InternalEvent(eventArg,
+ userParamArg,
+ eventDispatchProcArg,
+ eventDeleteProcArg),
+ dueTimeMiliseconds(dueTimeMilisecondsArg),
+ registerTimeMiliseconds(registerTimeMilisecondsArg)
+ {}
+
+ bool operator<(const InternalTimedEvent &other)
+ {
+ return registerTimeMiliseconds + dueTimeMiliseconds >
+ other.registerTimeMiliseconds + other.dueTimeMiliseconds;
+ }
+ };
+
+ // Internal event list
+ typedef std::list<InternalEvent> InternalEventList;
+
+ // Internal timed event list
+ typedef std::vector<InternalTimedEvent> InternalTimedEventVector;
+
+ // State managment
+ std::thread m_thread;
+ volatile bool m_abandon;
+ volatile bool m_running;
+ std::mutex m_stateMutex;
+ WaitableEvent m_quitEvent;
+
+ // Event processing
+ std::mutex m_eventMutex;
+ InternalEventList m_eventList;
+ WaitableEvent m_eventInvoker;
+
+ // Timed events processing
+ std::mutex m_timedEventMutex;
+ InternalTimedEventVector m_timedEventVector;
+ WaitableEvent m_timedEventInvoker;
+
+ // WaitableHandleWatchSupport
+ virtual Thread *GetInvokerThread();
+ virtual void HandleDirectInvoker();
+ bool m_directInvoke;
+
+ // Internals
+ unsigned long GetCurrentTimeMiliseconds() const;
+ void ProcessEvents();
+ void ProcessTimedEvents();
+
+ static void *StaticThreadEntry(void *param);
+
+ public:
+ explicit Thread();
+ virtual ~Thread();
+
+ /**
+ * Run thread. Does nothing if thread is already running
+ */
+ void Run();
+
+ /**
+ * Send quit message to thread and wait for its end
+ * Does nothing is thread is not running
+ */
+ void Quit();
+
+ /**
+ * Checks if current thread is main one
+ * Returns true if it is main program thread, false otherwise
+ */
+ static bool IsMainThread();
+
+ /**
+ * Current thread retrieval
+ * Returns DPL thread handle or NULL if it is main program thread
+ */
+ static Thread *GetCurrentThread();
+
+ /**
+ * Low-level event push, usually used only by EventSupport
+ */
+ void PushEvent(void *event,
+ EventDispatchProc eventDispatchProc,
+ EventDeleteProc eventDeleteProc,
+ void *userParam);
+
+ /**
+ * Low-level timed event push, usually used only by EventSupport
+ */
+ void PushTimedEvent(void *event,
+ double dueTimeSeconds,
+ EventDispatchProc eventDispatchProc,
+ EventDeleteProc eventDeleteProc,
+ void *userParam);
+
+ /**
+ * Sleep for a number of seconds
+ */
+ static void Sleep(uint64_t seconds);
+
+ /**
+ * Sleep for a number of miliseconds
+ */
+ static void MiliSleep(uint64_t miliseconds);
+
+ /**
+ * Sleep for a number of microseconds
+ */
+ static void MicroSleep(uint64_t microseconds);
+
+ /**
+ * Sleep for a number of nanoseconds
+ */
+ static void NanoSleep(uint64_t nanoseconds);
+};
+
+extern bool g_TLSforMainCreated;
+
+// In case of using TLV in main thread, pthread_exit(NULL) has to be called in
+// this thread explicitly.
+// On the other hand, possibly, because of the kernel bug, there exist
+// a problem, if any other thread than main exist during pthread_exit call
+// (process can become non-responsive)
+// TODO further investigation is required.
+template<typename Type>
+class ThreadLocalVariable :
+ public Noncopyable
+{
+ public:
+ typedef Type ValueType;
+
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, NullReference)
+ DECLARE_EXCEPTION_TYPE(Base, KeyCreateFailed)
+ };
+
+ private:
+ pthread_key_t m_key;
+
+ struct ManagedValue
+ {
+ ValueType value;
+ boost::optional<pthread_key_t> guardKey;
+ };
+
+ static void MainThreadExitClean()
+ {
+ // There is a possible bug in kernel. If this function is called
+ // before ALL threads are closed, process will hang!
+ // Because of that, by default this function has to be called in well
+ // known "threads state".
+
+ // pthread_exit(NULL);
+ }
+
+ static void InternalDestroy(void *specific)
+ {
+ // Destroy underlying type
+ ManagedValue *instance = static_cast<ManagedValue *>(specific);
+ if (!instance->guardKey) {
+ delete instance;
+ } else {
+ int result = pthread_setspecific(*(instance->guardKey), instance);
+
+ Assert(result == 0 &&
+ "Failed to set thread local variable");
+ }
+ }
+
+ Type &Reference(bool allowInstantiate = false)
+ {
+ ManagedValue *instance =
+ static_cast<ManagedValue *>(pthread_getspecific(m_key));
+
+ if (!instance) {
+ // Check if it is allowed to instantiate
+ if (!allowInstantiate) {
+ Throw(typename Exception::NullReference);
+ }
+
+ // checking, if specific data is created for Main thread
+ // If yes, pthread_exit(NULL) is required
+ if (!g_TLSforMainCreated) {
+ if (Thread::IsMainThread()) {
+ g_TLSforMainCreated = true;
+ atexit(&MainThreadExitClean);
+ }
+ }
+
+ // Need to instantiate underlying type
+ instance = new ManagedValue();
+
+ int result = pthread_setspecific(m_key, instance);
+
+ Assert(result == 0 &&
+ "Failed to set thread local variable");
+ }
+
+ return instance->value;
+ }
+
+ public:
+ ThreadLocalVariable()
+ {
+ int result = pthread_key_create(&m_key, &InternalDestroy);
+ if (result != 0) {
+ ThrowMsg(typename Exception::KeyCreateFailed,
+ "Failed to allocate thread local variable: " << result);
+ }
+ }
+
+ ~ThreadLocalVariable()
+ {
+ pthread_key_delete(m_key);
+ }
+
+ Type &operator=(const Type &other)
+ {
+ Type &reference = Reference(true);
+ reference = other;
+ return reference;
+ }
+
+ bool IsNull() const
+ {
+ return pthread_getspecific(m_key) == NULL;
+ }
+
+ Type& operator*()
+ {
+ return Reference();
+ }
+
+ const Type& operator*() const
+ {
+ return Reference();
+ }
+
+ const Type* operator->() const
+ {
+ return &Reference();
+ }
+
+ Type* operator->()
+ {
+ return &Reference();
+ }
+
+ bool operator!() const
+ {
+ return IsNull();
+ }
+
+ void Reset()
+ {
+ ManagedValue *specific =
+ static_cast<ManagedValue *>(pthread_getspecific(m_key));
+
+ if (!specific) {
+ return;
+ }
+
+ // TODO Should be an assert? is it developers fault to Reset Guarded
+ // value?
+ specific->guardKey = boost::optional<pthread_key_t>();
+
+ InternalDestroy(specific);
+
+ int result = pthread_setspecific(m_key, NULL);
+
+ Assert(result == 0 &&
+ "Failed to reset thread local variable");
+ }
+
+ // GuardValue(true) allows to defer destroy (by pthread internal
+ // functionality) thread specific value until GuardValue(false) will be
+ // called.
+ void GuardValue(bool guard)
+ {
+ ManagedValue *instance =
+ static_cast<ManagedValue *>(pthread_getspecific(m_key));
+
+ Assert(instance && "Failed to get the value");
+
+ instance->guardKey = guard ? m_key : boost::optional<pthread_key_t>();
+ }
+};
+} // namespace VcoreDPL
+
+#endif // DPL_THREAD_H
diff --git a/vcore/src/dpl/core/include/dpl/type_list.h b/vcore/src/dpl/core/include/dpl/type_list.h
new file mode 100644
index 0000000..e28172d
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/type_list.h
@@ -0,0 +1,159 @@
+/*
+ * 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 type_list.h
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief Generic type list template
+ */
+#ifndef DPL_TYPE_LIST_H
+#define DPL_TYPE_LIST_H
+
+#include <cstddef>
+
+namespace VcoreDPL {
+class TypeListGuard
+{
+ public:
+ template<size_t Index>
+ struct Element
+ {
+ struct ERROR_TypeListElementIndexIsOutOfBounds;
+ typedef ERROR_TypeListElementIndexIsOutOfBounds Type;
+ };
+
+ static const size_t Size = 0;
+};
+
+template<typename HeadType, typename TailType>
+class TypeList
+{
+ private:
+ class DummyClass
+ {};
+
+ template<typename List, size_t Enum>
+ struct TypeCounter : public TypeCounter<typename List::Tail, Enum + 1>
+ {};
+
+ template<size_t Enum>
+ struct TypeCounter<TypeListGuard, Enum>
+ {
+ static const size_t Size = Enum;
+ };
+
+ public:
+ typedef TailType Tail;
+ typedef HeadType Head;
+ typedef TypeList<HeadType, TailType> ThisType;
+
+ template<size_t Index, typename DummyType = DummyClass>
+ struct Element
+ {
+ typedef typename TailType::template Element<Index - 1>::Type Type;
+ };
+
+ template<typename DummyType>
+ struct Element<0, DummyType>
+ {
+ typedef HeadType Type;
+ };
+
+ template<typename Type, typename DummyType = DummyClass>
+ struct Contains
+ {
+ typedef typename TailType::template Contains<Type>::Yes Yes;
+ };
+
+ template<typename DummyType>
+ struct Contains<HeadType, DummyType>
+ {
+ typedef int Yes;
+ };
+
+ static const size_t Size = TypeCounter<ThisType, 0>::Size;
+};
+
+template<typename T1 = TypeListGuard, typename T2 = TypeListGuard,
+ typename T3 = TypeListGuard, typename T4 = TypeListGuard,
+ typename T5 = TypeListGuard, typename T6 = TypeListGuard,
+ typename T7 = TypeListGuard, typename T8 = TypeListGuard,
+ typename T9 = TypeListGuard, typename T10 = TypeListGuard,
+ typename T11 = TypeListGuard, typename T12 = TypeListGuard,
+ typename T13 = TypeListGuard, typename T14 = TypeListGuard,
+ typename T15 = TypeListGuard, typename T16 = TypeListGuard,
+ typename T17 = TypeListGuard, typename T18 = TypeListGuard,
+ typename T19 = TypeListGuard, typename T20 = TypeListGuard,
+ typename T21 = TypeListGuard, typename T22 = TypeListGuard,
+ typename T23 = TypeListGuard, typename T24 = TypeListGuard,
+ typename T25 = TypeListGuard, typename T26 = TypeListGuard,
+ typename T27 = TypeListGuard, typename T28 = TypeListGuard,
+ typename T29 = TypeListGuard, typename T30 = TypeListGuard,
+ typename T31 = TypeListGuard, typename T32 = TypeListGuard,
+ typename T33 = TypeListGuard, typename T34 = TypeListGuard,
+ typename T35 = TypeListGuard, typename T36 = TypeListGuard,
+ typename T37 = TypeListGuard, typename T38 = TypeListGuard,
+ typename T39 = TypeListGuard, typename T40 = TypeListGuard,
+ typename T41 = TypeListGuard, typename T42 = TypeListGuard,
+ typename T43 = TypeListGuard, typename T44 = TypeListGuard,
+ typename T45 = TypeListGuard, typename T46 = TypeListGuard,
+ typename T47 = TypeListGuard, typename T48 = TypeListGuard,
+ typename T49 = TypeListGuard, typename T50 = TypeListGuard,
+ typename T51 = TypeListGuard, typename T52 = TypeListGuard,
+ typename T53 = TypeListGuard, typename T54 = TypeListGuard,
+ typename T55 = TypeListGuard, typename T56 = TypeListGuard,
+ typename T57 = TypeListGuard, typename T58 = TypeListGuard,
+ typename T59 = TypeListGuard, typename T60 = TypeListGuard,
+ typename T61 = TypeListGuard, typename T62 = TypeListGuard,
+ typename T63 = TypeListGuard, typename T64 = TypeListGuard>
+struct TypeListDecl
+{
+ typedef TypeList<T1,
+ typename TypeListDecl<
+ T2, T3, T4, T5, T6, T7, T8,
+ T9, T10, T11, T12, T13, T14, T15,
+ T16, T17, T18, T19, T20, T21, T22,
+ T23, T24, T25, T26, T27, T28, T29,
+ T30, T31, T32, T33, T34, T35, T36,
+ T37, T38, T39, T40, T41, T42, T43,
+ T44, T45, T46, T47, T48, T49, T50,
+ T51, T52, T53, T54, T55, T56, T57,
+ T58, T59, T60, T61, T62, T63, T64>::Type> Type;
+};
+
+template<>
+struct TypeListDecl<TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard,
+ TypeListGuard, TypeListGuard, TypeListGuard, TypeListGuard>
+{
+ typedef TypeListGuard Type;
+};
+} // namespace VcoreDPL
+
+#endif // DPL_TYPE_LIST_H
diff --git a/vcore/src/dpl/core/include/dpl/waitable_event.h b/vcore/src/dpl/core/include/dpl/waitable_event.h
new file mode 100644
index 0000000..b6305b0
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/waitable_event.h
@@ -0,0 +1,59 @@
+/*
+ * 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 waitable_event.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of waitable event
+ */
+#ifndef DPL_WAITABLE_EVENT_H
+#define DPL_WAITABLE_EVENT_H
+
+#include <dpl/waitable_handle.h>
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <vector>
+
+namespace VcoreDPL {
+class WaitableEvent :
+ private Noncopyable
+{
+ public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, CreateFailed)
+ DECLARE_EXCEPTION_TYPE(Base, DestroyFailed)
+ DECLARE_EXCEPTION_TYPE(Base, SignalFailed)
+ DECLARE_EXCEPTION_TYPE(Base, ResetFailed)
+ };
+
+ private:
+ int m_pipe[2];
+
+ public:
+ WaitableEvent();
+ virtual ~WaitableEvent();
+
+ WaitableHandle GetHandle() const;
+
+ void Signal() const;
+ void Reset() const;
+};
+} // namespace VcoreDPL
+
+#endif // DPL_WAITABLE_EVENT_H
diff --git a/vcore/src/dpl/core/include/dpl/waitable_handle.h b/vcore/src/dpl/core/include/dpl/waitable_handle.h
new file mode 100644
index 0000000..5ffd76c
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/waitable_handle.h
@@ -0,0 +1,115 @@
+/*
+ * 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 waitable_handle.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of waitable handle
+ */
+#ifndef DPL_WAITABLE_HANDLE_H
+#define DPL_WAITABLE_HANDLE_H
+
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <vector>
+
+namespace VcoreDPL {
+/**
+ * Waitable unix wait handle definition
+ */
+typedef int WaitableHandle;
+
+/**
+ * Waitable handle list
+ */
+typedef std::vector<WaitableHandle> WaitableHandleList;
+
+/**
+ * Wait mode
+ */
+class WaitMode
+{
+ public:
+ enum Type
+ {
+ Read, ///< Wait for readability state changes
+ Write ///< Wait for writability state changes
+ };
+};
+
+/**
+ * Waitable handle list ex
+ */
+typedef std::vector<std::pair<WaitableHandle,
+ WaitMode::Type> > WaitableHandleListEx;
+
+/**
+ * Waitable handle index list
+ */
+typedef std::vector<size_t> WaitableHandleIndexList;
+
+/**
+ * Wait exceptions
+ */
+DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, WaitFailed)
+
+/**
+ * Wait for single handle readability
+ * Convience function.
+ *
+ * @return Signaled waitable handle index list
+ * @throw WaitFailed Fatal error occurred while waiting for signal
+ */
+WaitableHandleIndexList WaitForSingleHandle(
+ WaitableHandle handle,
+ unsigned long miliseconds =
+ 0xFFFFFFFF);
+
+/**
+ * Wait for single handle
+ * Convience function.
+ *
+ * @return Signaled waitable handle index list
+ * @throw WaitFailed Fatal error occurred while waiting for signal
+ */
+WaitableHandleIndexList WaitForSingleHandle(
+ WaitableHandle handle,
+ WaitMode::Type mode,
+ unsigned long miliseconds =
+ 0xFFFFFFFF);
+
+/**
+ * Wait for multiple handles readability
+ *
+ * @return Signaled waitable handle index list
+ * @throw WaitFailed Fatal error occurred while waiting for signal
+ */
+WaitableHandleIndexList WaitForMultipleHandles(
+ const WaitableHandleList &handleList,
+ unsigned long miliseconds = 0xFFFFFFFF);
+
+/**
+ * Wait for multiple handles readability
+ *
+ * @return Signaled waitable handle index list
+ * @throw WaitFailed Fatal error occurred while waiting for signal
+ */
+WaitableHandleIndexList WaitForMultipleHandles(
+ const WaitableHandleListEx &handleListEx,
+ unsigned long miliseconds = 0xFFFFFFFF);
+} // namespace VcoreDPL
+
+#endif // DPL_WAITABLE_HANDLE_H
diff --git a/vcore/src/dpl/core/include/dpl/waitable_handle_watch_support.h b/vcore/src/dpl/core/include/dpl/waitable_handle_watch_support.h
new file mode 100644
index 0000000..4f3f142
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/waitable_handle_watch_support.h
@@ -0,0 +1,149 @@
+/*
+ * 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 waitable_handle_watch_support.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of waitable handle watch
+ * support
+ */
+#ifndef DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H
+#define DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H
+
+#include <dpl/waitable_event.h>
+#include <dpl/waitable_handle.h>
+#include <dpl/exception.h>
+#include <list>
+#include <map>
+#include <mutex>
+
+namespace VcoreDPL {
+class Thread;
+
+class WaitableHandleWatchSupport
+{
+ public:
+ class WaitableHandleListener
+ {
+ public:
+ virtual ~WaitableHandleListener() {}
+
+ virtual void OnWaitableHandleEvent(WaitableHandle waitableHandle,
+ WaitMode::Type mode) = 0;
+ };
+
+ protected:
+ // Invoker waitable handle
+ // Signaled by Add/Remove methods
+ // After being signaled one must call Handle invoke to reset invoker
+ WaitableHandle WaitableInvokerHandle() const;
+
+ // Waitable handle ex list
+ WaitableHandleListEx WaitableWatcherHandles() const;
+
+ // Perform actions for signaled waitable handle
+ // Called in execution context, after
+ void HandleWatcher(WaitableHandle waitableHandle, WaitMode::Type mode);
+
+ // Perform actions after invoker was signaled
+ void InvokerFinished();
+
+ // Get invoker context
+ virtual Thread *GetInvokerThread() = 0;
+
+ // Invoke direct invoker
+ virtual void HandleDirectInvoker() = 0;
+
+ private:
+ // Waitable event watchers
+ struct WaitableHandleWatcher
+ {
+ WaitableHandleListener *listener;
+ WaitMode::Type mode;
+
+ WaitableHandleWatcher(WaitableHandleListener *l, WaitMode::Type m) :
+ listener(l),
+ mode(m)
+ {}
+ };
+
+ typedef std::list<WaitableHandleWatcher> WaitableHandleListenerList;
+
+ struct WaitableHandleWatchers
+ {
+ WaitableHandleListenerList listeners;
+ size_t readListenersCount;
+ size_t writeListenersCount;
+
+ WaitableHandleWatchers() :
+ readListenersCount(0),
+ writeListenersCount(0)
+ {}
+ };
+
+ typedef std::map<WaitableHandle,
+ WaitableHandleWatchers> WaitableHandleWatchersMap;
+
+ // Waitable event watch support
+ mutable std::recursive_mutex m_watchersMutex;
+ WaitableHandleWatchersMap m_watchersMap;
+ WaitableEvent m_watchersInvoker;
+ WaitableEvent m_watchersInvokerCommit;
+
+ // Invoke call
+ void CommitInvoker();
+
+ public:
+ /**
+ * Constructor
+ */
+ explicit WaitableHandleWatchSupport();
+
+ /**
+ * Destructor
+ */
+ virtual ~WaitableHandleWatchSupport();
+
+ /**
+ * Adds listener for specific waitable event
+ *
+ * @param[in] listener Listener to attach
+ * @param[in] waitableHandle Waitable handle to listen for changes
+ * @param[in] mode Type of changes to listen to
+ * @return none
+ * @see WaitMode::Type
+ */
+ void AddWaitableHandleWatch(WaitableHandleListener *listener,
+ WaitableHandle waitableHandle,
+ WaitMode::Type mode);
+
+ /**
+ * Remove listener for specific waitable event
+ *
+ * @param[in] listener Listener to detach
+ * @param[in] waitableHandle Waitable handle to unlisten for changes
+ * @param[in] mode Type of changes to unlisten to
+ * @return none
+ * @see WaitMode::Type
+ */
+ void RemoveWaitableHandleWatch(WaitableHandleListener *listener,
+ WaitableHandle waitableHandle,
+ WaitMode::Type mode);
+
+};
+} // namespace VcoreDPL
+
+#endif // DPL_WAITABLE_HANDLE_WATCH_SUPPORT_H
diff --git a/vcore/src/dpl/core/include/dpl/workaround.h b/vcore/src/dpl/core/include/dpl/workaround.h
new file mode 100644
index 0000000..19c26ef
--- /dev/null
+++ b/vcore/src/dpl/core/include/dpl/workaround.h
@@ -0,0 +1,43 @@
+/*
+ * 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 workaround.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of workaround
+ */
+#ifndef DPL_WORKAROUND_H
+#define DPL_WORKAROUND_H
+
+/**
+ * Define following macro to track invalid waitable handles
+ * in WaitForSingle/WaitForMultiple functions
+ */
+#define DPL_ENABLE_WAITABLE_HANDLE_BADF_CHECK
+
+/**
+ * Define following macro to enable workaround for problem
+ * with GLIB loop integration and EBADF error handling
+ */
+#define DPL_ENABLE_GLIB_LOOP_INTEGRATION_WORKAROUND
+
+/**
+ * Define following macro to enable workaround for problem
+ * with invalid conversions in htons/ntohs macros
+ */
+#define DPL_ENABLE_HTONS_NTOHS_I386_WORKAROUND
+
+#endif // DPL_WORKAROUND_H
diff --git a/vcore/src/dpl/core/src/assert.cpp b/vcore/src/dpl/core/src/assert.cpp
new file mode 100644
index 0000000..2e55877
--- /dev/null
+++ b/vcore/src/dpl/core/src/assert.cpp
@@ -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 assert.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of assert
+ */
+#include <cstdlib>
+#include <sstream>
+#include <stddef.h>
+#include <dpl/assert.h>
+#include <dpl/colors.h>
+#include <dpl/exception.h>
+#include <dpl/log/vcore_log.h>
+
+namespace VcoreDPL {
+void AssertProc(const char *condition,
+ const char *file,
+ int line,
+ const char *function)
+{
+
+#define INTERNAL_LOG(message) \
+do { \
+ std::ostringstream platformLog; \
+ platformLog << message; \
+ VcoreLogD("%s", platformLog.str().c_str()); \
+} while (0)
+
+ // Try to log failed assertion to log system
+ Try {
+ INTERNAL_LOG("########################################################################");
+ INTERNAL_LOG("### DPL assertion failed! ###");
+ INTERNAL_LOG("########################################################################");
+ INTERNAL_LOG("### Condition: " << condition);
+ INTERNAL_LOG("### File: " << file);
+ INTERNAL_LOG("### Line: " << line);
+ INTERNAL_LOG("### Function: " << function);
+ INTERNAL_LOG("########################################################################");
+ } catch (Exception) {
+ // Just ignore possible double errors
+ }
+
+ // Fail with c-library abort
+ abort();
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/binary_queue.cpp b/vcore/src/dpl/core/src/binary_queue.cpp
new file mode 100644
index 0000000..0b39a22
--- /dev/null
+++ b/vcore/src/dpl/core/src/binary_queue.cpp
@@ -0,0 +1,312 @@
+/*
+ * 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 binary_queue.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of binary queue
+ */
+#include <stddef.h>
+#include <dpl/binary_queue.h>
+#include <dpl/assert.h>
+#include <dpl/scoped_free.h>
+#include <algorithm>
+#include <malloc.h>
+#include <cstring>
+#include <new>
+
+namespace VcoreDPL {
+BinaryQueue::BinaryQueue() :
+ m_size(0)
+{}
+
+BinaryQueue::BinaryQueue(const BinaryQueue &other) :
+ m_size(0)
+{
+ AppendCopyFrom(other);
+}
+
+BinaryQueue::~BinaryQueue()
+{
+ // Remove all remainig buckets
+ Clear();
+}
+
+BinaryQueue &BinaryQueue::operator=(const BinaryQueue &other)
+{
+ if (this != &other) {
+ Clear();
+ AppendCopyFrom(other);
+ }
+
+ return *this;
+}
+
+void BinaryQueue::AppendCopyFrom(const BinaryQueue &other)
+{
+ // To speed things up, always copy as one bucket
+ void *bufferCopy = malloc(other.m_size);
+
+ if (bufferCopy == NULL) {
+ throw std::bad_alloc();
+ }
+
+ try {
+ other.Flatten(bufferCopy, other.m_size);
+ AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL);
+ } catch (const std::bad_alloc &) {
+ // Free allocated memory
+ free(bufferCopy);
+ throw;
+ }
+}
+
+void BinaryQueue::AppendMoveFrom(BinaryQueue &other)
+{
+ // Copy all buckets
+ std::copy(other.m_buckets.begin(),
+ other.m_buckets.end(), std::back_inserter(m_buckets));
+ m_size += other.m_size;
+
+ // Clear other, but do not free memory
+ other.m_buckets.clear();
+ other.m_size = 0;
+}
+
+void BinaryQueue::AppendCopyTo(BinaryQueue &other) const
+{
+ other.AppendCopyFrom(*this);
+}
+
+void BinaryQueue::AppendMoveTo(BinaryQueue &other)
+{
+ other.AppendMoveFrom(*this);
+}
+
+void BinaryQueue::Clear()
+{
+ std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket);
+ m_buckets.clear();
+ m_size = 0;
+}
+
+void BinaryQueue::AppendCopy(const void* buffer, size_t bufferSize)
+{
+ // Create data copy with malloc/free
+ void *bufferCopy = malloc(bufferSize);
+
+ // Check if allocation succeded
+ if (bufferCopy == NULL) {
+ throw std::bad_alloc();
+ }
+
+ // Copy user data
+ memcpy(bufferCopy, buffer, bufferSize);
+
+ try {
+ // Try to append new bucket
+ AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL);
+ } catch (const std::bad_alloc &) {
+ // Free allocated memory
+ free(bufferCopy);
+ throw;
+ }
+}
+
+void BinaryQueue::AppendUnmanaged(const void* buffer,
+ size_t bufferSize,
+ BufferDeleter deleter,
+ void* userParam)
+{
+ // Do not attach empty buckets
+ if (bufferSize == 0) {
+ deleter(buffer, bufferSize, userParam);
+ return;
+ }
+
+ // Just add new bucket with selected deleter
+ m_buckets.push_back(new Bucket(buffer, bufferSize, deleter, userParam));
+
+ // Increase total queue size
+ m_size += bufferSize;
+}
+
+size_t BinaryQueue::Size() const
+{
+ return m_size;
+}
+
+bool BinaryQueue::Empty() const
+{
+ return m_size == 0;
+}
+
+void BinaryQueue::Consume(size_t size)
+{
+ // Check parameters
+ if (size > m_size) {
+ Throw(Exception::OutOfData);
+ }
+
+ size_t bytesLeft = size;
+
+ // Consume data and/or remove buckets
+ while (bytesLeft > 0) {
+ // Get consume size
+ size_t count = std::min(bytesLeft, m_buckets.front()->left);
+
+ m_buckets.front()->ptr =
+ static_cast<const char *>(m_buckets.front()->ptr) + count;
+ m_buckets.front()->left -= count;
+ bytesLeft -= count;
+ m_size -= count;
+
+ if (m_buckets.front()->left == 0) {
+ DeleteBucket(m_buckets.front());
+ m_buckets.pop_front();
+ }
+ }
+}
+
+void BinaryQueue::Flatten(void *buffer, size_t bufferSize) const
+{
+ // Check parameters
+ if (bufferSize == 0) {
+ return;
+ }
+
+ if (bufferSize > m_size) {
+ Throw(Exception::OutOfData);
+ }
+
+ size_t bytesLeft = bufferSize;
+ void *ptr = buffer;
+ BucketList::const_iterator bucketIterator = m_buckets.begin();
+ Assert(m_buckets.end() != bucketIterator);
+
+ // Flatten data
+ while (bytesLeft > 0) {
+ // Get consume size
+ size_t count = std::min(bytesLeft, (*bucketIterator)->left);
+
+ // Copy data to user pointer
+ memcpy(ptr, (*bucketIterator)->ptr, count);
+
+ // Update flattened bytes count
+ bytesLeft -= count;
+ ptr = static_cast<char *>(ptr) + count;
+
+ // Take next bucket
+ ++bucketIterator;
+ }
+}
+
+void BinaryQueue::FlattenConsume(void *buffer, size_t bufferSize)
+{
+ // FIXME: Optimize
+ Flatten(buffer, bufferSize);
+ Consume(bufferSize);
+}
+
+void BinaryQueue::DeleteBucket(BinaryQueue::Bucket *bucket)
+{
+ delete bucket;
+}
+
+void BinaryQueue::BufferDeleterFree(const void* data,
+ size_t dataSize,
+ void* userParam)
+{
+ (void)dataSize;
+ (void)userParam;
+
+ // Default free deleter
+ free(const_cast<void *>(data));
+}
+
+BinaryQueue::Bucket::Bucket(const void* data,
+ size_t dataSize,
+ BufferDeleter dataDeleter,
+ void* userParam) :
+ buffer(data),
+ ptr(data),
+ size(dataSize),
+ left(dataSize),
+ deleter(dataDeleter),
+ param(userParam)
+{
+ Assert(data != NULL);
+ Assert(deleter != NULL);
+}
+
+BinaryQueue::Bucket::~Bucket()
+{
+ // Invoke deleter on bucket data
+ deleter(buffer, size, param);
+}
+
+BinaryQueue::BucketVisitor::~BucketVisitor()
+{}
+
+BinaryQueue::BucketVisitorCall::BucketVisitorCall(BucketVisitor *visitor) :
+ m_visitor(visitor)
+{}
+
+BinaryQueue::BucketVisitorCall::~BucketVisitorCall()
+{}
+
+void BinaryQueue::BucketVisitorCall::operator()(Bucket *bucket) const
+{
+ m_visitor->OnVisitBucket(bucket->ptr, bucket->left);
+}
+
+void BinaryQueue::VisitBuckets(BucketVisitor *visitor) const
+{
+ Assert(visitor != NULL);
+
+ // Visit all buckets
+ std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor));
+}
+
+BinaryQueueAutoPtr BinaryQueue::Read(size_t size)
+{
+ // Simulate input stream
+ size_t available = std::min(size, m_size);
+
+ ScopedFree<void> bufferCopy(malloc(available));
+
+ if (!bufferCopy) {
+ throw std::bad_alloc();
+ }
+
+ BinaryQueueAutoPtr result(new BinaryQueue());
+
+ Flatten(bufferCopy.Get(), available);
+ result->AppendUnmanaged(
+ bufferCopy.Get(), available, &BufferDeleterFree, NULL);
+ bufferCopy.Release();
+ Consume(available);
+
+ return result;
+}
+
+size_t BinaryQueue::Write(const BinaryQueue &buffer, size_t bufferSize)
+{
+ // Simulate output stream
+ AppendCopyFrom(buffer);
+ return bufferSize;
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/char_traits.cpp b/vcore/src/dpl/core/src/char_traits.cpp
new file mode 100644
index 0000000..32b9197
--- /dev/null
+++ b/vcore/src/dpl/core/src/char_traits.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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 char_traits.cpp
+ * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @version 1.0
+ * @biref Char traits are used to create basic_string extended with
+ * additional features
+ * Current char traits could be extended in feature to boost
+ * performance
+ */
+#include <stddef.h>
+#include <dpl/char_traits.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
diff --git a/vcore/src/dpl/core/src/colors.cpp b/vcore/src/dpl/core/src/colors.cpp
new file mode 100644
index 0000000..e918453
--- /dev/null
+++ b/vcore/src/dpl/core/src/colors.cpp
@@ -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.
+ */
+/*
+ * @file colors.cpp
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief Some constants with definition of colors for Console
+ * and html output
+ */
+#include <stddef.h>
+#include <dpl/colors.h>
+
+namespace VcoreDPL {
+namespace Colors {
+namespace Text {
+const char* BOLD_GREEN_BEGIN = "\033[1;32m";
+const char* BOLD_GREEN_END = "\033[m";
+const char* RED_BEGIN = "\033[0;31m";
+const char* RED_END = "\033[m";
+const char* PURPLE_BEGIN = "\033[0;35m";
+const char* PURPLE_END = "\033[m";
+const char* GREEN_BEGIN = "\033[0;32m";
+const char* GREEN_END = "\033[m";
+const char* CYAN_BEGIN = "\033[0;36m";
+const char* CYAN_END = "\033[m";
+const char* BOLD_RED_BEGIN = "\033[1;31m";
+const char* BOLD_RED_END = "\033[m";
+const char* BOLD_YELLOW_BEGIN = "\033[1;33m";
+const char* BOLD_YELLOW_END = "\033[m";
+const char* BOLD_GOLD_BEGIN = "\033[0;33m";
+const char* BOLD_GOLD_END = "\033[m";
+const char* BOLD_WHITE_BEGIN = "\033[1;37m";
+const char* BOLD_WHITE_END = "\033[m";
+} //namespace Text
+
+namespace Html {
+const char* BOLD_GREEN_BEGIN = "<font color=\"green\"><b>";
+const char* BOLD_GREEN_END = "</b></font>";
+const char* PURPLE_BEGIN = "<font color=\"purple\"><b>";
+const char* PURPLE_END = "</b></font>";
+const char* RED_BEGIN = "<font color=\"red\"><b>";
+const char* RED_END = "</b></font>";
+const char* GREEN_BEGIN = "<font color=\"green\">";
+const char* GREEN_END = "</font>";
+const char* CYAN_BEGIN = "<font color=\"cyan\">";
+const char* CYAN_END = "</font>";
+const char* BOLD_RED_BEGIN = "<font color=\"red\"><b>";
+const char* BOLD_RED_END = "</b></font>";
+const char* BOLD_YELLOW_BEGIN = "<font color=\"yellow\"><b>";
+const char* BOLD_YELLOW_END = "</b></font>";
+const char* BOLD_GOLD_BEGIN = "<font color=\"gold\"><b>";
+const char* BOLD_GOLD_END = "</b></font>";
+const char* BOLD_WHITE_BEGIN = "<font color=\"white\"><b>";
+const char* BOLD_WHITE_END = "</b></font>";
+} //namespace Html
+} //namespace Colors
+} //namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/errno_string.cpp b/vcore/src/dpl/core/src/errno_string.cpp
new file mode 100644
index 0000000..c4efc4d
--- /dev/null
+++ b/vcore/src/dpl/core/src/errno_string.cpp
@@ -0,0 +1,98 @@
+/*
+ * 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 errno_string.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of errno string
+ */
+#include <stddef.h>
+#include <dpl/errno_string.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/assert.h>
+#include <dpl/scoped_free.h>
+#include <string>
+#include <cstddef>
+#include <cstring>
+#include <malloc.h>
+#include <cerrno>
+#include <stdexcept>
+
+namespace VcoreDPL {
+namespace // anonymous
+{
+const size_t DEFAULT_ERRNO_STRING_SIZE = 32;
+} // namespace anonymous
+
+std::string GetErrnoString(int error)
+{
+ size_t size = DEFAULT_ERRNO_STRING_SIZE;
+ char *buffer = NULL;
+
+ for (;;) {
+ // Add one extra characted for end of string null value
+ char *newBuffer = static_cast<char *>(::realloc(buffer, size + 1));
+
+ if (!newBuffer) {
+ // Failed to realloc
+ ::free(buffer);
+ throw std::bad_alloc();
+ }
+
+ // Setup reallocated buffer
+ buffer = newBuffer;
+ ::memset(buffer, 0, size + 1);
+
+ // Try to retrieve error string
+#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
+ // The XSI-compliant version of strerror_r() is provided if:
+ int result = ::strerror_r(error, buffer, size);
+
+ if (result == 0) {
+ ScopedFree<char> scopedBufferFree(buffer);
+ return std::string(buffer);
+ }
+#else
+ errno = 0;
+
+ // Otherwise, the GNU-specific version is provided.
+ char *result = ::strerror_r(error, buffer, size);
+
+ if (result != NULL) {
+ ScopedFree<char> scopedBufferFree(buffer);
+ return std::string(result);
+ }
+#endif
+
+ // Interpret errors
+ switch (errno) {
+ case EINVAL:
+ // We got an invalid errno value
+ ::free(buffer);
+ ThrowMsg(InvalidErrnoValue, "Invalid errno value: " << error);
+
+ case ERANGE:
+ // Incease buffer size and retry
+ size <<= 1;
+ continue;
+
+ default:
+ AssertMsg(0, "Invalid errno value after call to strerror_r!");
+ }
+ }
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/exception.cpp b/vcore/src/dpl/core/src/exception.cpp
new file mode 100644
index 0000000..16a3c25
--- /dev/null
+++ b/vcore/src/dpl/core/src/exception.cpp
@@ -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 exception.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation of exception system
+ */
+#include <stddef.h>
+#include <dpl/exception.h>
+#include <dpl/log/vcore_log.h>
+#include <cstdio>
+
+namespace VcoreDPL {
+Exception* Exception::m_lastException = NULL;
+unsigned int Exception::m_exceptionCount = 0;
+void (*Exception::m_terminateHandler)() = NULL;
+
+void LogUnhandledException(const std::string &str)
+{
+ // Logging to dlog
+ VcoreLogD("%s", str.c_str());
+}
+
+void LogUnhandledException(const std::string &str,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ // Logging to dlog
+ VcoreLogE("Exception occured on file[%s] line[%d] function[%s] msg[%s]",
+ filename, line, function, str.c_str());
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/file_input.cpp b/vcore/src/dpl/core/src/file_input.cpp
new file mode 100644
index 0000000..18bef68
--- /dev/null
+++ b/vcore/src/dpl/core/src/file_input.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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 file_input.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of named input pipe
+ */
+#include <stddef.h>
+#include <dpl/file_input.h>
+#include <dpl/binary_queue.h>
+#include <dpl/log/log.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+namespace VcoreDPL {
+namespace // anonymous
+{
+const size_t DEFAULT_READ_BUFFER_SIZE = 4096;
+} // namespace anonymous
+
+FileInput::FileInput() :
+ m_fd(-1)
+{}
+
+FileInput::FileInput(const std::string& fileName) :
+ m_fd(-1)
+{
+ Open(fileName);
+}
+
+FileInput::~FileInput()
+{
+ Close();
+}
+
+void FileInput::Open(const std::string& fileName)
+{
+ // Open non-blocking
+ int fd = TEMP_FAILURE_RETRY(open(fileName.c_str(), O_RDONLY | O_NONBLOCK));
+
+ // Throw an exception if an error occurred
+ if (fd == -1) {
+ ThrowMsg(Exception::OpenFailed, fileName);
+ }
+
+ // Close if any existing
+ Close();
+
+ // Save new descriptor
+ m_fd = fd;
+
+ LogPedantic("Opened file: " << fileName);
+}
+
+void FileInput::Close()
+{
+ if (m_fd == -1) {
+ return;
+ }
+
+ if (TEMP_FAILURE_RETRY(close(m_fd)) == -1) {
+ Throw(Exception::CloseFailed);
+ }
+
+ m_fd = -1;
+
+ LogPedantic("Closed file");
+}
+
+BinaryQueueAutoPtr FileInput::Read(size_t size)
+{
+ size_t bytesToRead = size >
+ DEFAULT_READ_BUFFER_SIZE ? DEFAULT_READ_BUFFER_SIZE : size;
+
+ // Malloc default read buffer size
+ // It is unmanaged, so it can be then attached directly to binary queue
+ void *buffer = malloc(bytesToRead);
+
+ if (buffer == NULL) {
+ throw std::bad_alloc();
+ }
+
+ LogPedantic("Trying to read " << bytesToRead << " bytes");
+
+ ssize_t result = TEMP_FAILURE_RETRY(read(m_fd, buffer, bytesToRead));
+
+ LogPedantic("Read " << result << " bytes from file");
+
+ if (result > 0) {
+ // Succedded to read socket data
+ BinaryQueueAutoPtr binaryQueue(new BinaryQueue());
+
+ // Append unmanaged memory
+ binaryQueue->AppendUnmanaged(buffer,
+ result,
+ &BinaryQueue::BufferDeleterFree,
+ NULL);
+
+ // Return buffer
+ return binaryQueue;
+ } else if (result == 0) {
+ // Socket was gracefuly closed
+ free(buffer);
+
+ // Return empty buffer
+ return BinaryQueueAutoPtr(new BinaryQueue());
+ } else {
+ // Must first save errno value, because it may be altered
+ int lastErrno = errno;
+
+ // Free buffer
+ free(buffer);
+
+ // Interpret error result
+ (void)lastErrno;
+
+ // FIXME: Handle specific errno
+ Throw(AbstractInput::Exception::ReadFailed);
+ }
+}
+
+WaitableHandle FileInput::WaitableReadHandle() const
+{
+ return static_cast<WaitableHandle>(m_fd);
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/noncopyable.cpp b/vcore/src/dpl/core/src/noncopyable.cpp
new file mode 100644
index 0000000..74fc9af
--- /dev/null
+++ b/vcore/src/dpl/core/src/noncopyable.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 noncopyable.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of noncopyable
+ */
+#include <stddef.h>
+#include <dpl/noncopyable.h>
+
+namespace VcoreDPL {
+Noncopyable::Noncopyable()
+{}
+
+Noncopyable::~Noncopyable()
+{}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/singleton.cpp b/vcore/src/dpl/core/src/singleton.cpp
new file mode 100644
index 0000000..a76e8ac
--- /dev/null
+++ b/vcore/src/dpl/core/src/singleton.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 generic_event.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of singleton
+ */
+#include <stddef.h>
+#include <dpl/singleton.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
diff --git a/vcore/src/dpl/core/src/string.cpp b/vcore/src/dpl/core/src/string.cpp
new file mode 100644
index 0000000..fb2f79c
--- /dev/null
+++ b/vcore/src/dpl/core/src/string.cpp
@@ -0,0 +1,250 @@
+/*
+ * 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 string.cpp
+ * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ */
+#include <stddef.h>
+#include <memory>
+#include <dpl/string.h>
+#include <dpl/char_traits.h>
+#include <dpl/errno_string.h>
+#include <dpl/exception.h>
+#include <dpl/log/vcore_log.h>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cstring>
+#include <errno.h>
+#include <iconv.h>
+#include <unicode/ustring.h>
+
+// TODO: Completely move to ICU
+namespace VcoreDPL {
+namespace //anonymous
+{
+class ASCIIValidator
+{
+ const std::string& m_TestedString;
+
+ public:
+ ASCIIValidator(const std::string& aTestedString);
+
+ void operator()(char aCharacter) const;
+};
+
+ASCIIValidator::ASCIIValidator(const std::string& aTestedString) :
+ m_TestedString(aTestedString)
+{}
+
+void ASCIIValidator::operator()(char aCharacter) const
+{
+ // Check for ASCII data range
+ if (aCharacter <= 0) {
+ ThrowMsg(
+ StringException::InvalidASCIICharacter,
+ "invalid character code " << static_cast<int>(aCharacter)
+ << " from string [" <<
+ m_TestedString
+ << "] passed as ASCII");
+ }
+}
+
+const iconv_t gc_IconvOperError = reinterpret_cast<iconv_t>(-1);
+const size_t gc_IconvConvertError = static_cast<size_t>(-1);
+} // namespace anonymous
+
+String FromUTF8String(const std::string& aIn)
+{
+ if (aIn.empty()) {
+ return String();
+ }
+
+ size_t inbytes = aIn.size();
+
+ // Default iconv UTF-32 module adds BOM (4 bytes) in from of string
+ // The worst case is when 8bit UTF-8 char converts to 32bit UTF-32
+ // newsize = oldsize * 4 + end + bom
+ // newsize - bytes for UTF-32 string
+ // oldsize - letters in UTF-8 string
+ // end - end character for UTF-32 (\0)
+ // bom - Unicode header in front of string (0xfeff)
+ size_t outbytes = sizeof(wchar_t) * (inbytes + 2);
+ std::vector<wchar_t> output(inbytes + 2, 0);
+
+ size_t outbytesleft = outbytes;
+ char* inbuf = const_cast<char*>(aIn.c_str());
+
+ // vector is used to provide buffer for iconv which expects char* buffer
+ // but during conversion from UTF32 uses internaly wchar_t
+ char* outbuf = reinterpret_cast<char*>(&output[0]);
+
+ iconv_t iconvHandle = iconv_open("UTF-32", "UTF-8");
+
+ if (gc_IconvOperError == iconvHandle) {
+ int error = errno;
+
+ ThrowMsg(StringException::IconvInitErrorUTF8ToUTF32,
+ "iconv_open failed for " << "UTF-32 <- UTF-8" <<
+ "error: " << GetErrnoString(error));
+ }
+
+ size_t iconvRet = iconv(iconvHandle,
+ &inbuf,
+ &inbytes,
+ &outbuf,
+ &outbytesleft);
+
+ iconv_close(iconvHandle);
+
+ if (gc_IconvConvertError == iconvRet) {
+ ThrowMsg(StringException::IconvConvertErrorUTF8ToUTF32,
+ "iconv failed for " << "UTF-32 <- UTF-8" << "error: "
+ << GetErrnoString());
+ }
+
+ // Ignore BOM in front of UTF-32
+ return &output[1];
+}
+
+std::string ToUTF8String(const VcoreDPL::String& aIn)
+{
+ if (aIn.empty()) {
+ return std::string();
+ }
+
+ size_t inbytes = aIn.size() * sizeof(wchar_t);
+ size_t outbytes = inbytes + sizeof(char);
+
+ // wstring returns wchar_t but iconv expects char*
+ // iconv internally is processing input as wchar_t
+ char* inbuf = reinterpret_cast<char*>(const_cast<wchar_t*>(aIn.c_str()));
+ std::vector<char> output(inbytes, 0);
+ char* outbuf = &output[0];
+
+ size_t outbytesleft = outbytes;
+
+ iconv_t iconvHandle = iconv_open("UTF-8", "UTF-32");
+
+ if (gc_IconvOperError == iconvHandle) {
+ ThrowMsg(StringException::IconvInitErrorUTF32ToUTF8,
+ "iconv_open failed for " << "UTF-8 <- UTF-32"
+ << "error: " << GetErrnoString());
+ }
+
+ size_t iconvRet = iconv(iconvHandle,
+ &inbuf,
+ &inbytes,
+ &outbuf,
+ &outbytesleft);
+
+ iconv_close(iconvHandle);
+
+ if (gc_IconvConvertError == iconvRet) {
+ ThrowMsg(StringException::IconvConvertErrorUTF32ToUTF8,
+ "iconv failed for " << "UTF-8 <- UTF-32"
+ << "error: " << GetErrnoString());
+ }
+
+ return &output[0];
+}
+
+String FromASCIIString(const std::string& aString)
+{
+ String output;
+
+ std::for_each(aString.begin(), aString.end(), ASCIIValidator(aString));
+ std::copy(aString.begin(), aString.end(), std::back_inserter<String>(output));
+
+ return output;
+}
+
+String FromUTF32String(const std::wstring& aString)
+{
+ return String(&aString[0]);
+}
+
+static UChar *ConvertToICU(const String &inputString)
+{
+ std::unique_ptr<UChar[]> outputString;
+ int32_t size = 0;
+ int32_t convertedSize = 0;
+ UErrorCode error = U_ZERO_ERROR;
+
+ // Calculate size of output string
+ ::u_strFromWCS(NULL,
+ 0,
+ &size,
+ inputString.c_str(),
+ -1,
+ &error);
+
+ if (error == U_ZERO_ERROR ||
+ error == U_BUFFER_OVERFLOW_ERROR)
+ {
+ // What buffer size is ok ?
+ VcoreLogD("ICU: Output buffer size: %i", size);
+ } else {
+ ThrowMsg(StringException::ICUInvalidCharacterFound,
+ "ICU: Failed to retrieve output string size. Error: "
+ << error);
+ }
+
+ // Allocate proper buffer
+ outputString.reset(new UChar[size + 1]);
+ ::memset(outputString.get(), 0, sizeof(UChar) * (size + 1));
+
+ error = U_ZERO_ERROR;
+
+ // Do conversion
+ ::u_strFromWCS(outputString.get(),
+ size + 1,
+ &convertedSize,
+ inputString.c_str(),
+ -1,
+ &error);
+
+ if (!U_SUCCESS(error)) {
+ ThrowMsg(StringException::ICUInvalidCharacterFound,
+ "ICU: Failed to convert string. Error: " << error);
+ }
+
+ // Done
+ return outputString.release();
+}
+
+int StringCompare(const String &left,
+ const String &right,
+ bool caseInsensitive)
+{
+ // Convert input strings
+ std::unique_ptr<UChar[]> leftICU(ConvertToICU(left));
+ std::unique_ptr<UChar[]> rightICU(ConvertToICU(right));
+
+ if (caseInsensitive) {
+ return static_cast<int>(u_strcasecmp(leftICU.get(), rightICU.get(), 0));
+ } else {
+ return static_cast<int>(u_strcmp(leftICU.get(), rightICU.get()));
+ }
+}
+} //namespace VcoreDPL
+
+std::ostream& operator<<(std::ostream& aStream, const VcoreDPL::String& aString)
+{
+ return aStream << VcoreDPL::ToUTF8String(aString);
+}
diff --git a/vcore/src/dpl/core/src/thread.cpp b/vcore/src/dpl/core/src/thread.cpp
new file mode 100644
index 0000000..98fdd48
--- /dev/null
+++ b/vcore/src/dpl/core/src/thread.cpp
@@ -0,0 +1,609 @@
+/*
+ * 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 thread.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of thread
+ */
+#include <stddef.h>
+#include <dpl/thread.h>
+#include <dpl/log/vcore_log.h>
+#include <sys/time.h>
+#include <algorithm>
+#include <dpl/assert.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+
+namespace // anonymous
+{
+static const size_t NANOSECONDS_PER_SECOND =
+ static_cast<uint64_t>(1000 * 1000 * 1000);
+
+static const size_t NANOSECONDS_PER_MILISECOND =
+ static_cast<uint64_t>(1000 * 1000);
+
+static const size_t NANOSECONDS_PER_MICROSECOND =
+ static_cast<uint64_t>(1000);
+
+static const std::thread::id g_mainThread = std::this_thread::get_id();
+
+class ThreadSpecific
+{
+ public:
+ pthread_key_t threadSpecific;
+
+ ThreadSpecific() :
+ threadSpecific(0)
+ {
+ threadSpecific = 0;
+ pthread_key_create(&threadSpecific, NULL);
+ }
+
+ virtual ~ThreadSpecific()
+ {
+ pthread_key_delete(threadSpecific);
+ }
+};
+
+static ThreadSpecific g_threadSpecific;
+} // namespace anonymous
+
+namespace VcoreDPL {
+bool g_TLSforMainCreated = false;
+
+Thread::Thread() :
+ m_thread(),
+ m_abandon(false),
+ m_running(false),
+ m_directInvoke(false)
+{}
+
+Thread::~Thread()
+{
+ // Ensure that we quit thread
+ // Always wait thread by yourself; if thread is still running
+ // this may be sometimes very bad. When derived, some resources
+ // may leak or be doubly freed
+ Quit();
+
+ // Remove any remainig events
+ // Thread proc is surely not running now
+ for (InternalEventList::iterator iterator = m_eventList.begin();
+ iterator != m_eventList.end();
+ ++iterator)
+ {
+ iterator->eventDeleteProc(iterator->event, iterator->userParam);
+ }
+
+ m_eventList.clear();
+}
+
+bool Thread::IsMainThread()
+{
+ return (std::this_thread::get_id() == g_mainThread);
+}
+
+Thread *Thread::GetCurrentThread()
+{
+ if (std::this_thread::get_id() == g_mainThread) {
+ return NULL;
+ }
+
+ void *threadSpecific = pthread_getspecific(g_threadSpecific.threadSpecific);
+
+ // Is this a managed thread ?
+ if (threadSpecific == NULL) {
+ Throw(Exception::UnmanagedThread);
+ }
+
+ return static_cast<Thread *>(threadSpecific);
+}
+
+void *Thread::StaticThreadEntry(void *param)
+{
+ VcoreLogD("Entered static thread entry");
+
+ // Retrieve context
+ Thread *This = static_cast<Thread *>(param);
+ Assert(This != NULL);
+
+ // Set thread specific
+ int result = pthread_setspecific(g_threadSpecific.threadSpecific, This);
+
+ if (result)
+ VcoreLogE("Failed to set threadSpecific.");
+
+ // Enter thread proc
+ // Do not allow exceptions to hit pthread core
+ UNHANDLED_EXCEPTION_HANDLER_BEGIN
+ {
+ This->ThreadEntry();
+ }
+ UNHANDLED_EXCEPTION_HANDLER_END
+
+ // Critical section
+ {
+ // Leave running state
+ std::lock_guard<std::mutex> lock(This->m_stateMutex);
+
+ This->m_running = false;
+
+ // Abandon thread
+ if (This->m_abandon) {
+ VcoreLogD("Thread was abandoned");
+ This->m_thread.detach();
+ } else {
+ VcoreLogD("Thread is joinable");
+ }
+ }
+
+ return NULL;
+}
+
+int Thread::ThreadEntry()
+{
+ VcoreLogD("Entered default thread entry");
+ return Exec();
+}
+
+void Thread::ProcessEvents()
+{
+ VcoreLogD("Processing events");
+
+ // Steal current event list
+ InternalEventList stolenEvents;
+
+ // Enter event list critical section
+ {
+ std::lock_guard<std::mutex> lock(m_eventMutex);
+ m_eventList.swap(stolenEvents);
+ m_eventInvoker.Reset();
+ }
+
+ // Process event list
+ VcoreLogD("Stolen %u internal events", stolenEvents.size());
+
+ for (InternalEventList::iterator iterator = stolenEvents.begin();
+ iterator != stolenEvents.end();
+ ++iterator)
+ {
+ // Dispatch immediate event
+ iterator->eventDispatchProc(iterator->event, iterator->userParam);
+
+ // Delete event
+ iterator->eventDeleteProc(iterator->event, iterator->userParam);
+ }
+}
+
+void Thread::ProcessTimedEvents()
+{
+ // Critical section on timed events mutex
+ {
+ std::lock_guard<std::mutex> lock(m_timedEventMutex);
+
+ // Get current time
+ unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds();
+
+ // Info
+ VcoreLogD("Processing timed events. Time now: %lu ms", currentTimeMiliseconds);
+
+ // All timed events are sorted chronologically
+ // Emit timed out events
+ while (!m_timedEventVector.empty() &&
+ currentTimeMiliseconds >=
+ m_timedEventVector.begin()->registerTimeMiliseconds +
+ m_timedEventVector.begin()->dueTimeMiliseconds)
+ {
+ // Info
+ VcoreLogD("Transforming timed event into immediate event. Absolute due time: %lu ms",
+ (m_timedEventVector.begin()->registerTimeMiliseconds +
+ m_timedEventVector.begin()->dueTimeMiliseconds));
+
+ // Emit immediate event
+ PushEvent(m_timedEventVector.begin()->event,
+ m_timedEventVector.begin()->eventDispatchProc,
+ m_timedEventVector.begin()->eventDeleteProc,
+ m_timedEventVector.begin()->userParam);
+
+ // Remove timed eventand fix heap
+ std::pop_heap(m_timedEventVector.begin(), m_timedEventVector.end());
+ m_timedEventVector.pop_back();
+ }
+ }
+}
+
+unsigned long Thread::GetCurrentTimeMiliseconds() const
+{
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ return static_cast<unsigned long>(tv.tv_sec) * 1000 +
+ static_cast<unsigned long>(tv.tv_usec) / 1000;
+}
+
+int Thread::Exec()
+{
+ VcoreLogD("Executing thread event processing");
+
+ const std::size_t MIN_HANDLE_LIST_SIZE = 4;
+
+ // Start processing of events
+ WaitableHandleListEx handleList;
+
+ // index 0: Quit waitable event handle
+ handleList.push_back(std::make_pair(m_quitEvent.GetHandle(), WaitMode::Read));
+
+ // index 1: Event occurred event handle
+ handleList.push_back(std::make_pair(m_eventInvoker.GetHandle(),
+ WaitMode::Read));
+
+ // index 2: Timed event occurred event handle
+ handleList.push_back(std::make_pair(m_timedEventInvoker.GetHandle(),
+ WaitMode::Read));
+
+ // index 3: Waitable handle watch support invoker
+ handleList.push_back(std::make_pair(WaitableHandleWatchSupport::
+ WaitableInvokerHandle(),
+ WaitMode::Read));
+
+ //
+ // Watch list might have been initialized before threaded started
+ // Need to fill waitable event watch list in this case
+ //
+ {
+ WaitableHandleListEx waitableHandleWatchHandles =
+ WaitableHandleWatchSupport::WaitableWatcherHandles();
+ std::copy(
+ waitableHandleWatchHandles.begin(),
+ waitableHandleWatchHandles.end(), std::back_inserter(handleList));
+ }
+
+ // Quit flag
+ bool quit = false;
+
+ while (!quit) {
+ // Retrieve minimum wait time, according to timed events list
+ unsigned long minimumWaitTime;
+
+ // Critical section on timed events mutex
+ {
+ std::lock_guard<std::mutex> lock(m_timedEventMutex);
+
+ if (!m_timedEventVector.empty()) {
+ unsigned long currentTimeMiliseconds =
+ GetCurrentTimeMiliseconds();
+ unsigned long destinationTimeMiliseconds =
+ m_timedEventVector.begin()->registerTimeMiliseconds +
+ m_timedEventVector.begin()->dueTimeMiliseconds;
+
+ // Are we already late with timed event ?
+ if (currentTimeMiliseconds > destinationTimeMiliseconds) {
+ minimumWaitTime = 0;
+ } else {
+ minimumWaitTime = destinationTimeMiliseconds -
+ currentTimeMiliseconds;
+ }
+ } else {
+ minimumWaitTime = 0xFFFFFFFF; // Infinity
+ }
+ }
+
+ // Info
+ VcoreLogD("Thread loop minimum wait time: %lu ms", minimumWaitTime);
+
+ // Do thread waiting
+ WaitableHandleIndexList waitableHandleIndexList =
+ WaitForMultipleHandles(handleList, minimumWaitTime);
+
+ if (waitableHandleIndexList.empty()) {
+ // Timeout occurred. Process timed events.
+ VcoreLogD("Timed event list elapsed invoker");
+ ProcessTimedEvents();
+ continue;
+ }
+
+ // Go through each index
+ for (WaitableHandleIndexList::const_iterator
+ waitableHandleIndexIterator = waitableHandleIndexList.begin();
+ waitableHandleIndexIterator != waitableHandleIndexList.end();
+ ++waitableHandleIndexIterator)
+ {
+ size_t index = *waitableHandleIndexIterator;
+
+ VcoreLogD("Event loop triggered with index: %u", index);
+
+ switch (index) {
+ case 0:
+ // Quit waitable event handle
+ quit = true;
+ break;
+
+ case 1:
+ // Event occurred event handle
+ ProcessEvents();
+
+ // Handle direct invoker
+ if (m_directInvoke) {
+ m_directInvoke = false;
+
+ VcoreLogD("Handling direct invoker");
+
+ // Update list
+ while (handleList.size() > MIN_HANDLE_LIST_SIZE) {
+ handleList.pop_back();
+ }
+
+ // Insert current waitable event handles instead
+ {
+ WaitableHandleListEx waitableHandleWatchHandles =
+ WaitableHandleWatchSupport::WaitableWatcherHandles();
+ std::copy(
+ waitableHandleWatchHandles.begin(),
+ waitableHandleWatchHandles.end(),
+ std::back_inserter(handleList));
+ }
+ }
+
+ // Done
+ break;
+
+ case 2:
+ // Timed event list changed
+ VcoreLogD("Timed event list changed invoker");
+ ProcessTimedEvents();
+
+ // Reset timed event invoker
+ m_timedEventInvoker.Reset();
+
+ // Done
+ break;
+
+ case 3:
+ // Waitable handle watch support invoker
+ VcoreLogD("Waitable handle watch invoker event occurred");
+
+ // First, remove all previous handles
+ while (handleList.size() > MIN_HANDLE_LIST_SIZE) {
+ handleList.pop_back();
+ }
+
+ // Insert current waitable event handles instead
+ {
+ WaitableHandleListEx waitableHandleWatchHandles =
+ WaitableHandleWatchSupport::WaitableWatcherHandles();
+ std::copy(
+ waitableHandleWatchHandles.begin(),
+ waitableHandleWatchHandles.end(),
+ std::back_inserter(handleList));
+ }
+
+ // Handle invoker in waitable watch support
+ WaitableHandleWatchSupport::InvokerFinished();
+
+ VcoreLogD("Waitable handle watch invoker event handled");
+
+ // Done
+ break;
+
+ default:
+ // Waitable event watch list
+ VcoreLogD("Waitable handle watch event occurred");
+
+ // Handle event in waitable handle watch
+ {
+ std::pair<WaitableHandle,
+ WaitMode::Type> handle = handleList[index];
+ WaitableHandleWatchSupport::HandleWatcher(handle.first,
+ handle.second);
+ }
+
+ if (m_directInvoke) {
+ m_directInvoke = false;
+
+ VcoreLogD("Handling direct invoker");
+
+ // Update list
+ while (handleList.size() > MIN_HANDLE_LIST_SIZE) {
+ handleList.pop_back();
+ }
+
+ // Insert current waitable event handles instead
+ {
+ WaitableHandleListEx waitableHandleWatchHandles =
+ WaitableHandleWatchSupport::
+ WaitableWatcherHandles();
+ std::copy(waitableHandleWatchHandles.begin(),
+ waitableHandleWatchHandles.end(),
+ std::back_inserter(handleList));
+ }
+ }
+
+ VcoreLogD("Waitable handle watch event handled");
+
+ // Done
+ break;
+ }
+ }
+ }
+
+ VcoreLogD("Leaving thread event processing");
+ return 0;
+}
+
+void Thread::Run()
+{
+ VcoreLogD("Running thread");
+
+ // Critical section
+ {
+ std::lock_guard<std::mutex> lock(m_stateMutex);
+
+ if (m_running) {
+ return;
+ }
+
+ try{
+ m_thread = std::thread(StaticThreadEntry,this);
+ }catch(std::system_error e){
+ Throw(Exception::RunFailed);
+ }
+
+ // At default, we abandon thread
+ m_abandon = true;
+
+ // Enter running state
+ m_running = true;
+ }
+
+ VcoreLogD("Thread run");
+}
+
+void Thread::Quit()
+{
+ // Critical section
+ {
+ std::lock_guard<std::mutex> lock(m_stateMutex);
+
+ // Is thread running ?
+ if (!m_running) {
+ return;
+ }
+
+ VcoreLogD("Quitting thread...");
+
+ // Do not abandon thread, we will join
+ m_abandon = false;
+
+ // Singal quit waitable event
+ m_quitEvent.Signal();
+ }
+
+ try{
+ m_thread.join();
+ }catch(std::system_error e){
+ Throw(Exception::QuitFailed);
+ }
+
+ VcoreLogD("Thread quit");
+}
+
+void Thread::PushEvent(void *event,
+ EventDispatchProc eventDispatchProc,
+ EventDeleteProc eventDeleteProc,
+ void *userParam)
+{
+ // Enter event list critical section
+ std::lock_guard<std::mutex> lock(m_eventMutex);
+
+ // Push new event
+ m_eventList.push_back(InternalEvent(event, userParam, eventDispatchProc,
+ eventDeleteProc));
+
+ // Trigger invoker
+ m_eventInvoker.Signal();
+
+ VcoreLogD("Event pushed and invoker signaled");
+}
+
+void Thread::PushTimedEvent(void *event,
+ double dueTimeSeconds,
+ EventDispatchProc eventDispatchProc,
+ EventDeleteProc eventDeleteProc,
+ void *userParam)
+{
+ // Check for developer errors
+ Assert(dueTimeSeconds >= 0.0);
+
+ // Enter timed event list critical section
+ std::lock_guard<std::mutex> lock(m_timedEventMutex);
+
+ // Get current time
+ unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds();
+
+ // Convert to miliseconds
+ unsigned long dueTimeMiliseconds =
+ static_cast<unsigned long>(1000.0 * dueTimeSeconds);
+
+ // Push new timed event
+ m_timedEventVector.push_back(InternalTimedEvent(event, userParam,
+ dueTimeMiliseconds,
+ currentTimeMiliseconds,
+ eventDispatchProc,
+ eventDeleteProc));
+
+ // Heapify timed events
+ std::make_heap(m_timedEventVector.begin(), m_timedEventVector.end());
+
+ // Trigger invoker
+ m_timedEventInvoker.Signal();
+
+ VcoreLogD("Timed event pushed and invoker signaled: "
+ "due time: %lu ms, absolute due time: %lu ms",
+ dueTimeMiliseconds, currentTimeMiliseconds + dueTimeMiliseconds);
+}
+
+Thread *Thread::GetInvokerThread()
+{
+ return this;
+}
+
+void Thread::HandleDirectInvoker()
+{
+ // We must be in ProcessEvents call stack
+ // Mark that situation to handle direct invoker
+ m_directInvoke = true;
+}
+
+void Thread::Sleep(uint64_t seconds)
+{
+ NanoSleep(seconds * NANOSECONDS_PER_SECOND);
+}
+
+void Thread::MiliSleep(uint64_t miliseconds)
+{
+ NanoSleep(miliseconds * NANOSECONDS_PER_MILISECOND);
+}
+
+void Thread::MicroSleep(uint64_t microseconds)
+{
+ NanoSleep(microseconds * NANOSECONDS_PER_MICROSECOND);
+}
+
+void Thread::NanoSleep(uint64_t nanoseconds)
+{
+ timespec requestedTime = {
+ static_cast<time_t>(
+ nanoseconds / NANOSECONDS_PER_SECOND),
+
+ static_cast<long>(
+ nanoseconds % NANOSECONDS_PER_SECOND)
+ };
+
+ timespec remainingTime;
+
+ for (;;) {
+ if (nanosleep(&requestedTime, &remainingTime) == 0) {
+ break;
+ }
+
+ int error = errno;
+ Assert(error == EINTR);
+
+ requestedTime = remainingTime;
+ }
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/type_list.cpp b/vcore/src/dpl/core/src/type_list.cpp
new file mode 100644
index 0000000..fa94806
--- /dev/null
+++ b/vcore/src/dpl/core/src/type_list.cpp
@@ -0,0 +1,31 @@
+/*
+ * 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 type_list.cpp
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief Generic type list template
+ */
+#include <stddef.h>
+#include <dpl/type_list.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
diff --git a/vcore/src/dpl/core/src/waitable_event.cpp b/vcore/src/dpl/core/src/waitable_event.cpp
new file mode 100644
index 0000000..8ff1417
--- /dev/null
+++ b/vcore/src/dpl/core/src/waitable_event.cpp
@@ -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.
+ */
+/*
+ * @file waitable_event.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of waitable event
+ */
+#include <stddef.h>
+#include <dpl/waitable_event.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <errno.h>
+
+namespace VcoreDPL {
+WaitableEvent::WaitableEvent()
+{
+ if (pipe(m_pipe) == -1) {
+ Throw(Exception::CreateFailed);
+ }
+
+ if (fcntl(m_pipe[0], F_SETFL, O_NONBLOCK |
+ fcntl(m_pipe[0], F_GETFL)) == -1)
+ {
+ Throw(Exception::CreateFailed);
+ }
+}
+
+WaitableEvent::~WaitableEvent()
+{
+ if (TEMP_FAILURE_RETRY(close(m_pipe[0])) == -1) {
+ Throw(Exception::DestroyFailed);
+ }
+
+ if (TEMP_FAILURE_RETRY(close(m_pipe[1])) == -1) {
+ Throw(Exception::DestroyFailed);
+ }
+}
+
+WaitableHandle WaitableEvent::GetHandle() const
+{
+ return m_pipe[0];
+}
+
+void WaitableEvent::Signal() const
+{
+ char data = 0;
+
+ if (TEMP_FAILURE_RETRY(write(m_pipe[1], &data, 1)) != 1) {
+ Throw(Exception::SignalFailed);
+ }
+}
+
+void WaitableEvent::Reset() const
+{
+ char data;
+
+ if (TEMP_FAILURE_RETRY(read(m_pipe[0], &data, 1)) != 1) {
+ Throw(Exception::ResetFailed);
+ }
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/waitable_handle.cpp b/vcore/src/dpl/core/src/waitable_handle.cpp
new file mode 100644
index 0000000..58d0a35
--- /dev/null
+++ b/vcore/src/dpl/core/src/waitable_handle.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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 waitable_handle.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of waitable handle
+ */
+#include <stddef.h>
+#include <dpl/waitable_event.h>
+#include <dpl/workaround.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dpl/assert.h>
+
+namespace VcoreDPL {
+namespace // anonymous
+{
+void CheckWaitableHandle(WaitableHandle handle)
+{
+#ifdef DPL_ENABLE_WAITABLE_HANDLE_BADF_CHECK
+ // Try to get descriptor flags
+ int result = fcntl(handle, F_GETFL);
+
+ if (result == -1 && errno == EBADF) {
+ AssertMsg(0, "CheckWaitableHandle: Invalid WaitableHandle! (EBADF)");
+ }
+
+ AssertMsg(result != -1, "CheckWaitableHandle: Invalid WaitableHandle!");
+#endif // DPL_ENABLE_WAITABLE_HANDLE_BADF_CHECK
+}
+} // namespace anonymous
+
+WaitableHandleIndexList WaitForSingleHandle(WaitableHandle handle,
+ unsigned long miliseconds)
+{
+ WaitableHandleList waitHandles;
+ waitHandles.push_back(handle);
+ return WaitForMultipleHandles(waitHandles, miliseconds);
+}
+
+WaitableHandleIndexList WaitForSingleHandle(WaitableHandle handle,
+ WaitMode::Type mode,
+ unsigned long miliseconds)
+{
+ WaitableHandleListEx waitHandles;
+ waitHandles.push_back(std::make_pair(handle, mode));
+ return WaitForMultipleHandles(waitHandles, miliseconds);
+}
+
+WaitableHandleIndexList WaitForMultipleHandles(
+ const WaitableHandleList &waitableHandleList,
+ unsigned long miliseconds)
+{
+ WaitableHandleListEx handleList;
+
+ for (WaitableHandleList::const_iterator iterator = waitableHandleList.begin();
+ iterator != waitableHandleList.end();
+ ++iterator)
+ {
+ // Wait for multiple objects
+ handleList.push_back(std::make_pair(*iterator, WaitMode::Read));
+ }
+
+ // Do waiting
+ return WaitForMultipleHandles(handleList, miliseconds);
+}
+
+WaitableHandleIndexList WaitForMultipleHandles(
+ const WaitableHandleListEx &waitableHandleListEx,
+ unsigned long miliseconds)
+{
+ fd_set readFds, writeFds, errorFds;
+
+ // Fill sets
+ int maxFd = -1;
+
+ FD_ZERO(&readFds);
+ FD_ZERO(&writeFds);
+ FD_ZERO(&errorFds);
+
+ // Add read wait handles
+ for (WaitableHandleListEx::const_iterator iterator =
+ waitableHandleListEx.begin();
+ iterator != waitableHandleListEx.end();
+ ++iterator)
+ {
+ if (iterator->first > maxFd) {
+ maxFd = iterator->first;
+ }
+
+ CheckWaitableHandle(iterator->first);
+
+ // Handle errors along with read and write events
+ FD_SET(iterator->first, &errorFds);
+
+ if (iterator->second == WaitMode::Read) {
+ FD_SET(iterator->first, &readFds);
+ } else if (iterator->second == WaitMode::Write) {
+ FD_SET(iterator->first, &writeFds);
+ }
+ }
+
+ // Do select
+ timeval timeout;
+ timeval *effectiveTimeout = NULL;
+ if (miliseconds != 0xFFFFFFFF) {
+ timeout.tv_sec = miliseconds / 1000;
+ timeout.tv_usec = (miliseconds % 1000) * 1000;
+ effectiveTimeout = &timeout;
+ }
+
+ if (TEMP_FAILURE_RETRY(select(maxFd + 1, &readFds, &writeFds, &errorFds,
+ effectiveTimeout)) == -1)
+ {
+ Throw(WaitFailed);
+ }
+
+ // Check results
+ WaitableHandleIndexList indexes;
+ size_t index = 0;
+
+ for (WaitableHandleListEx::const_iterator iterator =
+ waitableHandleListEx.begin();
+ iterator != waitableHandleListEx.end();
+ ++iterator)
+ {
+ // Always return errors, no matter what type of listening is set
+ if (FD_ISSET(iterator->first, &errorFds)) {
+ indexes.push_back(index);
+ } else if (iterator->second == WaitMode::Read) {
+ if (FD_ISSET(iterator->first, &readFds)) {
+ indexes.push_back(index);
+ }
+ } else if (iterator->second == WaitMode::Write) {
+ if (FD_ISSET(iterator->first, &writeFds)) {
+ indexes.push_back(index);
+ }
+ }
+ ++index;
+ }
+
+ // Successfuly awaited some events or timeout occurred
+ return indexes;
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/core/src/waitable_handle_watch_support.cpp b/vcore/src/dpl/core/src/waitable_handle_watch_support.cpp
new file mode 100644
index 0000000..fb46539
--- /dev/null
+++ b/vcore/src/dpl/core/src/waitable_handle_watch_support.cpp
@@ -0,0 +1,376 @@
+/*
+ * 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 waitable_handle_watch_support.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of waitable handle watch
+ * support
+ */
+#include <stddef.h>
+#include <dpl/waitable_handle_watch_support.h>
+#include <dpl/thread.h>
+#include <dpl/log/vcore_log.h>
+#include <algorithm>
+#include <dpl/assert.h>
+
+namespace VcoreDPL {
+WaitableHandleWatchSupport::WaitableHandleWatchSupport()
+{}
+
+WaitableHandleWatchSupport::~WaitableHandleWatchSupport()
+{
+ // Developer assertions
+ if (!m_watchersMap.empty()) {
+ VcoreLogW("### Leaked watchers map dump ###");
+
+ for (WaitableHandleWatchersMap::const_iterator iterator =
+ m_watchersMap.begin();
+ iterator != m_watchersMap.end();
+ ++iterator)
+ {
+ VcoreLogW("### Waitable handle: %i", iterator->first);
+
+ VcoreLogW("### Read listeners: %u", iterator->second.readListenersCount);
+ VcoreLogW("### Write listeners: %u", iterator->second.writeListenersCount);
+
+ for (WaitableHandleListenerList::const_iterator listenersIterator =
+ iterator->second.listeners.begin();
+ listenersIterator != iterator->second.listeners.end();
+ ++listenersIterator)
+ {
+ VcoreLogW("### Mode: %i. Listener: %p",
+ listenersIterator->mode, listenersIterator->listener);
+ }
+ }
+ }
+}
+
+WaitableHandle WaitableHandleWatchSupport::WaitableInvokerHandle() const
+{
+ return m_watchersInvoker.GetHandle();
+}
+
+WaitableHandleListEx WaitableHandleWatchSupport::WaitableWatcherHandles() const
+{
+ // Critical section
+ {
+ std::lock_guard<std::recursive_mutex> lock(m_watchersMutex);
+
+ WaitableHandleListEx handleList;
+
+ for (WaitableHandleWatchersMap::const_iterator iterator =
+ m_watchersMap.begin();
+ iterator != m_watchersMap.end();
+ ++iterator)
+ {
+ // Register waitable event id for wait
+ // Check if there are any read listeners and write listeners
+ // and register for both if applicable
+ if (iterator->second.readListenersCount > 0) {
+ handleList.push_back(std::make_pair(iterator->first,
+ WaitMode::Read));
+ }
+
+ if (iterator->second.writeListenersCount > 0) {
+ handleList.push_back(std::make_pair(iterator->first,
+ WaitMode::Write));
+ }
+ }
+
+ return handleList;
+ }
+}
+
+void WaitableHandleWatchSupport::InvokerFinished()
+{
+ VcoreLogD("Invoker finished called");
+
+ // Reset invoker
+ m_watchersInvoker.Reset();
+
+ // Commit invoke
+ m_watchersInvokerCommit.Signal();
+}
+
+void WaitableHandleWatchSupport::HandleWatcher(WaitableHandle waitableHandle,
+ WaitMode::Type mode)
+{
+ //
+ // Waitable event occurred
+ // Now call all listeners for that waitable event. It is possible
+ // that some of listeners early disappeared. This is not a problem.
+ // Warning: Listeners and/or watcher may also disappear during dispatching
+ // handlers!
+ //
+ VcoreLogD("Waitable event occurred");
+
+ // Critical section for other threads
+ {
+ std::lock_guard<std::recursive_mutex> lock(m_watchersMutex);
+
+ // Notice: We must carefully call watchers here as they may disappear
+ // (zero listeners) or be created during each of handler call
+ // All removed listeners are handled correctly. Adding
+ // additional listener to the same waitable handle
+ // during handler dispatch sequence is _not_ supported.
+ WaitableHandleWatchersMap trackedWatchers = m_watchersMap;
+
+ for (WaitableHandleWatchersMap::const_iterator trackedWatchersIterator
+ = trackedWatchers.begin();
+ trackedWatchersIterator != trackedWatchers.end();
+ ++trackedWatchersIterator)
+ {
+ // Check if this watcher still exists
+ // If not, go to next tracked watcher
+ if (m_watchersMap.find(trackedWatchersIterator->first) ==
+ m_watchersMap.end())
+ {
+ VcoreLogD("Watcher disappeared during watcher handler");
+ continue;
+ }
+
+ // Is this is a waitable handle that we are searching for ?
+ if (waitableHandle != trackedWatchersIterator->first) {
+ continue;
+ }
+
+ // Track watcher listeners list
+ WaitableHandleListenerList trackedListeners =
+ trackedWatchersIterator->second.listeners;
+
+ VcoreLogD("Calling waitable event listeners (%u)...",
+ trackedListeners.size());
+
+ // Notice: We must carefully call listeners here as they may
+ // disappear or be created during each of handler call
+ // All removed listeners are handled correctly. Adding
+ // additional listener to the same waitable handle
+ // during handler dispatch sequence is should be also
+ // handled, as an extremly case.
+
+ // Call all waitable event listeners who listen for that event
+ for (WaitableHandleListenerList::const_iterator
+ trackedListenersIterator = trackedListeners.begin();
+ trackedListenersIterator != trackedListeners.end();
+ ++trackedListenersIterator)
+ {
+ // Check if this watcher still exists
+ // If not, there cannot be another one. Must exit now (after
+ // break, we actually exit)
+ if (m_watchersMap.find(trackedWatchersIterator->first) ==
+ m_watchersMap.end())
+ {
+ VcoreLogD("Watcher disappeared during watcher handler");
+ break;
+ }
+
+ // Check if this watcher listener still exists
+ // If not, go to next tracked watcher listener
+ bool listenerStillExists = false;
+
+ for (WaitableHandleListenerList::const_iterator
+ searchListenerIterator =
+ trackedWatchersIterator->second.listeners.begin();
+ searchListenerIterator !=
+ trackedWatchersIterator->second.listeners.end();
+ ++searchListenerIterator)
+ {
+ if (searchListenerIterator->listener ==
+ trackedListenersIterator->listener &&
+ searchListenerIterator->mode ==
+ trackedListenersIterator->mode)
+ {
+ listenerStillExists = true;
+ break;
+ }
+ }
+
+ if (!listenerStillExists) {
+ VcoreLogD("Watcher listener disappeared during watcher handler");
+ break;
+ }
+
+ // Is this is a listener mode that we are searching for ?
+ if (mode != trackedListenersIterator->mode) {
+ continue;
+ }
+
+ // Call waitable event watch listener
+ VcoreLogD("Before tracker listener call...");
+ trackedListenersIterator->listener->OnWaitableHandleEvent(
+ trackedWatchersIterator->first,
+ trackedListenersIterator->mode);
+ VcoreLogD("After tracker listener call...");
+ }
+
+ // Now call all those listeners who registered during listener calls
+ // FIXME: Implement! Notice, that scenario may be recursive!
+
+ VcoreLogD("Waitable event listeners called");
+
+ // No more waitable events possible - consistency check
+ break;
+ }
+ }
+}
+
+void WaitableHandleWatchSupport::AddWaitableHandleWatch(
+ WaitableHandleListener* listener,
+ WaitableHandle waitableHandle,
+ WaitMode::Type mode)
+{
+ // Enter waitable event list critical section
+ std::lock_guard<std::recursive_mutex> lock(m_watchersMutex);
+
+ // Find proper list to register into
+ WaitableHandleWatchersMap::iterator mapIterator = m_watchersMap.find(
+ waitableHandle);
+
+ if (mapIterator != m_watchersMap.end()) {
+ // Assert if there is no such listener already that is listening in this
+ // mode
+ for (WaitableHandleListenerList::iterator listenersIterator =
+ mapIterator->second.listeners.begin();
+ listenersIterator != mapIterator->second.listeners.end();
+ ++listenersIterator)
+ {
+ // Must not insert same listener-mode pair
+ Assert(
+ listenersIterator->listener != listener ||
+ listenersIterator->mode != mode);
+ }
+ }
+
+ VcoreLogD("Adding waitable handle watch: %i", waitableHandle);
+
+ // Push new waitable event watch
+ if (mapIterator != m_watchersMap.end()) {
+ mapIterator->second.listeners.push_back(WaitableHandleWatcher(listener,
+ mode));
+ } else {
+ m_watchersMap[waitableHandle].listeners.push_back(WaitableHandleWatcher(
+ listener, mode));
+ }
+
+ // Update counters
+ switch (mode) {
+ case WaitMode::Read:
+ m_watchersMap[waitableHandle].readListenersCount++;
+ break;
+
+ case WaitMode::Write:
+ m_watchersMap[waitableHandle].writeListenersCount++;
+ break;
+
+ default:
+ Assert(0);
+ }
+
+ // Trigger waitable event invoker to commit changes
+ CommitInvoker();
+
+ VcoreLogD("Waitable event watch added and invoker signaled");
+}
+
+void WaitableHandleWatchSupport::RemoveWaitableHandleWatch(
+ WaitableHandleListener *listener,
+ WaitableHandle waitableHandle,
+ WaitMode::Type mode)
+{
+ // Enter waitable event list critical section
+ std::lock_guard<std::recursive_mutex> lock(m_watchersMutex);
+
+ // Find proper list with listener
+ WaitableHandleWatchersMap::iterator mapIterator = m_watchersMap.find(
+ waitableHandle);
+
+ Assert(mapIterator != m_watchersMap.end());
+
+ // Assert if there is such listener and mode
+ WaitableHandleListenerList::iterator listIterator =
+ mapIterator->second.listeners.end();
+
+ for (WaitableHandleListenerList::iterator listenersIterator =
+ mapIterator->second.listeners.begin();
+ listenersIterator != mapIterator->second.listeners.end();
+ ++listenersIterator)
+ {
+ // Check same pair listener-mode
+ if (listenersIterator->listener == listener &&
+ listenersIterator->mode == mode)
+ {
+ listIterator = listenersIterator;
+ break;
+ }
+ }
+
+ // Same pair listener-mode must exist
+ Assert(listIterator != mapIterator->second.listeners.end());
+
+ VcoreLogD("Removing waitable handle watch: %i", waitableHandle);
+
+ // Remove waitable event watch
+ mapIterator->second.listeners.erase(listIterator);
+
+ // Update counters
+ switch (mode) {
+ case WaitMode::Read:
+ mapIterator->second.readListenersCount--;
+ break;
+
+ case WaitMode::Write:
+ mapIterator->second.writeListenersCount--;
+ break;
+
+ default:
+ Assert(0);
+ }
+
+ // If list is empty, remove it too
+ if (mapIterator->second.listeners.empty()) {
+ m_watchersMap.erase(mapIterator);
+ }
+
+ // Trigger waitable event invoker to commit changes
+ CommitInvoker();
+
+ VcoreLogD("Waitable event watch removed and invoker signaled");
+}
+
+void WaitableHandleWatchSupport::CommitInvoker()
+{
+ // Check calling context and execute invoker
+ if (Thread::GetCurrentThread() == GetInvokerThread()) {
+ VcoreLogD("Calling direct invoker");
+
+ // Direct invoker call
+ HandleDirectInvoker();
+ } else {
+ VcoreLogD("Calling indirect invoker");
+
+ // Indirect invoker call
+ m_watchersInvoker.Signal();
+
+ WaitableHandleList waitHandles;
+ waitHandles.push_back(m_watchersInvokerCommit.GetHandle());
+ WaitForMultipleHandles(waitHandles);
+
+ m_watchersInvokerCommit.Reset();
+ }
+}
+
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/db/include/dpl/db/naive_synchronization_object.h b/vcore/src/dpl/db/include/dpl/db/naive_synchronization_object.h
new file mode 100644
index 0000000..d774ce0
--- /dev/null
+++ b/vcore/src/dpl/db/include/dpl/db/naive_synchronization_object.h
@@ -0,0 +1,45 @@
+/*
+ * 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 naive_synchronization_object.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of SQL naive
+ * synchronization object
+ */
+#ifndef DPL_NAIVE_SYNCHRONIZATION_OBJECT_H
+#define DPL_NAIVE_SYNCHRONIZATION_OBJECT_H
+
+#include <dpl/db/sql_connection.h>
+
+namespace VcoreDPL {
+namespace DB {
+/**
+ * Naive synchronization object used to synchronize SQL connection
+ * to the same database across different threads and processes
+ */
+class NaiveSynchronizationObject :
+ public SqlConnection::SynchronizationObject
+{
+ public:
+ // [SqlConnection::SynchronizationObject]
+ virtual void Synchronize();
+ virtual void NotifyAll();
+};
+} // namespace DB
+} // namespace VcoreDPL
+
+#endif // DPL_NAIVE_SYNCHRONIZATION_OBJECT_H
diff --git a/vcore/src/dpl/db/include/dpl/db/orm.h b/vcore/src/dpl/db/include/dpl/db/orm.h
new file mode 100644
index 0000000..39d0503
--- /dev/null
+++ b/vcore/src/dpl/db/include/dpl/db/orm.h
@@ -0,0 +1,1117 @@
+/*
+ * 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 orm.h
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief DPL-ORM: Object-relational mapping for sqlite database, written on top of DPL.
+ */
+
+#include <cstdlib>
+#include <cstdio>
+#include <string>
+#include <typeinfo>
+#include <utility>
+#include <set>
+#include <list>
+#include <memory>
+#include <boost/optional.hpp>
+
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/orm_interface.h>
+#include <dpl/string.h>
+#include <dpl/type_list.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+
+#ifndef DPL_ORM_H
+#define DPL_ORM_H
+
+namespace VcoreDPL {
+namespace DB {
+namespace ORM {
+
+//TODO move to type utils
+#define DPL_CHECK_TYPE_INSTANTIABILITY(type) \
+ { \
+ type _ignored_; \
+ (void)_ignored_; \
+ }
+
+#define DECLARE_COLUMN_TYPE_LIST() typedef VcoreDPL::TypeListDecl<
+#define SELECTED_COLUMN(table_name, column_name) table_name::column_name,
+#define DECLARE_COLUMN_TYPE_LIST_END(name) VcoreDPL::TypeListGuard>::Type name;
+
+typedef size_t ColumnIndex;
+typedef size_t ArgumentIndex;
+typedef boost::optional<VcoreDPL::String> OptionalString;
+typedef boost::optional<int> OptionalInteger;
+typedef VcoreDPL::DB::SqlConnection::DataCommand DataCommand;
+
+namespace RelationTypes {
+ extern const char Equal[];
+ extern const char LessThan[];
+ extern const char And[];
+ extern const char Or[];
+ extern const char Is[];
+ extern const char In[];
+ //TODO define more relation types
+}
+
+namespace DataCommandUtils {
+ //TODO move to VcoreDPL::DataCommand?
+ void BindArgument(DataCommand *command, ArgumentIndex index, int argument);
+ void BindArgument(DataCommand *command, ArgumentIndex index, const OptionalInteger& argument);
+ void BindArgument(DataCommand *command, ArgumentIndex index, const VcoreDPL::String& argument);
+ void BindArgument(DataCommand *command, ArgumentIndex index, const OptionalString& argument);
+}
+class __attribute__ ((visibility("hidden"))) Expression {
+public:
+ virtual ~Expression() {}
+ virtual std::string GetString() const = 0;
+ virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index) = 0;
+};
+
+typedef std::shared_ptr<Expression> ExpressionPtr;
+
+namespace OrderingUtils {
+
+template<typename CompoundType> inline std::string OrderByInternal()
+{
+ std::string order = OrderByInternal<typename CompoundType::Tail>();
+ if(!order.empty()) return CompoundType::Head::GetString() + ", " + order;
+ else return CompoundType::Head::GetString();
+}
+
+template<> inline std::string OrderByInternal<TypeListGuard>()
+{
+ return std::string();
+}
+
+}
+
+template<typename ColumnType>
+class __attribute__ ((visibility("hidden"))) OrderingExpression {
+protected:
+ static std::string GetSchemaAndName()
+ {
+ std::string statement;
+ statement += ColumnType::GetTableName();
+ statement += ".";
+ statement += ColumnType::GetColumnName();
+ statement += " ";
+ return statement;
+ }
+public:
+ virtual ~OrderingExpression() {}
+};
+
+template<const char* Operator, typename LeftExpression, typename RightExpression>
+class __attribute__ ((visibility("hidden"))) BinaryExpression : public Expression {
+protected:
+ LeftExpression m_leftExpression;
+ RightExpression m_rightExpression;
+ bool m_outerParenthesis;
+public:
+ BinaryExpression(const LeftExpression& leftExpression, const RightExpression& rightExpression, bool outerParenthesis = true) :
+ m_leftExpression(leftExpression),
+ m_rightExpression(rightExpression),
+ m_outerParenthesis(outerParenthesis)
+ {}
+
+ virtual std::string GetString() const
+ {
+ return (m_outerParenthesis ? "( " : " " ) +
+ m_leftExpression.GetString() + " " + Operator + " " + m_rightExpression.GetString() +
+ (m_outerParenthesis ? " )" : " " ) ;
+ }
+
+ virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index)
+ {
+ index = m_leftExpression.BindTo(command, index);
+ return m_rightExpression.BindTo(command, index);
+ }
+
+ template<typename TableDefinition>
+ struct ValidForTable {
+ typedef std::pair<typename LeftExpression ::template ValidForTable<TableDefinition>::Yes ,
+ typename RightExpression::template ValidForTable<TableDefinition>::Yes >
+ Yes;
+ };
+};
+
+template<typename LeftExpression, typename RightExpression>
+BinaryExpression<RelationTypes::And, LeftExpression, RightExpression>
+ And(const LeftExpression& leftExpression, const RightExpression& rightExpression)
+{
+ return BinaryExpression<RelationTypes::And, LeftExpression, RightExpression>
+ (leftExpression, rightExpression);
+}
+
+template<typename LeftExpression, typename RightExpression>
+BinaryExpression<RelationTypes::Or, LeftExpression, RightExpression>
+ Or(const LeftExpression& leftExpression, const RightExpression& rightExpression)
+{
+ return BinaryExpression<RelationTypes::Or, LeftExpression, RightExpression>
+ (leftExpression, rightExpression);
+}
+
+template<typename ArgumentType>
+class __attribute__ ((visibility("hidden"))) ExpressionWithArgument : public Expression {
+protected:
+ ArgumentType argument;
+
+public:
+ explicit ExpressionWithArgument(const ArgumentType& _argument) : argument(_argument) {}
+
+ virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index)
+ {
+ DataCommandUtils::BindArgument(command, index, argument);
+ return index + 1;
+ }
+};
+
+template<typename ColumnData, const char* Relation>
+class __attribute__ ((visibility("hidden"))) Compare : public ExpressionWithArgument<typename ColumnData::ColumnType> {
+public:
+ explicit Compare(typename ColumnData::ColumnType column) :
+ ExpressionWithArgument<typename ColumnData::ColumnType>(column)
+ {}
+
+ virtual std::string GetString() const
+ {
+ std::string statement;
+ statement += ColumnData::GetTableName();
+ statement += ".";
+ statement += ColumnData::GetColumnName();
+ statement += " ";
+ statement += Relation;
+ statement += " ?";
+ return statement;
+ }
+
+ template<typename TableDefinition>
+ struct ValidForTable {
+ typedef typename TableDefinition::ColumnList::template Contains<ColumnData> Yes;
+ };
+};
+#define ORM_DEFINE_COMPARE_EXPRESSION(name, relationType) \
+ template<typename ColumnData> \
+ class __attribute__ ((visibility("hidden"))) name : public Compare<ColumnData, RelationTypes::relationType> { \
+ public: \
+ name(typename ColumnData::ColumnType column) : \
+ Compare<ColumnData, RelationTypes::relationType>(column) \
+ {} \
+ };
+
+ORM_DEFINE_COMPARE_EXPRESSION(Equals, Equal)
+ORM_DEFINE_COMPARE_EXPRESSION(Is, Is)
+
+#define ORM_DEFINE_ORDERING_EXPRESSION(name, value) \
+ template<typename ColumnType> \
+ class __attribute__ ((visibility("hidden"))) name \
+ : OrderingExpression<ColumnType> { \
+ public: \
+ static std::string GetString() \
+ { \
+ std::string statement = OrderingExpression<ColumnType>::GetSchemaAndName(); \
+ statement += value; \
+ return statement; \
+ } \
+ };
+
+ORM_DEFINE_ORDERING_EXPRESSION(OrderingAscending, "ASC")
+ORM_DEFINE_ORDERING_EXPRESSION(OrderingDescending, "DESC")
+
+template<typename ColumnData1, typename ColumnData2>
+class __attribute__ ((visibility("hidden"))) CompareBinaryColumn {
+private:
+ std::string m_relation;
+public:
+ CompareBinaryColumn(const char* Relation) :
+ m_relation(Relation)
+ {}
+
+ virtual ~CompareBinaryColumn() {}
+
+ virtual std::string GetString() const
+ {
+ std::string statement;
+ statement += ColumnData1::GetTableName();
+ statement += ".";
+ statement += ColumnData1::GetColumnName();
+ statement += " ";
+ statement += m_relation;
+ statement += " ";
+ statement += ColumnData2::GetTableName();
+ statement += ".";
+ statement += ColumnData2::GetColumnName();
+
+ return statement;
+ }
+};
+
+template<typename ColumnData1, typename ColumnData2>
+CompareBinaryColumn<ColumnData1, ColumnData2>
+ Equal()
+{
+ return CompareBinaryColumn<ColumnData1, ColumnData2>(RelationTypes::Equal);
+}
+
+template<typename ColumnData, const char* Relation>
+class __attribute__ ((visibility("hidden"))) NumerousArguments : public Expression {
+protected:
+ std::set<typename ColumnData::ColumnType> m_argumentList;
+public:
+ NumerousArguments(const std::set<typename ColumnData::ColumnType>& argumentList) : m_argumentList(argumentList) {}
+
+ virtual std::string GetString() const
+ {
+ std::string statement;
+ statement += ColumnData::GetColumnName();
+ statement += " ";
+ statement += Relation;
+ statement += " ( ";
+
+ int argumentCount = m_argumentList.size();
+ while(argumentCount)
+ {
+ statement += "?";
+ argumentCount--;
+ if (argumentCount)
+ {
+ statement += ", ";
+ }
+ }
+
+ statement += " )";
+
+ return statement;
+ }
+
+ virtual ArgumentIndex BindTo(DataCommand *command, ArgumentIndex index)
+ {
+ ArgumentIndex argumentIndex = index;
+ FOREACH(argumentIt, m_argumentList)
+ {
+ DataCommandUtils::BindArgument(command, argumentIndex, *argumentIt);
+ argumentIndex++;
+ }
+ return argumentIndex + 1;
+ }
+
+ template<typename TableDefinition>
+ struct ValidForTable {
+ typedef typename TableDefinition::ColumnList::template Contains<ColumnData> Yes;
+ };
+};
+
+#define ORM_DEFINE_COMPARE_EXPRESSION_NUMEROUS_ARGUMENTS(name, relationType) \
+ template<typename ColumnData> \
+ class __attribute__ ((visibility("hidden"))) name : public NumerousArguments<ColumnData, RelationTypes::relationType> { \
+ public: \
+ name(std::set<typename ColumnData::ColumnType> column) : \
+ NumerousArguments<ColumnData, RelationTypes::relationType>(column) \
+ {} \
+ };
+
+ORM_DEFINE_COMPARE_EXPRESSION_NUMEROUS_ARGUMENTS(In, In)
+
+template<typename ColumnType>
+ColumnType GetColumnFromCommand(ColumnIndex columnIndex, DataCommand *command);
+
+class __attribute__ ((visibility("hidden"))) CustomColumnBase {
+public:
+ CustomColumnBase() {}
+ virtual ~CustomColumnBase() {}
+};
+
+template<typename ColumnType>
+class __attribute__ ((visibility("hidden"))) CustomColumn : public CustomColumnBase {
+private:
+ ColumnType m_columnData;
+
+public:
+ CustomColumn() {}
+ CustomColumn(ColumnType data)
+ {
+ m_columnData = data;
+ }
+
+ void SetColumnData(ColumnType data)
+ {
+ m_columnData = data;
+ }
+
+ ColumnType GetColumnData() const
+ {
+ return m_columnData;
+ }
+};
+
+template<typename ColumnList>
+class __attribute__ ((visibility("hidden"))) CustomRowUtil {
+public:
+ static void MakeColumnList(std::vector<CustomColumnBase*>& columnList)
+ {
+ typedef CustomColumn<typename ColumnList::Head::ColumnType> Type;
+ Type* pColumn = new Type();
+ columnList.push_back(pColumn);
+ CustomRowUtil<typename ColumnList::Tail>::MakeColumnList(columnList);
+ }
+
+ static void CopyColumnList(const std::vector<CustomColumnBase*>& srcList, std::vector<CustomColumnBase*>& dstList)
+ {
+ CopyColumnList(srcList, dstList, 0);
+ }
+
+ static ColumnIndex GetColumnIndex(const std::string& columnName)
+ {
+ return GetColumnIndex(columnName, 0);
+ }
+
+private:
+ static void CopyColumnList(const std::vector<CustomColumnBase*>& srcList, std::vector<CustomColumnBase*>& dstList, ColumnIndex index)
+ {
+ typedef CustomColumn<typename ColumnList::Head::ColumnType> Type;
+ Type* pColumn = new Type(((Type*)(srcList.at(index)))->GetColumnData());
+ dstList.push_back(pColumn);
+ CustomRowUtil<typename ColumnList::Tail>::CopyColumnList(srcList, dstList, index + 1);
+ }
+
+ static ColumnIndex GetColumnIndex(const std::string& columnName, ColumnIndex index)
+ {
+ if (ColumnList::Head::GetColumnName() == columnName)
+ return index;
+
+ return CustomRowUtil<typename ColumnList::Tail>::GetColumnIndex(columnName, index + 1);
+ }
+
+template<typename Other>
+friend class CustomRowUtil;
+};
+
+template<>
+class __attribute__ ((visibility("hidden"))) CustomRowUtil<VcoreDPL::TypeListGuard> {
+public:
+ static void MakeColumnList(std::vector<CustomColumnBase*>&) {}
+private:
+ static void CopyColumnList(const std::vector<CustomColumnBase*>&, std::vector<CustomColumnBase*>&, ColumnIndex) {}
+ static ColumnIndex GetColumnIndex(const std::string&, ColumnIndex) { return -1; }
+
+template<typename Other>
+friend class CustomRowUtil;
+};
+
+template<typename ColumnList>
+class __attribute__ ((visibility("hidden"))) CustomRow {
+private:
+ std::vector<CustomColumnBase*> m_columns;
+
+public:
+ CustomRow()
+ {
+ CustomRowUtil<ColumnList>::MakeColumnList(m_columns);
+ }
+
+ CustomRow(const CustomRow& r)
+ {
+ CustomRowUtil<ColumnList>::CopyColumnList(r.m_columns, m_columns);
+ }
+
+ virtual ~CustomRow()
+ {
+ while (!m_columns.empty())
+ {
+ CustomColumnBase* pCustomColumn = m_columns.back();
+ m_columns.pop_back();
+ if (pCustomColumn)
+ delete pCustomColumn;
+ }
+ }
+
+ template<typename ColumnType>
+ void SetColumnData(ColumnIndex columnIndex, ColumnType data)
+ {
+ typedef CustomColumn<ColumnType> Type;
+ Assert(columnIndex < m_columns.size());
+ Type* pColumn = dynamic_cast<Type*>(m_columns.at(columnIndex));
+ Assert(pColumn);
+ pColumn->SetColumnData(data);
+ }
+
+ template<typename ColumnData>
+ typename ColumnData::ColumnType GetColumnData()
+ {
+ typedef CustomColumn<typename ColumnData::ColumnType> Type;
+ ColumnIndex index = CustomRowUtil<ColumnList>::GetColumnIndex(ColumnData::GetColumnName());
+ Assert(index < m_columns.size());
+ Type* pColumn = dynamic_cast<Type*>(m_columns.at(index));
+ Assert(pColumn);
+ return pColumn->GetColumnData();
+ }
+};
+
+template<typename CustomRow, typename ColumnType>
+void SetColumnData(CustomRow& row, ColumnType columnData, ColumnIndex columnIndex)
+{
+ row.SetColumnData<ColumnType>(columnIndex, columnData);
+}
+
+template<typename ColumnList, typename CustomRow>
+class __attribute__ ((visibility("hidden"))) FillCustomRowUtil {
+public:
+ static void FillCustomRow(CustomRow& row, DataCommand* command)
+ {
+ FillCustomRow(row, 0, command);
+ }
+
+private:
+ static void FillCustomRow(CustomRow& row, ColumnIndex columnIndex, DataCommand* command)
+ {
+ typename ColumnList::Head::ColumnType columnData;
+ columnData = GetColumnFromCommand<typename ColumnList::Head::ColumnType>(columnIndex, command);
+ SetColumnData<CustomRow, typename ColumnList::Head::ColumnType>(row, columnData, columnIndex);
+ FillCustomRowUtil<typename ColumnList::Tail, CustomRow>::FillCustomRow(row, columnIndex + 1, command);
+ }
+
+template<typename Other, typename OtherRow>
+friend class FillCustomRowUtil;
+};
+
+template<typename CustomRow>
+class __attribute__ ((visibility("hidden"))) FillCustomRowUtil<VcoreDPL::TypeListGuard, CustomRow> {
+private:
+ static void FillCustomRow(CustomRow&, ColumnIndex, DataCommand *)
+ { /* do nothing, we're past the last element of column list */ }
+
+template<typename Other, typename OtherRow>
+friend class FillCustomRowUtil;
+};
+
+template<typename ColumnList, typename Row>
+class __attribute__ ((visibility("hidden"))) FillRowUtil {
+public:
+ static void FillRow(Row& row, DataCommand *command)
+ {
+ FillRow(row, 0, command);
+ }
+
+private:
+ static void FillRow(Row& row, ColumnIndex columnIndex, DataCommand *command)
+ {
+ typename ColumnList::Head::ColumnType rowField;
+ rowField = GetColumnFromCommand<typename ColumnList::Head::ColumnType>(columnIndex, command);
+ ColumnList::Head::SetRowField(row, rowField);
+ FillRowUtil<typename ColumnList::Tail, Row>::FillRow(row, columnIndex + 1, command);
+ }
+
+template<typename Other, typename OtherRow>
+friend class FillRowUtil;
+};
+
+template<typename Row>
+class __attribute__ ((visibility("hidden"))) FillRowUtil<VcoreDPL::TypeListGuard, Row> {
+private:
+ static void FillRow(Row&, ColumnIndex, DataCommand *)
+ { /* do nothing, we're past the last element of column list */ }
+
+template<typename Other, typename OtherRow>
+friend class FillRowUtil;
+};
+
+template<typename ColumnList>
+class __attribute__ ((visibility("hidden"))) JoinUtil {
+public:
+ static std::string GetColumnNames()
+ {
+ std::string result;
+ result = ColumnList::Head::GetTableName();
+ result += ".";
+ result += ColumnList::Head::GetColumnName();
+ if (ColumnList::Tail::Size > 0)
+ result += ", ";
+
+ return result += JoinUtil<typename ColumnList::Tail>::GetColumnNames();
+ }
+
+ static std::string GetJoinTableName(const std::string& tableName)
+ {
+ std::string joinTableName = ColumnList::Head::GetTableName();
+ if (tableName.find(joinTableName) == std::string::npos)
+ return joinTableName;
+
+ return JoinUtil<typename ColumnList::Tail>::GetJoinTableName(tableName);
+ }
+};
+
+template<>
+class __attribute__ ((visibility("hidden"))) JoinUtil<VcoreDPL::TypeListGuard> {
+public:
+ static std::string GetColumnNames() { return ""; }
+ static std::string GetJoinTableName(std::string) { return ""; }
+};
+
+class Exception {
+public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, SelectReuseWithDifferentQuerySignature)
+ DECLARE_EXCEPTION_TYPE(Base, RowFieldNotInitialized)
+ DECLARE_EXCEPTION_TYPE(Base, EmptyUpdateStatement)
+};
+
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Query
+{
+protected:
+ explicit Query(IOrmInterface* interface) :
+ m_interface(interface),
+ m_command(NULL)
+ {
+ }
+
+ virtual ~Query()
+ {
+ if (m_command == NULL)
+ return;
+
+ TableDefinition::FreeTableDataCommand(m_command, m_interface);
+ }
+
+ IOrmInterface* m_interface;
+ DataCommand *m_command;
+ std::string m_commandString;
+ ArgumentIndex m_bindArgumentIndex;
+};
+
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) QueryWithWhereClause : public Query<TableDefinition>
+{
+protected:
+ ExpressionPtr m_whereExpression;
+
+ void Prepare()
+ {
+ if ( !!m_whereExpression )
+ {
+ this->m_commandString += " WHERE ";
+ this->m_commandString += m_whereExpression->GetString();
+ }
+ }
+
+ void Bind()
+ {
+ if ( !!m_whereExpression )
+ {
+ this->m_bindArgumentIndex = m_whereExpression->BindTo(
+ this->m_command, this->m_bindArgumentIndex);
+ }
+ }
+
+public:
+ explicit QueryWithWhereClause(IOrmInterface* interface) :
+ Query<TableDefinition>(interface)
+ {
+ }
+
+ template<typename Expression>
+ void Where(const Expression& expression)
+ {
+ DPL_CHECK_TYPE_INSTANTIABILITY(typename Expression::template ValidForTable<TableDefinition>::Yes);
+ if ( !!m_whereExpression && ( typeid(Expression) != typeid(*m_whereExpression) ) )
+ {
+ std::ostringstream str;
+ str << "Current ORM implementation doesn't allow to reuse Select"
+ " instance with different query signature (particularly "
+ "WHERE on different column).\n";
+ str << "Query: ";
+ str << this->m_commandString;
+ ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature,
+ str.str());
+ }
+ //TODO maybe don't make a copy here but just generate the string part of the query.
+ m_whereExpression.reset(new Expression(expression));
+ }
+
+};
+
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Delete : public QueryWithWhereClause<TableDefinition>
+{
+protected:
+ void Prepare()
+ {
+ if ( !this->m_command)
+ {
+ this->m_commandString = "DELETE FROM ";
+ this->m_commandString += TableDefinition::GetName();
+
+ QueryWithWhereClause<TableDefinition>::Prepare();
+
+ this->m_command = TableDefinition::AllocTableDataCommand(
+ this->m_commandString.c_str(),
+ Query<TableDefinition>::m_interface);
+ VcoreLogD("Prepared SQL command %s", this->m_commandString.c_str());
+ }
+ }
+
+ void Bind()
+ {
+ this->m_bindArgumentIndex = 1;
+ QueryWithWhereClause<TableDefinition>::Bind();
+ }
+
+public:
+ explicit Delete(IOrmInterface *interface = NULL) :
+ QueryWithWhereClause<TableDefinition>(interface)
+ {
+ }
+
+ void Execute()
+ {
+ Prepare();
+ Bind();
+ this->m_command->Step();
+ this->m_command->Reset();
+ }
+};
+
+namespace {
+class BindVisitor {
+private:
+ DataCommand *m_command;
+public:
+ ArgumentIndex m_bindArgumentIndex;
+
+ BindVisitor(DataCommand *command) :
+ m_command(command),
+ m_bindArgumentIndex(1)
+ {}
+
+ template<typename ColumnType>
+ void Visit(const char*, const ColumnType& value, bool isSet)
+ {
+ if ( isSet )
+ {
+ DataCommandUtils::BindArgument(m_command, m_bindArgumentIndex, value);
+ m_bindArgumentIndex++;
+ }
+ }
+};
+} //anonymous namespace
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Insert : public Query<TableDefinition>
+{
+public:
+ typedef typename TableDefinition::Row Row;
+ typedef VcoreDPL::DB::SqlConnection::RowID RowID;
+
+protected:
+ boost::optional<std::string> m_orClause;
+ Row m_row;
+
+ class PrepareVisitor {
+ public:
+ std::string m_columnNames;
+ std::string m_values;
+
+ template<typename ColumnType>
+ void Visit(const char* name, const ColumnType&, bool isSet)
+ {
+ if ( isSet )
+ {
+ if ( !m_columnNames.empty() )
+ {
+ m_columnNames += ", ";
+ m_values += ", ";
+ }
+ m_columnNames += name;
+ m_values += "?";
+ }
+ }
+ };
+
+ void Prepare()
+ {
+ if ( !this->m_command )
+ {
+ this->m_commandString = "INSERT ";
+ if ( !!m_orClause )
+ {
+ this->m_commandString += " OR " + *m_orClause + " ";
+ }
+ this->m_commandString += "INTO ";
+ this->m_commandString += TableDefinition::GetName();
+
+ PrepareVisitor visitor;
+ m_row.VisitColumns(visitor);
+
+ this->m_commandString += " ( " + visitor.m_columnNames + " ) ";
+ this->m_commandString += "VALUES ( " + visitor.m_values + " )";
+
+ VcoreLogD("Prepared SQL command %s", this->m_commandString.c_str());
+ this->m_command = TableDefinition::AllocTableDataCommand(
+ this->m_commandString.c_str(),
+ Query<TableDefinition>::m_interface);
+ }
+ }
+
+ void Bind()
+ {
+ BindVisitor visitor(this->m_command);
+ m_row.VisitColumns(visitor);
+ }
+
+public:
+ explicit Insert(
+ IOrmInterface* interface = NULL,
+ const boost::optional<std::string>& orClause = boost::optional<std::string>()) :
+ Query<TableDefinition>(interface),
+ m_orClause(orClause)
+ {
+ }
+
+ void Values(const Row& row)
+ {
+ if ( this->m_command )
+ {
+ if ( !row.IsSignatureMatching(m_row) )
+ {
+ ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature,
+ "Current ORM implementation doesn't allow to reuse Insert instance "
+ "with different query signature.");
+ }
+ }
+ m_row = row;
+ }
+
+ RowID Execute()
+ {
+ Prepare();
+ Bind();
+ this->m_command->Step();
+
+ RowID result = TableDefinition::GetLastInsertRowID(
+ Query<TableDefinition>::m_interface);
+
+ this->m_command->Reset();
+ return result;
+ }
+};
+
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Select : public QueryWithWhereClause<TableDefinition>
+{
+public:
+ typedef typename TableDefinition::ColumnList ColumnList;
+ typedef typename TableDefinition::Row Row;
+
+ typedef std::list<Row> RowList;
+protected:
+ boost::optional<std::string> m_orderBy;
+ std::string m_JoinClause;
+ bool m_distinctResults;
+
+ void Prepare(const char* selectColumnName)
+ {
+ if ( !this->m_command )
+ {
+ this->m_commandString = "SELECT ";
+ if (m_distinctResults)
+ this->m_commandString += "DISTINCT ";
+ this->m_commandString += selectColumnName;
+ this->m_commandString += " FROM ";
+ this->m_commandString += TableDefinition::GetName();
+
+ this->m_commandString += m_JoinClause;
+
+ QueryWithWhereClause<TableDefinition>::Prepare();
+
+ if ( !!m_orderBy )
+ {
+ this->m_commandString += " ORDER BY " + *m_orderBy;
+ }
+
+ this->m_command = TableDefinition::AllocTableDataCommand(
+ this->m_commandString.c_str(),
+ Query<TableDefinition>::m_interface);
+
+ VcoreLogD("Prepared SQL command %s", this->m_commandString.c_str());
+ }
+ }
+
+ void Bind()
+ {
+ this->m_bindArgumentIndex = 1;
+ QueryWithWhereClause<TableDefinition>::Bind();
+ }
+
+ template<typename ColumnType>
+ ColumnType GetColumn(ColumnIndex columnIndex)
+ {
+ return GetColumnFromCommand<ColumnType>(columnIndex, this->m_command);
+ }
+
+ Row GetRow()
+ {
+ Row row;
+ FillRowUtil<ColumnList, Row>::FillRow(row, this->m_command);
+ return row;
+ }
+
+ template<typename ColumnList, typename CustomRow>
+ CustomRow GetCustomRow()
+ {
+ CustomRow row;
+ FillCustomRowUtil<ColumnList, CustomRow>::FillCustomRow(row, this->m_command);
+ return row;
+ }
+
+public:
+
+ explicit Select(IOrmInterface *interface = NULL) :
+ QueryWithWhereClause<TableDefinition>(interface),
+ m_distinctResults(false)
+ {
+ }
+
+ void Distinct()
+ {
+ m_distinctResults = true;
+ }
+
+ template<typename CompoundType>
+ void OrderBy(const CompoundType&)
+ {
+ m_orderBy = OrderingUtils::OrderByInternal<typename CompoundType::Type>();
+ }
+
+ void OrderBy(const std::string & orderBy) //backward compatibility
+ {
+ m_orderBy = orderBy;
+ }
+
+ void OrderBy(const char * orderBy) //backward compatibility
+ {
+ m_orderBy = std::string(orderBy);
+ }
+
+ template<typename ColumnList, typename Expression>
+ void Join(const Expression& expression) {
+ std::string usedTableNames = TableDefinition::GetName();
+ if (!m_JoinClause.empty())
+ usedTableNames += m_JoinClause;
+
+ this->m_JoinClause += " JOIN ";
+ this->m_JoinClause += JoinUtil<ColumnList>::GetJoinTableName(usedTableNames);
+ this->m_JoinClause += " ON ";
+ this->m_JoinClause += expression.GetString();
+ }
+
+ template<typename ColumnData>
+ typename ColumnData::ColumnType GetSingleValue()
+ {
+ Prepare(ColumnData::GetColumnName());
+ Bind();
+ this->m_command->Step();
+
+ typename ColumnData::ColumnType result =
+ GetColumn<typename ColumnData::ColumnType>(0);
+
+ this->m_command->Reset();
+ return result;
+ }
+
+ //TODO return range - pair of custom iterators
+ template<typename ColumnData>
+ std::list<typename ColumnData::ColumnType> GetValueList()
+ {
+ Prepare(ColumnData::GetColumnName());
+ Bind();
+
+ std::list<typename ColumnData::ColumnType> resultList;
+
+ while (this->m_command->Step())
+ resultList.push_back(GetColumn<typename ColumnData::ColumnType>(0));
+
+ this->m_command->Reset();
+ return resultList;
+ }
+
+ Row GetSingleRow()
+ {
+ Prepare("*");
+ Bind();
+ this->m_command->Step();
+
+ Row result = GetRow();
+
+ this->m_command->Reset();
+ return result;
+ }
+
+ //TODO return range - pair of custom iterators
+ RowList GetRowList()
+ {
+ Prepare("*");
+ Bind();
+
+ RowList resultList;
+
+ while (this->m_command->Step())
+ resultList.push_back(GetRow());
+
+ this->m_command->Reset();
+ return resultList;
+ }
+
+ template<typename ColumnList, typename CustomRow>
+ CustomRow GetCustomSingleRow()
+ {
+ Prepare(JoinUtil<ColumnList>::GetColumnNames().c_str());
+ Bind();
+ this->m_command->Step();
+
+ CustomRow result = GetCustomRow<ColumnList, CustomRow>();
+
+ this->m_command->Reset();
+ return result;
+ }
+
+ template<typename ColumnList, typename CustomRow>
+ std::list<CustomRow> GetCustomRowList()
+ {
+ Prepare(JoinUtil<ColumnList>::GetColumnNames().c_str());
+ Bind();
+
+ std::list<CustomRow> resultList;
+
+ while (this->m_command->Step())
+ resultList.push_back(GetCustomRow<ColumnList, CustomRow>());
+
+ this->m_command->Reset();
+ return resultList;
+ }
+};
+
+template<typename TableDefinition>
+class __attribute__ ((visibility("hidden"))) Update : public QueryWithWhereClause<TableDefinition> {
+public:
+ typedef typename TableDefinition::Row Row;
+
+protected:
+ boost::optional<std::string> m_orClause;
+ Row m_row;
+
+ class PrepareVisitor {
+ public:
+ std::string m_setExpressions;
+
+ template<typename ColumnType>
+ void Visit(const char* name, const ColumnType&, bool isSet)
+ {
+ if ( isSet )
+ {
+ if ( !m_setExpressions.empty() )
+ {
+ m_setExpressions += ", ";
+ }
+ m_setExpressions += name;
+ m_setExpressions += " = ";
+ m_setExpressions += "?";
+ }
+ }
+ };
+
+ void Prepare()
+ {
+ if ( !this->m_command )
+ {
+ this->m_commandString = "UPDATE ";
+ if ( !!m_orClause )
+ {
+ this->m_commandString += " OR " + *m_orClause + " ";
+ }
+ this->m_commandString += TableDefinition::GetName();
+ this->m_commandString += " SET ";
+
+ // got through row columns and values
+ PrepareVisitor visitor;
+ m_row.VisitColumns(visitor);
+
+ if(visitor.m_setExpressions.empty())
+ {
+ ThrowMsg(Exception::EmptyUpdateStatement, "No SET expressions in update statement");
+ }
+
+ this->m_commandString += visitor.m_setExpressions;
+
+ // where
+ QueryWithWhereClause<TableDefinition>::Prepare();
+
+ this->m_command = TableDefinition::AllocTableDataCommand(
+ this->m_commandString.c_str(),
+ Query<TableDefinition>::m_interface);
+ VcoreLogD("Prepared SQL command %s", this->m_commandString.c_str());
+ }
+ }
+
+ void Bind()
+ {
+ BindVisitor visitor(this->m_command);
+ m_row.VisitColumns(visitor);
+
+ this->m_bindArgumentIndex = visitor.m_bindArgumentIndex;
+ QueryWithWhereClause<TableDefinition>::Bind();
+ }
+
+
+public:
+ explicit Update(IOrmInterface *interface = NULL,
+ const boost::optional<std::string>& orClause = boost::optional<std::string>()) :
+ QueryWithWhereClause<TableDefinition>(interface),
+ m_orClause(orClause)
+ {
+ }
+
+ void Values(const Row& row)
+ {
+ if ( this->m_command )
+ {
+ if ( !row.IsSignatureMatching(m_row) )
+ {
+ ThrowMsg(Exception::SelectReuseWithDifferentQuerySignature,
+ "Current ORM implementation doesn't allow to reuse Update instance "
+ "with different query signature.");
+ }
+ }
+ m_row = row;
+ }
+
+ void Execute()
+ {
+ Prepare();
+ Bind();
+ this->m_command->Step();
+ this->m_command->Reset();
+ }
+};
+
+} //namespace ORM
+} //namespace DB
+} //namespace VcoreDPL
+
+#endif // DPL_ORM_H
diff --git a/vcore/src/dpl/db/include/dpl/db/orm_generator.h b/vcore/src/dpl/db/include/dpl/db/orm_generator.h
new file mode 100644
index 0000000..dd1b0dd
--- /dev/null
+++ b/vcore/src/dpl/db/include/dpl/db/orm_generator.h
@@ -0,0 +1,382 @@
+/*
+ * 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 orm_generator.h
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief Macro definitions for generating the DPL-ORM table definitions from database definitions.
+ */
+
+#ifndef ORM_GENERATOR_DATABASE_NAME
+#error You need to define database name in ORM_GENERATOR_DATABASE_NAME define before you include orm_generator.h file
+#endif
+
+#include <dpl/db/orm_interface.h>
+
+#define ORM_GENERATOR_DATABASE_NAME_LOCAL <ORM_GENERATOR_DATABASE_NAME>
+
+#ifdef DPL_ORM_GENERATOR_H
+#warning orm_generator.h is included multiply times. Make sure it has different ORM_GENERATOR_DATABASE_NAME set.
+#endif
+
+#define DPL_ORM_GENERATOR_H
+
+
+#include <boost/optional.hpp>
+#include <dpl/string.h>
+#include <dpl/type_list.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/orm.h>
+#include <dpl/assert.h>
+#include <string>
+
+/*
+
+This is true only when exactly one db is available.
+
+#if (defined DECLARE_COLUMN) || (defined INT) || (defined TINYINT) || \
+ (defined INTEGER) || (defined BIGINT) || defined(VARCHAR) || defined(TEXT) || \
+ (defined SQL) || (defined TABLE_CONSTRAINTS) || (defined OPTIONAL) || \
+ (defined DATABASE_START) || (defined DATABASE_END) || (defined CREATE_TABLE) || \
+ (defined COLUMN) || (defined COLUMN_NOT_NULL) || (defined CREATE_TABLE_END)
+
+#error This file temporarily defines many macros with generic names. To avoid name clash please include \
+ this file as early as possible. If this is not possible please report this problem to DPL developers.
+
+#endif
+*/
+
+namespace VcoreDPL {
+namespace DB {
+namespace ORM {
+
+// Global macros
+
+#define STRINGIFY(s) _str(s)
+#define _str(s) #s
+#define DECLARE_COLUMN(FIELD, TYPE) \
+ struct FIELD { \
+ typedef TYPE ColumnType; \
+ static const char* GetTableName() { return GetName(); } \
+ static const char* GetColumnName() { return STRINGIFY(FIELD); } \
+ static void SetRowField(Row& row, const TYPE& _value) { row.Set_##FIELD(_value);} \
+ };
+
+#define INT int
+#define TINYINT int
+#define INTEGER int //TODO: should be long long?
+#define BIGINT int //TODO: should be long long?
+#define VARCHAR(x) VcoreDPL::String
+#define TEXT VcoreDPL::String
+
+#define SQL(...)
+#define TABLE_CONSTRAINTS(...)
+#define OPTIONAL(type) boost::optional< type >
+#define DATABASE_START(db_name) \
+ namespace db_name \
+ { \
+ class ScopedTransaction \
+ { \
+ bool m_commited; \
+ IOrmInterface *m_interface; \
+ \
+ public: \
+ ScopedTransaction(IOrmInterface *interface) : \
+ m_commited(false), \
+ m_interface(interface) \
+ { \
+ Assert(interface != NULL); \
+ m_interface->TransactionBegin(); \
+ } \
+ \
+ ~ScopedTransaction() \
+ { \
+ if (!m_commited) \
+ m_interface->TransactionRollback(); \
+ } \
+ \
+ void Commit() \
+ { \
+ m_interface->TransactionCommit(); \
+ m_commited = true; \
+ } \
+ };
+
+#define DATABASE_END() }
+
+// RowBase ostream operator<< declaration
+
+#define CREATE_TABLE(name) \
+ namespace name { \
+ class RowBase; \
+ inline std::ostream& operator<<(std::ostream& ostr, const RowBase& row); \
+ }
+#define COLUMN_NOT_NULL(name, type, ...)
+#define COLUMN(name, type, ...)
+#define CREATE_TABLE_END()
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+#undef DATABASE_START
+#define DATABASE_START(db_name) namespace db_name {
+
+// RowBase class
+
+#define CREATE_TABLE(name) namespace name { class RowBase { \
+ public: friend std::ostream& operator<<(std::ostream&, const RowBase&);
+#define COLUMN_NOT_NULL(name, type, ...) \
+ protected: type name; bool m_##name##_set; \
+ public: void Set_##name(const type& _value) { \
+ m_##name##_set = true; \
+ this->name = _value; \
+ } \
+ public: type Get_##name() const { \
+ if ( !m_##name##_set ) { \
+ ThrowMsg(Exception::RowFieldNotInitialized, \
+ "You tried to read a row field that hasn't been set yet."); \
+ } \
+ return name; \
+ }
+
+#define COLUMN(name, type, ...) \
+ protected: OPTIONAL(type) name; bool m_##name##_set; \
+ public: void Set_##name(const OPTIONAL(type)& _value) { \
+ m_##name##_set = true; \
+ this->name = _value; \
+ } \
+ public: OPTIONAL(type) Get_##name() const { \
+ if ( !m_##name##_set ) { \
+ ThrowMsg(Exception::RowFieldNotInitialized, \
+ "You tried to read a row field that hasn't been set yet."); \
+ } \
+ return name; \
+ }
+#define CREATE_TABLE_END() }; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// RowBase ostream operator<<
+
+#define CREATE_TABLE(name) std::ostream& name::operator<<(std::ostream& ostr, const RowBase& row) { using ::operator<< ; ostr << STRINGIFY(name) << " (";
+#define COLUMN_NOT_NULL(name, type, ...) ostr << " '" << row.name << "'" ;
+#define COLUMN(name, type, ...) ostr << " '" << row.name << "'" ;
+#define CREATE_TABLE_END() ostr << " )" ; return ostr; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// RowBase2 class (== RowBase + operator==)
+
+#define CREATE_TABLE(name) namespace name { class RowBase2 : public RowBase { \
+ public: bool operator==(const RowBase2& row) const { return true
+#define COLUMN_NOT_NULL(name, type, ...) && (this->name == row.name)
+#define COLUMN(name, type, ...) && (this->name == row.name)
+#define CREATE_TABLE_END() ; } }; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// RowBase3 class (== RowBase2 + operator<)
+
+#define CREATE_TABLE(name) namespace name { class RowBase3 : public RowBase2 { \
+ public: bool operator<(const RowBase3& row) const {
+#define COLUMN_NOT_NULL(name, type, ...) if (this->name < row.name) { return true; } if (this->name > row.name) { return false; }
+#define COLUMN(name, type, ...) if (this->name < row.name) { return true; } if (this->name > row.name) { return false; }
+#define CREATE_TABLE_END() return false; } }; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// RowBase4 class (== RowBase3 + IsSignatureMatching )
+
+#define CREATE_TABLE(name) namespace name { class RowBase4 : public RowBase3 { \
+ public: bool IsSignatureMatching(const RowBase4& row) const { return true
+#define COLUMN_NOT_NULL(name, type, ...) && (this->m_##name##_set == row.m_##name##_set)
+#define COLUMN(name, type, ...) && (this->m_##name##_set == row.m_##name##_set)
+#define CREATE_TABLE_END() ; } }; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// RowBase5 class (== RowBase4 + default constructor)
+
+#define CREATE_TABLE(name) namespace name { class RowBase5 : public RowBase4 { \
+ public: RowBase5() {
+#define COLUMN_NOT_NULL(name, type, ...) m_##name##_set = false;
+#define COLUMN(name, type, ...) m_##name##_set = false;
+#define CREATE_TABLE_END() } }; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// Row class (== RowBase5 + ForEachColumn )
+
+#define CREATE_TABLE(name) namespace name { class Row : public RowBase5 { \
+ public: template<typename Visitor> \
+ void VisitColumns(Visitor& visitor) const {
+#define COLUMN_NOT_NULL(name, type, ...) visitor.Visit(STRINGIFY(name), this->name, this->m_##name##_set);
+#define COLUMN(name, type, ...) visitor.Visit(STRINGIFY(name), this->name, this->m_##name##_set);
+#define CREATE_TABLE_END() } }; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// Field structure declarations
+
+#define CREATE_TABLE(name) namespace name { \
+ static const char* GetName() { return STRINGIFY(name); }
+#define COLUMN_NOT_NULL(name, type, ...) DECLARE_COLUMN(name, type)
+#define COLUMN(name, type, ...) DECLARE_COLUMN(name, OPTIONAL(type))
+#define CREATE_TABLE_END() }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// ColumnList typedef
+
+#define CREATE_TABLE(name) namespace name { typedef VcoreDPL::TypeListDecl<
+#define COLUMN_NOT_NULL(name, type, ...) name,
+#define COLUMN(name, type, ...) name,
+#define CREATE_TABLE_END() VcoreDPL::TypeListGuard>::Type ColumnList; }
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// TableDefinition struct
+
+#define CREATE_TABLE(table_name) \
+ namespace table_name { \
+ struct TableDefinition { \
+ typedef table_name::ColumnList ColumnList; \
+ typedef table_name::Row Row; \
+ static const char* GetName() { return STRINGIFY(table_name); } \
+ static VcoreDPL::DB::SqlConnection::DataCommand *AllocTableDataCommand( \
+ const std::string &statement, \
+ IOrmInterface *interface) \
+ { \
+ Assert(interface != NULL); \
+ return interface->AllocDataCommand(statement); \
+ } \
+ static void FreeTableDataCommand( \
+ VcoreDPL::DB::SqlConnection::DataCommand *command, \
+ IOrmInterface *interface) \
+ { \
+ Assert(interface != NULL); \
+ interface->FreeDataCommand(command); \
+ } \
+ static VcoreDPL::DB::SqlConnection::RowID GetLastInsertRowID( \
+ IOrmInterface *interface) \
+ { \
+ Assert(interface != NULL); \
+ return interface->GetLastInsertRowID(); \
+ } \
+ }; \
+ }
+
+#define COLUMN_NOT_NULL(name, type, ...)
+#define COLUMN(name, type, ...)
+#define CREATE_TABLE_END()
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+// Query typedefs
+
+#define CREATE_TABLE(name) \
+ namespace name { \
+ typedef Select<TableDefinition> Select; \
+ typedef Insert<TableDefinition> Insert; \
+ typedef Delete<TableDefinition> Delete; \
+ typedef Update<TableDefinition> Update; \
+ }
+#define COLUMN_NOT_NULL(name, type, ...)
+#define COLUMN(name, type, ...)
+#define CREATE_TABLE_END()
+
+#include ORM_GENERATOR_DATABASE_NAME_LOCAL
+
+#undef CREATE_TABLE
+#undef COLUMN_NOT_NULL
+#undef COLUMN
+#undef CREATE_TABLE_END
+
+
+// Global undefs
+#undef INT
+#undef TINYINT
+#undef INTEGER
+#undef BIGINT
+#undef VARCHAR
+#undef TEXT
+
+#undef SQL
+#undef TABLE_CONSTRAINTS
+#undef OPTIONAL
+#undef DATABASE_START
+#undef DATABASE_END
+
+} //namespace ORM
+} //namespace DB
+} //namespace VcoreDPL
+
+#undef ORM_GENERATOR_DATABASE_NAME
+#undef ORM_GENERATOR_DATABASE_NAME_LOCAL
diff --git a/vcore/src/dpl/db/include/dpl/db/orm_interface.h b/vcore/src/dpl/db/include/dpl/db/orm_interface.h
new file mode 100644
index 0000000..025c642
--- /dev/null
+++ b/vcore/src/dpl/db/include/dpl/db/orm_interface.h
@@ -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 orm_interface.h
+ * @author Lukasz Marek (l.marek@samsung.com)
+ * @version 1.0
+ */
+
+#include <string>
+#include <dpl/db/sql_connection.h>
+
+#ifndef DPL_ORM_INTERFACE_H
+#define DPL_ORM_INTERFACE_H
+
+namespace VcoreDPL {
+namespace DB {
+namespace ORM {
+class IOrmInterface
+{
+ public:
+ virtual ~IOrmInterface() {}
+ virtual VcoreDPL::DB::SqlConnection::DataCommand *AllocDataCommand(
+ const std::string &statement) = 0;
+ virtual void FreeDataCommand(VcoreDPL::DB::SqlConnection::DataCommand *command)
+ = 0;
+ virtual void TransactionBegin() = 0;
+ virtual void TransactionCommit() = 0;
+ virtual void TransactionRollback() = 0;
+ virtual VcoreDPL::DB::SqlConnection::RowID GetLastInsertRowID() = 0;
+};
+}
+}
+}
+
+#endif
diff --git a/vcore/src/dpl/db/include/dpl/db/orm_macros.h b/vcore/src/dpl/db/include/dpl/db/orm_macros.h
new file mode 100644
index 0000000..a038523
--- /dev/null
+++ b/vcore/src/dpl/db/include/dpl/db/orm_macros.h
@@ -0,0 +1,34 @@
+/*
+ * 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 orm_macros.h
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief Macro definitions for generating the SQL input file from
+ * database definition.
+ */
+
+//Do not include this file directly! It is used only for SQL code generation.
+
+#define CREATE_TABLE(name) CREATE TABLE name(
+#define COLUMN(name, type, ...) name type __VA_ARGS__,
+#define COLUMN_NOT_NULL(name, type, ...) name type __VA_ARGS__ not null,
+#define SQL(...) __VA_ARGS__
+#define TABLE_CONSTRAINTS(...) __VA_ARGS__,
+#define CREATE_TABLE_END() CHECK(1) );
+#define DATABASE_START(db_name)
+#define DATABASE_END()
+
diff --git a/vcore/src/dpl/db/include/dpl/db/sql_connection.h b/vcore/src/dpl/db/include/dpl/db/sql_connection.h
new file mode 100644
index 0000000..56714ee
--- /dev/null
+++ b/vcore/src/dpl/db/include/dpl/db/sql_connection.h
@@ -0,0 +1,519 @@
+/*
+ * 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 sql_connection.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of SQL connection
+ */
+#ifndef DPL_SQL_CONNECTION_H
+#define DPL_SQL_CONNECTION_H
+
+#include <dpl/noncopyable.h>
+#include <dpl/exception.h>
+#include <dpl/availability.h>
+#include <memory>
+#include <boost/optional.hpp>
+#include <dpl/string.h>
+#include <dpl/log/vcore_log.h>
+#include <sqlite3.h>
+#include <string>
+#include <dpl/assert.h>
+#include <memory>
+#include <stdint.h>
+
+namespace VcoreDPL {
+namespace DB {
+/**
+ * SQL connection class
+ */
+class SqlConnection
+{
+ public:
+ /**
+ * SQL Exception classes
+ */
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, SyntaxError)
+ DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken)
+ DECLARE_EXCEPTION_TYPE(Base, InternalError)
+ DECLARE_EXCEPTION_TYPE(Base, InvalidColumn)
+ };
+
+ typedef int ColumnIndex;
+ typedef int ArgumentIndex;
+
+ /*
+ * SQL processed data command
+ */
+ class DataCommand :
+ private Noncopyable
+ {
+ private:
+ SqlConnection *m_masterConnection;
+ sqlite3_stmt *m_stmt;
+
+ void CheckBindResult(int result);
+ void CheckColumnIndex(SqlConnection::ColumnIndex column);
+
+ DataCommand(SqlConnection *connection, const char *buffer);
+
+ friend class SqlConnection;
+
+ public:
+ virtual ~DataCommand();
+
+ /**
+ * Bind null to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ */
+ void BindNull(ArgumentIndex position);
+
+ /**
+ * Bind int to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInteger(ArgumentIndex position, int value);
+
+ /**
+ * Bind int8_t to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt8(ArgumentIndex position, int8_t value);
+
+ /**
+ * Bind int16 to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt16(ArgumentIndex position, int16_t value);
+
+ /**
+ * Bind int32 to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt32(ArgumentIndex position, int32_t value);
+
+ /**
+ * Bind int64 to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt64(ArgumentIndex position, int64_t value);
+
+ /**
+ * Bind float to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindFloat(ArgumentIndex position, float value);
+
+ /**
+ * Bind double to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindDouble(ArgumentIndex position, double value);
+
+ /**
+ * Bind string to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindString(ArgumentIndex position, const char *value);
+
+ /**
+ * Bind string to the prepared statement argument
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindString(ArgumentIndex position, const String& value);
+
+ /**
+ * Bind optional int to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInteger(ArgumentIndex position, const boost::optional<int> &value);
+
+ /**
+ * Bind optional int8 to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt8(ArgumentIndex position, const boost::optional<int8_t> &value);
+
+ /**
+ * Bind optional int16 to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt16(ArgumentIndex position, const boost::optional<int16_t> &value);
+
+ /**
+ * Bind optional int32 to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt32(ArgumentIndex position, const boost::optional<int32_t> &value);
+
+ /**
+ * Bind optional int64 to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindInt64(ArgumentIndex position, const boost::optional<int64_t> &value);
+
+ /**
+ * Bind optional float to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindFloat(ArgumentIndex position, const boost::optional<float> &value);
+
+ /**
+ * Bind optional double to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindDouble(ArgumentIndex position, const boost::optional<double> &value);
+
+ /**
+ * Bind optional string to the prepared statement argument.
+ * If optional is not set null will be bound
+ *
+ * @param position Index of argument to bind value to
+ * @param value Value to bind
+ */
+ void BindString(ArgumentIndex position, const boost::optional<String> &value);
+
+ /**
+ * Execute the prepared statement and/or move
+ * to the next row of the result
+ *
+ * @return True when there was a row returned
+ */
+ bool Step();
+
+ /**
+ * Reset prepared statement's arguments
+ * All parameters will become null
+ */
+ void Reset();
+
+ /**
+ * Checks whether column value is null
+ *
+ * @throw Exception::InvalidColumn
+ */
+ bool IsColumnNull(ColumnIndex column);
+
+ /**
+ * Get integer value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ int GetColumnInteger(ColumnIndex column);
+
+ /**
+ * Get int8 value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ int8_t GetColumnInt8(ColumnIndex column);
+
+ /**
+ * Get int16 value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ int16_t GetColumnInt16(ColumnIndex column);
+ /**
+ * Get int32 value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ int32_t GetColumnInt32(ColumnIndex column);
+
+ /**
+ * Get int64 value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ int64_t GetColumnInt64(ColumnIndex column);
+
+ /**
+ * Get float value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ float GetColumnFloat(ColumnIndex column);
+
+ /**
+ * Get double value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ double GetColumnDouble(ColumnIndex column);
+
+ /**
+ * Get string value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ std::string GetColumnString(ColumnIndex column);
+
+ /**
+ * Get optional integer value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<int> GetColumnOptionalInteger(ColumnIndex column);
+
+ /**
+ * Get optional int8 value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<int8_t> GetColumnOptionalInt8(ColumnIndex column);
+
+ /**
+ * Get optional int16value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<int16_t> GetColumnOptionalInt16(ColumnIndex column);
+
+ /**
+ * Get optional int32 value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<int32_t> GetColumnOptionalInt32(ColumnIndex column);
+
+ /**
+ * Get optional int64 value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<int64_t> GetColumnOptionalInt64(ColumnIndex column);
+
+ /**
+ * Get optional float value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<float> GetColumnOptionalFloat(ColumnIndex column);
+
+ /**
+ * Get optional double value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<double> GetColumnOptionalDouble(ColumnIndex column);
+
+ /**
+ * Get optional string value from column in current row.
+ *
+ * @throw Exception::InvalidColumn
+ */
+ boost::optional<String> GetColumnOptionalString(ColumnIndex column);
+ };
+
+ // Move on copy semantics
+ typedef std::auto_ptr<DataCommand> DataCommandAutoPtr;
+
+ // Open flags
+ class Flag
+ {
+ public:
+ enum Type
+ {
+ None = 1 << 0,
+ UseLucene = 1 << 1
+ };
+
+ enum Option
+ {
+ RO = SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READONLY,
+ /**
+ * *TODO: please remove CREATE option from RW flag when all places
+ * that need that switched do CRW
+ */
+ RW = SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE |
+ SQLITE_OPEN_CREATE,
+ CRW = RW | SQLITE_OPEN_CREATE
+ };
+ };
+
+ // RowID
+ typedef sqlite3_int64 RowID;
+
+ /**
+ * Synchronization object used to synchronize SQL connection
+ * to the same database across different threads and processes
+ */
+ class SynchronizationObject
+ {
+ public:
+ virtual ~SynchronizationObject() {}
+
+ /**
+ * Synchronizes SQL connection for multiple clients.
+ */
+ virtual void Synchronize() = 0;
+
+ /**
+ * Notify all waiting clients that the connection is no longer locked.
+ */
+ virtual void NotifyAll() = 0;
+ };
+
+ protected:
+ sqlite3 *m_connection;
+
+ // Options
+ bool m_usingLucene;
+
+ // Stored data procedures
+ int m_dataCommandsCount;
+
+ // Synchronization object
+ std::unique_ptr<SynchronizationObject> m_synchronizationObject;
+
+ virtual void Connect(const std::string &address,
+ Flag::Type = Flag::None, Flag::Option = Flag::RO);
+ virtual void Disconnect();
+
+ void TurnOnForeignKeys();
+
+ static SynchronizationObject *AllocDefaultSynchronizationObject();
+
+ public:
+ /**
+ * Open SQL connection
+ *
+ * Synchronization is archieved by using provided asynchronization object.
+ * If synchronizationObject is set to NULL, so synchronization is performed.
+ * Ownership of the synchronization object is transfered to sql connection
+ * object.
+ *
+ * @param address Database file name
+ * @param flags Open flags
+ * @param synchronizationObject A synchronization object to use.
+ */
+ explicit SqlConnection(const std::string &address = std::string(),
+ Flag::Type flags = Flag::None,
+ Flag::Option options = Flag::RO,
+ SynchronizationObject *synchronizationObject =
+ AllocDefaultSynchronizationObject());
+
+ /**
+ * Destructor
+ */
+ virtual ~SqlConnection();
+
+ /**
+ * Execute SQL command without result
+ *
+ * @param format
+ * @param ...
+ */
+ void ExecCommand(const char *format, ...) DPL_DEPRECATED_WITH_MESSAGE(
+ "To prevent sql injection do not use this \
+ method for direct sql execution");
+
+ /**
+ * Execute BEGIN; command to start new transaction
+ *
+ */
+ void BeginTransaction();
+
+ /**
+ * Execute ROLLBACK; command to discard changes made
+ *
+ */
+ void RollbackTransaction();
+
+ /**
+ * Execute COMMIT; command to commit changes in database
+ *
+ */
+ void CommitTransaction();
+
+ /**
+ * Prepare stored procedure
+ *
+ * @param format SQL statement
+ * @return Data command representing stored procedure
+ */
+ DataCommandAutoPtr PrepareDataCommand(const char *format, ...);
+
+ /**
+ * Check whether given table exists
+ *
+ * @param tableName Name of the table to check
+ * @return True if given table name exists
+ */
+ bool CheckTableExist(const char *tableName);
+
+ /**
+ * Get last insert operation new row id
+ *
+ * @return Row ID
+ */
+ RowID GetLastInsertRowID() const;
+
+ private:
+ int db_util_open_with_options(const char *pszFilePath, sqlite3 **ppDB,
+ int flags, const char *zVfs);
+ int db_util_close(sqlite3 *pDB);
+
+};
+} // namespace DB
+} // namespace VcoreDPL
+
+#endif // DPL_SQL_CONNECTION_H
diff --git a/vcore/src/dpl/db/include/dpl/db/thread_database_support.h b/vcore/src/dpl/db/include/dpl/db/thread_database_support.h
new file mode 100644
index 0000000..5c82ae5
--- /dev/null
+++ b/vcore/src/dpl/db/include/dpl/db/thread_database_support.h
@@ -0,0 +1,300 @@
+/*
+ * 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 thread_database_support.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk)
+ * @version 1.0
+ * @brief This file contains the declaration of thread database support
+ */
+
+#ifndef DPL_THREAD_DATABASE_SUPPORT_H
+#define DPL_THREAD_DATABASE_SUPPORT_H
+
+#include <string>
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/orm_interface.h>
+#include <dpl/thread.h>
+#include <dpl/assert.h>
+#include <stdint.h>
+
+namespace VcoreDPL {
+namespace DB {
+/**
+ * Thread database support
+ *
+ * Associate database connection with thread lifecycle
+ *
+ */
+
+class ThreadDatabaseSupport :
+ public VcoreDPL::DB::ORM::IOrmInterface
+{
+ private:
+ typedef VcoreDPL::DB::SqlConnection *SqlConnectionPtr;
+ typedef VcoreDPL::ThreadLocalVariable<SqlConnectionPtr> TLVSqlConnectionPtr;
+ typedef VcoreDPL::ThreadLocalVariable<size_t> TLVSizeT;
+ typedef VcoreDPL::ThreadLocalVariable<bool> TLVBool;
+
+ TLVSqlConnectionPtr m_connection;
+ TLVBool m_linger;
+ TLVSizeT m_refCounter;
+ TLVSizeT m_transactionDepth;
+ TLVSizeT m_attachCount;
+ TLVBool m_transactionCancel;
+ std::string m_address;
+ VcoreDPL::DB::SqlConnection::Flag::Type m_flags;
+
+ TLVSqlConnectionPtr &Connection()
+ {
+ return m_connection;
+ }
+
+ TLVBool &Linger()
+ {
+ return m_linger;
+ }
+
+ TLVSizeT &RefCounter()
+ {
+ return m_refCounter;
+ }
+
+ TLVSizeT &TransactionDepth()
+ {
+ return m_transactionDepth;
+ }
+
+ TLVSizeT &AttachCount()
+ {
+ return m_attachCount;
+ }
+
+ TLVBool &TransactionCancel()
+ {
+ return m_transactionCancel;
+ }
+
+ void CheckedConnectionDelete()
+ {
+ Assert(!Connection().IsNull());
+ Assert(*Linger() == true);
+
+ if (*RefCounter() > 0 || *AttachCount() > 0) {
+ return;
+ }
+
+ // Destroy connection
+ VcoreLogD("Destroying thread database connection: %s", m_address.c_str());
+
+ delete *Connection();
+
+ // Blocking destroy
+ Connection().GuardValue(false);
+ Linger().GuardValue(false);
+ RefCounter().GuardValue(false);
+ TransactionCancel().GuardValue(false);
+ TransactionDepth().GuardValue(false);
+ AttachCount().GuardValue(false);
+
+ Connection().Reset();
+ Linger().Reset();
+ RefCounter().Reset();
+ TransactionCancel().Reset();
+ TransactionDepth().Reset();
+ AttachCount().Reset();
+ }
+
+ void TransactionUnref()
+ {
+ VcoreLogD("Unref transaction");
+
+ if (--(*TransactionDepth()) == 0) {
+ VcoreLogD("Transaction is finalized");
+
+ if (*TransactionCancel()) {
+ VcoreLogD("Transaction will be rolled back");
+ (*Connection())->RollbackTransaction();
+ } else {
+ VcoreLogD("Transaction will be commited");
+ (*Connection())->CommitTransaction();
+ }
+ }
+ }
+
+ public:
+ ThreadDatabaseSupport(const std::string &address,
+ VcoreDPL::DB::SqlConnection::Flag::Type flags) :
+ m_address(address),
+ m_flags(flags)
+ {}
+
+ virtual ~ThreadDatabaseSupport()
+ {}
+
+ void AttachToThread(
+ VcoreDPL::DB::SqlConnection::Flag::Option options =
+ VcoreDPL::DB::SqlConnection::Flag::RO)
+ {
+ Linger() = false;
+
+ if (!Connection().IsNull()) {
+ // Add reference
+ ++*AttachCount();
+ return;
+ }
+
+ // Initialize SQL connection described in traits
+ VcoreLogD("Attaching thread database connection: %s", m_address.c_str());
+
+ Connection() = new VcoreDPL::DB::SqlConnection(
+ m_address.c_str(), m_flags, options);
+
+ RefCounter() = 0;
+
+ AttachCount() = 1;
+
+ //Init Transaction related variables
+ TransactionDepth() = 0;
+ TransactionCancel() = false;
+
+ // Blocking destroy
+ Connection().GuardValue(true);
+ Linger().GuardValue(true);
+ RefCounter().GuardValue(true);
+ TransactionDepth().GuardValue(true);
+ AttachCount().GuardValue(true);
+ TransactionCancel().GuardValue(true);
+ }
+
+ void DetachFromThread()
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ // Remove reference
+ --*AttachCount();
+
+ if (*AttachCount() > 0) {
+ return;
+ }
+
+ // It must not be in linger state yet
+ Assert(*Linger() == false);
+
+ VcoreLogD("Detaching thread database connection: %s", m_address.c_str());
+
+ // Enter linger state
+ *Linger() = true;
+
+ // Checked delete
+ CheckedConnectionDelete();
+ }
+
+ bool IsAttached()
+ {
+ return !AttachCount().IsNull() && *AttachCount() > 0;
+ }
+
+ VcoreDPL::DB::SqlConnection::DataCommand *AllocDataCommand(
+ const std::string &statement)
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ // Calling thread must not be in linger state
+ Assert(*Linger() == false);
+
+ // Add reference
+ ++*RefCounter();
+
+ // Create new unmanaged data command
+ return (*Connection())->PrepareDataCommand(statement.c_str()).release();
+ }
+
+ void FreeDataCommand(VcoreDPL::DB::SqlConnection::DataCommand *command)
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ // Delete data command
+ delete command;
+
+ // Unreference SQL connection
+ --*RefCounter();
+
+ // If it is linger state, connection may be destroyed
+ if (*Linger() == true) {
+ CheckedConnectionDelete();
+ }
+ }
+
+ void TransactionBegin()
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ VcoreLogD("Begin transaction");
+
+ // Addref transaction
+ if (++(*TransactionDepth()) == 1) {
+ VcoreLogD("Transaction is initialized");
+
+ TransactionCancel() = false;
+ (*Connection())->BeginTransaction();
+ }
+ }
+
+ void TransactionCommit()
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ VcoreLogD("Commit transaction");
+
+ // Unref transation
+ TransactionUnref();
+ }
+
+ void TransactionRollback()
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ // Cancel and unref transaction
+ TransactionCancel() = true;
+ TransactionUnref();
+ }
+
+ VcoreDPL::DB::SqlConnection::RowID GetLastInsertRowID()
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ return (*Connection())->GetLastInsertRowID();
+ }
+
+ bool CheckTableExist(const char *name)
+ {
+ // Calling thread must support thread database connections
+ Assert(!Connection().IsNull());
+
+ return (*Connection())->CheckTableExist(name);
+ }
+};
+}
+}
+
+#endif // DPL_THREAD_DATABASE_SUPPORT_H
diff --git a/vcore/src/dpl/db/src/naive_synchronization_object.cpp b/vcore/src/dpl/db/src/naive_synchronization_object.cpp
new file mode 100644
index 0000000..f67694a
--- /dev/null
+++ b/vcore/src/dpl/db/src/naive_synchronization_object.cpp
@@ -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.
+ */
+/*
+ * @file naive_synchronization_object.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of SQL naive
+ * synchronization object
+ */
+#include <stddef.h>
+#include <dpl/db/naive_synchronization_object.h>
+#include <dpl/thread.h>
+
+namespace {
+ unsigned int seed = time(NULL);
+}
+
+namespace VcoreDPL {
+namespace DB {
+void NaiveSynchronizationObject::Synchronize()
+{
+ // Sleep for about 10ms - 30ms
+ Thread::MiliSleep(10 + rand_r(&seed) % 20);
+}
+
+void NaiveSynchronizationObject::NotifyAll()
+{
+ // No need to inform about anything
+}
+} // namespace DB
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/db/src/orm.cpp b/vcore/src/dpl/db/src/orm.cpp
new file mode 100644
index 0000000..6e79d46
--- /dev/null
+++ b/vcore/src/dpl/db/src/orm.cpp
@@ -0,0 +1,102 @@
+/*
+ * 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 orm.cpp
+ * @author Bartosz Janiak (b.janiak@samsung.com)
+ * @version 1.0
+ * @brief Static definitions and function template specialziations of
+ * DPL-ORM.
+ */
+#include <stddef.h>
+#include <dpl/db/orm.h>
+
+namespace VcoreDPL {
+namespace DB {
+namespace ORM {
+namespace RelationTypes {
+const char Equal[] = "=";
+const char LessThan[] = "<";
+const char And[] = "AND";
+const char Or[] = "OR";
+const char Is[] = "IS";
+const char In[] = "IN";
+}
+
+template<>
+int GetColumnFromCommand<int>(ColumnIndex columnIndex,
+ DataCommand *command)
+{
+ return command->GetColumnInteger(columnIndex);
+}
+
+template<>
+VcoreDPL::String GetColumnFromCommand<VcoreDPL::String>(ColumnIndex columnIndex,
+ DataCommand *command)
+{
+ return VcoreDPL::FromUTF8String(command->GetColumnString(columnIndex));
+}
+
+template<>
+OptionalInteger GetColumnFromCommand<OptionalInteger>(ColumnIndex columnIndex,
+ DataCommand *command)
+{
+ return command->GetColumnOptionalInteger(columnIndex);
+}
+
+template<>
+OptionalString GetColumnFromCommand<OptionalString>(ColumnIndex columnIndex,
+ DataCommand *command)
+{
+ return command->GetColumnOptionalString(columnIndex);
+}
+
+template<>
+double GetColumnFromCommand<double>(ColumnIndex columnIndex,
+ DataCommand *command)
+{
+ return command->GetColumnDouble(columnIndex);
+}
+
+void DataCommandUtils::BindArgument(DataCommand *command,
+ ArgumentIndex index,
+ int argument)
+{
+ command->BindInteger(index, argument);
+}
+
+void DataCommandUtils::BindArgument(DataCommand *command,
+ ArgumentIndex index,
+ const OptionalInteger& argument)
+{
+ command->BindInteger(index, argument);
+}
+
+void DataCommandUtils::BindArgument(DataCommand *command,
+ ArgumentIndex index,
+ const VcoreDPL::String& argument)
+{
+ command->BindString(index, argument);
+}
+
+void DataCommandUtils::BindArgument(DataCommand *command,
+ ArgumentIndex index,
+ const OptionalString& argument)
+{
+ command->BindString(index, argument);
+}
+}
+}
+}
diff --git a/vcore/src/dpl/db/src/sql_connection.cpp b/vcore/src/dpl/db/src/sql_connection.cpp
new file mode 100644
index 0000000..9da8266
--- /dev/null
+++ b/vcore/src/dpl/db/src/sql_connection.cpp
@@ -0,0 +1,896 @@
+/*
+ * 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 sql_connection.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of SQL connection
+ */
+#include <stddef.h>
+#include <dpl/db/sql_connection.h>
+#include <dpl/db/naive_synchronization_object.h>
+#include <dpl/free_deleter.h>
+#include <memory>
+#include <dpl/noncopyable.h>
+#include <dpl/assert.h>
+#include <unistd.h>
+#include <cstdio>
+#include <cstdarg>
+
+namespace VcoreDPL {
+namespace DB {
+namespace // anonymous
+{
+class ScopedNotifyAll :
+ public Noncopyable
+{
+ private:
+ SqlConnection::SynchronizationObject *m_synchronizationObject;
+
+ public:
+ explicit ScopedNotifyAll(
+ SqlConnection::SynchronizationObject *synchronizationObject) :
+ m_synchronizationObject(synchronizationObject)
+ {}
+
+ ~ScopedNotifyAll()
+ {
+ if (!m_synchronizationObject) {
+ return;
+ }
+
+ VcoreLogD("Notifying after successful synchronize");
+ m_synchronizationObject->NotifyAll();
+ }
+};
+} // namespace anonymous
+
+SqlConnection::DataCommand::DataCommand(SqlConnection *connection,
+ const char *buffer) :
+ m_masterConnection(connection),
+ m_stmt(NULL)
+{
+ Assert(connection != NULL);
+
+ // Notify all after potentially synchronized database connection access
+ ScopedNotifyAll notifyAll(connection->m_synchronizationObject.get());
+
+ for (;;) {
+ int ret = sqlite3_prepare_v2(connection->m_connection,
+ buffer, strlen(buffer),
+ &m_stmt, NULL);
+
+ if (ret == SQLITE_OK) {
+ VcoreLogD("Data command prepared successfuly");
+ break;
+ } else if (ret == SQLITE_BUSY) {
+ VcoreLogD("Collision occurred while preparing SQL command");
+
+ // Synchronize if synchronization object is available
+ if (connection->m_synchronizationObject) {
+ VcoreLogD("Performing synchronization");
+ connection->m_synchronizationObject->Synchronize();
+ continue;
+ }
+
+ // No synchronization object defined. Fail.
+ }
+
+ // Fatal error
+ const char *error = sqlite3_errmsg(m_masterConnection->m_connection);
+
+ VcoreLogD("SQL prepare data command failed");
+ VcoreLogD(" Statement: %s", buffer);
+ VcoreLogD(" Error: %s", error);
+
+ ThrowMsg(Exception::SyntaxError, error);
+ }
+
+ VcoreLogD("Prepared data command: %s", buffer);
+
+ // Increment stored data command count
+ ++m_masterConnection->m_dataCommandsCount;
+}
+
+SqlConnection::DataCommand::~DataCommand()
+{
+ VcoreLogD("SQL data command finalizing");
+
+ if (sqlite3_finalize(m_stmt) != SQLITE_OK) {
+ VcoreLogD("Failed to finalize data command");
+ }
+
+ // Decrement stored data command count
+ --m_masterConnection->m_dataCommandsCount;
+}
+
+void SqlConnection::DataCommand::CheckBindResult(int result)
+{
+ if (result != SQLITE_OK) {
+ const char *error = sqlite3_errmsg(
+ m_masterConnection->m_connection);
+
+ VcoreLogD("Failed to bind SQL statement parameter");
+ VcoreLogD(" Error: %s", error);
+
+ ThrowMsg(Exception::SyntaxError, error);
+ }
+}
+
+void SqlConnection::DataCommand::BindNull(
+ SqlConnection::ArgumentIndex position)
+{
+ CheckBindResult(sqlite3_bind_null(m_stmt, position));
+ VcoreLogD("SQL data command bind null: [%i]", position);
+}
+
+void SqlConnection::DataCommand::BindInteger(
+ SqlConnection::ArgumentIndex position,
+ int value)
+{
+ CheckBindResult(sqlite3_bind_int(m_stmt, position, value));
+ VcoreLogD("SQL data command bind integer: [%i] -> %i", position, value);
+}
+
+void SqlConnection::DataCommand::BindInt8(
+ SqlConnection::ArgumentIndex position,
+ int8_t value)
+{
+ CheckBindResult(sqlite3_bind_int(m_stmt, position,
+ static_cast<int>(value)));
+ VcoreLogD("SQL data command bind int8: [%i] -> %i", position, value);
+}
+
+void SqlConnection::DataCommand::BindInt16(
+ SqlConnection::ArgumentIndex position,
+ int16_t value)
+{
+ CheckBindResult(sqlite3_bind_int(m_stmt, position,
+ static_cast<int>(value)));
+ VcoreLogD("SQL data command bind int16: [%i] -> %i", position, value);
+}
+
+void SqlConnection::DataCommand::BindInt32(
+ SqlConnection::ArgumentIndex position,
+ int32_t value)
+{
+ CheckBindResult(sqlite3_bind_int(m_stmt, position,
+ static_cast<int>(value)));
+ VcoreLogD("SQL data command bind int32: [%i] -> %i", position, value);
+}
+
+void SqlConnection::DataCommand::BindInt64(
+ SqlConnection::ArgumentIndex position,
+ int64_t value)
+{
+ CheckBindResult(sqlite3_bind_int64(m_stmt, position,
+ static_cast<sqlite3_int64>(value)));
+ VcoreLogD("SQL data command bind int64: [%i] -> %lli", position, value);
+}
+
+void SqlConnection::DataCommand::BindFloat(
+ SqlConnection::ArgumentIndex position,
+ float value)
+{
+ CheckBindResult(sqlite3_bind_double(m_stmt, position,
+ static_cast<double>(value)));
+ VcoreLogD("SQL data command bind float: [%i] -> %f", position, value);
+}
+
+void SqlConnection::DataCommand::BindDouble(
+ SqlConnection::ArgumentIndex position,
+ double value)
+{
+ CheckBindResult(sqlite3_bind_double(m_stmt, position, value));
+ VcoreLogD("SQL data command bind double: [%i] -> %f", position, value);
+}
+
+void SqlConnection::DataCommand::BindString(
+ SqlConnection::ArgumentIndex position,
+ const char *value)
+{
+ if (!value) {
+ BindNull(position);
+ return;
+ }
+
+ // Assume that text may disappear
+ CheckBindResult(sqlite3_bind_text(m_stmt, position,
+ value, strlen(value),
+ SQLITE_TRANSIENT));
+
+ VcoreLogD("SQL data command bind string: [%i] -> %s", position, value);
+}
+
+void SqlConnection::DataCommand::BindString(
+ SqlConnection::ArgumentIndex position,
+ const String &value)
+{
+ BindString(position, ToUTF8String(value).c_str());
+}
+
+void SqlConnection::DataCommand::BindInteger(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<int> &value)
+{
+ if (!value) {
+ BindNull(position);
+ } else {
+ BindInteger(position, *value);
+ }
+}
+
+void SqlConnection::DataCommand::BindInt8(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<int8_t> &value)
+{
+ if (!value) {
+ BindNull(position);
+ } else {
+ BindInt8(position, *value);
+ }
+}
+
+void SqlConnection::DataCommand::BindInt16(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<int16_t> &value)
+{
+ if (!value) {
+ BindNull(position);
+ } else {
+ BindInt16(position, *value);
+ }
+}
+
+void SqlConnection::DataCommand::BindInt32(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<int32_t> &value)
+{
+ if (!value) {
+ BindNull(position);
+ } else {
+ BindInt32(position, *value);
+ }
+}
+
+void SqlConnection::DataCommand::BindInt64(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<int64_t> &value)
+{
+ if (!value) {
+ BindNull(position);
+ } else {
+ BindInt64(position, *value);
+ }
+}
+
+void SqlConnection::DataCommand::BindFloat(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<float> &value)
+{
+ if (!value) {
+ BindNull(position);
+ } else {
+ BindFloat(position, *value);
+ }
+}
+
+void SqlConnection::DataCommand::BindDouble(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<double> &value)
+{
+ if (!value) {
+ BindNull(position);
+ } else {
+ BindDouble(position, *value);
+ }
+}
+
+void SqlConnection::DataCommand::BindString(
+ SqlConnection::ArgumentIndex position,
+ const boost::optional<String> &value)
+{
+ if (!!value) {
+ BindString(position, ToUTF8String(*value).c_str());
+ } else {
+ BindNull(position);
+ }
+}
+
+bool SqlConnection::DataCommand::Step()
+{
+ // Notify all after potentially synchronized database connection access
+ ScopedNotifyAll notifyAll(
+ m_masterConnection->m_synchronizationObject.get());
+
+ for (;;) {
+ int ret = sqlite3_step(m_stmt);
+
+ if (ret == SQLITE_ROW) {
+ VcoreLogD("SQL data command step ROW");
+ return true;
+ } else if (ret == SQLITE_DONE) {
+ VcoreLogD("SQL data command step DONE");
+ return false;
+ } else if (ret == SQLITE_BUSY) {
+ VcoreLogD("Collision occurred while executing SQL command");
+
+ // Synchronize if synchronization object is available
+ if (m_masterConnection->m_synchronizationObject) {
+ VcoreLogD("Performing synchronization");
+
+ m_masterConnection->
+ m_synchronizationObject->Synchronize();
+
+ continue;
+ }
+
+ // No synchronization object defined. Fail.
+ }
+
+ // Fatal error
+ const char *error = sqlite3_errmsg(m_masterConnection->m_connection);
+
+ VcoreLogD("SQL step data command failed");
+ VcoreLogD(" Error: %s", error);
+
+ ThrowMsg(Exception::InternalError, error);
+ }
+}
+
+void SqlConnection::DataCommand::Reset()
+{
+ /*
+ * According to:
+ * http://www.sqlite.org/c3ref/stmt.html
+ *
+ * if last sqlite3_step command on this stmt returned an error,
+ * then sqlite3_reset will return that error, althought it is not an error.
+ * So sqlite3_reset allways succedes.
+ */
+ sqlite3_reset(m_stmt);
+
+ VcoreLogD("SQL data command reset");
+}
+
+void SqlConnection::DataCommand::CheckColumnIndex(
+ SqlConnection::ColumnIndex column)
+{
+ if (column < 0 || column >= sqlite3_column_count(m_stmt)) {
+ ThrowMsg(Exception::InvalidColumn, "Column index is out of bounds");
+ }
+}
+
+bool SqlConnection::DataCommand::IsColumnNull(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column type: [%i]", column);
+ CheckColumnIndex(column);
+ return sqlite3_column_type(m_stmt, column) == SQLITE_NULL;
+}
+
+int SqlConnection::DataCommand::GetColumnInteger(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column integer: [%i]", column);
+ CheckColumnIndex(column);
+ int value = sqlite3_column_int(m_stmt, column);
+ VcoreLogD(" Value: %i", value);
+ return value;
+}
+
+int8_t SqlConnection::DataCommand::GetColumnInt8(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column int8: [%i]", column);
+ CheckColumnIndex(column);
+ int8_t value = static_cast<int8_t>(sqlite3_column_int(m_stmt, column));
+ VcoreLogD(" Value: %i", value);
+ return value;
+}
+
+int16_t SqlConnection::DataCommand::GetColumnInt16(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column int16: [%i]", column);
+ CheckColumnIndex(column);
+ int16_t value = static_cast<int16_t>(sqlite3_column_int(m_stmt, column));
+ VcoreLogD(" Value: %i", value);
+ return value;
+}
+
+int32_t SqlConnection::DataCommand::GetColumnInt32(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column int32: [%i]", column);
+ CheckColumnIndex(column);
+ int32_t value = static_cast<int32_t>(sqlite3_column_int(m_stmt, column));
+ VcoreLogD(" Value: %i", value);
+ return value;
+}
+
+int64_t SqlConnection::DataCommand::GetColumnInt64(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column int64: [%i]", column);
+ CheckColumnIndex(column);
+ int64_t value = static_cast<int64_t>(sqlite3_column_int64(m_stmt, column));
+ VcoreLogD(" Value: %lli", value);
+ return value;
+}
+
+float SqlConnection::DataCommand::GetColumnFloat(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column float: [%i]", column);
+ CheckColumnIndex(column);
+ float value = static_cast<float>(sqlite3_column_double(m_stmt, column));
+ VcoreLogD(" Value: %f", value);
+ return value;
+}
+
+double SqlConnection::DataCommand::GetColumnDouble(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column double: [%i]", column);
+ CheckColumnIndex(column);
+ double value = sqlite3_column_double(m_stmt, column);
+ VcoreLogD(" Value: %f", value);
+ return value;
+}
+
+std::string SqlConnection::DataCommand::GetColumnString(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column string: [%i]", column);
+ CheckColumnIndex(column);
+
+ const char *value = reinterpret_cast<const char *>(
+ sqlite3_column_text(m_stmt, column));
+
+ VcoreLogD(" Value: %s", value);
+
+ if (value == NULL) {
+ return std::string();
+ }
+
+ return std::string(value);
+}
+
+boost::optional<int> SqlConnection::DataCommand::GetColumnOptionalInteger(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional integer: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<int>();
+ }
+ int value = sqlite3_column_int(m_stmt, column);
+ VcoreLogD(" Value: %i", value);
+ return boost::optional<int>(value);
+}
+
+boost::optional<int8_t> SqlConnection::DataCommand::GetColumnOptionalInt8(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional int8: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<int8_t>();
+ }
+ int8_t value = static_cast<int8_t>(sqlite3_column_int(m_stmt, column));
+ VcoreLogD(" Value: %i", value);
+ return boost::optional<int8_t>(value);
+}
+
+boost::optional<int16_t> SqlConnection::DataCommand::GetColumnOptionalInt16(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional int16: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<int16_t>();
+ }
+ int16_t value = static_cast<int16_t>(sqlite3_column_int(m_stmt, column));
+ VcoreLogD(" Value: %i", value);
+ return boost::optional<int16_t>(value);
+}
+
+boost::optional<int32_t> SqlConnection::DataCommand::GetColumnOptionalInt32(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional int32: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<int32_t>();
+ }
+ int32_t value = static_cast<int32_t>(sqlite3_column_int(m_stmt, column));
+ VcoreLogD(" Value: %i", value);
+ return boost::optional<int32_t>(value);
+}
+
+boost::optional<int64_t> SqlConnection::DataCommand::GetColumnOptionalInt64(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional int64: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<int64_t>();
+ }
+ int64_t value = static_cast<int64_t>(sqlite3_column_int64(m_stmt, column));
+ VcoreLogD(" Value: %lli", value);
+ return boost::optional<int64_t>(value);
+}
+
+boost::optional<float> SqlConnection::DataCommand::GetColumnOptionalFloat(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional float: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<float>();
+ }
+ float value = static_cast<float>(sqlite3_column_double(m_stmt, column));
+ VcoreLogD(" Value: %f", value);
+ return boost::optional<float>(value);
+}
+
+boost::optional<double> SqlConnection::DataCommand::GetColumnOptionalDouble(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional double: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<double>();
+ }
+ double value = sqlite3_column_double(m_stmt, column);
+ VcoreLogD(" Value: %f", value);
+ return boost::optional<double>(value);
+}
+
+boost::optional<String> SqlConnection::DataCommand::GetColumnOptionalString(
+ SqlConnection::ColumnIndex column)
+{
+ VcoreLogD("SQL data command get column optional string: [%i]", column);
+ CheckColumnIndex(column);
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL) {
+ return boost::optional<String>();
+ }
+ const char *value = reinterpret_cast<const char *>(
+ sqlite3_column_text(m_stmt, column));
+ VcoreLogD(" Value: %s", value);
+ String s = FromUTF8String(value);
+ return boost::optional<String>(s);
+}
+
+void SqlConnection::Connect(const std::string &address,
+ Flag::Type type,
+ Flag::Option flag)
+{
+ if (m_connection != NULL) {
+ VcoreLogD("Already connected.");
+ return;
+ }
+ VcoreLogD("Connecting to DB: %s...", address.c_str());
+
+ // Connect to database
+ int result;
+ if (type & Flag::UseLucene) {
+ result = db_util_open_with_options(
+ address.c_str(),
+ &m_connection,
+ flag,
+ NULL);
+
+ m_usingLucene = true;
+ VcoreLogD("Lucene index enabled");
+ } else {
+ result = sqlite3_open_v2(
+ address.c_str(),
+ &m_connection,
+ flag,
+ NULL);
+
+ m_usingLucene = false;
+ VcoreLogD("Lucene index disabled");
+ }
+
+ if (result == SQLITE_OK) {
+ VcoreLogD("Connected to DB");
+ } else {
+ VcoreLogD("Failed to connect to DB!");
+ ThrowMsg(Exception::ConnectionBroken, address);
+ }
+
+ // Enable foreign keys
+ TurnOnForeignKeys();
+}
+
+void SqlConnection::Disconnect()
+{
+ if (m_connection == NULL) {
+ VcoreLogD("Already disconnected.");
+ return;
+ }
+
+ VcoreLogD("Disconnecting from DB...");
+
+ // All stored data commands must be deleted before disconnect
+ AssertMsg(m_dataCommandsCount == 0,
+ "All stored procedures must be deleted"
+ " before disconnecting SqlConnection");
+
+ int result;
+
+ if (m_usingLucene) {
+ result = db_util_close(m_connection);
+ } else {
+ result = sqlite3_close(m_connection);
+ }
+
+ if (result != SQLITE_OK) {
+ const char *error = sqlite3_errmsg(m_connection);
+ VcoreLogD("SQL close failed");
+ VcoreLogD(" Error: %s", error);
+ Throw(Exception::InternalError);
+ }
+
+ m_connection = NULL;
+
+ VcoreLogD("Disconnected from DB");
+}
+
+bool SqlConnection::CheckTableExist(const char *tableName)
+{
+ if (m_connection == NULL) {
+ VcoreLogD("Cannot execute command. Not connected to DB!");
+ return false;
+ }
+
+ DataCommandAutoPtr command =
+ PrepareDataCommand("select tbl_name from sqlite_master where name=?;");
+
+ command->BindString(1, tableName);
+
+ if (!command->Step()) {
+ VcoreLogD("No matching records in table");
+ return false;
+ }
+
+ return command->GetColumnString(0) == tableName;
+}
+
+SqlConnection::SqlConnection(const std::string &address,
+ Flag::Type flag,
+ Flag::Option option,
+ SynchronizationObject *synchronizationObject) :
+ m_connection(NULL),
+ m_usingLucene(false),
+ m_dataCommandsCount(0),
+ m_synchronizationObject(synchronizationObject)
+{
+ VcoreLogD("Opening database connection to: %s", address.c_str());
+
+ // Connect to DB
+ SqlConnection::Connect(address, flag, option);
+
+ if (!m_synchronizationObject) {
+ VcoreLogD("No synchronization object defined");
+ }
+}
+
+SqlConnection::~SqlConnection()
+{
+ VcoreLogD("Closing database connection");
+
+ // Disconnect from DB
+ Try
+ {
+ SqlConnection::Disconnect();
+ }
+ Catch(Exception::Base)
+ {
+ VcoreLogD("Failed to disconnect from database");
+ }
+}
+
+void SqlConnection::ExecCommand(const char *format, ...)
+{
+ if (m_connection == NULL) {
+ VcoreLogD("Cannot execute command. Not connected to DB!");
+ return;
+ }
+
+ if (format == NULL) {
+ VcoreLogD("Null query!");
+ ThrowMsg(Exception::SyntaxError, "Null statement");
+ }
+
+ char *rawBuffer;
+
+ va_list args;
+ va_start(args, format);
+
+ if (vasprintf(&rawBuffer, format, args) == -1) {
+ rawBuffer = NULL;
+ }
+
+ va_end(args);
+
+ std::unique_ptr<char[],free_deleter> buffer(rawBuffer);
+
+ if (!buffer) {
+ VcoreLogD("Failed to allocate statement string");
+ return;
+ }
+
+ VcoreLogD("Executing SQL command: %s", buffer.get());
+
+ // Notify all after potentially synchronized database connection access
+ ScopedNotifyAll notifyAll(m_synchronizationObject.get());
+
+ for (;;) {
+ char *errorBuffer;
+
+ int ret = sqlite3_exec(m_connection,
+ buffer.get(),
+ NULL,
+ NULL,
+ &errorBuffer);
+
+ std::string errorMsg;
+
+ // Take allocated error buffer
+ if (errorBuffer != NULL) {
+ errorMsg = errorBuffer;
+ sqlite3_free(errorBuffer);
+ }
+
+ if (ret == SQLITE_OK) {
+ return;
+ }
+
+ if (ret == SQLITE_BUSY) {
+ VcoreLogD("Collision occurred while executing SQL command");
+
+ // Synchronize if synchronization object is available
+ if (m_synchronizationObject) {
+ VcoreLogD("Performing synchronization");
+ m_synchronizationObject->Synchronize();
+ continue;
+ }
+
+ // No synchronization object defined. Fail.
+ }
+
+ // Fatal error
+ VcoreLogD("Failed to execute SQL command. Error: %s", errorMsg.c_str());
+ ThrowMsg(Exception::SyntaxError, errorMsg);
+ }
+}
+
+SqlConnection::DataCommandAutoPtr SqlConnection::PrepareDataCommand(
+ const char *format,
+ ...)
+{
+ if (m_connection == NULL) {
+ VcoreLogD("Cannot execute data command. Not connected to DB!");
+ return DataCommandAutoPtr();
+ }
+
+ char *rawBuffer;
+
+ va_list args;
+ va_start(args, format);
+
+ if (vasprintf(&rawBuffer, format, args) == -1) {
+ rawBuffer = NULL;
+ }
+
+ va_end(args);
+
+ std::unique_ptr<char[],free_deleter> buffer(rawBuffer);
+
+ if (!buffer) {
+ VcoreLogD("Failed to allocate statement string");
+ return DataCommandAutoPtr();
+ }
+
+ VcoreLogD("Executing SQL data command: %s", buffer.get());
+
+ return DataCommandAutoPtr(new DataCommand(this, buffer.get()));
+}
+
+SqlConnection::RowID SqlConnection::GetLastInsertRowID() const
+{
+ return static_cast<RowID>(sqlite3_last_insert_rowid(m_connection));
+}
+
+void SqlConnection::TurnOnForeignKeys()
+{
+ ExecCommand("PRAGMA foreign_keys = ON;");
+}
+
+void SqlConnection::BeginTransaction()
+{
+ ExecCommand("BEGIN;");
+}
+
+void SqlConnection::RollbackTransaction()
+{
+ ExecCommand("ROLLBACK;");
+}
+
+void SqlConnection::CommitTransaction()
+{
+ ExecCommand("COMMIT;");
+}
+
+SqlConnection::SynchronizationObject *
+SqlConnection::AllocDefaultSynchronizationObject()
+{
+ return new NaiveSynchronizationObject();
+}
+
+int SqlConnection::db_util_open_with_options(const char *pszFilePath, sqlite3 **ppDB,
+ int flags, const char *zVfs)
+{
+ int mode;
+
+ if((pszFilePath == NULL) || (ppDB == NULL)) {
+ VcoreLogW("sqlite3 handle null error");
+ return SQLITE_ERROR;
+ }
+
+ mode = R_OK;
+
+ if((geteuid() != 0) && (access(pszFilePath, mode))) {
+ if(errno == EACCES) {
+ VcoreLogD("file access permission error");
+ return SQLITE_PERM;
+ }
+ }
+
+ /* Open DB */
+ int rc = sqlite3_open_v2(pszFilePath, ppDB, flags, zVfs);
+ if (SQLITE_OK != rc) {
+ VcoreLogE("sqlite3_open_v2 error(%d)",rc);
+ return rc;
+ }
+
+ //rc = __db_util_open(*ppDB);
+
+ return rc;
+}
+
+
+int SqlConnection::db_util_close(sqlite3 *pDB)
+{
+ char *pszErrorMsg = NULL;
+
+ /* Close DB */
+ int rc = sqlite3_close(pDB);
+ if (SQLITE_OK != rc) {
+ VcoreLogW("Fail to change journal mode: %s\n", pszErrorMsg);
+ sqlite3_free(pszErrorMsg);
+ return rc;
+ }
+
+ return SQLITE_OK;
+}
+
+} // namespace DB
+} // namespace VcoreDPL
diff --git a/vcore/src/vcore/SoupMessageSendAsync.cpp b/vcore/src/dpl/db/src/thread_database_support.cpp
index d8bb132..101640f 100644
--- a/vcore/src/vcore/SoupMessageSendAsync.cpp
+++ b/vcore/src/dpl/db/src/thread_database_support.cpp
@@ -13,3 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+/*
+ * @file thread_database_support.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk)
+ * @version 1.0
+ * @brief This file contains the definition of thread database support
+ */
+#include <stddef.h>
+#include <dpl/db/thread_database_support.h> \ No newline at end of file
diff --git a/vcore/src/dpl/log/include/dpl/log/abstract_log_provider.h b/vcore/src/dpl/log/include/dpl/log/abstract_log_provider.h
new file mode 100644
index 0000000..9061156
--- /dev/null
+++ b/vcore/src/dpl/log/include/dpl/log/abstract_log_provider.h
@@ -0,0 +1,59 @@
+/*
+ * 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 abstract_log_provider.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of abstract log provider
+ */
+#ifndef DPL_ABSTRACT_LOG_PROVIDER_H
+#define DPL_ABSTRACT_LOG_PROVIDER_H
+
+namespace VcoreDPL {
+namespace Log {
+class AbstractLogProvider
+{
+ public:
+ virtual ~AbstractLogProvider() {}
+
+ virtual void Debug(const char *message,
+ const char *fileName,
+ int line,
+ const char *function) = 0;
+ virtual void Info(const char *message,
+ const char *fileName,
+ int line,
+ const char *function) = 0;
+ virtual void Warning(const char *message,
+ const char *fileName,
+ int line,
+ const char *function) = 0;
+ virtual void Error(const char *message,
+ const char *fileName,
+ int line,
+ const char *function) = 0;
+ virtual void Pedantic(const char *message,
+ const char *fileName,
+ int line,
+ const char *function) = 0;
+
+ protected:
+ static const char *LocateSourceFileName(const char *filename);
+};
+}
+} // namespace VcoreDPL
+
+#endif // DPL_ABSTRACT_LOG_PROVIDER_H
diff --git a/vcore/src/dpl/log/include/dpl/log/dlog_log_provider.h b/vcore/src/dpl/log/include/dpl/log/dlog_log_provider.h
new file mode 100644
index 0000000..263d1e3
--- /dev/null
+++ b/vcore/src/dpl/log/include/dpl/log/dlog_log_provider.h
@@ -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 dlog_log_provider.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of DLOG log provider
+ */
+#ifndef DPL_DLOG_LOG_PROVIDER_H
+#define DPL_DLOG_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <dpl/scoped_free.h>
+#include <string>
+
+namespace VcoreDPL {
+namespace Log {
+class DLOGLogProvider :
+ public AbstractLogProvider
+{
+ private:
+ VcoreDPL::ScopedFree<char> m_tag;
+
+ static std::string FormatMessage(const char *message,
+ const char *filename,
+ int line,
+ const char *function);
+
+ public:
+ DLOGLogProvider();
+ virtual ~DLOGLogProvider();
+
+ virtual void Debug(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Info(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Warning(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Error(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Pedantic(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+
+ // Set global Tag according to DLOG
+ void SetTag(const char *tag);
+};
+}
+} // namespace VcoreDPL
+
+#endif // DPL_DLOG_LOG_PROVIDER_H
diff --git a/vcore/src/dpl/log/include/dpl/log/log.h b/vcore/src/dpl/log/include/dpl/log/log.h
new file mode 100644
index 0000000..43f4844
--- /dev/null
+++ b/vcore/src/dpl/log/include/dpl/log/log.h
@@ -0,0 +1,171 @@
+/*
+ * 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 log.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of log system
+ */
+#ifndef DPL_LOG_H
+#define DPL_LOG_H
+
+#include <dpl/singleton.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <sstream>
+#include <list>
+
+namespace VcoreDPL {
+namespace Log {
+/**
+ * DPL log system
+ *
+ * To switch logs into old style, export
+ * DPL_USE_OLD_STYLE_LOGS before application start
+ */
+class LogSystem :
+ private Noncopyable
+{
+ private:
+ typedef std::list<AbstractLogProvider *> AbstractLogProviderPtrList;
+ AbstractLogProviderPtrList m_providers;
+
+ DLOGLogProvider *m_dlogProvider;
+ OldStyleLogProvider *m_oldStyleProvider;
+
+ bool m_isLoggingEnabled;
+
+ public:
+ bool IsLoggingEnabled() const;
+ LogSystem();
+ virtual ~LogSystem();
+
+ /**
+ * Log debug message
+ */
+ void Debug(const char *message,
+ const char *filename,
+ int line,
+ const char *function);
+
+ /**
+ * Log info message
+ */
+ void Info(const char *message,
+ const char *filename,
+ int line,
+ const char *function);
+
+ /**
+ * Log warning message
+ */
+ void Warning(const char *message,
+ const char *filename,
+ int line,
+ const char *function);
+
+ /**
+ * Log error message
+ */
+ void Error(const char *message,
+ const char *filename,
+ int line,
+ const char *function);
+
+ /**
+ * Log pedantic message
+ */
+ void Pedantic(const char *message,
+ const char *filename,
+ int line,
+ const char *function);
+
+ /**
+ * Set default's DLOG provider Tag
+ */
+ void SetTag(const char *tag);
+
+ /**
+ * Add abstract provider to providers list
+ *
+ * @notice Ownership is transfered to LogSystem and deleted upon exit
+ */
+ void AddProvider(AbstractLogProvider *provider);
+
+ /**
+ * Remove abstract provider from providers list
+ */
+ void RemoveProvider(AbstractLogProvider *provider);
+};
+
+/*
+ * Replacement low overhead null logging class
+ */
+class NullStream
+{
+ public:
+ NullStream() {}
+
+ template <typename T>
+ NullStream& operator<<(const T&)
+ {
+ return *this;
+ }
+};
+
+/**
+ * Log system singleton
+ */
+typedef Singleton<LogSystem> LogSystemSingleton;
+}
+} // namespace VcoreDPL
+
+//
+// Log support
+//
+//
+
+#ifdef DPL_LOGS_ENABLED
+ #define DPL_MACRO_FOR_LOGGING(message, function) \
+ do \
+ { \
+ if (VcoreDPL::Log::LogSystemSingleton::Instance().IsLoggingEnabled()) \
+ { \
+ std::ostringstream platformLog; \
+ platformLog << message; \
+ VcoreDPL::Log::LogSystemSingleton::Instance().function( \
+ platformLog.str().c_str(), \
+ __FILE__, __LINE__, __FUNCTION__); \
+ } \
+ } while (0)
+#else
+/* avoid warnings about unused variables */
+ #define DPL_MACRO_FOR_LOGGING(message, function) \
+ do { \
+ VcoreDPL::Log::NullStream ns; \
+ ns << message; \
+ } while (0)
+#endif
+
+#define LogDebug(message) DPL_MACRO_FOR_LOGGING(message, Debug)
+#define LogInfo(message) DPL_MACRO_FOR_LOGGING(message, Info)
+#define LogWarning(message) DPL_MACRO_FOR_LOGGING(message, Warning)
+#define LogError(message) DPL_MACRO_FOR_LOGGING(message, Error)
+#define LogPedantic(message) DPL_MACRO_FOR_LOGGING(message, Pedantic)
+
+#endif // DPL_LOG_H
diff --git a/vcore/src/dpl/log/include/dpl/log/old_style_log_provider.h b/vcore/src/dpl/log/include/dpl/log/old_style_log_provider.h
new file mode 100644
index 0000000..fc14c7f
--- /dev/null
+++ b/vcore/src/dpl/log/include/dpl/log/old_style_log_provider.h
@@ -0,0 +1,84 @@
+/*
+ * 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 old_style_log_provider.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of old style log provider
+ */
+#ifndef DPL_OLD_STYLE_LOG_PROVIDER_H
+#define DPL_OLD_STYLE_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <string>
+
+namespace VcoreDPL {
+namespace Log {
+class OldStyleLogProvider :
+ public AbstractLogProvider
+{
+ private:
+ bool m_showDebug;
+ bool m_showInfo;
+ bool m_showWarning;
+ bool m_showError;
+ bool m_showPedantic;
+ bool m_printStdErr;
+
+ static std::string FormatMessage(const char *message,
+ const char *filename,
+ int line,
+ const char *function);
+
+ public:
+ OldStyleLogProvider(bool showDebug,
+ bool showInfo,
+ bool showWarning,
+ bool showError,
+ bool showPedantic);
+ OldStyleLogProvider(bool showDebug,
+ bool showInfo,
+ bool showWarning,
+ bool showError,
+ bool showPedantic,
+ bool printStdErr);
+ virtual ~OldStyleLogProvider() {}
+
+ virtual void Debug(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Info(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Warning(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Error(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+ virtual void Pedantic(const char *message,
+ const char *fileName,
+ int line,
+ const char *function);
+};
+}
+} // namespace VcoreDPL
+
+#endif // DPL_OLD_STYLE_LOG_PROVIDER_H
diff --git a/vcore/src/dpl/log/include/dpl/log/vcore_log.h b/vcore/src/dpl/log/include/dpl/log/vcore_log.h
new file mode 100644
index 0000000..01116bf
--- /dev/null
+++ b/vcore/src/dpl/log/include/dpl/log/vcore_log.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 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_LOG_H
+#define VCORE_LOG_H
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "CERT_SVC_VCORE"
+
+#include <dlog.h>
+
+#define COLOR_ERROR "\033[38;5;160;1m" // bold red
+#define COLOR_WARNING "\033[38;5;202;1m" // bold orange
+#define COLOR_INFO "\033[38;5;243;1m" // bold light gray
+#define COLOR_DEBUG "\033[38;5;243;0m" // normal light gray
+#define COLOR_END "\033[0m"
+
+#define INTERNAL_SECURE_LOG __extension__ SECURE_SLOG
+#define VCORE_LOG(priority, color, format, ...) \
+do { \
+ INTERNAL_SECURE_LOG(priority, LOG_TAG, color format "%s", __VA_ARGS__); \
+} while(0)
+
+
+/*
+ * Please use following macros
+ */
+#define VcoreLogD(...) VCORE_LOG(LOG_DEBUG, COLOR_DEBUG, __VA_ARGS__, COLOR_END)
+#define VcoreLogI(...) VCORE_LOG(LOG_INFO, COLOR_INFO, __VA_ARGS__, COLOR_END)
+#define VcoreLogW(...) VCORE_LOG(LOG_WARN, COLOR_WARNING, __VA_ARGS__, COLOR_END)
+#define VcoreLogE(...) VCORE_LOG(LOG_ERROR, COLOR_ERROR, __VA_ARGS__, COLOR_END)
+
+#endif
diff --git a/vcore/src/dpl/log/include/dpl/log/wrt_log.h b/vcore/src/dpl/log/include/dpl/log/wrt_log.h
new file mode 100644
index 0000000..b0a3d2e
--- /dev/null
+++ b/vcore/src/dpl/log/include/dpl/log/wrt_log.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 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_WRT_LOG_H
+#define VCORE_WRT_LOG_H
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "CERT_SVC_VCORE"
+
+#include <dlog.h>
+
+#define COLOR_ERROR "\033[38;5;160;1m" // bold red
+#define COLOR_WARNING "\033[38;5;202;1m" // bold orange
+#define COLOR_INFO "\033[38;5;243;1m" // bold light gray
+#define COLOR_DEBUG "\033[38;5;243;0m" // normal light gray
+#define COLOR_END "\033[0m"
+
+#define INTERNAL_SECURE_LOG __extension__ SECURE_SLOG
+#define WRT_LOG(priority, color, format, ...) \
+do { \
+ INTERNAL_SECURE_LOG(priority, LOG_TAG, color format "%s", __VA_ARGS__); \
+} while(0)
+
+
+/*
+ * Please use following macros
+ */
+#define WrtLogD(...) WRT_LOG(LOG_DEBUG, COLOR_DEBUG, __VA_ARGS__, COLOR_END)
+#define WrtLogI(...) WRT_LOG(LOG_INFO, COLOR_INFO, __VA_ARGS__, COLOR_END)
+#define WrtLogW(...) WRT_LOG(LOG_WARN, COLOR_WARNING, __VA_ARGS__, COLOR_END)
+#define WrtLogE(...) WRT_LOG(LOG_ERROR, COLOR_ERROR, __VA_ARGS__, COLOR_END)
+
+#endif
diff --git a/vcore/src/dpl/log/src/abstract_log_provider.cpp b/vcore/src/dpl/log/src/abstract_log_provider.cpp
new file mode 100644
index 0000000..05a80f7
--- /dev/null
+++ b/vcore/src/dpl/log/src/abstract_log_provider.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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 abstract_log_provider.cpp
+ * @author Pawel Sikorski (p.sikorski@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of abstract log provider
+ */
+#include <stddef.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <cstring>
+
+namespace VcoreDPL {
+namespace Log {
+const char *AbstractLogProvider::LocateSourceFileName(const char *filename)
+{
+ const char *ptr = strrchr(filename, '/');
+ return ptr != NULL ? ptr + 1 : filename;
+}
+}
+}
diff --git a/vcore/src/dpl/log/src/dlog_log_provider.cpp b/vcore/src/dpl/log/src/dlog_log_provider.cpp
new file mode 100644
index 0000000..8958fe0
--- /dev/null
+++ b/vcore/src/dpl/log/src/dlog_log_provider.cpp
@@ -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.
+ */
+/*
+ * @file dlog_log_provider.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of DLOG log provider
+ */
+#include <stddef.h>
+#include <dpl/log/dlog_log_provider.h>
+#include <cstring>
+#include <sstream>
+#include <dlog.h>
+
+#ifdef SECURE_LOG
+ #define INTERNAL_DLP_LOG_ SECURE_LOG
+#else
+ #define INTERNAL_DLP_LOG_ LOG
+#endif
+
+/*
+ * The __extension__ keyword in the following define is required because
+ * macros used here from dlog.h use non-standard extension that cause
+ * gcc to show unwanted warnings when compiling with -pedantic switch.
+ */
+#define INTERNAL_DLP_LOG __extension__ INTERNAL_DLP_LOG_
+
+namespace VcoreDPL {
+namespace Log {
+std::string DLOGLogProvider::FormatMessage(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ std::ostringstream val;
+
+ val << std::string("[") <<
+ LocateSourceFileName(filename) << std::string(":") << line <<
+ std::string("] ") << function << std::string("(): ") << message;
+
+ return val.str();
+}
+
+DLOGLogProvider::DLOGLogProvider()
+{}
+
+DLOGLogProvider::~DLOGLogProvider()
+{}
+
+void DLOGLogProvider::SetTag(const char *tag)
+{
+ m_tag.Reset(strdup(tag));
+}
+
+void DLOGLogProvider::Debug(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ INTERNAL_DLP_LOG(LOG_DEBUG, m_tag.Get(), "%s",
+ FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Info(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ INTERNAL_DLP_LOG(LOG_INFO, m_tag.Get(), "%s",
+ FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Warning(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ INTERNAL_DLP_LOG(LOG_WARN, m_tag.Get(), "%s",
+ FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Error(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ INTERNAL_DLP_LOG(LOG_ERROR, m_tag.Get(), "%s",
+ FormatMessage(message, filename, line, function).c_str());
+}
+
+void DLOGLogProvider::Pedantic(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ INTERNAL_DLP_LOG(LOG_DEBUG, "DPL", "%s",
+ FormatMessage(message, filename, line, function).c_str());
+}
+}
+} // namespace VcoreDPL
+
+#undef INTERNAL_DLP_LOG
+#undef INTERNAL_DLP_LOG_
+
diff --git a/vcore/src/dpl/log/src/log.cpp b/vcore/src/dpl/log/src/log.cpp
new file mode 100644
index 0000000..283b849
--- /dev/null
+++ b/vcore/src/dpl/log/src/log.cpp
@@ -0,0 +1,222 @@
+/*
+ * 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 log.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of log system
+ */
+#include <stddef.h>
+#include <dpl/log/log.h>
+#include <dpl/singleton_impl.h>
+
+IMPLEMENT_SINGLETON(VcoreDPL::Log::LogSystem)
+
+namespace VcoreDPL {
+namespace Log {
+namespace // anonymous
+{
+const char *OLD_STYLE_LOGS_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS";
+const char *OLD_STYLE_PEDANTIC_LOGS_ENV_NAME =
+ "DPL_USE_OLD_STYLE_PEDANTIC_LOGS";
+const char *OLD_STYLE_LOGS_MASK_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS_MASK";
+const char *DPL_LOG_OFF = "DPL_LOG_OFF";
+} // namespace anonymous
+
+bool LogSystem::IsLoggingEnabled() const
+{
+ return m_isLoggingEnabled;
+}
+
+LogSystem::LogSystem() :
+ m_dlogProvider(NULL),
+ m_oldStyleProvider(NULL),
+ m_isLoggingEnabled(!getenv(DPL_LOG_OFF))
+{
+ bool oldStyleLogs = false;
+ bool oldStyleDebugLogs = true;
+ bool oldStyleInfoLogs = true;
+ bool oldStyleWarningLogs = true;
+ bool oldStyleErrorLogs = true;
+ bool oldStylePedanticLogs = false;
+
+ // Check environment settings about pedantic logs
+ const char *value = getenv(OLD_STYLE_LOGS_ENV_NAME);
+
+ if (value != NULL && !strcmp(value, "1")) {
+ oldStyleLogs = true;
+ }
+
+ value = getenv(OLD_STYLE_PEDANTIC_LOGS_ENV_NAME);
+
+ if (value != NULL && !strcmp(value, "1")) {
+ oldStylePedanticLogs = true;
+ }
+
+ value = getenv(OLD_STYLE_LOGS_MASK_ENV_NAME);
+
+ if (value != NULL) {
+ size_t len = strlen(value);
+
+ if (len >= 1) {
+ if (value[0] == '0') {
+ oldStyleDebugLogs = false;
+ } else if (value[0] == '1') {
+ oldStyleDebugLogs = true;
+ }
+ }
+
+ if (len >= 2) {
+ if (value[1] == '0') {
+ oldStyleInfoLogs = false;
+ } else if (value[1] == '1') {
+ oldStyleInfoLogs = true;
+ }
+ }
+
+ if (len >= 3) {
+ if (value[2] == '0') {
+ oldStyleWarningLogs = false;
+ } else if (value[2] == '1') {
+ oldStyleWarningLogs = true;
+ }
+ }
+
+ if (len >= 4) {
+ if (value[3] == '0') {
+ oldStyleErrorLogs = false;
+ } else if (value[3] == '1') {
+ oldStyleErrorLogs = true;
+ }
+ }
+ }
+
+ // Setup default DLOG and old style logging
+ if (oldStyleLogs) {
+ // Old style
+ m_oldStyleProvider = new OldStyleLogProvider(oldStyleDebugLogs,
+ oldStyleInfoLogs,
+ oldStyleWarningLogs,
+ oldStyleErrorLogs,
+ oldStylePedanticLogs);
+ AddProvider(m_oldStyleProvider);
+ } else {
+ // DLOG
+ m_dlogProvider = new DLOGLogProvider();
+ AddProvider(m_dlogProvider);
+ }
+}
+
+LogSystem::~LogSystem()
+{
+ // Delete all providers
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+ iterator != m_providers.end();
+ ++iterator)
+ {
+ delete *iterator;
+ }
+
+ m_providers.clear();
+
+ // And even default providers
+ m_dlogProvider = NULL;
+ m_oldStyleProvider = NULL;
+}
+
+void LogSystem::SetTag(const char* tag)
+{
+ if (m_dlogProvider != NULL) {
+ m_dlogProvider->SetTag(tag);
+ }
+}
+
+void LogSystem::AddProvider(AbstractLogProvider *provider)
+{
+ m_providers.push_back(provider);
+}
+
+void LogSystem::RemoveProvider(AbstractLogProvider *provider)
+{
+ m_providers.remove(provider);
+}
+
+void LogSystem::Debug(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+ iterator != m_providers.end();
+ ++iterator)
+ {
+ (*iterator)->Debug(message, filename, line, function);
+ }
+}
+
+void LogSystem::Info(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+ iterator != m_providers.end();
+ ++iterator)
+ {
+ (*iterator)->Info(message, filename, line, function);
+ }
+}
+
+void LogSystem::Warning(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+ iterator != m_providers.end();
+ ++iterator)
+ {
+ (*iterator)->Warning(message, filename, line, function);
+ }
+}
+
+void LogSystem::Error(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+ iterator != m_providers.end();
+ ++iterator)
+ {
+ (*iterator)->Error(message, filename, line, function);
+ }
+}
+
+void LogSystem::Pedantic(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin();
+ iterator != m_providers.end();
+ ++iterator)
+ {
+ (*iterator)->Pedantic(message, filename, line, function);
+ }
+}
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/log/src/old_style_log_provider.cpp b/vcore/src/dpl/log/src/old_style_log_provider.cpp
new file mode 100644
index 0000000..d13c66e
--- /dev/null
+++ b/vcore/src/dpl/log/src/old_style_log_provider.cpp
@@ -0,0 +1,200 @@
+/*
+ * 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 old_style_log_provider.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of old style log provider
+ */
+#include <stddef.h>
+#include <dpl/log/old_style_log_provider.h>
+#include <dpl/colors.h>
+#include <cstdio>
+#include <cstring>
+#include <sstream>
+#include <sys/time.h>
+#include <unistd.h>
+
+namespace VcoreDPL {
+namespace Log {
+namespace // anonymous
+{
+using namespace VcoreDPL::Colors::Text;
+const char *DEBUG_BEGIN = GREEN_BEGIN;
+const char *DEBUG_END = GREEN_END;
+const char *INFO_BEGIN = CYAN_BEGIN;
+const char *INFO_END = CYAN_END;
+const char *ERROR_BEGIN = RED_BEGIN;
+const char *ERROR_END = RED_END;
+const char *WARNING_BEGIN = BOLD_GOLD_BEGIN;
+const char *WARNING_END = BOLD_GOLD_END;
+const char *PEDANTIC_BEGIN = PURPLE_BEGIN;
+const char *PEDANTIC_END = PURPLE_END;
+
+std::string GetFormattedTime()
+{
+ timeval tv;
+ tm localNowTime;
+
+ gettimeofday(&tv, NULL);
+ localtime_r(&tv.tv_sec, &localNowTime);
+
+ char format[64];
+ snprintf(format,
+ sizeof(format),
+ "%02i:%02i:%02i.%03i",
+ localNowTime.tm_hour,
+ localNowTime.tm_min,
+ localNowTime.tm_sec,
+ static_cast<int>(tv.tv_usec / 1000));
+ return format;
+}
+} // namespace anonymous
+
+std::string OldStyleLogProvider::FormatMessage(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ std::ostringstream val;
+
+ val << std::string("[") << GetFormattedTime() << std::string("] [") <<
+ static_cast<unsigned long>(pthread_self()) << "/" <<
+ static_cast<int>(getpid()) << std::string("] [") <<
+ LocateSourceFileName(filename) << std::string(":") << line <<
+ std::string("] ") << function << std::string("(): ") << message;
+
+ return val.str();
+}
+
+OldStyleLogProvider::OldStyleLogProvider(bool showDebug,
+ bool showInfo,
+ bool showWarning,
+ bool showError,
+ bool showPedantic) :
+ m_showDebug(showDebug),
+ m_showInfo(showInfo),
+ m_showWarning(showWarning),
+ m_showError(showError),
+ m_showPedantic(showPedantic),
+ m_printStdErr(false)
+{}
+
+OldStyleLogProvider::OldStyleLogProvider(bool showDebug,
+ bool showInfo,
+ bool showWarning,
+ bool showError,
+ bool showPedantic,
+ bool printStdErr) :
+ m_showDebug(showDebug),
+ m_showInfo(showInfo),
+ m_showWarning(showWarning),
+ m_showError(showError),
+ m_showPedantic(showPedantic),
+ m_printStdErr(printStdErr)
+{}
+
+void OldStyleLogProvider::Debug(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ if (m_showDebug) {
+ if (m_printStdErr) {
+ fprintf(stderr, "%s%s%s\n", DEBUG_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), DEBUG_END);
+ } else {
+ fprintf(stdout, "%s%s%s\n", DEBUG_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), DEBUG_END);
+ }
+ }
+}
+
+void OldStyleLogProvider::Info(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ if (m_showInfo) {
+ if (m_printStdErr) {
+ fprintf(stderr, "%s%s%s\n", INFO_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), INFO_END);
+ } else {
+ fprintf(stdout, "%s%s%s\n", INFO_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), INFO_END);
+ }
+ }
+}
+
+void OldStyleLogProvider::Warning(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ if (m_showWarning) {
+ if (m_printStdErr) {
+ fprintf(stderr, "%s%s%s\n", WARNING_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), WARNING_END);
+ } else {
+ fprintf(stdout, "%s%s%s\n", WARNING_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), WARNING_END);
+ }
+ }
+}
+
+void OldStyleLogProvider::Error(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ if (m_showError) {
+ if (m_printStdErr) {
+ fprintf(stderr, "%s%s%s\n", ERROR_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), ERROR_END);
+ } else {
+ fprintf(stdout, "%s%s%s\n", ERROR_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), ERROR_END);
+ }
+ }
+}
+
+void OldStyleLogProvider::Pedantic(const char *message,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ if (m_showPedantic) {
+ if (m_printStdErr) {
+ fprintf(stderr, "%s%s%s\n", PEDANTIC_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), PEDANTIC_END);
+ } else {
+ fprintf(stdout, "%s%s%s\n", PEDANTIC_BEGIN,
+ FormatMessage(message, filename, line,
+ function).c_str(), PEDANTIC_END);
+ }
+ }
+}
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/test/include/dpl/test/abstract_input_parser.h b/vcore/src/dpl/test/include/dpl/test/abstract_input_parser.h
new file mode 100644
index 0000000..a7043ea
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/abstract_input_parser.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013 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 abstract_input_parser.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Simple parser abstraction to be included into reader
+ */
+
+#ifndef ABSTRACT_INPUT_PARSER_H
+#define ABSTRACT_INPUT_PARSER_H
+
+#include <dpl/exception.h>
+
+#include <memory>
+
+namespace VcoreDPL {
+
+/**
+ * Abstract class of parser that produces some higher level abstraction
+ * basing on incoming tokens
+ */
+template<class Result, class Token> class AbstractInputParser
+{
+public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, ParserError)
+ };
+
+ typedef Result ResultType;
+ typedef Token TokenType;
+
+ virtual ~AbstractInputParser() {}
+
+ virtual void ConsumeToken(std::unique_ptr<Token> && token) = 0;
+ virtual bool IsStateValid() = 0;
+ virtual Result GetResult() const = 0;
+};
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/include/dpl/test/abstract_input_reader.h b/vcore/src/dpl/test/include/dpl/test/abstract_input_reader.h
new file mode 100644
index 0000000..cf7bd7b
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/abstract_input_reader.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013 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 abstract_input_reader.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Simple output reader template
+ *
+ * This generic skeleton for parser which assume being composed from abstract two logical components:
+ *
+ * - parser,
+ * - tokenizer/lexer,
+ * which implements token flow logic. Logic of components may be arbitrary. See depending change for uses.
+ *
+ * Components are created at start time of reader (constructor which moves arguments).
+ * Virtuality (abstract base classes) are for enforcing same token type.
+ * I assumed it's more clear than writen static asserts in code enforcing this.
+ */
+
+#ifndef ABSTRACT_INPUT_READER_H
+#define ABSTRACT_INPUT_READER_H
+
+#include <memory>
+
+#include <dpl/test/abstract_input_tokenizer.h>
+#include <dpl/test/abstract_input_parser.h>
+#include <dpl/abstract_input.h>
+
+namespace VcoreDPL {
+
+/**
+ * Base reader class that can be used with any AbstractInput instance
+ *
+ * This class is encapsulation class for tokenizer and reader subelements
+ * and contains basic calculation pattern
+ *
+ * There a waste in form of virtuality for parser and tokenizer
+ * -> this for forcing same tokenT type in both components
+ */
+template<class ResultT, class TokenT> class AbstractInputReader
+{
+public:
+ typedef ResultT TokenType;
+ typedef TokenT ResultType;
+ typedef AbstractInputParser<ResultT, TokenT> ParserBase;
+ typedef AbstractInputTokenizer<TokenT> TokenizerBase;
+
+ class Exception
+ {
+ public:
+ typedef typename TokenizerBase::Exception::TokenizerError TokenizerError;
+ typedef typename ParserBase::Exception::ParserError ParserError;
+ };
+
+ AbstractInputReader(std::shared_ptr<AbstractInput> ia,
+ std::unique_ptr<ParserBase> && parser,
+ std::unique_ptr<TokenizerBase> && tokenizer)
+ : m_parser(std::move(parser)), m_tokenizer(std::move(tokenizer))
+ {
+ m_tokenizer->Reset(ia);
+ }
+
+ virtual ~AbstractInputReader() {}
+
+ ResultT ReadInput()
+ {
+ typedef typename Exception::TokenizerError TokenizerError;
+ typedef typename Exception::ParserError ParserError;
+
+ while(true)
+ {
+ std::unique_ptr<TokenT> token = m_tokenizer->GetNextToken();
+ if(!token)
+ {
+ if(!m_tokenizer->IsStateValid())
+ {
+ ThrowMsg(TokenizerError, "Tokenizer error");
+ }
+ if(!m_parser->IsStateValid())
+ {
+ ThrowMsg(ParserError, "Parser error");
+ }
+
+ return m_parser->GetResult();
+ }
+ m_parser->ConsumeToken(std::move(token));
+ }
+ }
+
+protected:
+ std::unique_ptr<ParserBase> m_parser;
+ std::unique_ptr<TokenizerBase> m_tokenizer;
+};
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/include/dpl/test/abstract_input_tokenizer.h b/vcore/src/dpl/test/include/dpl/test/abstract_input_tokenizer.h
new file mode 100644
index 0000000..03e00a9
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/abstract_input_tokenizer.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013 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 abstract_input_tokenizer.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Simple tokenizer abstraction
+ */
+
+#ifndef ABSTRACT_INPUT_TOKENIZER_H
+#define ABSTRACT_INPUT_TOKENIZER_H
+
+#include <memory>
+#include <string>
+
+#include <dpl/abstract_input.h>
+#include <dpl/exception.h>
+
+namespace VcoreDPL {
+
+/**
+ * Tokenizer abstract base class
+ *
+ * This class is supposed to accept AbstractInput in constructor
+ * and produce tokens until end of source. If parsing ends in invalid state
+ * then IsStateValid() should return false
+ */
+template<class Token> class AbstractInputTokenizer
+{
+public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, TokenizerError)
+ };
+
+ typedef Token TokenType;
+
+ AbstractInputTokenizer() {}
+ virtual ~AbstractInputTokenizer() {}
+
+ /**
+ * @brief Reset resets data source
+ * @param wia AbstractWaitableInputAdapter instance
+ */
+ virtual void Reset(std::shared_ptr<AbstractInput> wia)
+ {
+ m_input = wia;
+ }
+
+ /**
+ * @brief GetNextToken
+ *
+ * Parses next token.
+ * Returns pointer to token
+ * @throw TokenizerError in condition of input source error
+ * If returned empty pointer IsStateValid() == true -> end of input
+ * IsStateValid() == false -> error
+ *
+ * @param token token to be set
+ * @return
+ */
+ virtual std::unique_ptr<Token> GetNextToken() = 0;
+ virtual bool IsStateValid() = 0;
+
+protected:
+ std::shared_ptr<AbstractInput> m_input;
+};
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/include/dpl/test/process_pipe.h b/vcore/src/dpl/test/include/dpl/test/process_pipe.h
new file mode 100644
index 0000000..bfc124b
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/process_pipe.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 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 process_pipe.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation pipe from process
+ */
+#ifndef PROCESS_PIPE_H
+#define PROCESS_PIPE_H
+
+#include <dpl/file_input.h>
+#include <dpl/exception.h>
+
+#include <cstdio>
+
+namespace VcoreDPL {
+
+class ProcessPipe : public FileInput
+{
+public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, DoubleOpen)
+ };
+
+ enum class PipeErrorPolicy
+ {
+ NONE,
+ OFF,
+ PIPE
+ };
+
+ explicit ProcessPipe(PipeErrorPolicy err = PipeErrorPolicy::NONE);
+ virtual ~ProcessPipe();
+
+ void Open(const std::string &command);
+ void Close();
+
+private:
+ FILE * m_file;
+ PipeErrorPolicy m_errPolicy;
+};
+
+}
+
+#endif // PROCESS_PIPE_H
diff --git a/vcore/src/dpl/test/include/dpl/test/test_results_collector.h b/vcore/src/dpl/test/include/dpl/test/test_results_collector.h
new file mode 100644
index 0000000..5d86ef6
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/test_results_collector.h
@@ -0,0 +1,96 @@
+/*
+ * 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 test_results_collector.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief Header file with declaration of TestResultsCollectorBase
+ */
+
+#ifndef DPL_TEST_RESULTS_COLLECTOR_H
+#define DPL_TEST_RESULTS_COLLECTOR_H
+
+#include <dpl/noncopyable.h>
+#include <dpl/availability.h>
+#include <vector>
+#include <list>
+#include <map>
+#include <string>
+#include <memory>
+
+namespace VcoreDPL {
+namespace Test {
+class TestResultsCollectorBase;
+typedef std::shared_ptr<TestResultsCollectorBase>
+TestResultsCollectorBasePtr;
+
+class TestResultsCollectorBase :
+ private VcoreDPL::Noncopyable
+{
+ public:
+ typedef TestResultsCollectorBase* (*CollectorConstructorFunc)();
+ typedef std::list<std::string> TestCaseIdList;
+ struct FailStatus
+ {
+ enum Type
+ {
+ NONE,
+ FAILED,
+ IGNORED,
+ INTERNAL
+ };
+ };
+
+ virtual ~TestResultsCollectorBase() {}
+
+ virtual bool Configure()
+ {
+ return true;
+ }
+ virtual void Start(int count) { DPL_UNUSED_PARAM(count); }
+ virtual void Finish() { }
+ virtual void CollectCurrentTestGroupName(const std::string& /*groupName*/)
+ {}
+
+ virtual void CollectTestsCasesList(const TestCaseIdList& /*list*/) {}
+ virtual void CollectResult(const std::string& id,
+ const std::string& description,
+ const FailStatus::Type status = FailStatus::NONE,
+ const std::string& reason = "") = 0;
+ virtual std::string CollectorSpecificHelp() const
+ {
+ return "";
+ }
+ virtual bool ParseCollectorSpecificArg (const std::string& /*arg*/)
+ {
+ return false;
+ }
+
+ static TestResultsCollectorBase* Create(const std::string& name);
+ static void RegisterCollectorConstructor(
+ const std::string& name,
+ CollectorConstructorFunc
+ constructor);
+ static std::vector<std::string> GetCollectorsNames();
+
+ private:
+ typedef std::map<std::string, CollectorConstructorFunc> ConstructorsMap;
+ static ConstructorsMap m_constructorsMap;
+};
+}
+}
+
+#endif /* DPL_TEST_RESULTS_COLLECTOR_H */
diff --git a/vcore/src/dpl/test/include/dpl/test/test_runner.h b/vcore/src/dpl/test/include/dpl/test/test_runner.h
new file mode 100644
index 0000000..3b980e1
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/test_runner.h
@@ -0,0 +1,231 @@
+/*
+ * 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 test_runner.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of test runner
+ */
+#ifndef DPL_TEST_RUNNER_H
+#define DPL_TEST_RUNNER_H
+
+#include <dpl/singleton.h>
+#include <dpl/availability.h>
+#include <dpl/test/test_results_collector.h>
+
+#include <atomic>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <list>
+#include <set>
+#include <map>
+
+namespace VcoreDPL {
+namespace Test {
+class TestRunner
+{
+ typedef std::map<std::string, TestResultsCollectorBasePtr>
+ TestResultsCollectors;
+ TestResultsCollectors m_collectors;
+
+ std::string m_startTestId;
+ bool m_runIgnored;
+
+ public:
+ TestRunner()
+ : m_runIgnored(false)
+ , m_allowChildLogs(false)
+ , m_terminate(false)
+ , m_totalAssertions(0)
+ {}
+
+ typedef void (*TestCase)();
+
+ private:
+ struct TestCaseStruct
+ {
+ std::string name;
+ TestCase proc;
+
+ bool operator <(const TestCaseStruct &other) const
+ {
+ return name < other.name;
+ }
+
+ bool operator ==(const TestCaseStruct &other) const
+ {
+ return name == other.name;
+ }
+
+ TestCaseStruct(const std::string &n, TestCase p) :
+ name(n),
+ proc(p)
+ {}
+ };
+
+ typedef std::list<TestCaseStruct> TestCaseStructList;
+ typedef std::map<std::string, TestCaseStructList> TestCaseGroupMap;
+ TestCaseGroupMap m_testGroups;
+
+ typedef std::set<std::string> SelectedTestNameSet;
+ SelectedTestNameSet m_selectedTestNamesSet;
+ typedef std::set<std::string> SelectedTestGroupSet;
+ SelectedTestGroupSet m_selectedTestGroupSet;
+ std::string m_currentGroup;
+
+ // Terminate without any logs.
+ // Some test requires to call fork function.
+ // Child process must not produce any logs and should die quietly.
+ bool m_allowChildLogs;
+ bool m_terminate;
+
+ std::atomic<int> m_totalAssertions;
+
+ void Banner();
+ void InvalidArgs(const std::string& message = "Invalid arguments!");
+ void Usage();
+
+ bool filterGroupsByXmls(const std::vector<std::string> & files);
+ bool filterByXML(std::map<std::string, bool> & casesMap);
+ void normalizeXMLTag(std::string& str, const std::string& testcase);
+
+ enum Status { FAILED, IGNORED, PASS };
+
+ Status RunTestCase(const TestCaseStruct& testCase);
+
+ void RunTests();
+
+ void CollectResult(const std::string& id,
+ const std::string& description,
+ const TestResultsCollectorBase::FailStatus::Type status
+ = TestResultsCollectorBase::FailStatus::NONE,
+ const std::string& reason = std::string());
+
+ public:
+ class TestFailed
+ {
+ private:
+ std::string m_message;
+
+ public:
+ TestFailed()
+ {}
+
+ //! \brief Failed test message creator
+ //!
+ //! \param[in] aTest string for tested expression
+ //! \param[in] aFile source file name
+ //! \param[in] aLine source file line
+ //! \param[in] aMessage error message
+ TestFailed(const char* aTest,
+ const char* aFile,
+ int aLine,
+ const std::string &aMessage);
+
+ TestFailed(const std::string &message);
+
+ std::string GetMessage() const
+ {
+ return m_message;
+ }
+ };
+
+ class Ignored
+ {
+ private:
+ std::string m_message;
+
+ public:
+ Ignored()
+ {}
+
+ Ignored(const std::string &message) :
+ m_message(message)
+ {}
+
+ std::string GetMessage() const
+ {
+ return m_message;
+ }
+ };
+
+ void MarkAssertion();
+
+ void RegisterTest(const char *testName, TestCase proc);
+ void InitGroup(const char* name);
+
+ int ExecTestRunner(int argc, char *argv[]);
+ typedef std::vector<std::string> ArgsList;
+ int ExecTestRunner(const ArgsList& args);
+ bool getRunIgnored() const;
+ // The runner will terminate as soon as possible (after current test).
+ void Terminate();
+ bool GetAllowChildLogs();
+};
+
+typedef VcoreDPL::Singleton<TestRunner> TestRunnerSingleton;
+}
+} // namespace VcoreDPL
+
+#define RUNNER_TEST_GROUP_INIT(GroupName) \
+ static int Static##GroupName##Init() \
+ { \
+ VcoreDPL::Test::TestRunnerSingleton::Instance().InitGroup(#GroupName); \
+ return 0; \
+ } \
+ const int DPL_UNUSED Static##GroupName##InitVar = \
+ Static##GroupName##Init();
+
+#define RUNNER_TEST(Proc) \
+ void Proc(); \
+ static int Static##Proc##Init() \
+ { \
+ VcoreDPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc);\
+ return 0; \
+ } \
+ const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \
+ void Proc()
+
+#define RUNNER_ASSERT_MSG(test, message) \
+ do \
+ { \
+ VcoreDPL::Test::TestRunnerSingleton::Instance().MarkAssertion(); \
+ \
+ if (!(test)) \
+ { \
+ std::ostringstream assertMsg; \
+ assertMsg << message; \
+ throw VcoreDPL::Test::TestRunner::TestFailed(#test, \
+ __FILE__, \
+ __LINE__, \
+ assertMsg.str()); \
+ } \
+ } while (0)
+
+#define RUNNER_ASSERT(test) RUNNER_ASSERT_MSG(test, "")
+
+#define RUNNER_FAIL RUNNER_ASSERT(false)
+
+#define RUNNER_IGNORED_MSG(message) \
+ do { \
+ std::ostringstream assertMsg; \
+ assertMsg << message; \
+ throw VcoreDPL::Test::TestRunner::Ignored( assertMsg.str() ); \
+ } while (0)
+
+#endif // DPL_TEST_RUNNER_H
diff --git a/vcore/src/dpl/test/include/dpl/test/test_runner_child.h b/vcore/src/dpl/test/include/dpl/test/test_runner_child.h
new file mode 100644
index 0000000..86bf17e
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/test_runner_child.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013 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 test_runner_child.h
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of test runner
+ */
+#ifndef DPL_TEST_RUNNER_CHILD_H
+#define DPL_TEST_RUNNER_CHILD_H
+
+#include <dpl/test/test_runner.h>
+
+namespace VcoreDPL {
+namespace Test {
+
+class PipeWrapper : VcoreDPL::Noncopyable
+{
+ public:
+ enum Usage {
+ READONLY,
+ WRITEONLY
+ };
+
+ enum Status {
+ SUCCESS,
+ TIMEOUT,
+ ERROR
+ };
+
+ PipeWrapper();
+
+ bool isReady();
+
+ void setUsage(Usage usage);
+
+ virtual ~PipeWrapper();
+
+ Status send(int code, std::string &message);
+
+ Status receive(int &code, std::string &data, time_t deadline);
+
+ void closeAll();
+
+ protected:
+
+ std::string toBinaryString(int data);
+
+ void closeHelp(int desc);
+
+ Status writeHelp(const void *buffer, int size);
+
+ Status readHelp(void *buf, int size, time_t deadline);
+
+ static const int PIPE_CLOSED = -1;
+
+ int m_pipefd[2];
+};
+
+void RunChildProc(TestRunner::TestCase procChild);
+} // namespace Test
+} // namespace VcoreDPL
+
+#define RUNNER_CHILD_TEST(Proc) \
+ void Proc(); \
+ void Proc##Child(); \
+ static int Static##Proc##Init() \
+ { \
+ VcoreDPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
+ return 0; \
+ } \
+ const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \
+ void Proc(){ \
+ VcoreDPL::Test::RunChildProc(&Proc##Child); \
+ } \
+ void Proc##Child()
+
+#endif // DPL_TEST_RUNNER_CHILD_H
diff --git a/vcore/src/dpl/test/include/dpl/test/test_runner_multiprocess.h b/vcore/src/dpl/test/include/dpl/test/test_runner_multiprocess.h
new file mode 100644
index 0000000..3fbf6f7
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/test_runner_multiprocess.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013 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 test_runner_multiprocess.h
+ * @author Marcin Niesluchowski (m.niesluchow@samsung.com)
+ * @version 1.0
+ * @brief This file is the header file of multiprocess test runner
+ */
+#ifndef DPL_TEST_RUNNER_MULTIPROCESS_H
+#define DPL_TEST_RUNNER_MULTIPROCESS_H
+
+#include <dpl/test/test_runner_child.h>
+
+namespace VcoreDPL {
+namespace Test {
+
+class SimplePipeWrapper :
+ public PipeWrapper
+{
+ public:
+ SimplePipeWrapper();
+
+ virtual ~SimplePipeWrapper();
+
+ Status send(std::string &message);
+ Status receive(std::string &data, bool &empty, time_t deadline);
+};
+
+void RunMultiProc(TestRunner::TestCase procMulti);
+} // namespace Test
+} // namespace VcoreDPL
+
+#define RUNNER_MULTIPROCESS_TEST(Proc) \
+ void Proc(); \
+ void Proc##Multi(); \
+ static int Static##Proc##Init() \
+ { \
+ VcoreDPL::Test::TestRunnerSingleton::Instance().RegisterTest(#Proc, &Proc); \
+ return 0; \
+ } \
+ const int DPL_UNUSED Static##Proc##InitVar = Static##Proc##Init(); \
+ void Proc(){ \
+ VcoreDPL::Test::RunMultiProc(&Proc##Multi); \
+ } \
+ void Proc##Multi()
+
+#endif // DPL_TEST_RUNNER_MULTIPROCESS_H
diff --git a/vcore/src/dpl/test/include/dpl/test/value_separated_parser.h b/vcore/src/dpl/test/include/dpl/test/value_separated_parser.h
new file mode 100644
index 0000000..d679610
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/value_separated_parser.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013 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 value_separated_parser.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Parser for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_PARSER_H
+#define VALUE_SEPARATED_PARSER_H
+
+#include<string>
+#include<vector>
+#include<memory>
+
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/test/abstract_input_parser.h>
+
+namespace VcoreDPL {
+
+typedef std::vector<std::string> VSLine;
+typedef std::vector<VSLine> VSResult;
+typedef std::shared_ptr<VSResult> VSResultPtr;
+
+/**
+ * Value Seperated parser
+ *
+ * Requires following policy class:
+ *
+ * template<VSResultPtr>
+ * struct CSVParserPolicy
+ * {
+ * static bool SkipLine(VSLine & );
+ * static bool Validate(VSResultPtr& result);
+ * };
+ */
+template<class ParserPolicy>
+class VSParser : public AbstractInputParser<VSResultPtr, VSToken>
+{
+public:
+ VSParser() : m_switchLine(true), m_result(new VSResult()) {}
+
+ void ConsumeToken(std::unique_ptr<VSToken> && token)
+ {
+ if(m_switchLine)
+ {
+ m_result->push_back(VSLine());
+ m_switchLine = false;
+ }
+ if(token->isNewLine())
+ {
+ if(ParserPolicy::SkipLine(*m_result->rbegin()))
+ {
+ m_result->pop_back();
+ }
+ m_switchLine = true;
+ }
+ else
+ {
+ m_result->rbegin()->push_back(token->cell());
+ }
+ }
+
+ bool IsStateValid()
+ {
+ return ParserPolicy::Validate(m_result);
+ }
+
+ VSResultPtr GetResult() const
+ {
+ return m_result;
+ }
+
+private:
+ bool m_switchLine;
+ VSResultPtr m_result;
+};
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/include/dpl/test/value_separated_policies.h b/vcore/src/dpl/test/include/dpl/test/value_separated_policies.h
new file mode 100644
index 0000000..7c758a0
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/value_separated_policies.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 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 value_separated_policies.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Example policy classes for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_POLICIES_H
+#define VALUE_SEPARATED_POLICIES_H
+
+#include<string>
+#include<vector>
+#include<memory>
+
+namespace VcoreDPL {
+
+struct CSVTokenizerPolicy
+{
+ static std::string GetSeperators(); //cells in line are separated by given characters
+ static bool SkipEmpty(); //if cell is empty, shoudl I skip?
+ static void PrepareValue(std::string &); //transform each value
+ static bool TryAgainAtEnd(int); //read is nonblocking so dat may not be yet available, should I retry?
+};
+
+struct CSVParserPolicy
+{
+ static bool SkipLine(const std::vector<std::string> & ); //should I skip whole readline?
+ static bool Validate(std::shared_ptr<std::vector<std::vector<std::string> > > & result); //validate and adjust output data
+};
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/include/dpl/test/value_separated_reader.h b/vcore/src/dpl/test/include/dpl/test/value_separated_reader.h
new file mode 100644
index 0000000..a85eb1e
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/value_separated_reader.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013 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 value_separated_reader.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Reader for some value seperated files/data
+ *
+ * This is parser for files containing lines with values seperated with custom charaters.
+ * Purpose of this is to parse output similar to csv and hide (no need for rewriting)
+ * buffers, reads, code errors. Result is two dimensional array.
+ *
+ * Reader is designed as class configured with policies classes:
+ * http://en.wikipedia.org/wiki/Policy-based_design
+ */
+
+#ifndef VALUE_SEPARATED_READER_H
+#define VALUE_SEPARATED_READER_H
+
+#include<dpl/test/abstract_input_reader.h>
+#include<dpl/test/value_separated_tokenizer.h>
+#include<dpl/test/value_separated_parser.h>
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/test/value_separated_policies.h>
+
+namespace VcoreDPL {
+
+/**
+ * Reader for input with values separated with defined characters
+ *
+ * Usage:
+ * - define both policies classes for defining and customize exact behaviour of reader
+ * - make typedef for VSReader template instance with your policies
+ *
+ */
+template<class ParserPolicy, class TokenizerPolicy>
+class VSReader : public AbstractInputReader<VSResultPtr, VSToken>
+{
+public:
+ VSReader(std::shared_ptr<AbstractInput> wia)
+ : AbstractInputReader<VSResultPtr, VSToken>(wia,
+ std::unique_ptr<ParserBase>(new VSParser<ParserPolicy>()),
+ std::unique_ptr<TokenizerBase>(new VSTokenizer<TokenizerPolicy>()))
+ {}
+};
+
+typedef VSReader<CSVParserPolicy, CSVTokenizerPolicy> CSVReader;
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/include/dpl/test/value_separated_tokenizer.h b/vcore/src/dpl/test/include/dpl/test/value_separated_tokenizer.h
new file mode 100644
index 0000000..d45823f
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/value_separated_tokenizer.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013 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 value_separated_tokenizer.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Tokenizer for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_TOKENIZER_H
+#define VALUE_SEPARATED_TOKENIZER_H
+
+#include<dpl/test/abstract_input_tokenizer.h>
+#include<dpl/test/value_separated_tokens.h>
+#include<dpl/binary_queue.h>
+
+
+namespace VcoreDPL {
+
+/**
+ * Value Sperated tokenizer
+ *
+ * Requires following policy class:
+ *
+ * struct TokenizerPolicy
+ * {
+ * static std::string GetSeperators();
+ * static bool SkipEmpty();
+ * static void PrepareValue(std::string & value);
+ * };
+ */
+template<class TokenizerPolicy>
+class VSTokenizer : public AbstractInputTokenizer<VSToken>
+{
+public:
+ VSTokenizer() {}
+
+ void Reset(std::shared_ptr<AbstractInput> ia)
+ {
+ AbstractInputTokenizer<VSToken>::Reset(ia);
+ m_queue.Clear();
+ m_finished = false;
+ m_newline = false;
+ }
+
+ std::unique_ptr<VSToken> GetNextToken()
+ {
+ std::unique_ptr<VSToken> token;
+ std::string data;
+ char byte;
+ int tryNumber = 0;
+
+ while(true)
+ {
+ //check if newline was approched
+ if(m_newline)
+ {
+ token.reset(new VSToken());
+ m_newline = false;
+ return token;
+ }
+
+ //read next data
+ if(m_queue.Empty())
+ {
+ if(m_finished)
+ {
+ return token;
+ }
+ else
+ {
+ auto baptr = m_input->Read(4096);
+ if(baptr.get() == 0)
+ {
+ ThrowMsg(Exception::TokenizerError, "Input read failed");
+ }
+ if(baptr->Empty())
+ {
+ if(TokenizerPolicy::TryAgainAtEnd(tryNumber))
+ {
+ ++tryNumber;
+ continue;
+ }
+ m_finished = true;
+ return token;
+ }
+ m_queue.AppendMoveFrom(*baptr);
+ }
+ }
+
+ //process
+ m_queue.FlattenConsume(&byte, 1); //queue uses pointer to consume bytes, this do not causes reallocations
+ if(byte == '\n')
+ {
+ m_newline = true;
+ if(!data.empty() || !TokenizerPolicy::SkipEmpty())
+ {
+ ProduceString(token, data);
+ return token;
+ }
+ }
+ else if(TokenizerPolicy::GetSeperators().find(byte) != std::string::npos)
+ {
+ if(!data.empty() || !TokenizerPolicy::SkipEmpty())
+ {
+ ProduceString(token, data);
+ return token;
+ }
+ }
+ else
+ {
+ data += byte;
+ }
+ }
+ }
+
+ bool IsStateValid()
+ {
+ if(!m_queue.Empty() && m_finished) return false;
+ return true;
+ }
+
+protected:
+ void ProduceString(std::unique_ptr<VSToken> & token, std::string & data)
+ {
+ TokenizerPolicy::PrepareValue(data);
+ token.reset(new VSToken(data));
+ }
+
+ BinaryQueue m_queue;
+ bool m_finished;
+ bool m_newline;
+};
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/include/dpl/test/value_separated_tokens.h b/vcore/src/dpl/test/include/dpl/test/value_separated_tokens.h
new file mode 100644
index 0000000..f0e9938
--- /dev/null
+++ b/vcore/src/dpl/test/include/dpl/test/value_separated_tokens.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 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 value_separated_tokens.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief Token class for some value seperated files/data
+ */
+
+#ifndef VALUE_SEPARATED_TOKENS_H
+#define VALUE_SEPARATED_TOKENS_H
+
+#include<string>
+
+namespace VcoreDPL {
+
+class VSToken
+{
+public:
+ VSToken(const std::string & c);
+ VSToken(); //newline token - no new class to simplify
+ const std::string & cell() const;
+
+ bool isNewLine();
+private:
+ bool m_newline;
+ std::string m_cell;
+};
+
+}
+
+#endif
diff --git a/vcore/src/dpl/test/src/process_pipe.cpp b/vcore/src/dpl/test/src/process_pipe.cpp
new file mode 100644
index 0000000..11023f7
--- /dev/null
+++ b/vcore/src/dpl/test/src/process_pipe.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2013 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 process_pipe.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation pipe from process
+ */
+
+#include<dpl/test/process_pipe.h>
+#include<dpl/log/vcore_log.h>
+
+namespace VcoreDPL {
+
+ProcessPipe::ProcessPipe(PipeErrorPolicy err) : m_file(NULL), m_errPolicy(err)
+{
+}
+
+ProcessPipe::~ProcessPipe()
+{
+}
+
+void ProcessPipe::Open(const std::string & command)
+{
+ if(m_file != NULL)
+ {
+ ThrowMsg(Exception::DoubleOpen, "Trying to open pipe second time. Close it first");
+ }
+
+ std::string stdErrRedirection;
+ switch(m_errPolicy)
+ {
+ case PipeErrorPolicy::NONE: break;
+ case PipeErrorPolicy::OFF: stdErrRedirection = " 2>/dev/null"; break;
+ case PipeErrorPolicy::PIPE: stdErrRedirection = " 2>&1"; break;
+ default: break;
+ }
+
+ std::string fcommand = command + stdErrRedirection;
+ FILE * file = popen(fcommand.c_str(), "r");
+
+ // Throw an exception if an error occurred
+ if (file == NULL) {
+ ThrowMsg(FileInput::Exception::OpenFailed, fcommand);
+ }
+
+ // Save new descriptor
+ m_file = file;
+ m_fd = fileno(m_file);
+
+ VcoreLogD("Opened pipe: %s", fcommand.c_str());
+}
+
+void ProcessPipe::Close()
+{
+ if (m_fd == -1) {
+ return;
+ }
+
+ if (pclose(m_file) == -1) {
+ Throw(FileInput::Exception::CloseFailed);
+ }
+
+ m_fd = -1;
+ m_file = NULL;
+
+ VcoreLogD("Closed pipe");
+}
+
+}
diff --git a/vcore/src/dpl/test/src/test_results_collector.cpp b/vcore/src/dpl/test/src/test_results_collector.cpp
new file mode 100644
index 0000000..e64da8a
--- /dev/null
+++ b/vcore/src/dpl/test/src/test_results_collector.cpp
@@ -0,0 +1,984 @@
+/*
+ * 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 test_results_collector.h
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief Implementation file some concrete TestResulstsCollector
+ */
+#include <cstddef>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/colors.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/scoped_fclose.h>
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+#include <dpl/lexical_cast.h>
+#include <dpl/availability.h>
+
+#include <string>
+#include <string.h>
+#include <cstdio>
+#include <fstream>
+#include <sstream>
+#include <cstdlib>
+
+#define GREEN_RESULT_OK "[%s%s%s]\n", BOLD_GREEN_BEGIN, " OK ", \
+ BOLD_GREEN_END
+
+namespace VcoreDPL {
+namespace Test {
+namespace {
+const char *DEFAULT_HTML_FILE_NAME = "index.html";
+const char *DEFAULT_TAP_FILE_NAME = "results.tap";
+const char *DEFAULT_XML_FILE_NAME = "results.xml";
+
+bool ParseCollectorFileArg(const std::string &arg, std::string &filename)
+{
+ const std::string argname = "--file=";
+ if (arg.find(argname) == 0 ) {
+ filename = arg.substr(argname.size());
+ return true;
+ }
+ return false;
+}
+
+class Statistic
+{
+ public:
+ Statistic() :
+ m_failed(0),
+ m_ignored(0),
+ m_passed(0),
+ m_count(0)
+ {}
+
+ void AddTest(TestResultsCollectorBase::FailStatus::Type type)
+ {
+ ++m_count;
+ switch (type) {
+ case TestResultsCollectorBase::FailStatus::INTERNAL:
+ case TestResultsCollectorBase::FailStatus::FAILED: ++m_failed;
+ break;
+ case TestResultsCollectorBase::FailStatus::IGNORED: ++m_ignored;
+ break;
+ case TestResultsCollectorBase::FailStatus::NONE: ++m_passed;
+ break;
+ default:
+ Assert(false && "Bad FailStatus");
+ }
+ }
+
+ std::size_t GetTotal() const
+ {
+ return m_count;
+ }
+ std::size_t GetPassed() const
+ {
+ return m_passed;
+ }
+ std::size_t GetSuccesed() const
+ {
+ return m_passed;
+ }
+ std::size_t GetFailed() const
+ {
+ return m_failed;
+ }
+ std::size_t GetIgnored() const
+ {
+ return m_ignored;
+ }
+ float GetPassedOrIgnoredPercend() const
+ {
+ float passIgnoredPercent =
+ 100.0f * (static_cast<float>(m_passed)
+ + static_cast<float>(m_ignored))
+ / static_cast<float>(m_count);
+ return passIgnoredPercent;
+ }
+
+ private:
+ std::size_t m_failed;
+ std::size_t m_ignored;
+ std::size_t m_passed;
+ std::size_t m_count;
+};
+
+class ConsoleCollector :
+ public TestResultsCollectorBase
+{
+ public:
+ static TestResultsCollectorBase* Constructor();
+
+ private:
+ ConsoleCollector() {}
+
+ virtual void CollectCurrentTestGroupName(const std::string& name)
+ {
+ printf("Starting group %s\n", name.c_str());
+ m_currentGroup = name;
+ }
+
+ virtual void Finish()
+ {
+ using namespace VcoreDPL::Colors::Text;
+
+ // Show result
+ FOREACH(group, m_groupsStats) {
+ PrintStats(group->first, group->second);
+ }
+ PrintStats("All tests together", m_stats);
+ }
+
+ virtual void CollectResult(const std::string& id,
+ const std::string& /*description*/,
+ const FailStatus::Type status = FailStatus::NONE,
+ const std::string& reason = "")
+ {
+ using namespace VcoreDPL::Colors::Text;
+ std::string tmp = "'" + id + "' ...";
+
+ printf("Running test case %-60s", tmp.c_str());
+ switch (status) {
+ case TestResultsCollectorBase::FailStatus::NONE:
+ printf(GREEN_RESULT_OK);
+ break;
+ case TestResultsCollectorBase::FailStatus::FAILED:
+ PrintfErrorMessage(" FAILED ", reason, true);
+ break;
+ case TestResultsCollectorBase::FailStatus::IGNORED:
+ PrintfIgnoredMessage("Ignored ", reason, true);
+ break;
+ case TestResultsCollectorBase::FailStatus::INTERNAL:
+ PrintfErrorMessage("INTERNAL", reason, true);
+ break;
+ default:
+ Assert(false && "Bad status");
+ }
+ m_stats.AddTest(status);
+ m_groupsStats[m_currentGroup].AddTest(status);
+ }
+
+ void PrintfErrorMessage(const char* type,
+ const std::string& message,
+ bool verbosity)
+ {
+ using namespace VcoreDPL::Colors::Text;
+ if (verbosity) {
+ printf("[%s%s%s] %s%s%s\n",
+ BOLD_RED_BEGIN,
+ type,
+ BOLD_RED_END,
+ BOLD_YELLOW_BEGIN,
+ message.c_str(),
+ BOLD_YELLOW_END);
+ } else {
+ printf("[%s%s%s]\n",
+ BOLD_RED_BEGIN,
+ type,
+ BOLD_RED_END);
+ }
+ }
+
+ void PrintfIgnoredMessage(const char* type,
+ const std::string& message,
+ bool verbosity)
+ {
+ using namespace VcoreDPL::Colors::Text;
+ if (verbosity) {
+ printf("[%s%s%s] %s%s%s\n",
+ CYAN_BEGIN,
+ type,
+ CYAN_END,
+ BOLD_GOLD_BEGIN,
+ message.c_str(),
+ BOLD_GOLD_END);
+ } else {
+ printf("[%s%s%s]\n",
+ CYAN_BEGIN,
+ type,
+ CYAN_END);
+ }
+ }
+
+ void PrintStats(const std::string& title, const Statistic& stats)
+ {
+ using namespace VcoreDPL::Colors::Text;
+ printf("\n%sResults [%s]: %s\n", BOLD_GREEN_BEGIN,
+ title.c_str(), BOLD_GREEN_END);
+ printf("%s%s%3d%s\n",
+ CYAN_BEGIN,
+ "Total tests: ",
+ stats.GetTotal(),
+ CYAN_END);
+ printf(" %s%s%3d%s\n",
+ CYAN_BEGIN,
+ "Succeeded: ",
+ stats.GetPassed(),
+ CYAN_END);
+ printf(" %s%s%3d%s\n",
+ CYAN_BEGIN,
+ "Failed: ",
+ stats.GetFailed(),
+ CYAN_END);
+ printf(" %s%s%3d%s\n",
+ CYAN_BEGIN,
+ "Ignored: ",
+ stats.GetIgnored(),
+ CYAN_END);
+ }
+
+ Statistic m_stats;
+ std::map<std::string, Statistic> m_groupsStats;
+ std::string m_currentGroup;
+};
+
+TestResultsCollectorBase* ConsoleCollector::Constructor()
+{
+ return new ConsoleCollector();
+}
+
+class HtmlCollector :
+ public TestResultsCollectorBase
+{
+ public:
+ static TestResultsCollectorBase* Constructor();
+
+ private:
+ HtmlCollector() : m_filename(DEFAULT_HTML_FILE_NAME) {}
+
+ virtual void CollectCurrentTestGroupName(const std::string& name)
+ {
+ fprintf(m_fp.Get(), "<b>Starting group %s", name.c_str());
+ m_currentGroup = name;
+ }
+
+ virtual bool Configure()
+ {
+ m_fp.Reset(fopen(m_filename.c_str(), "w"));
+ if (!m_fp)
+ return false;
+
+ return true;
+ }
+ virtual std::string CollectorSpecificHelp() const
+ {
+ return "--file=<filename> - name of file for output\n"
+ " default - index.html\n";
+ }
+
+ virtual void Start(int count)
+ {
+ DPL_UNUSED_PARAM(count);
+ AssertMsg(!!m_fp, "File handle must not be null");
+ fprintf(m_fp.Get(),
+ "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0"
+ "Transitional//EN\" "
+ "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\""
+ ">\n");
+ fprintf(m_fp.Get(),
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" "
+ "lang=\"en\" dir=\"ltr\">\n");
+ fprintf(m_fp.Get(), "<body style=\"background-color: black;\">\n");
+ fprintf(m_fp.Get(), "<pre>\n");
+ fprintf(m_fp.Get(), "<font color=\"white\">\n");
+ }
+
+ virtual void Finish()
+ {
+ using namespace VcoreDPL::Colors::Html;
+ // Show result
+ FOREACH(group, m_groupsStats) {
+ PrintStats(group->first, group->second);
+ }
+ PrintStats("All tests together", m_stats);
+ fprintf(m_fp.Get(), "</font>\n");
+ fprintf(m_fp.Get(), "</pre>\n");
+ fprintf(m_fp.Get(), "</body>\n");
+ fprintf(m_fp.Get(), "</html>\n");
+ }
+
+ virtual bool ParseCollectorSpecificArg(const std::string& arg)
+ {
+ return ParseCollectorFileArg(arg, m_filename);
+ }
+
+ virtual void CollectResult(const std::string& id,
+ const std::string& /*description*/,
+ const FailStatus::Type status = FailStatus::NONE,
+ const std::string& reason = "")
+ {
+ using namespace VcoreDPL::Colors::Html;
+ std::string tmp = "'" + id + "' ...";
+
+ fprintf(m_fp.Get(), "Running test case %-100s", tmp.c_str());
+ switch (status) {
+ case TestResultsCollectorBase::FailStatus::NONE:
+ fprintf(m_fp.Get(), GREEN_RESULT_OK);
+ break;
+ case TestResultsCollectorBase::FailStatus::FAILED:
+ PrintfErrorMessage(" FAILED ", reason, true);
+ break;
+ case TestResultsCollectorBase::FailStatus::IGNORED:
+ PrintfIgnoredMessage("Ignored ", reason, true);
+ break;
+ case TestResultsCollectorBase::FailStatus::INTERNAL:
+ PrintfErrorMessage("INTERNAL", reason, true);
+ break;
+ default:
+ Assert(false && "Bad status");
+ }
+ m_groupsStats[m_currentGroup].AddTest(status);
+ m_stats.AddTest(status);
+ }
+
+ void PrintfErrorMessage(const char* type,
+ const std::string& message,
+ bool verbosity)
+ {
+ using namespace VcoreDPL::Colors::Html;
+ if (verbosity) {
+ fprintf(m_fp.Get(),
+ "[%s%s%s] %s%s%s\n",
+ BOLD_RED_BEGIN,
+ type,
+ BOLD_RED_END,
+ BOLD_YELLOW_BEGIN,
+ message.c_str(),
+ BOLD_YELLOW_END);
+ } else {
+ fprintf(m_fp.Get(),
+ "[%s%s%s]\n",
+ BOLD_RED_BEGIN,
+ type,
+ BOLD_RED_END);
+ }
+ }
+
+ void PrintfIgnoredMessage(const char* type,
+ const std::string& message,
+ bool verbosity)
+ {
+ using namespace VcoreDPL::Colors::Html;
+
+ if (verbosity) {
+ fprintf(m_fp.Get(),
+ "[%s%s%s] %s%s%s\n",
+ CYAN_BEGIN,
+ type,
+ CYAN_END,
+ BOLD_GOLD_BEGIN,
+ message.c_str(),
+ BOLD_GOLD_END);
+ } else {
+ fprintf(m_fp.Get(),
+ "[%s%s%s]\n",
+ CYAN_BEGIN,
+ type,
+ CYAN_END);
+ }
+ }
+
+ void PrintStats(const std::string& name, const Statistic& stats)
+ {
+ using namespace VcoreDPL::Colors::Html;
+ fprintf(
+ m_fp.Get(), "\n%sResults [%s]:%s\n", BOLD_GREEN_BEGIN,
+ name.c_str(), BOLD_GREEN_END);
+ fprintf(
+ m_fp.Get(), "%s%s%3d%s\n", CYAN_BEGIN,
+ "Total tests: ", stats.GetTotal(), CYAN_END);
+ fprintf(
+ m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN,
+ "Succeeded: ", stats.GetPassed(), CYAN_END);
+ fprintf(
+ m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN,
+ "Failed: ", stats.GetFailed(), CYAN_END);
+ fprintf(
+ m_fp.Get(), " %s%s%3d%s\n", CYAN_BEGIN,
+ "Ignored: ", stats.GetIgnored(), CYAN_END);
+ }
+
+ std::string m_filename;
+ ScopedFClose m_fp;
+ Statistic m_stats;
+ std::string m_currentGroup;
+ std::map<std::string, Statistic> m_groupsStats;
+};
+
+TestResultsCollectorBase* HtmlCollector::Constructor()
+{
+ return new HtmlCollector();
+}
+
+class XmlCollector :
+ public TestResultsCollectorBase
+{
+ public:
+ static TestResultsCollectorBase* Constructor();
+
+ private:
+ XmlCollector() : m_filename(DEFAULT_XML_FILE_NAME) {}
+
+ virtual void CollectCurrentTestGroupName(const std::string& name)
+ {
+ std::size_t pos = GetCurrentGroupPosition();
+ if (std::string::npos != pos) {
+ GroupFinish(pos);
+ FlushOutput();
+ m_stats = Statistic();
+ }
+
+ pos = m_outputBuffer.find("</testsuites>");
+ if (std::string::npos == pos) {
+ ThrowMsg(VcoreDPL::Exception, "Could not find test suites closing tag");
+ }
+ GroupStart(pos, name);
+ }
+
+ void GroupStart(const std::size_t pos, const std::string& name)
+ {
+ std::stringstream groupHeader;
+ groupHeader << "\n\t<testsuite";
+ groupHeader << " name=\"" << EscapeSpecialCharacters(name) << "\"";
+ groupHeader << R"( tests="1")"; // include SegFault
+ groupHeader << R"( failures="1")"; // include SegFault
+ groupHeader << R"( skipped="0")";
+ groupHeader << ">";
+
+ groupHeader << "\n\t\t<testcase name=\"unknown\" status=\"FAILED\">";
+ groupHeader <<
+ "\n\t\t\t<failure type=\"FAILED\" message=\"segmentation fault\"/>";
+ groupHeader << "\n\t\t</testcase>";
+
+ groupHeader << "\n\t</testsuite>";
+
+ m_outputBuffer.insert(pos - 1, groupHeader.str());
+ }
+
+ virtual bool Configure()
+ {
+ m_fp.Reset(fopen(m_filename.c_str(), "w"));
+ if (!m_fp)
+ return false;
+
+ return true;
+ }
+
+ virtual std::string CollectorSpecificHelp() const
+ {
+ return "--file=<filename> - name of file for output\n"
+ " default - results.xml\n";
+ }
+
+ virtual void Start(int count)
+ {
+ AssertMsg(!!m_fp, "File handle must not be null");
+ m_outputBuffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+ m_outputBuffer.append("<testsuites ");
+ if(count >= 0)
+ {
+ m_outputBuffer.append("total=\"");
+ m_outputBuffer.append(VcoreDPL::lexical_cast<std::string>(count));
+ m_outputBuffer.append("\"");
+ }
+ m_outputBuffer.append(" >\n</testsuites>");
+ FlushOutput();
+ }
+
+ virtual void Finish()
+ {
+ std::size_t pos = GetCurrentGroupPosition();
+ if (std::string::npos != pos) {
+ GroupFinish(pos);
+ FlushOutput();
+ }
+ }
+
+ virtual bool ParseCollectorSpecificArg(const std::string& arg)
+ {
+ return ParseCollectorFileArg(arg, m_filename);
+ }
+
+ virtual void CollectResult(const std::string& id,
+ const std::string& /*description*/,
+ const FailStatus::Type status = FailStatus::NONE,
+ const std::string& reason = "")
+ {
+ m_resultBuffer.erase();
+ m_resultBuffer.append("\t\t<testcase name=\"");
+ m_resultBuffer.append(EscapeSpecialCharacters(id));
+ m_resultBuffer.append("\"");
+ switch (status) {
+ case TestResultsCollectorBase::FailStatus::NONE:
+ m_resultBuffer.append(" status=\"OK\"/>\n");
+ break;
+ case TestResultsCollectorBase::FailStatus::FAILED:
+ m_resultBuffer.append(" status=\"FAILED\">\n");
+ PrintfErrorMessage("FAILED", EscapeSpecialCharacters(reason), true);
+ m_resultBuffer.append("\t\t</testcase>\n");
+ break;
+ case TestResultsCollectorBase::FailStatus::IGNORED:
+ m_resultBuffer.append(" status=\"Ignored\">\n");
+ PrintfIgnoredMessage("Ignored", EscapeSpecialCharacters(
+ reason), true);
+ m_resultBuffer.append("\t\t</testcase>\n");
+ break;
+ case TestResultsCollectorBase::FailStatus::INTERNAL:
+ m_resultBuffer.append(" status=\"FAILED\">\n");
+ PrintfErrorMessage("INTERNAL", EscapeSpecialCharacters(
+ reason), true);
+ m_resultBuffer.append("\t\t</testcase>");
+ break;
+ default:
+ Assert(false && "Bad status");
+ }
+ std::size_t group_pos = GetCurrentGroupPosition();
+ if (std::string::npos == group_pos) {
+ ThrowMsg(VcoreDPL::Exception, "No current group set");
+ }
+
+ std::size_t last_case_pos = m_outputBuffer.find(
+ "<testcase name=\"unknown\"",
+ group_pos);
+ if (std::string::npos == last_case_pos) {
+ ThrowMsg(VcoreDPL::Exception, "Could not find SegFault test case");
+ }
+ m_outputBuffer.insert(last_case_pos - 2, m_resultBuffer);
+
+ m_stats.AddTest(status);
+
+ UpdateGroupHeader(group_pos,
+ m_stats.GetTotal() + 1, // include SegFault
+ m_stats.GetFailed() + 1, // include SegFault
+ m_stats.GetIgnored());
+ FlushOutput();
+ }
+
+ std::size_t GetCurrentGroupPosition() const
+ {
+ return m_outputBuffer.rfind("<testsuite ");
+ }
+
+ void UpdateGroupHeader(const std::size_t groupPosition,
+ const unsigned int tests,
+ const unsigned int failures,
+ const unsigned int skipped)
+ {
+ UpdateElementAttribute(groupPosition, "tests", UIntToString(tests));
+ UpdateElementAttribute(groupPosition, "failures", UIntToString(failures));
+ UpdateElementAttribute(groupPosition, "skipped", UIntToString(skipped));
+ }
+
+ void UpdateElementAttribute(const std::size_t elementPosition,
+ const std::string& name,
+ const std::string& value)
+ {
+ std::string pattern = name + "=\"";
+
+ std::size_t start = m_outputBuffer.find(pattern, elementPosition);
+ if (std::string::npos == start) {
+ ThrowMsg(VcoreDPL::Exception,
+ "Could not find attribute " << name << " beginning");
+ }
+
+ std::size_t end = m_outputBuffer.find("\"", start + pattern.length());
+ if (std::string::npos == end) {
+ ThrowMsg(VcoreDPL::Exception,
+ "Could not find attribute " << name << " end");
+ }
+
+ m_outputBuffer.replace(start + pattern.length(),
+ end - start - pattern.length(),
+ value);
+ }
+
+ std::string UIntToString(const unsigned int value)
+ {
+ std::stringstream result;
+ result << value;
+ return result.str();
+ }
+
+ void GroupFinish(const std::size_t groupPosition)
+ {
+ std::size_t segFaultStart =
+ m_outputBuffer.find("<testcase name=\"unknown\"", groupPosition);
+ if (std::string::npos == segFaultStart) {
+ ThrowMsg(VcoreDPL::Exception,
+ "Could not find SegFault test case start position");
+ }
+ segFaultStart -= 2; // to erase tabs
+
+ std::string closeTag = "</testcase>";
+ std::size_t segFaultEnd = m_outputBuffer.find(closeTag, segFaultStart);
+ if (std::string::npos == segFaultEnd) {
+ ThrowMsg(VcoreDPL::Exception,
+ "Could not find SegFault test case end position");
+ }
+ segFaultEnd += closeTag.length() + 1; // to erase new line
+
+ m_outputBuffer.erase(segFaultStart, segFaultEnd - segFaultStart);
+
+ UpdateGroupHeader(groupPosition,
+ m_stats.GetTotal(),
+ m_stats.GetFailed(),
+ m_stats.GetIgnored());
+ }
+
+ void FlushOutput()
+ {
+ int fd = fileno(m_fp.Get());
+ if (-1 == fd) {
+ int error = errno;
+ ThrowMsg(VcoreDPL::Exception, VcoreDPL::GetErrnoString(error));
+ }
+
+ if (-1 == TEMP_FAILURE_RETRY(ftruncate(fd, 0L))) {
+ int error = errno;
+ ThrowMsg(VcoreDPL::Exception, VcoreDPL::GetErrnoString(error));
+ }
+
+ if (-1 == TEMP_FAILURE_RETRY(fseek(m_fp.Get(), 0L, SEEK_SET))) {
+ int error = errno;
+ ThrowMsg(VcoreDPL::Exception, VcoreDPL::GetErrnoString(error));
+ }
+
+ if (m_outputBuffer.size() !=
+ fwrite(m_outputBuffer.c_str(), 1, m_outputBuffer.size(),
+ m_fp.Get()))
+ {
+ int error = errno;
+ ThrowMsg(VcoreDPL::Exception, VcoreDPL::GetErrnoString(error));
+ }
+
+ if (-1 == TEMP_FAILURE_RETRY(fflush(m_fp.Get()))) {
+ int error = errno;
+ ThrowMsg(VcoreDPL::Exception, VcoreDPL::GetErrnoString(error));
+ }
+ }
+
+ void PrintfErrorMessage(const char* type,
+ const std::string& message,
+ bool verbosity)
+ {
+ if (verbosity) {
+ m_resultBuffer.append("\t\t\t<failure type=\"");
+ m_resultBuffer.append(EscapeSpecialCharacters(type));
+ m_resultBuffer.append("\" message=\"");
+ m_resultBuffer.append(EscapeSpecialCharacters(message));
+ m_resultBuffer.append("\"/>\n");
+ } else {
+ m_resultBuffer.append("\t\t\t<failure type=\"");
+ m_resultBuffer.append(EscapeSpecialCharacters(type));
+ m_resultBuffer.append("\"/>\n");
+ }
+ }
+
+ void PrintfIgnoredMessage(const char* type,
+ const std::string& message,
+ bool verbosity)
+ {
+ if (verbosity) {
+ m_resultBuffer.append("\t\t\t<skipped type=\"");
+ m_resultBuffer.append(EscapeSpecialCharacters(type));
+ m_resultBuffer.append("\" message=\"");
+ m_resultBuffer.append(EscapeSpecialCharacters(message));
+ m_resultBuffer.append("\"/>\n");
+ } else {
+ m_resultBuffer.append("\t\t\t<skipped type=\"");
+ m_resultBuffer.append(EscapeSpecialCharacters(type));
+ m_resultBuffer.append("\"/>\n");
+ }
+ }
+
+ std::string EscapeSpecialCharacters(std::string s)
+ {
+ for (unsigned int i = 0; i < s.size();) {
+ switch (s[i]) {
+ case '"':
+ s.erase(i, 1);
+ s.insert(i, "&quot;");
+ i += 6;
+ break;
+
+ case '&':
+ s.erase(i, 1);
+ s.insert(i, "&amp;");
+ i += 5;
+ break;
+
+ case '<':
+ s.erase(i, 1);
+ s.insert(i, "&lt;");
+ i += 4;
+ break;
+
+ case '>':
+ s.erase(i, 1);
+ s.insert(i, "&gt;");
+ i += 4;
+ break;
+
+ case '\'':
+ s.erase(i, 1);
+ s.insert(i, "&#39;");
+ i += 5;
+ break;
+ default:
+ ++i;
+ break;
+ }
+ }
+ return s;
+ }
+
+ std::string m_filename;
+ ScopedFClose m_fp;
+ Statistic m_stats;
+ std::string m_outputBuffer;
+ std::string m_resultBuffer;
+};
+
+TestResultsCollectorBase* XmlCollector::Constructor()
+{
+ return new XmlCollector();
+}
+
+class CSVCollector :
+ public TestResultsCollectorBase
+{
+ public:
+ static TestResultsCollectorBase* Constructor();
+
+ private:
+ CSVCollector() {}
+
+ virtual void Start(int count)
+ {
+ DPL_UNUSED_PARAM(count);
+ printf("GROUP;ID;RESULT;REASON\n");
+ }
+
+ virtual void CollectCurrentTestGroupName(const std::string& name)
+ {
+ m_currentGroup = name;
+ }
+
+ virtual void CollectResult(const std::string& id,
+ const std::string& /*description*/,
+ const FailStatus::Type status = FailStatus::NONE,
+ const std::string& reason = "")
+ {
+ std::string statusMsg = "";
+ switch (status) {
+ case TestResultsCollectorBase::FailStatus::NONE: statusMsg = "OK";
+ break;
+ case TestResultsCollectorBase::FailStatus::FAILED: statusMsg = "FAILED";
+ break;
+ case TestResultsCollectorBase::FailStatus::IGNORED: statusMsg =
+ "IGNORED";
+ break;
+ case TestResultsCollectorBase::FailStatus::INTERNAL: statusMsg =
+ "FAILED";
+ break;
+ default:
+ Assert(false && "Bad status");
+ }
+ printf("%s;%s;%s;%s\n",
+ m_currentGroup.c_str(),
+ id.c_str(),
+ statusMsg.c_str(),
+ reason.c_str());
+ }
+
+ std::string m_currentGroup;
+};
+
+TestResultsCollectorBase* CSVCollector::Constructor()
+{
+ return new CSVCollector();
+}
+}
+
+class TAPCollector :
+ public TestResultsCollectorBase
+{
+ public:
+ static TestResultsCollectorBase* Constructor();
+
+ private:
+ TAPCollector() : m_filename(DEFAULT_TAP_FILE_NAME) {}
+
+ virtual bool Configure()
+ {
+ m_output.open(m_filename.c_str(), std::ios_base::trunc);
+ if (m_output.fail())
+ return false;
+
+ return true;
+ }
+ virtual std::string CollectorSpecificHelp() const
+ {
+ std::string retVal = "--file=<filename> - name of file for output\n"
+ " default - ";
+ retVal += DEFAULT_TAP_FILE_NAME;
+ retVal += "\n";
+ return retVal;
+ }
+
+ virtual void Start(int count)
+ {
+ DPL_UNUSED_PARAM(count);
+ AssertMsg(m_output.good(), "Output file must be opened.");
+ m_output << "TAP version 13" << std::endl;
+ m_testIndex = 0;
+ }
+
+ virtual void Finish()
+ {
+ m_output << "1.." << m_testIndex << std::endl;
+ m_output << m_collectedData.rdbuf();
+ m_output.close();
+ }
+
+ virtual bool ParseCollectorSpecificArg(const std::string& arg)
+ {
+ return ParseCollectorFileArg(arg, m_filename);
+ }
+
+ virtual void CollectResult(const std::string& id,
+ const std::string& description,
+ const FailStatus::Type status = FailStatus::NONE,
+ const std::string& reason = "")
+ {
+ m_testIndex++;
+ switch (status) {
+ case TestResultsCollectorBase::FailStatus::NONE:
+ LogBasicTAP(true, id, description);
+ endTAPLine();
+ break;
+ case TestResultsCollectorBase::FailStatus::FAILED:
+ LogBasicTAP(false, id, description);
+ endTAPLine();
+ break;
+ case TestResultsCollectorBase::FailStatus::IGNORED:
+ LogBasicTAP(true, id, description);
+ m_collectedData << " # skip " << reason;
+ endTAPLine();
+ break;
+ case TestResultsCollectorBase::FailStatus::INTERNAL:
+ LogBasicTAP(true, id, description);
+ endTAPLine();
+ m_collectedData << " ---" << std::endl;
+ m_collectedData << " message: " << reason << std::endl;
+ m_collectedData << " severity: Internal" << std::endl;
+ m_collectedData << " ..." << std::endl;
+ break;
+ default:
+ Assert(false && "Bad status");
+ }
+ }
+
+ void LogBasicTAP(bool isOK, const std::string& id,
+ const std::string& description)
+ {
+ if (!isOK) {
+ m_collectedData << "not ";
+ }
+ m_collectedData << "ok " << m_testIndex << " [" <<
+ id << "] " << description;
+ }
+
+ void endTAPLine()
+ {
+ m_collectedData << std::endl;
+ }
+
+ std::string m_filename;
+ std::stringstream m_collectedData;
+ std::ofstream m_output;
+ int m_testIndex;
+};
+
+TestResultsCollectorBase* TAPCollector::Constructor()
+{
+ return new TAPCollector();
+}
+
+void TestResultsCollectorBase::RegisterCollectorConstructor(
+ const std::string& name,
+ TestResultsCollectorBase::CollectorConstructorFunc func)
+{
+ Assert(m_constructorsMap.find(name) == m_constructorsMap.end());
+ m_constructorsMap[name] = func;
+}
+
+TestResultsCollectorBase* TestResultsCollectorBase::Create(
+ const std::string& name)
+{
+ ConstructorsMap::iterator found = m_constructorsMap.find(name);
+ if (found != m_constructorsMap.end()) {
+ return found->second();
+ } else {
+ return NULL;
+ }
+}
+
+std::vector<std::string> TestResultsCollectorBase::GetCollectorsNames()
+{
+ std::vector<std::string> list;
+ FOREACH(it, m_constructorsMap)
+ {
+ list.push_back(it->first);
+ }
+ return list;
+}
+
+TestResultsCollectorBase::ConstructorsMap TestResultsCollectorBase::
+ m_constructorsMap;
+
+namespace {
+static int RegisterCollectorConstructors();
+static const int RegisterHelperVariable = RegisterCollectorConstructors();
+int RegisterCollectorConstructors()
+{
+ (void)RegisterHelperVariable;
+
+ TestResultsCollectorBase::RegisterCollectorConstructor(
+ "text",
+ &ConsoleCollector::Constructor);
+ TestResultsCollectorBase::RegisterCollectorConstructor(
+ "html",
+ &HtmlCollector::Constructor);
+ TestResultsCollectorBase::RegisterCollectorConstructor(
+ "csv",
+ &CSVCollector::Constructor);
+ TestResultsCollectorBase::RegisterCollectorConstructor(
+ "tap",
+ &TAPCollector::Constructor);
+ TestResultsCollectorBase::RegisterCollectorConstructor(
+ "xml",
+ &XmlCollector::Constructor);
+
+ return 0;
+}
+}
+}
+}
+#undef GREEN_RESULT_OK
diff --git a/vcore/src/dpl/test/src/test_runner.cpp b/vcore/src/dpl/test/src/test_runner.cpp
new file mode 100644
index 0000000..5002bfd
--- /dev/null
+++ b/vcore/src/dpl/test/src/test_runner.cpp
@@ -0,0 +1,696 @@
+/*
+ * 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 test_runner.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of test runner
+ */
+#include <stddef.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/exception.h>
+#include <dpl/free_deleter.h>
+#include <memory>
+#include <dpl/foreach.h>
+#include <dpl/colors.h>
+#include <pcrecpp.h>
+#include <algorithm>
+#include <cstdio>
+#include <memory.h>
+#include <libgen.h>
+#include <cstring>
+#include <cstdlib>
+
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <dpl/singleton_impl.h>
+IMPLEMENT_SINGLETON(VcoreDPL::Test::TestRunner)
+
+namespace {
+
+std::string getXMLNode(xmlNodePtr node)
+{
+ std::string ret;
+ xmlChar * value = xmlNodeGetContent(node);
+ if (value != NULL) {
+ ret = std::string(reinterpret_cast<char*>(value));
+ xmlFree(value);
+ }
+ return ret;
+}
+
+}
+
+
+namespace VcoreDPL {
+namespace Test {
+namespace // anonymous
+{
+std::string BaseName(std::string aPath)
+{
+ std::unique_ptr<char[],free_deleter> path(strdup(aPath.c_str()));
+ if (NULL == path.get()) {
+ throw std::bad_alloc();
+ }
+ char* baseName = basename(path.get());
+ std::string retValue = baseName;
+ return retValue;
+}
+} // namespace anonymous
+
+//! \brief Failed test message creator
+//!
+//! \param[in] aTest string for tested expression
+//! \param[in] aFile source file name
+//! \param[in] aLine source file line
+//! \param[in] aMessage error message
+TestRunner::TestFailed::TestFailed(const char* aTest,
+ const char* aFile,
+ int aLine,
+ const std::string &aMessage)
+{
+ std::ostringstream assertMsg;
+ assertMsg << "[" << BaseName(aFile) << ":" << aLine
+ << "] Assertion failed ("
+ << aTest << ") " << aMessage;
+ m_message = assertMsg.str();
+}
+
+TestRunner::TestFailed::TestFailed(const std::string &message)
+{
+ m_message = message;
+}
+
+void TestRunner::RegisterTest(const char *testName, TestCase proc)
+{
+ m_testGroups[m_currentGroup].push_back(TestCaseStruct(testName, proc));
+}
+
+void TestRunner::InitGroup(const char* name)
+{
+ m_currentGroup = name;
+}
+
+void TestRunner::normalizeXMLTag(std::string& str, const std::string& testcase)
+{
+ //Add testcase if missing
+ std::string::size_type pos = str.find(testcase);
+ if(pos != 0)
+ {
+ str = testcase + "_" + str;
+ }
+
+ //dpl test runner cannot have '-' character in name so it have to be replaced
+ // for TCT case to make comparision works
+ std::replace(str.begin(), str.end(), '-', '_');
+}
+
+bool TestRunner::filterGroupsByXmls(const std::vector<std::string> & files)
+{
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, XMLError)
+
+ const std::string idPath = "/test_definition/suite/set/testcase/@id";
+
+ bool success = true;
+ std::map<std::string, bool> casesMap;
+
+ std::string testsuite;
+ if(!m_testGroups.empty())
+ {
+ for(TestCaseGroupMap::const_iterator cit = m_testGroups.begin(); cit != m_testGroups.end(); ++cit)
+ {
+ if(!cit->second.empty())
+ {
+ for(TestCaseStructList::const_iterator cj = cit->second.begin(); cj != cit->second.end(); ++cj)
+ {
+ std::string name = cj->name;
+ std::string::size_type st = name.find('_');
+ if(st != std::string::npos)
+ {
+ name = name.substr(0, st);
+ testsuite = name;
+ break;
+ }
+ }
+ if(!testsuite.empty()) break;
+ }
+ }
+ }
+
+ xmlInitParser();
+ LIBXML_TEST_VERSION
+ xmlXPathInit();
+
+ Try
+ {
+ FOREACH(file, files)
+ {
+ xmlDocPtr doc;
+ xmlXPathContextPtr xpathCtx;
+
+ doc = xmlReadFile(file->c_str(), NULL, 0);
+ if (doc == NULL) {
+ ThrowMsg(XMLError, "File Problem");
+ } else {
+ //context
+ xpathCtx = xmlXPathNewContext(doc);
+ if (xpathCtx == NULL) {
+ ThrowMsg(XMLError,
+ "Error: unable to create new XPath context\n");
+ }
+ xpathCtx->node = xmlDocGetRootElement(doc);
+ }
+
+ std::string result;
+ xmlXPathObjectPtr xpathObject;
+ //get requested node's values
+ xpathObject = xmlXPathEvalExpression(BAD_CAST idPath.c_str(), xpathCtx);
+ if (xpathObject == NULL)
+ {
+ ThrowMsg(XMLError, "XPath evaluation failure: " << idPath);
+ }
+ xmlNodeSetPtr nodes = xpathObject->nodesetval;
+ unsigned size = (nodes) ? nodes->nodeNr : 0;
+ for(unsigned i = 0; i < size; ++i)
+ {
+ if (nodes->nodeTab[i]->type == XML_ATTRIBUTE_NODE) {
+ xmlNodePtr curNode = nodes->nodeTab[i];
+ result = getXMLNode(curNode);
+ normalizeXMLTag(result, testsuite);
+ casesMap.insert(make_pair(result, false));
+ }
+ }
+ //Cleanup of XPath data
+ xmlXPathFreeObject(xpathObject);
+ xmlXPathFreeContext(xpathCtx);
+ xmlFreeDoc(doc);
+ }
+ }
+ Catch(XMLError)
+ {
+ success = false;
+ }
+ xmlCleanupParser();
+
+ if(!filterByXML(casesMap))
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+bool TestRunner::filterByXML(std::map<std::string, bool> & casesMap)
+{
+ FOREACH(group, m_testGroups) {
+ TestCaseStructList newList;
+ FOREACH(iterator, group->second)
+ {
+ if (casesMap.find(iterator->name) != casesMap.end()) {
+ casesMap[iterator->name] = true;
+ newList.push_back(*iterator);
+ }
+ }
+ group->second = newList;
+ }
+ FOREACH(cs, casesMap)
+ {
+ if(cs->second == false)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+TestRunner::Status TestRunner::RunTestCase(const TestCaseStruct& testCase)
+{
+ try {
+ testCase.proc();
+ } catch (const TestFailed &e) {
+ // Simple test failure
+ CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::FAILED,
+ e.GetMessage());
+ return FAILED;
+ } catch (const Ignored &e) {
+ if (m_runIgnored) {
+ // Simple test have to be implemented
+ CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::IGNORED,
+ e.GetMessage());
+ }
+
+ return IGNORED;
+ } catch (const VcoreDPL::Exception &e) {
+ // DPL exception failure
+ CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::INTERNAL,
+ "DPL exception:" + e.GetMessage() + "\n" + e.DumpToString());
+
+ return FAILED;
+ } catch (const std::exception &) {
+ // std exception failure
+ CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::INTERNAL,
+ "std exception");
+
+ return FAILED;
+ } catch (...) {
+ // Unknown exception failure
+ CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::INTERNAL,
+ "unknown exception");
+
+ return FAILED;
+ }
+
+ CollectResult(testCase.name,
+ "",
+ TestResultsCollectorBase::FailStatus::NONE);
+
+ // Everything OK
+ return PASS;
+}
+
+void TestRunner::RunTests()
+{
+ using namespace VcoreDPL::Colors::Text;
+
+ Banner();
+
+ unsigned count = 0;
+ FOREACH(group, m_testGroups) {
+ count += group->second.size();
+ }
+
+ std::for_each(m_collectors.begin(),
+ m_collectors.end(),
+ [count] (const TestResultsCollectors::value_type & collector)
+ {
+ collector.second->Start(count);
+ });
+
+ fprintf(stderr, "%sFound %d testcases...%s\n", GREEN_BEGIN, count, GREEN_END);
+ fprintf(stderr, "%s%s%s\n", GREEN_BEGIN, "Running tests...", GREEN_END);
+ FOREACH(group, m_testGroups) {
+ TestCaseStructList list = group->second;
+ if (!list.empty()) {
+ std::for_each(
+ m_collectors.begin(),
+ m_collectors.end(),
+ [&group](const TestResultsCollectors::value_type & collector)
+ {
+ collector.second->
+ CollectCurrentTestGroupName(group->first);
+ });
+ list.sort();
+
+ for (TestCaseStructList::const_iterator iterator = list.begin();
+ iterator != list.end();
+ ++iterator)
+ {
+ TestCaseStruct test = *iterator;
+ if (m_startTestId == test.name) {
+ m_startTestId = "";
+ }
+
+ if (m_startTestId.empty()) {
+ RunTestCase(test);
+ }
+ if (m_terminate == true) {
+ // Terminate quietly without any logs
+ return;
+ }
+ }
+ }
+ }
+
+ std::for_each(m_collectors.begin(),
+ m_collectors.end(),
+ [] (const TestResultsCollectors::value_type & collector)
+ {
+ collector.second->Finish();
+ });
+
+ // Finished
+ fprintf(stderr, "%s%s%s\n\n", GREEN_BEGIN, "Finished", GREEN_END);
+}
+
+void TestRunner::CollectResult(
+ const std::string& id,
+ const std::string& description,
+ const TestResultsCollectorBase::FailStatus::Type status,
+ const std::string& reason)
+{
+ std::for_each(m_collectors.begin(),
+ m_collectors.end(),
+ [&](const TestResultsCollectors::value_type & collector)
+ {
+ collector.second->CollectResult(id,
+ description,
+ status,
+ reason);
+ });
+}
+
+void TestRunner::Banner()
+{
+ using namespace VcoreDPL::Colors::Text;
+ fprintf(stderr,
+ "%s%s%s\n",
+ BOLD_GREEN_BEGIN,
+ "DPL tests runner",
+ BOLD_GREEN_END);
+ fprintf(stderr,
+ "%s%s%s%s\n\n",
+ GREEN_BEGIN,
+ "Build: ",
+ __TIMESTAMP__,
+ GREEN_END);
+}
+
+void TestRunner::InvalidArgs(const std::string& message)
+{
+ using namespace VcoreDPL::Colors::Text;
+ fprintf(stderr,
+ "%s%s%s\n",
+ BOLD_RED_BEGIN,
+ message.c_str(),
+ BOLD_RED_END);
+}
+
+void TestRunner::Usage()
+{
+ fprintf(stderr, "Usage: runner [options]\n\n");
+ fprintf(stderr, "Output type:\n");
+ fprintf(stderr, " --output=<output type> --output=<output type> ...\n");
+ fprintf(stderr, "\n possible output types:\n");
+ FOREACH(type, TestResultsCollectorBase::GetCollectorsNames()) {
+ fprintf(stderr, " --output=%s\n", type->c_str());
+ }
+ fprintf(stderr, "\n example:\n");
+ fprintf(stderr,
+ " test-binary --output=text --output=xml --file=output.xml\n\n");
+ fprintf(stderr, "Other parameters:\n");
+ fprintf(stderr,
+ " --regexp='regexp'\t Only selected tests"
+ " which names match regexp run\n\n");
+ fprintf(stderr, " --start=<test id>\tStart from concrete test id");
+ fprintf(stderr, " --group=<group name>\t Run tests only from one group\n");
+ fprintf(stderr, " --runignored\t Run also ignored tests\n");
+ fprintf(stderr, " --list\t Show a list of Test IDs\n");
+ fprintf(stderr, " --listgroups\t Show a list of Test Group names \n");
+ fprintf(stderr, " --only-from-xml=<xml file>\t Run only testcases specified in XML file \n"
+ " XML name is taken from attribute id=\"part1_part2\" as whole.\n"
+ " If part1 is not found (no _) then it is implicitily "
+ "set according to suite part1 from binary tests\n");
+ fprintf(
+ stderr,
+ " --listingroup=<group name>\t Show a list of Test IDS in one group\n");
+ fprintf(stderr, " --allowchildlogs\t Allow to print logs from child process on screen.\n");
+ fprintf(stderr, " When active child process will be able to print logs on stdout and stderr.\n");
+ fprintf(stderr, " Both descriptors will be closed after test.\n");
+ fprintf(stderr, " --help\t This help\n\n");
+ std::for_each(m_collectors.begin(),
+ m_collectors.end(),
+ [] (const TestResultsCollectors::value_type & collector)
+ {
+ fprintf(stderr,
+ "Output %s has specific args:\n",
+ collector.first.c_str());
+ fprintf(stderr,
+ "%s\n",
+ collector.second->
+ CollectorSpecificHelp().c_str());
+ });
+ fprintf(stderr, "For bug reporting, please write to:\n");
+ fprintf(stderr, "<p.dobrowolsk@samsung.com>\n");
+}
+
+int TestRunner::ExecTestRunner(int argc, char *argv[])
+{
+ std::vector<std::string> args;
+ for (int i = 0; i < argc; ++i) {
+ args.push_back(argv[i]);
+ }
+ return ExecTestRunner(args);
+}
+
+void TestRunner::MarkAssertion()
+{
+ ++m_totalAssertions;
+}
+
+int TestRunner::ExecTestRunner(const ArgsList& value)
+{
+ m_runIgnored = false;
+ ArgsList args = value;
+ // Parse command line
+ if (args.size() == 1) {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+
+ args.erase(args.begin());
+
+ bool showHelp = false;
+ bool justList = false;
+ std::vector<std::string> xmlFiles;
+
+ TestResultsCollectorBasePtr currentCollector;
+
+ // Parse each argument
+ FOREACH(it, args)
+ {
+ std::string arg = *it;
+ const std::string regexp = "--regexp=";
+ const std::string output = "--output=";
+ const std::string groupId = "--group=";
+ const std::string runIgnored = "--runignored";
+ const std::string listCmd = "--list";
+ const std::string startCmd = "--start=";
+ const std::string listGroupsCmd = "--listgroups";
+ const std::string listInGroup = "--listingroup=";
+ const std::string allowChildLogs = "--allowchildlogs";
+ const std::string onlyFromXML = "--only-from-xml=";
+
+ if (currentCollector) {
+ if (currentCollector->ParseCollectorSpecificArg(arg)) {
+ continue;
+ }
+ }
+
+ if (arg.find(startCmd) == 0) {
+ arg.erase(0, startCmd.length());
+ FOREACH(group, m_testGroups) {
+ FOREACH(tc, group->second) {
+ if (tc->name == arg) {
+ m_startTestId = arg;
+ break;
+ }
+ }
+ if (!m_startTestId.empty()) {
+ break;
+ }
+ }
+ if (!m_startTestId.empty()) {
+ continue;
+ }
+ InvalidArgs();
+ fprintf(stderr, "Start test id has not been found\n");
+ Usage();
+ return 0;
+ } else if (arg.find(groupId) == 0) {
+ arg.erase(0, groupId.length());
+ TestCaseGroupMap::iterator found = m_testGroups.find(arg);
+ if (found != m_testGroups.end()) {
+ std::string name = found->first;
+ TestCaseStructList newList = found->second;
+ m_testGroups.clear();
+ m_testGroups[name] = newList;
+ } else {
+ fprintf(stderr, "Group %s not found\n", arg.c_str());
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+ } else if (arg == runIgnored) {
+ m_runIgnored = true;
+ } else if (arg == listCmd) {
+ justList = true;
+ } else if (arg == listGroupsCmd) {
+ FOREACH(group, m_testGroups) {
+ printf("GR:%s\n", group->first.c_str());
+ }
+ return 0;
+ } else if (arg.find(listInGroup) == 0) {
+ arg.erase(0, listInGroup.length());
+ FOREACH(test, m_testGroups[arg]) {
+ printf("ID:%s\n", test->name.c_str());
+ }
+ return 0;
+ } else if (arg.find(allowChildLogs) == 0) {
+ arg.erase(0, allowChildLogs.length());
+ m_allowChildLogs = true;
+ } else if (arg == "--help") {
+ showHelp = true;
+ } else if (arg.find(output) == 0) {
+ arg.erase(0, output.length());
+ if (m_collectors.find(arg) != m_collectors.end()) {
+ InvalidArgs(
+ "Multiple outputs of the same type are not supported!");
+ Usage();
+ return -1;
+ }
+ currentCollector.reset(TestResultsCollectorBase::Create(arg));
+ if (!currentCollector) {
+ InvalidArgs("Unsupported output type!");
+ Usage();
+ return -1;
+ }
+ m_collectors[arg] = currentCollector;
+ } else if (arg.find(regexp) == 0) {
+ arg.erase(0, regexp.length());
+ if (arg.length() == 0) {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+
+ if (arg[0] == '\'' && arg[arg.length() - 1] == '\'') {
+ arg.erase(0);
+ arg.erase(arg.length() - 1);
+ }
+
+ if (arg.length() == 0) {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+
+ pcrecpp::RE re(arg.c_str());
+ FOREACH(group, m_testGroups) {
+ TestCaseStructList newList;
+ FOREACH(iterator, group->second)
+ {
+ if (re.PartialMatch(iterator->name)) {
+ newList.push_back(*iterator);
+ }
+ }
+ group->second = newList;
+ }
+ } else if(arg.find(onlyFromXML) == 0) {
+ arg.erase(0, onlyFromXML.length());
+ if (arg.length() == 0) {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+
+ if (arg[0] == '\'' && arg[arg.length() - 1] == '\'') {
+ arg.erase(0);
+ arg.erase(arg.length() - 1);
+ }
+
+ if (arg.length() == 0) {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+
+ xmlFiles.push_back(arg);
+ } else {
+ InvalidArgs();
+ Usage();
+ return -1;
+ }
+ }
+
+ if(!xmlFiles.empty())
+ {
+ if(!filterGroupsByXmls(xmlFiles))
+ {
+ fprintf(stderr, "XML file is not correct\n");
+ return 0;
+ }
+ }
+
+ if(justList)
+ {
+ FOREACH(group, m_testGroups) {
+ FOREACH(test, group->second) {
+ printf("ID:%s:%s\n", group->first.c_str(), test->name.c_str());
+ }
+ }
+ return 0;
+ }
+
+ currentCollector.reset();
+
+ // Show help
+ if (showHelp) {
+ Usage();
+ return 0;
+ }
+
+ if (m_collectors.empty()) {
+ TestResultsCollectorBasePtr collector(
+ TestResultsCollectorBase::Create("text"));
+ m_collectors["text"] = collector;
+ }
+
+ for (auto it = m_collectors.begin(); it != m_collectors.end(); ++it) {
+ if (!it->second->Configure()) {
+ fprintf(stderr, "Could not configure selected output");
+ return 0;
+ }
+ }
+
+ // Run tests
+ RunTests();
+
+ return 0;
+}
+
+bool TestRunner::getRunIgnored() const
+{
+ return m_runIgnored;
+}
+
+void TestRunner::Terminate()
+{
+ m_terminate = true;
+}
+
+bool TestRunner::GetAllowChildLogs()
+{
+ return m_allowChildLogs;
+}
+
+}
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/test/src/test_runner_child.cpp b/vcore/src/dpl/test/src/test_runner_child.cpp
new file mode 100644
index 0000000..0ebe86c
--- /dev/null
+++ b/vcore/src/dpl/test/src/test_runner_child.cpp
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2013 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 test_runner_child.cpp
+ * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of test runner
+ */
+#include <stddef.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <dpl/test/test_results_collector.h>
+#include <dpl/binary_queue.h>
+#include <dpl/exception.h>
+#include <dpl/scoped_free.h>
+#include <dpl/foreach.h>
+#include <dpl/colors.h>
+#include <pcrecpp.h>
+#include <algorithm>
+#include <cstdio>
+#include <memory.h>
+#include <libgen.h>
+#include <cstring>
+#include <cstdlib>
+#include <ctime>
+#include <unistd.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+namespace {
+const int CHILD_TEST_FAIL = 0;
+const int CHILD_TEST_PASS = 1;
+const int CHILD_TEST_IGNORED = 2;
+
+int closeOutput() {
+ int devnull;
+ int retcode = -1;
+ if (-1 == (devnull = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY))))
+ return -1;
+
+ // replace stdout with /dev/null
+ if (-1 == TEMP_FAILURE_RETRY(dup2(devnull, STDOUT_FILENO)))
+ goto end;
+
+ // replace stderr with /dev/null
+ if (-1 == TEMP_FAILURE_RETRY(dup2(devnull, STDERR_FILENO)))
+ goto end;
+
+ retcode = 0;
+
+end:
+ close(devnull);
+ return retcode;
+}
+
+} // namespace anonymous
+
+namespace VcoreDPL {
+namespace Test {
+
+PipeWrapper::PipeWrapper()
+{
+ if (-1 == pipe(m_pipefd)) {
+ m_pipefd[0] = PIPE_CLOSED;
+ m_pipefd[1] = PIPE_CLOSED;
+ }
+}
+
+PipeWrapper::~PipeWrapper()
+{
+ closeHelp(0);
+ closeHelp(1);
+}
+
+bool PipeWrapper::isReady()
+{
+ return m_pipefd[0] != PIPE_CLOSED || m_pipefd[1] != PIPE_CLOSED;
+}
+
+void PipeWrapper::setUsage(Usage usage)
+{
+ if (usage == READONLY) {
+ closeHelp(1);
+ }
+ if (usage == WRITEONLY) {
+ closeHelp(0);
+ }
+}
+
+PipeWrapper::Status PipeWrapper::send(int code, std::string &message)
+{
+ if (m_pipefd[1] == PIPE_CLOSED) {
+ return ERROR;
+ }
+
+ std::ostringstream output;
+ output << toBinaryString(code);
+ output << toBinaryString(static_cast<int>(message.size()));
+ output << message;
+
+ std::string binary = output.str();
+ int size = binary.size();
+
+ if ((writeHelp(&size,
+ sizeof(int)) == ERROR) ||
+ (writeHelp(binary.c_str(), size) == ERROR))
+ {
+ return ERROR;
+ }
+ return SUCCESS;
+}
+
+PipeWrapper::Status PipeWrapper::receive(int &code, std::string &data, time_t deadline)
+{
+ if (m_pipefd[0] == PIPE_CLOSED) {
+ return ERROR;
+ }
+
+ int size;
+ Status ret;
+
+ if ((ret = readHelp(&size, sizeof(int), deadline)) != SUCCESS) {
+ return ret;
+ }
+
+ std::vector<char> buffer;
+ buffer.resize(size);
+
+ if ((ret = readHelp(&buffer[0], size, deadline)) != SUCCESS) {
+ return ret;
+ }
+
+ try {
+ VcoreDPL::BinaryQueue queue;
+ queue.AppendCopy(&buffer[0], size);
+
+ queue.FlattenConsume(&code, sizeof(int));
+ queue.FlattenConsume(&size, sizeof(int));
+
+ buffer.resize(size);
+
+ queue.FlattenConsume(&buffer[0], size);
+ data.assign(buffer.begin(), buffer.end());
+ } catch (VcoreDPL::BinaryQueue::Exception::Base &e) {
+ return ERROR;
+ }
+ return SUCCESS;
+}
+
+void PipeWrapper::closeAll()
+{
+ closeHelp(0);
+ closeHelp(1);
+}
+
+std::string PipeWrapper::toBinaryString(int data)
+{
+ char buffer[sizeof(int)];
+ memcpy(buffer, &data, sizeof(int));
+ return std::string(buffer, buffer + sizeof(int));
+}
+
+void PipeWrapper::closeHelp(int desc)
+{
+ if (m_pipefd[desc] != PIPE_CLOSED) {
+ TEMP_FAILURE_RETRY(close(m_pipefd[desc]));
+ m_pipefd[desc] = PIPE_CLOSED;
+ }
+}
+
+PipeWrapper::Status PipeWrapper::writeHelp(const void *buffer, int size)
+{
+ int ready = 0;
+ const char *p = static_cast<const char *>(buffer);
+ while (ready != size) {
+ int ret = write(m_pipefd[1], &p[ready], size - ready);
+
+ if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
+ continue;
+ }
+
+ if (ret == -1) {
+ closeHelp(1);
+ return ERROR;
+ }
+
+ ready += ret;
+ }
+ return SUCCESS;
+}
+
+PipeWrapper::Status PipeWrapper::readHelp(void *buf, int size, time_t deadline)
+{
+ int ready = 0;
+ char *buffer = static_cast<char*>(buf);
+ while (ready != size) {
+ time_t wait = deadline - time(0);
+ wait = wait < 1 ? 1 : wait;
+ pollfd fds = { m_pipefd[0], POLLIN, 0 };
+
+ int pollReturn = poll(&fds, 1, wait * 1000);
+
+ if (pollReturn == 0) {
+ return TIMEOUT; // Timeout
+ }
+
+ if (pollReturn < -1) {
+ return ERROR;
+ }
+
+ int ret = read(m_pipefd[0], &buffer[ready], size - ready);
+
+ if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
+ continue;
+ }
+
+ if (ret == -1 || ret == 0) {
+ closeHelp(0);
+ return ERROR;
+ }
+
+ ready += ret;
+ }
+ return SUCCESS;
+}
+
+void RunChildProc(TestRunner::TestCase procChild)
+{
+ PipeWrapper pipe;
+ if (!pipe.isReady()) {
+ throw TestRunner::TestFailed("Pipe creation failed");
+ }
+
+ pid_t pid = fork();
+
+ if (pid == -1) {
+ throw TestRunner::TestFailed("Child creation failed");
+ }
+
+ if (pid != 0) {
+ // parent code
+ pipe.setUsage(PipeWrapper::READONLY);
+
+ int code;
+ std::string message;
+
+ int pipeReturn = pipe.receive(code, message, time(0) + 10);
+
+ if (pipeReturn != PipeWrapper::SUCCESS) { // Timeout or reading error
+ pipe.closeAll();
+ kill(pid, SIGKILL);
+ }
+
+ int status;
+ waitpid(pid, &status, 0);
+
+ if (pipeReturn == PipeWrapper::TIMEOUT) {
+ throw TestRunner::TestFailed("Timeout");
+ }
+
+ if (pipeReturn == PipeWrapper::ERROR) {
+ throw TestRunner::TestFailed("Reading pipe error");
+ }
+
+ if (code == CHILD_TEST_FAIL) {
+ throw TestRunner::TestFailed(message);
+ } else if (code == CHILD_TEST_IGNORED) {
+ throw TestRunner::Ignored(message);
+ }
+ } else {
+ // child code
+
+ // End Runner after current test
+ TestRunnerSingleton::Instance().Terminate();
+
+ int code = CHILD_TEST_PASS;
+ std::string msg;
+
+ bool allowLogs = TestRunnerSingleton::Instance().GetAllowChildLogs();
+
+ close(STDIN_FILENO);
+ if (!allowLogs) {
+ closeOutput(); // if fails nothing we can do
+ }
+
+ pipe.setUsage(PipeWrapper::WRITEONLY);
+
+ try {
+ procChild();
+ } catch (const VcoreDPL::Test::TestRunner::TestFailed &e) {
+ msg = e.GetMessage();
+ code = CHILD_TEST_FAIL;
+ } catch (const VcoreDPL::Test::TestRunner::Ignored &e) {
+ msg = e.GetMessage();
+ code = CHILD_TEST_IGNORED;
+ } catch (...) { // catch all exception generated by "user" code
+ msg = "unhandled exeception";
+ code = CHILD_TEST_FAIL;
+ }
+
+ if (allowLogs) {
+ closeOutput();
+ }
+
+ pipe.send(code, msg);
+ }
+}
+} // namespace Test
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/test/src/test_runner_multiprocess.cpp b/vcore/src/dpl/test/src/test_runner_multiprocess.cpp
new file mode 100644
index 0000000..f377b1e
--- /dev/null
+++ b/vcore/src/dpl/test/src/test_runner_multiprocess.cpp
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2013 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 test_runner_multiprocess.cpp
+ * @author Marcin Niesluchowski (m.niesluchow@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of multiprocess test runner
+ */
+
+#include <sys/file.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <dpl/test/test_runner_multiprocess.h>
+#include <poll.h>
+#include <limits.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+namespace {
+
+const int MULTI_TEST_ERROR = -1;
+const int MULTI_TEST_PASS = 0;
+const int MULTI_TEST_FAILED = 1;
+const int MULTI_TEST_IGNORED = 2;
+const int MULTI_TEST_INTERNAL = 3;
+
+}
+
+namespace VcoreDPL {
+namespace Test {
+
+SimplePipeWrapper::SimplePipeWrapper()
+: PipeWrapper()
+{
+
+}
+
+SimplePipeWrapper::~SimplePipeWrapper()
+{
+
+}
+
+PipeWrapper::Status SimplePipeWrapper::send(std::string &message)
+{
+ if (m_pipefd[1] == PIPE_CLOSED) {
+ return ERROR;
+ }
+
+ if (message.size() > PIPE_BUF-1) {
+ return ERROR;
+ }
+
+ char buffer[PIPE_BUF] = { 0 };
+
+
+ for(unsigned int i = 0; i < message.size(); ++i) {
+ buffer[i] = message[i];
+ }
+
+ return writeHelp(buffer, PIPE_BUF);
+}
+
+PipeWrapper::Status SimplePipeWrapper::receive(std::string &data, bool &empty, time_t deadline)
+{
+ if (m_pipefd[0] == PIPE_CLOSED) {
+ return ERROR;
+ }
+
+ empty = false;
+
+ data.resize(PIPE_BUF);
+
+ char buffer[PIPE_BUF] = { 0 };
+
+ int ready = 0;
+ while (ready != PIPE_BUF) {
+ time_t wait = deadline - time(0);
+ wait = wait < 1 ? 1 : wait;
+ pollfd fds = { m_pipefd[0], POLLIN, 0 };
+
+ int pollReturn = poll(&fds, 1, wait * 1000);
+
+ if (pollReturn == 0) {
+ return TIMEOUT; // Timeout
+ }
+
+ if (pollReturn < -1) {
+ return ERROR;
+ }
+ int ret = read(m_pipefd[0], &buffer[ready], PIPE_BUF - ready);
+ if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
+ continue;
+ }
+
+ if (ret == -1) {
+ closeHelp(0);
+ return ERROR;
+ }
+ if (ret == 0) {
+ empty = true;
+ break;
+ }
+
+ ready += ret;
+ }
+
+
+ for(unsigned int i = 0; i < PIPE_BUF; ++i){
+ if(buffer[i] == 0) {
+ data.resize(i);
+ return SUCCESS;
+ }
+ data[i] = buffer[i];
+ }
+
+ return ERROR;
+}
+
+void RunMultiProc(TestRunner::TestCase procMulti)
+{
+ SimplePipeWrapper pipe;
+ int code = MULTI_TEST_PASS;
+ std::string msg = "";
+ int pipeReturn;
+
+ int waitStatus;
+
+ pid_t top_pid = getpid();
+
+ if (!pipe.isReady()) {
+ throw TestRunner::TestFailed("Pipe creation failed");
+ }
+ // pipe
+
+ try {
+ procMulti();
+ } catch (const TestRunner::TestFailed &e) {
+ code = MULTI_TEST_FAILED;
+ msg = e.GetMessage();
+ } catch (const TestRunner::Ignored &e) {
+ code = MULTI_TEST_IGNORED;
+ msg = e.GetMessage();
+ } catch (const VcoreDPL::Exception &e) {
+ code = MULTI_TEST_INTERNAL;
+ msg = "DPL exception:" + e.GetMessage();
+ } catch (const std::exception &) {
+ code = MULTI_TEST_INTERNAL;
+ msg = "std exception";
+ } catch (...) {
+ // Unknown exception failure
+ code = MULTI_TEST_INTERNAL;
+ msg = "unknown exception";
+ }
+
+ while (true) {
+ pid_t child_pid = wait(&waitStatus);
+ if (child_pid == -1) {
+ if (errno == ECHILD) {
+ if (top_pid == getpid()) {
+ std::string recMsg="";
+
+ pipe.setUsage(PipeWrapper::READONLY);
+
+ bool empty=false;
+ while(true) {
+ pipeReturn = pipe.receive(recMsg, empty, time(0) + 10);
+
+ if (empty) {
+ break;
+ }
+ if (pipeReturn == PipeWrapper::ERROR) {
+ pipe.closeAll();
+ throw TestRunner::TestFailed("Reading pipe error");
+ } else if (pipeReturn == PipeWrapper::TIMEOUT) {
+ pipe.closeAll();
+ throw TestRunner::TestFailed("Timeout error");
+ }
+ msg = msg + "\n" + recMsg;
+ }
+ pipe.closeAll();
+
+ switch(code) {
+ case MULTI_TEST_PASS:
+ return;
+ case MULTI_TEST_FAILED:
+ throw TestRunner::TestFailed(msg);
+ case MULTI_TEST_IGNORED:
+ throw TestRunner::Ignored(msg);
+ case MULTI_TEST_INTERNAL:
+ throw TestRunner::TestFailed(msg);
+ default:
+ throw TestRunner::TestFailed(msg);
+ }
+ } else {
+ pipe.setUsage(PipeWrapper::WRITEONLY);
+
+ pipeReturn = pipe.send(msg);
+
+ if (pipeReturn == PipeWrapper::ERROR) {
+ pipe.closeAll();
+ code = MULTI_TEST_ERROR;
+ }
+
+ exit(code);
+ }
+ }
+ } else if (WIFEXITED(waitStatus)) {
+ if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_FAILED) {
+ switch (code) {
+ case MULTI_TEST_PASS:
+ code = MULTI_TEST_FAILED;
+ break;
+ case MULTI_TEST_FAILED:
+ break;
+ case MULTI_TEST_IGNORED:
+ code = MULTI_TEST_FAILED;
+ break;
+ case MULTI_TEST_INTERNAL:
+ break;
+ default:
+ break;
+ }
+ } else if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_IGNORED) {
+ switch (code) {
+ case MULTI_TEST_PASS:
+ code = MULTI_TEST_IGNORED;
+ break;
+ case MULTI_TEST_FAILED:
+ break;
+ case MULTI_TEST_IGNORED:
+ break;
+ case MULTI_TEST_INTERNAL:
+ break;
+ default:
+ break;
+ }
+ } else if ((signed char)WEXITSTATUS(waitStatus) == MULTI_TEST_INTERNAL) {
+ switch (code) {
+ case MULTI_TEST_PASS:
+ code = MULTI_TEST_INTERNAL;
+ break;
+ case MULTI_TEST_FAILED:
+ code = MULTI_TEST_INTERNAL;
+ break;
+ case MULTI_TEST_IGNORED:
+ code = MULTI_TEST_INTERNAL;
+ break;
+ case MULTI_TEST_INTERNAL:
+ break;
+ default:
+ break;
+ }
+ } else if ((signed char)WEXITSTATUS(waitStatus) != MULTI_TEST_PASS) {
+ code = MULTI_TEST_ERROR;
+ msg = "PROCESS BAD CODE RETURN";
+ }
+ }
+ }
+}
+} // namespace Test
+} // namespace VcoreDPL
diff --git a/vcore/src/dpl/test/src/value_separated_policies.cpp b/vcore/src/dpl/test/src/value_separated_policies.cpp
new file mode 100644
index 0000000..4fc282a
--- /dev/null
+++ b/vcore/src/dpl/test/src/value_separated_policies.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013 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 value_separated_policies.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief ...
+ */
+
+#include<dpl/test/value_separated_policies.h>
+#include<dpl/foreach.h>
+
+namespace VcoreDPL {
+
+std::string CSVTokenizerPolicy::GetSeperators()
+{
+ return ",";
+}
+
+bool CSVTokenizerPolicy::SkipEmpty()
+{
+ return false;
+}
+
+void CSVTokenizerPolicy::PrepareValue(std::string &)
+{
+}
+
+bool CSVTokenizerPolicy::TryAgainAtEnd(int)
+{
+ return false;
+}
+
+bool CSVParserPolicy::SkipLine(const std::vector<std::string> & )
+{
+ return false;
+}
+
+bool CSVParserPolicy::Validate(std::shared_ptr<std::vector<std::vector<std::string> > > & result)
+{
+ int num = -1;
+ FOREACH(r, *result)
+ {
+ int size = r->size();
+ if(num != -1 && num != size)
+ return false;
+
+ num = size;
+ }
+ return true;
+}
+
+}
diff --git a/vcore/src/dpl/test/src/value_separated_tokens.cpp b/vcore/src/dpl/test/src/value_separated_tokens.cpp
new file mode 100644
index 0000000..03e4a45
--- /dev/null
+++ b/vcore/src/dpl/test/src/value_separated_tokens.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 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 value_separated_tokens.cpp
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief ...
+ */
+
+#include <dpl/test/value_separated_tokens.h>
+
+namespace VcoreDPL {
+
+VSToken::VSToken(const std::string & c) : m_newline(false), m_cell(c)
+{
+}
+
+VSToken::VSToken() : m_newline(true)
+{
+}
+
+const std::string & VSToken::cell() const
+{
+ return m_cell;
+}
+
+bool VSToken::isNewLine()
+{
+ return m_newline;
+}
+
+}
diff --git a/vcore/src/server/include/cert-server-logic.h b/vcore/src/server/include/cert-server-logic.h
new file mode 100644
index 0000000..a9960a5
--- /dev/null
+++ b/vcore/src/server/include/cert-server-logic.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2015 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 cert_svc_server_main.h
+ * @author Madhan A K (madhan.ak@samsung.com)
+ * @version 1.0
+ * @brief cert-server routines.
+ */
+
+#ifndef CERT_SVC_SERVER_MAIN_H_
+#define CERT_SVC_SERVER_MAIN_H_
+
+#include <db-util.h>
+
+int getCertificateDetailFromStore(sqlite3 *db_handle, int storeType, int certType, const char* pGname, char* pCertBuffer, size_t *certLength);
+
+int getCertificateDetailFromSystemStore(sqlite3 *db_handle, const char* pGname, char* pCertBuffer, size_t *certLength);
+
+int deleteCertificateFromStore(sqlite3 *db_handle, int storeType, const char* pGname);
+
+int getCertificateStatusFromStore(sqlite3 *db_handle, int storeType, const char* pGname, int *status);
+
+int setCertificateStatusToStore(sqlite3 *db_handle, int storeType, int is_root_app, const char* pGname, int status);
+
+int checkAliasExistsInStore(sqlite3 *db_handle, int storeType, const char* alias, int *status);
+
+int installCertificateToStore(sqlite3 *db_handle, int storeType, const char* pGname, const char *common_name, const char *private_key_gname, const char *associated_gname, const char *pCertBuffer, size_t certLength, int certType);
+
+int getCertificateListFromStore(sqlite3 *db_handle, int reqType, int storeType, int is_root_app, char **ppCertListBuffer, size_t *bufferLen, int *certCount);
+
+int getCertificateAliasFromStore(sqlite3 *db_handle, int storeType, const char* pGname, char* alias);
+
+int loadCertificatesFromStore(sqlite3 *db_handle, int storeType, const char* pGname, char **ppCertBlockBuffer, size_t *bufferLen, int *certBlockCount);
+
+int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t certLength);
+
+#endif
diff --git a/vcore/src/server/src/cert-server-logic.c b/vcore/src/server/src/cert-server-logic.c
new file mode 100644
index 0000000..f23f42b
--- /dev/null
+++ b/vcore/src/server/src/cert-server-logic.c
@@ -0,0 +1,1604 @@
+/**
+ * Copyright (c) 2015 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 cert-server-logic.c
+ * @author Madhan A K (madhan.ak@samsung.com)
+ * Kyungwook Tak (k.tak@samsung.com)
+ * @version 1.0
+ * @brief cert-server logic.
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <glib.h>
+#include <dirent.h>
+#include <sys/smack.h>
+#include <sys/socket.h>
+
+#include <ckmc/ckmc-manager.h>
+#include <ckmc/ckmc-error.h>
+
+#include <cert-service.h>
+#include <cert-service-debug.h>
+#include <cert-svc/cerror.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc-client.h>
+
+#include <cert-server-logic.h>
+
+char *add_shared_owner_prefix(const char *name)
+{
+ size_t alias_len = strlen(name) + strlen(ckmc_label_shared_owner) + strlen(ckmc_label_name_separator);
+ char *ckm_alias = (char *)malloc(alias_len + 1);
+ if (!ckm_alias) {
+ SLOGE("Failed to allocate memory");
+ return NULL;
+ }
+ memset(ckm_alias, 0, alias_len + 1);
+ strncat(ckm_alias, ckmc_label_shared_owner, alias_len + 1);
+ strncat(ckm_alias, ckmc_label_name_separator, alias_len + 1 - strlen(ckmc_label_shared_owner));
+ strncat(ckm_alias, name, alias_len + 1 - strlen(ckmc_label_shared_owner) + strlen(ckmc_label_name_separator));
+
+ return ckm_alias;
+}
+
+int ckmc_remove_alias_with_shared_owner_prefix(const char *name, int *result)
+{
+ char *ckm_alias = add_shared_owner_prefix(name);
+ if (!ckm_alias) {
+ SLOGE("Failed to allocate memory");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ *result = ckmc_remove_alias(ckm_alias);
+
+ free(ckm_alias);
+
+ return CERTSVC_SUCCESS;
+}
+
+char *get_complete_path(const char *str1, const char *str2)
+{
+ char *result = NULL;
+ int as_result;
+
+ if (!str1 || !str2)
+ return NULL;
+
+ if (str1[strlen(str1) - 1] != '/')
+ as_result = asprintf(&result, "%s/%s", str1, str2);
+ else
+ as_result = asprintf(&result, "%s%s", str1, str2);
+
+ if (as_result >= CERTSVC_SUCCESS)
+ return result;
+ else
+ return NULL;
+}
+
+/* TODO: root ssl file system refactor */
+int add_file_to_dir(const char* dir, const char* pGname, const char* pData, size_t dataLen)
+{
+ char *systemFile = get_complete_path(dir, pGname);
+ if (!systemFile) {
+ SLOGE("Failed to get system file path.");
+ return CERTSVC_FAIL;
+ }
+
+ char realFile[FILENAME_MAX] = {0};
+ if (!realpath(systemFile, realFile)) {
+ SLOGE("Failed to get realpath. systemFile[%s]", systemFile);
+ return CERTSVC_FAIL;
+ }
+
+ FILE *stream = fopen(realFile, "ab");
+ if (!stream) {
+ SLOGE("Fail to open file [%s]", realFile);
+ return CERTSVC_FAIL;
+ }
+
+ if (fwrite(pData, sizeof(char), dataLen, stream) != dataLen) {
+ SLOGE("Fail to write file in system store.");
+ fclose(stream);
+ return CERTSVC_FAIL;
+ }
+
+ fclose(stream);
+ return CERTSVC_SUCCESS;
+}
+
+int add_file_to_system_cert_dir(const char* pGname, const char* pData, size_t dataLen)
+{
+ return add_file_to_dir(SYSTEM_CERT_DIR, pGname, pData, dataLen);
+}
+
+/* TODO: root ssl file system refactor */
+int del_file_from_dir(const char* dir, const char *pGname)
+{
+ const char *systemFile = get_complete_path(dir, pGname);
+ if (!systemFile) {
+ SLOGE("Failed to construct source file path.");
+ return CERTSVC_FAIL;
+ }
+
+ char realFile[FILENAME_MAX] = {0};
+ if (!realpath(systemFile, realFile)) {
+ SLOGE("Failed to get realpath. systemFile[%s]", systemFile);
+ return CERTSVC_FAIL;
+ }
+
+ /* instead of removing the file, the file is trimmed to zero size */
+ FILE *stream = fopen(realFile, "wb");
+ if (!stream) {
+ SLOGE("Failed to open the file for writing, [%s].", realFile);
+ return CERTSVC_FAIL;
+ }
+
+ fclose(stream);
+ return CERTSVC_SUCCESS;
+}
+
+int del_file_from_system_cert_dir(const char *pGname)
+{
+ return del_file_from_dir(SYSTEM_CERT_DIR, pGname);
+}
+
+int execute_insert_update_query(sqlite3 *db_handle, char *query)
+{
+ if (!db_handle) {
+ SLOGE("Database not initialised.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ if (!query) {
+ SLOGE("Query is NULL.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ /* Begin transaction */
+ int result = sqlite3_exec(db_handle, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
+ if (result != SQLITE_OK) {
+ SLOGE("Failed to begin transaction.");
+ return CERTSVC_FAIL;
+ }
+
+ /* Executing command */
+ result = sqlite3_exec(db_handle, query, NULL, NULL, NULL);
+ if (result != SQLITE_OK) {
+ SLOGE("Failed to execute query (%s).", query);
+ return CERTSVC_FAIL;
+ }
+
+ /* Committing the transaction */
+ result = sqlite3_exec(db_handle, "COMMIT", NULL, NULL, NULL);
+ if (result) {
+ SLOGE("Failed to commit transaction. Roll back now.");
+ result = sqlite3_exec(db_handle, "ROLLBACK", NULL, NULL, NULL);
+ if (result != SQLITE_OK)
+ SLOGE("Failed to commit transaction. Roll back now.");
+
+ return CERTSVC_FAIL;
+ }
+
+ SLOGD("Transaction Commit and End.");
+
+ return CERTSVC_SUCCESS;
+}
+
+int execute_select_query(sqlite3 *db_handle, char *query, sqlite3_stmt **stmt)
+{
+ if (!db_handle || !query)
+ return CERTSVC_WRONG_ARGUMENT;
+
+ sqlite3_stmt *stmts = NULL;
+ if (sqlite3_prepare_v2(db_handle, query, strlen(query), &stmts, NULL) != SQLITE_OK) {
+ SLOGE("sqlite3_prepare_v2 failed [%s].", query);
+ return CERTSVC_FAIL;
+ }
+
+ *stmt = stmts;
+ return CERTSVC_SUCCESS;
+}
+
+int write_to_file(const char *fileName, const char *mode_of_writing, const char *certBuffer, size_t certLength)
+{
+ int result = CERTSVC_SUCCESS;
+ FILE *fp_write = NULL;
+
+ if (!certBuffer || certLength <= 0) {
+ SLOGE("Input buffer is NULL.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ if (!(fp_write = fopen(fileName, mode_of_writing))) {
+ SLOGE("Failed to open the file for writing, [%s].", fileName);
+ return CERTSVC_FAIL;
+ }
+
+ /* if mode of writing is to append, then goto end of file */
+ if (strcmp(mode_of_writing,"ab") == 0)
+ fseek(fp_write, 0L, SEEK_END);
+
+ if (fwrite(certBuffer, sizeof(char), certLength, fp_write) != certLength) {
+ SLOGE("Fail to write into file.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ /* adding empty line at the end */
+ fwrite("\n",sizeof(char), 1, fp_write);
+
+error:
+ if (fp_write)
+ fclose(fp_write);
+
+ return result;
+}
+
+int write_to_ca_cert_crt_file(const char *mode_of_writing, const char *certBuffer, size_t certLength)
+{
+ return write_to_file(CERTSVC_CRT_FILE_PATH, mode_of_writing, certBuffer, certLength);
+}
+
+int saveCertificateToStore(
+ const char *pGname,
+ const char *pData,
+ size_t dataLen)
+{
+ if (!pGname || !pData || dataLen < 1) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ ckmc_policy_s cert_policy;
+ cert_policy.password = NULL;
+ cert_policy.extractable = true;
+
+ ckmc_raw_buffer_s cert_data;
+ cert_data.data = (unsigned char *)pData;
+ cert_data.size = dataLen;
+
+ char *ckm_alias = add_shared_owner_prefix(pGname);
+ if (!ckm_alias) {
+ SLOGE("Failed to make alias. memory allocation error.");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ int result = ckmc_save_data(ckm_alias, cert_data, cert_policy);
+ free(ckm_alias);
+
+ if (result != CKMC_ERROR_NONE) {
+ SLOGE("Failed to save trusted data. ckm errcode[%d]", result);
+ return CERTSVC_FAIL;
+ }
+
+ return CERTSVC_SUCCESS;
+}
+
+int saveCertificateToSystemStore(
+ const char *pGname,
+ const char *pData,
+ size_t dataLen)
+{
+ if (!pGname || !pData || dataLen < 1) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ int result = add_file_to_system_cert_dir(pGname, pData, dataLen);
+ if (result != CERTSVC_SUCCESS)
+ SLOGE("Failed to store the certificate in store.");
+
+ return result;
+}
+
+int get_certificate_buffer_from_store(
+ sqlite3 *db_handle,
+ CertStoreType storeType,
+ const char *pGname,
+ char **certBuffer,
+ size_t *certSize)
+{
+ int result = CERTSVC_SUCCESS;
+ int records = 0;
+ char *tempBuffer = NULL;
+ char *query = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ if (!pGname) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ if (storeType != SYSTEM_STORE)
+ query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
+ ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
+ (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
+ else
+ query = sqlite3_mprintf("select certificate from ssl where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
+ pGname, ENABLED, ENABLED);
+
+ result = execute_select_query(db_handle, query, &stmt);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW || records == SQLITE_DONE) {
+ SLOGE("No valid records found for given gname [%s].",pGname);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ tempBuffer = (char *)malloc(sizeof(char) * VCORE_MAX_RECV_DATA_SIZE);
+ if (!tempBuffer) {
+ SLOGE("Fail to allocate memory");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ memset(tempBuffer, 0x00, VCORE_MAX_RECV_DATA_SIZE);
+
+ if (storeType == SYSTEM_STORE)
+ result = getCertificateDetailFromSystemStore(db_handle, pGname, tempBuffer, certSize);
+ else
+ result = getCertificateDetailFromStore(db_handle, storeType, PEM_CRT, pGname, tempBuffer, certSize);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to set request data.");
+ result = CERTSVC_WRONG_ARGUMENT;
+ goto error;
+ }
+
+ *certBuffer = tempBuffer;
+
+error:
+ if (result != CERTSVC_SUCCESS)
+ free(tempBuffer);
+
+ if (query)
+ sqlite3_free(query);
+
+ if (stmt)
+ sqlite3_finalize(stmt);
+
+ return result;
+}
+
+int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t certLength)
+{
+ int result = CERTSVC_SUCCESS;
+ int records = 0;
+ int count = 0;
+ int counter = 0;
+ char *pValue = NULL;
+ char *query = NULL;
+ const char *text;
+ sqlite3_stmt *stmt = NULL;
+
+ int storeType[4] = {SYSTEM_STORE, WIFI_STORE, VPN_STORE, EMAIL_STORE};
+
+ /* During install of a root certificate, the root certificate gets appended at
+ * the end to optimise the write operation onto ca-certificate.crt file. */
+ if (certBuffer && certLength > 0) {
+ result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to write to file.");
+ result = CERTSVC_FAIL;
+ }
+ goto error_and_exit;
+ }
+
+ while (count < 4) {
+ /* get the ssl certificate from database */
+ if (count == 0)
+ query = sqlite3_mprintf("select certificate from ssl where enabled=%d and is_root_app_enabled=%d", ENABLED, ENABLED);
+ else if (count > 0 && count < 4)
+ /* gets all the gname which is marked as root certificate and enabled = TRUE */
+ query = sqlite3_mprintf("select gname from %Q where is_root_cert=%d and enabled=%d and is_root_app_enabled=%d", \
+ ((count == 1)?"wifi":(count == 2)?"vpn":"email"), ENABLED, ENABLED, ENABLED);
+
+ result = execute_select_query(db_handle, query, &stmt);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ goto next;
+ }
+
+ /* update the ca-certificate.crt file */
+ while (1) {
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW || records == SQLITE_DONE) {
+ result = CERTSVC_SUCCESS;
+ break;
+ }
+
+ if (records == SQLITE_ROW) {
+ certLength = 0;
+ certBuffer = NULL;
+ pValue = NULL;
+
+ if (count == 0) {
+ /* gets the certificate from database for system store */
+ text = (const char *)sqlite3_column_text(stmt, 0);
+ if (text) {
+ certLength = strlen(text);
+ certBuffer = strndup(text, certLength);
+ }
+ } else {
+ /* gets the certificate from key-manager for other stores */
+ text = (const char *)sqlite3_column_text(stmt, 0);
+ if (text)
+ pValue = strndup(text, strlen(text));
+
+ result = get_certificate_buffer_from_store(db_handle, storeType[count], pValue, &certBuffer, &certLength);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to get certificate buffer from key-manager.");
+ goto error_and_exit;
+ }
+ }
+
+ if (certBuffer) {
+ if (counter++ == 0)
+ result = write_to_ca_cert_crt_file("wb", certBuffer, certLength);
+ else
+ result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to write to file.");
+ result = CERTSVC_FAIL;
+ goto error_and_exit;
+ }
+ }
+ }
+ }
+next:
+ count++;
+ if (query) {
+ sqlite3_free(query);
+ query = NULL;
+ }
+ }
+ SLOGD("Successfully updated ca-certificate.crt file.");
+
+error_and_exit:
+ if (query)
+ sqlite3_free(query);
+
+ if (stmt)
+ sqlite3_finalize(stmt);
+
+ return result;
+}
+
+int enable_disable_cert_status(
+ sqlite3 *db_handle,
+ CertStoreType storeType,
+ int is_root_app,
+ const char *pGname,
+ CertStatus status)
+{
+ int ckmc_result = CKMC_ERROR_UNKNOWN;
+ int result = CERTSVC_SUCCESS;
+ int records = 0;
+ size_t certSize = 0;
+ size_t certLength = 0;
+ char *certBuffer = NULL;
+ char *query = NULL;
+ const char *text = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ if (status != DISABLED && status != ENABLED) {
+ SLOGE("Invalid cert status");
+ return CERTSVC_INVALID_STATUS;
+ }
+
+ query = sqlite3_mprintf("select * from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
+ (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS || !stmt) {
+ SLOGE("Querying database failed.");
+ return CERTSVC_FAIL;
+ }
+
+ records = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ if (records != SQLITE_ROW) {
+ SLOGE("No valid records found.");
+ return CERTSVC_FAIL;
+ }
+
+ if (status == DISABLED) {
+ /* check certificate presence in disabled_certs table before inserting */
+ query = sqlite3_mprintf("select * from disabled_certs where gname=%Q", pGname);
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+ query = NULL;
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ return CERTSVC_FAIL;
+ }
+
+ records = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ if (records == SQLITE_ROW) {
+ SLOGE("Selected certificate identifier is already disabled.", pGname);
+ return CERTSVC_FAIL;
+ }
+
+ /* get certificate from keymanager*/
+ result = get_certificate_buffer_from_store(db_handle, storeType, pGname, &certBuffer, &certSize);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to get certificate buffer. result[%d]", result);
+ return result;
+ }
+
+ /* inserting the disabled certificate to disabled_certs table */
+ query = sqlite3_mprintf("insert into disabled_certs (gname, certificate) values (%Q, %Q)", pGname, certBuffer);
+ free(certBuffer);
+
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_insert_update_query(db_handle, query);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Insert to database failed.");
+ return result;
+ }
+
+ if (storeType != SYSTEM_STORE) {
+ result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
+
+ if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
+ SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
+ return CERTSVC_FAIL;
+ }
+
+ } else {
+ result = del_file_from_system_cert_dir(pGname);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Error in del_file_from_system_cert_dir. ret[%d]", result);
+ return result;
+ }
+ }
+ } else { /* moving the certificate to enabled state */
+ query = sqlite3_mprintf("select certificate from disabled_certs where gname=%Q", pGname);
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ return CERTSVC_FAIL;
+ }
+
+ records = sqlite3_step(stmt);
+ if (records == SQLITE_ROW) {
+ text = (const char *)sqlite3_column_text(stmt, 0);
+
+ if (!text) {
+ SLOGE("Invalid column text");
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ certBuffer = strndup(text, strlen(text));
+
+ sqlite3_finalize(stmt);
+
+ if (!certBuffer) {
+ SLOGE("Failed to allocate memory");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ certLength = strlen(certBuffer);
+
+ if (storeType == SYSTEM_STORE)
+ result = saveCertificateToSystemStore(pGname, certBuffer, certLength);
+ else
+ result = saveCertificateToStore(pGname, certBuffer, certLength);
+
+ free(certBuffer);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to save certificate to key-manager. ret[%d]", result);
+ return result;
+ }
+
+ query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_insert_update_query(db_handle, query);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Unable to delete certificate entry from database. ret[%d]", result);
+ return result;
+ }
+ }
+ }
+
+ if (is_root_app == ENABLED)
+ query = sqlite3_mprintf("update %Q set is_root_app_enabled=%d , enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
+ (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), status, status, pGname);
+ else
+ query = sqlite3_mprintf("update %Q set enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
+ (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), status, pGname);
+
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_insert_update_query(db_handle, query);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Update failed. ret[%d]", result);
+ return result;
+ }
+
+ return result;
+}
+
+int setCertificateStatusToStore(
+ sqlite3 *db_handle,
+ int storeType,
+ int is_root_app,
+ const char *pGname,
+ int status)
+{
+ if (!pGname) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ int result = enable_disable_cert_status(db_handle, storeType, is_root_app, pGname, status);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to disable certificate.");
+ return result;
+ }
+
+ SLOGD("Successfully updated the certificate status from %s to %s.",
+ (status == DISABLED) ? "ENABLED" : "DISABLED", (status == DISABLED) ? "DISABLED" : "ENABLED");
+ return CERTSVC_SUCCESS;
+}
+
+int getCertificateStatusFromStore(
+ sqlite3 *db_handle,
+ int storeType,
+ const char* pGname,
+ int *status)
+{
+ if (!pGname) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ char *query = sqlite3_mprintf("select gname, common_name, enabled from %Q where gname=%Q",\
+ ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
+ (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ sqlite3_stmt *stmt = NULL;
+ int result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS || !stmt) {
+ SLOGE("Querying database failed.");
+ *status = DISABLED;
+ return CERTSVC_FAIL;
+ }
+
+ result = sqlite3_step(stmt);
+ if (result != SQLITE_ROW || result == SQLITE_DONE) {
+ SLOGE("No valid records found.");
+ *status = DISABLED;
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ *status = sqlite3_column_int(stmt, 2);
+
+ sqlite3_finalize(stmt);
+
+ return CERTSVC_SUCCESS;
+}
+
+int check_alias_exist_in_database(
+ sqlite3 *db_handle,
+ CertStoreType storeType,
+ const char *alias,
+ int *status)
+{
+ sqlite3_stmt *stmt = NULL;
+
+ if (!alias || !status) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ char *query = sqlite3_mprintf("select * from %Q where common_name=%Q", ((storeType == WIFI_STORE)? "wifi" : \
+ (storeType == VPN_STORE)? "vpn" : "email"),alias);
+
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ int result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS || !stmt) {
+ SLOGE("Querying database failed.");
+ return CERTSVC_FAIL;
+ }
+
+ result = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+
+ if (result != SQLITE_ROW) {
+ SLOGD("No records found with the alias passed (%s).", alias);
+ *status = CERTSVC_TRUE;
+ } else {
+ SLOGD("Records found with the alias passed (%s).", alias);
+ *status = CERTSVC_FALSE;
+ }
+
+ return CERTSVC_SUCCESS;
+}
+
+int installCertificateToStore(
+ sqlite3 *db_handle,
+ int storeType,
+ const char *pGname,
+ const char *common_name,
+ const char *private_key_gname,
+ const char *associated_gname,
+ const char *dataBlock,
+ size_t dataBlockLen,
+ int certType)
+{
+ if ((!pGname)
+ || (certType == P12_END_USER && !common_name && !private_key_gname)
+ || (certType != P12_END_USER && !common_name && !associated_gname)) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ if (storeType != SYSTEM_STORE
+ && saveCertificateToStore(
+ pGname,
+ dataBlock,
+ dataBlockLen) != CERTSVC_SUCCESS) {
+ SLOGE("FAIL to save certificate to key-manager.");
+ return CERTSVC_FAIL;
+ }
+
+ if (certType == P12_PKEY) {
+ SLOGD("Don't save private key in store");
+ return CERTSVC_SUCCESS;
+ }
+
+ char *query = NULL;
+ if (certType == P12_END_USER && private_key_gname) {
+ query = sqlite3_mprintf("insert into %Q (gname, common_name, private_key_gname, associated_gname, enabled, is_root_app_enabled) "\
+ "values (%Q, %Q, %Q, %Q, %d, %d)",((storeType == WIFI_STORE)? "wifi" : \
+ (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, private_key_gname, pGname, ENABLED, ENABLED);
+ } else if (certType == PEM_CRT || certType == P12_TRUSTED) {
+ query = sqlite3_mprintf("insert into %Q (gname, common_name, is_root_cert, associated_gname, enabled, is_root_app_enabled) values "\
+ "(%Q, %Q, %d, %Q, %d, %d)", ((storeType == WIFI_STORE)? "wifi" : \
+ (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, ENABLED, associated_gname, ENABLED, ENABLED);
+ } else if (certType == P12_INTERMEDIATE) {
+ query = sqlite3_mprintf("insert into %Q (gname, common_name, associated_gname, enabled, is_root_app_enabled) values (%Q, %Q, %Q, %d, %d)", \
+ ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"),
+ pGname, common_name, associated_gname, ENABLED, ENABLED);
+ }
+
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ int result = execute_insert_update_query(db_handle, query);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Insert to database failed.");
+ return CERTSVC_FAIL;
+ }
+
+ return CERTSVC_SUCCESS;
+}
+
+int checkAliasExistsInStore(
+ sqlite3 *db_handle,
+ int storeType,
+ const char* alias,
+ int *status)
+{
+ if (!alias) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ *status = CERTSVC_FAIL;
+ int result = check_alias_exist_in_database(db_handle, storeType, alias, status);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to check_alias_exist_in_database. err[%d]", result);
+ return CERTSVC_FAIL;
+ }
+
+ if (*status == CERTSVC_TRUE) {
+ SLOGD("Alias (%s) does not exist in %s store.",
+ alias,
+ (storeType == VPN_STORE) ? "VPN" :
+ (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
+ } else {
+ SLOGD("Alias (%s) exist in %s store.",
+ alias,
+ (storeType == VPN_STORE) ? "VPN" :
+ (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
+ }
+
+ return CERTSVC_SUCCESS;
+}
+
+int getCertificateDetailFromStore(
+ sqlite3 *db_handle,
+ int storeType,
+ int certType,
+ const char *pGname,
+ char *pOutData,
+ size_t *size)
+{
+ int result = CERTSVC_SUCCESS;
+ int records = 0;
+ char *query = NULL;
+ const char *text = NULL;
+ sqlite3_stmt *stmt = NULL;
+ ckmc_raw_buffer_s *cert_data = NULL;
+
+ if (!pGname || !pOutData) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ /* start constructing query */
+ if (certType == P12_PKEY) {
+ /* From the given certificate identifier, get the associated_gname for the certificate.
+ * Then query the database for records matching the associated_gname to get the private key */
+ query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", \
+ ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), pGname);
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ return result;
+ }
+
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW) {
+ SLOGE("No valid records found.");
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ text = (const char *)sqlite3_column_text(stmt, 0);
+
+ if (!text) {
+ SLOGE("No valid column text");
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
+ ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), text, ENABLED, ENABLED);
+
+ sqlite3_finalize(stmt);
+ } else if (storeType != SYSTEM_STORE) {
+ query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
+ ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
+ (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
+ }
+
+ if (!query) {
+ SLOGE("Failed to generate query");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ return result;
+ }
+
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW) {
+ SLOGE("No valid records found.");
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ if (certType == P12_PKEY) {
+ if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
+ SLOGE("No valid column text");
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ pGname = text;
+ }
+
+ char *ckm_alias = add_shared_owner_prefix(pGname);
+ if (!ckm_alias) {
+ SLOGE("Failed to make alias. memory allocation error.");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = ckmc_get_data(ckm_alias, NULL, &cert_data);
+ free(ckm_alias);
+
+ sqlite3_finalize(stmt);
+
+ if (result != CKMC_ERROR_NONE) {
+ SLOGE("Failed to get certificate from key-manager. ckm ret[%d]", result);
+ *size = CERTSVC_FAIL;
+ return CERTSVC_FAIL;
+ }
+
+ memcpy(pOutData, cert_data->data, cert_data->size);
+ pOutData[cert_data->size] = 0;
+ *size = cert_data->size;
+
+ ckmc_buffer_free(cert_data);
+
+ return CERTSVC_SUCCESS;
+}
+
+int getCertificateDetailFromSystemStore(
+ sqlite3 *db_handle,
+ const char *pGname,
+ char *pOutData,
+ size_t *size)
+{
+ int result = CERTSVC_SUCCESS;
+ int records = 0;
+ size_t certLength = 0;
+ char *query = NULL;
+ const char *text = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ if (!pGname) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ query = sqlite3_mprintf("select certificate from ssl where gname=%Q and is_root_app_enabled=%d", \
+ pGname, ENABLED, ENABLED);
+ if (!query) {
+ SLOGE("Query is NULL.");
+ return CERTSVC_FAIL;
+ }
+
+ result = execute_select_query(db_handle, query, &stmt);
+ sqlite3_free(query);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ return result;
+ }
+
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW) {
+ SLOGE("No valid records found for passed gname [%s].", pGname);
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ text = (const char *)sqlite3_column_text(stmt, 0);
+
+ if (!text) {
+ SLOGE("Fail to sqlite3_column_text");
+ sqlite3_finalize(stmt);
+ return CERTSVC_FAIL;
+ }
+
+ certLength = strlen(text);
+ if (certLength >= 4096) {
+ sqlite3_finalize(stmt);
+ SLOGE("certificate is too long");
+ return CERTSVC_FAIL;
+ }
+
+ memcpy(pOutData, text, certLength);
+ pOutData[certLength] = 0;
+ *size = certLength;
+
+ sqlite3_finalize(stmt);
+ return CERTSVC_SUCCESS;
+}
+
+int deleteCertificateFromStore(sqlite3 *db_handle, int storeType, const char* pGname) {
+
+ int result = CERTSVC_SUCCESS;
+ int ckmc_result = CKMC_ERROR_UNKNOWN;
+ int records = 0;
+ char *query = NULL;
+ char *private_key_name = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ if (!pGname) {
+ SLOGE("Invalid input parameter passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ if (storeType != SYSTEM_STORE) {
+ /* start constructing query */
+ query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" :\
+ (storeType == VPN_STORE)? "vpn" : "email"), pGname);
+
+ result = execute_select_query(db_handle, query, &stmt);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ records = sqlite3_step(stmt);
+ if ((records != SQLITE_ROW) || (records == SQLITE_DONE)) {
+ SLOGE("No valid records found for passed gname [%s].",pGname);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ /* if a cert is having private-key in it, the private key should
+ * be deleted first from key-manager, then the actual cert */
+ if (sqlite3_column_text(stmt, 0) != NULL) {
+ private_key_name = strdup((const char *)sqlite3_column_text(stmt, 0));
+ result = ckmc_remove_alias_with_shared_owner_prefix(private_key_name, &ckmc_result);
+ if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
+ SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ }
+
+ /* removing the actual cert */
+ result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
+ if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
+ query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
+ result = execute_insert_update_query(db_handle, query);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Unable to delete certificate entry from database.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ }
+
+ if (query) {
+ sqlite3_free(query);
+ query = NULL;
+ }
+
+ if (stmt) {
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+ }
+
+ query = sqlite3_mprintf("delete from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
+ (storeType == VPN_STORE)? "vpn" : "email"), pGname);
+
+ result = execute_insert_update_query(db_handle, query);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Unable to delete certificate entry from database.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ } else {
+ SLOGE("Invalid store type passed.");
+ result = CERTSVC_INVALID_STORE_TYPE;
+ }
+ SLOGD("Success in deleting the certificate from store.");
+
+error:
+ if (query)
+ sqlite3_free(query);
+
+ if (stmt)
+ sqlite3_finalize(stmt);
+
+ free(private_key_name);
+ return result;
+}
+
+
+int getCertificateListFromStore(
+ sqlite3 *db_handle,
+ int reqType,
+ int storeType,
+ int is_root_app,
+ char **certListBuffer,
+ size_t *bufferLen,
+ int *certCount)
+{
+ int result = CERTSVC_SUCCESS;
+ CertSvcStoreCertList *rootCertHead = NULL;
+ CertSvcStoreCertList *tmpNode = NULL;
+ CertSvcStoreCertList *currentNode = NULL;
+ sqlite3_stmt *stmt = NULL;
+ char *query = NULL;
+ int loopCount = 0;
+ int records = 0;
+ int count = 0;
+ int i = 0;
+
+
+ while (1) {
+ /* Iteration only possible from VPN_STORE till SYSTEM_STORE */
+ if (loopCount == (MAX_STORE_ENUMS - 1))
+ break;
+
+ /* Check if the passed store type matches with any of the in-built store type */
+ if ((1 << loopCount) & storeType) {
+ /* if a store type matches, put that value as storetype argument in the below function */
+ CertStoreType tempStore = (CertStoreType) (1 << loopCount);
+ SLOGD("Processing storetype [%s]", (tempStore == WIFI_STORE)? "WIFI" : (tempStore == VPN_STORE)? "VPN" : \
+ (tempStore == EMAIL_STORE)? "EMAIL" : "SYSTEM");
+
+ if (reqType == CERTSVC_GET_ROOT_CERTIFICATE_LIST) {
+ // For get_root_certificate_list_from_store
+ if (storeType == SYSTEM_STORE) {
+ query = sqlite3_mprintf("select gname, common_name, enabled from %Q where enabled=%d "\
+ "and is_root_app_enabled=%d and order by common_name asc", "ssl", ENABLED, ENABLED);
+ } else {
+ query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
+ "is_root_cert IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
+ (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
+ (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
+ }
+ } else if (reqType == CERTSVC_GET_USER_CERTIFICATE_LIST) {
+ // For get_end_user_certificate_list_from_store
+ if (storeType == SYSTEM_STORE) {
+ SLOGE("Invalid store type passed.");
+ return CERTSVC_WRONG_ARGUMENT;
+ } else {
+ query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
+ "private_key_gname IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
+ (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
+ (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
+ }
+ } else {
+ // For get_certificate_list_from_store
+ if (is_root_app != ENABLED) {
+ /* Gets only the list of certificates where is_root_app = 1 (which are enabled by the master application) */
+ if (tempStore == SYSTEM_STORE) {
+ query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
+ "is_root_app_enabled=%d order by common_name asc", \
+ (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
+ (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
+ } else {
+ query = sqlite3_mprintf("select gname, common_name, enabled from %Q where is_root_app_enabled=%d", \
+ (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
+ (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
+ }
+ } else {
+ /* Gets all the certificates from store without any restrictions */
+ if (tempStore == SYSTEM_STORE) {
+ query = sqlite3_mprintf("select gname, common_name, enabled from %Q order by common_name asc", \
+ (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
+ (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
+ } else {
+ query = sqlite3_mprintf("select gname, common_name, enabled from %Q", \
+ (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
+ (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
+ }
+ }
+ }
+
+ result = execute_select_query(db_handle, query, &stmt);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ while (1) {
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW || records == SQLITE_DONE) {
+ if (count < 0) {
+ SLOGE("No records found");
+ result = CERTSVC_SUCCESS;
+ goto error;
+ } else {
+ break;
+ }
+ }
+
+ if (records == SQLITE_ROW) {
+ tmpNode = (CertSvcStoreCertList *)malloc(sizeof(CertSvcStoreCertList));
+ if (!tmpNode) {
+ SLOGE("Failed to allocate memory.");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ } else {
+ tmpNode->next = NULL;
+ const char *textGname = (const char *)sqlite3_column_text(stmt, 0);
+ const char *textAlias = (const char *)sqlite3_column_text(stmt, 1);
+ if (!textGname || !textAlias) {
+ SLOGE("Failed to read texts from records");
+ free(tmpNode);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ int gnameLen = strlen(textGname);
+ int aliasLen = strlen(textAlias);
+
+ tmpNode->gname = (char *)malloc(sizeof(char) * (gnameLen + 1));
+ tmpNode->title = (char *)malloc(sizeof(char) * (aliasLen + 1));
+ if (!tmpNode->title || !tmpNode->gname) {
+ free(tmpNode->gname);
+ free(tmpNode->title);
+ free(tmpNode);
+ SLOGE("Failed to allocate memory");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ }
+
+ memset(tmpNode->gname, 0x00, gnameLen + 1);
+ memset(tmpNode->title, 0x00, aliasLen + 1);
+
+ memcpy(tmpNode->gname, textGname, gnameLen);
+ memcpy(tmpNode->title, textAlias, aliasLen);
+
+ tmpNode->status = (int)sqlite3_column_int(stmt, 2); /* for status */
+ tmpNode->storeType = tempStore;
+ }
+
+ /* When multiple stores are passed, we need to ensure that the rootcerthead is
+ assigned to currentNode once, else previous store data gets overwritten */
+ if (count == 0) {
+ rootCertHead = tmpNode;
+ currentNode = rootCertHead;
+ tmpNode = NULL;
+ } else {
+ currentNode->next = tmpNode;
+ currentNode = tmpNode;
+ tmpNode = NULL;
+ }
+ count++;
+ }
+ }
+
+ if (count <=0 ) {
+ SLOGD("No entries found in database.");
+ result = CERTSVC_SUCCESS;
+ }
+
+ if (query) {
+ sqlite3_free(query);
+ query = NULL;
+ }
+
+ if (stmt) {
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+ }
+ }
+ loopCount++;
+ }
+
+ *certCount = count;
+ VcoreCertResponseData *respCertData = (VcoreCertResponseData *)malloc(count * sizeof(VcoreCertResponseData));
+ if (!respCertData) {
+ SLOGE("Failed to allocate memory");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ }
+ if (count > 0)
+ memset(respCertData, 0x00, count * sizeof(VcoreCertResponseData));
+ VcoreCertResponseData* currRespCertData = NULL;
+
+ currentNode = rootCertHead;
+ for (i = 0; i < count; i++) {
+ tmpNode = currentNode->next;
+
+ currRespCertData = respCertData + i;
+ if (strlen(currentNode->gname) > sizeof(currRespCertData->gname)
+ || strlen(currentNode->title) > sizeof(currRespCertData->title)) {
+ SLOGE("String is too long. [%s], [%s]", currentNode->gname, currentNode->title);
+ result = CERTSVC_FAIL;
+ *certListBuffer = NULL;
+ free(respCertData);
+ goto error;
+ }
+ strncpy(currRespCertData->gname, currentNode->gname, strlen(currentNode->gname));
+ strncpy(currRespCertData->title, currentNode->title, strlen(currentNode->title));
+ currRespCertData->status = currentNode->status;
+ currRespCertData->storeType = currentNode->storeType;
+ //SLOGD("get cert list: %d th cert: gname=%s, title=%s, status=%d, storeType=%d", i, currRespCertData->gname, currRespCertData->title, currRespCertData->status, currRespCertData->storeType);
+
+ currentNode = tmpNode;
+ }
+
+ *certListBuffer = (char *) respCertData;
+ *bufferLen = count * sizeof(VcoreCertResponseData);
+
+ SLOGD("Success to create certificate list. cert_count=%d", count);
+ result= CERTSVC_SUCCESS;
+error:
+ if (query)
+ sqlite3_free(query);
+
+ if (stmt)
+ sqlite3_finalize(stmt);
+
+ if (rootCertHead) {
+ currentNode = rootCertHead;
+ while (currentNode) {
+ tmpNode = currentNode->next;
+ free(currentNode->title);
+ free(currentNode->gname);
+ free(currentNode);
+ currentNode=tmpNode;
+ }
+ rootCertHead = NULL;
+ }
+
+ return result;
+}
+
+int getCertificateAliasFromStore(sqlite3 *db_handle, int storeType, const char* gname, char* alias)
+{
+ int result = CERTSVC_SUCCESS;
+ int records = 0;
+ sqlite3_stmt *stmt = NULL;
+ char *query = NULL;
+ const char *text = NULL;
+
+ query = sqlite3_mprintf("select common_name from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
+ (storeType==VPN_STORE)? "vpn" : "email"), gname);
+
+ result = execute_select_query(db_handle, query, &stmt);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW || records == SQLITE_DONE) {
+ SLOGE("No valid records found for gname passed [%s].",gname);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
+ SLOGE("No column text in returned records");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ strncpy(alias, text, strlen(text));
+
+ if (strlen(alias) == 0) {
+ SLOGE("Unable to get the alias name for the gname passed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ result = CERTSVC_SUCCESS;
+
+ SLOGD("success : getCertificateAliasFromStore");
+error:
+ if (query)
+ sqlite3_free(query);
+
+ if (stmt)
+ sqlite3_finalize(stmt);
+
+ return result;
+}
+
+int loadCertificatesFromStore(
+ sqlite3 *db_handle,
+ int storeType,
+ const char* gname,
+ char **ppCertBlockBuffer,
+ size_t *bufferLen,
+ int *certBlockCount)
+{
+ int result = CERTSVC_SUCCESS;
+ int count = 0;
+ int records = 0;
+ sqlite3_stmt *stmt = NULL;
+ char *query = NULL;
+ char **certs = NULL;
+ const char *tmpText = NULL;
+ int i = 0;
+
+ query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
+ (storeType==VPN_STORE)? "vpn" : "email"), gname);
+
+ result = execute_select_query(db_handle, query, &stmt);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW || records == SQLITE_DONE) {
+ SLOGE("No valid records found for gname passed [%s].",gname);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+
+ if (records == SQLITE_ROW) {
+ if (query)
+ sqlite3_free(query);
+
+ const char *columnText = (const char *)sqlite3_column_text(stmt, 0);
+ if (!columnText) {
+ SLOGE("Failed to sqlite3_column_text");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ query = sqlite3_mprintf("select gname from %Q where associated_gname=%Q and enabled=%d and is_root_app_enabled=%d", \
+ ((storeType==WIFI_STORE)? "wifi" : (storeType==VPN_STORE)? "vpn" : "email"), \
+ columnText, ENABLED, ENABLED);
+
+ if (stmt)
+ sqlite3_finalize(stmt);
+
+ result = execute_select_query(db_handle, query, &stmt);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Querying database failed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ while (1) {
+ records = sqlite3_step(stmt);
+ if (records != SQLITE_ROW || records == SQLITE_DONE)
+ break;
+
+ if (count == 0) {
+ certs = (char**) malloc(4 * sizeof(char *));
+ if (!certs) {
+ SLOGE("Failed to allocate memory");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ }
+ memset(certs, 0x00, 4 * sizeof(char *));
+ }
+
+ if (records == SQLITE_ROW) {
+ tmpText = (const char *)sqlite3_column_text(stmt, 0);
+ if (!tmpText) {
+ SLOGE("Failed to sqlite3_column_text.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ if (!((certs)[count] = strdup(tmpText))) {
+ SLOGE("Failed to allocate memory");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ }
+ }
+
+ count++;
+ }
+
+ if (count == 0) {
+ SLOGE("No valid records found for the gname passed [%s].",gname);
+ return CERTSVC_FAIL;
+ }
+ }
+
+ *certBlockCount = count;
+ *bufferLen = count * sizeof(ResponseCertBlock);
+ ResponseCertBlock *certBlockList = (ResponseCertBlock *) malloc(*bufferLen);
+ if (!certBlockList) {
+ SLOGE("Failed to allocate memory for ResponseCertBlock");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ }
+
+ if (count > 0)
+ memset(certBlockList, 0x00, *bufferLen);
+
+ ResponseCertBlock *currentBlock = NULL;
+ for (i = 0; i < count; i++) {
+ currentBlock = certBlockList + i;
+ if (sizeof(currentBlock->dataBlock) < strlen(certs[i])) {
+ SLOGE("src is longer than dst. src[%s] dst size[%d]", certs[i], sizeof(currentBlock->dataBlock));
+ free(certBlockList);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ strncpy(currentBlock->dataBlock, certs[i], strlen(certs[i]));
+ currentBlock->dataBlockLen = strlen(certs[i]);
+ }
+ *ppCertBlockBuffer = (char *)certBlockList;
+
+ result = CERTSVC_SUCCESS;
+
+ SLOGD("success: loadCertificatesFromStore. CERT_COUNT=%d", count);
+
+error:
+ if (query)
+ sqlite3_free(query);
+
+ if (stmt)
+ sqlite3_finalize(stmt);
+
+ if (certs) {
+ for(i = 0; i < count; i++)
+ free(certs[i]);
+
+ free(certs);
+ }
+
+ return result;
+}
diff --git a/vcore/src/server/src/cert-server-main.c b/vcore/src/server/src/cert-server-main.c
new file mode 100644
index 0000000..7624a50
--- /dev/null
+++ b/vcore/src/server/src/cert-server-main.c
@@ -0,0 +1,479 @@
+/**
+ * Copyright (c) 2015 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 cert-server-main.c
+ * @author Madhan A K (madhan.ak@samsung.com)
+ * Kyungwook Tak (k.tak@samsung.com)
+ * @version 1.0
+ * @brief cert-svc server.
+ */
+
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <systemd/sd-daemon.h>
+
+#include <cert-service-debug.h>
+#include <cert-svc/cerror.h>
+#include <cert-svc/ccert.h>
+#include <cert-svc-client.h>
+
+#include <cert-server-logic.h>
+
+sqlite3 *cert_store_db = NULL;
+
+int open_db(sqlite3 **db_handle, const char *db_path) {
+
+ int result = CERTSVC_FAIL;
+ sqlite3 *handle;
+
+ if (access(db_path, F_OK) == 0) {
+ result = db_util_open(db_path, &handle, 0);
+ if (result != SQLITE_OK) {
+ SLOGE("connect db [%s] failed!", db_path);
+ return CERTSVC_FAIL;
+ }
+ *db_handle = handle;
+ return CERTSVC_SUCCESS;
+ }
+ SLOGD("%s DB does not exists. Creating one!!", db_path);
+
+ result = db_util_open(db_path, &handle, 0);
+ if (result != SQLITE_OK) {
+ SLOGE("connect to db [%s] failed!.", db_path);
+ return CERTSVC_FAIL;
+ }
+ *db_handle = handle;
+ return CERTSVC_SUCCESS;
+}
+
+int evaluate_query(sqlite3 *db_handle, char *query) {
+
+ int result = CERTSVC_SUCCESS;
+ sqlite3_stmt* p_statement;
+
+ if (!db_handle) {
+ SLOGE("Database not initialised.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ if (!query) {
+ SLOGE("Query is NULL.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ result = sqlite3_prepare_v2(db_handle, query, strlen(query), &p_statement, NULL);
+ if (result != SQLITE_OK) {
+ SLOGE("Sqlite3 error [%d] : <%s> preparing <%s> query.", result, sqlite3_errmsg(db_handle), query);
+ return CERTSVC_FAIL;
+ }
+
+ result = sqlite3_step(p_statement);
+ if (result != SQLITE_DONE) {
+ SLOGE("Sqlite3 error [%d] : <%s> executing <%s> statement.", result, sqlite3_errmsg(db_handle), query);
+ return CERTSVC_FAIL;
+ }
+
+ result = sqlite3_finalize(p_statement);
+ if (result != SQLITE_OK) {
+ SLOGE("Sqlite3 error [%d] : <%s> finalising <%s> statement.", result, sqlite3_errmsg(db_handle), query);
+ return CERTSVC_FAIL;
+ }
+ return CERTSVC_SUCCESS;
+}
+
+int initialize_db(void) {
+
+ int result = CERTSVC_SUCCESS;
+// int i=0;
+// static int reentry = 1;
+// char *query = NULL;
+// char db_list[][6]={"wifi","vpn","email"};
+
+ if (cert_store_db == NULL) {
+ result = open_db(&cert_store_db, CERTSVC_SYSTEM_STORE_DB);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Certsvc store DB creation failed. result[%d]", result);
+ return result;
+ }
+ }
+
+/*
+ if (reentry == 1) {
+ for (i=0; i<3; i++) {
+ query = sqlite3_mprintf("create table if not exists %Q (gname text primary key not null, " \
+ "common_name text key not null, private_key_gname text, " \
+ "associated_gname text, is_root_cert integer, " \
+ "enabled integer key not null,"
+ "is_root_app_enabled integer key not null)", db_list[i]);
+
+ result = evaluate_query(cert_store_db, query);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Certificate store database initialisation Failed.");
+ result = CERTSVC_FAIL;
+ }
+ sqlite3_free(query); query=NULL;
+ }
+
+ query = sqlite3_mprintf("create table if not exists disabled_certs "\
+ "(gname text primary key not null, certificate text key not null)");
+
+ result = evaluate_query(cert_store_db, query);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("wifi store DB initialisation Failed.");
+ result = CERTSVC_FAIL;
+ }
+
+ sqlite3_free(query); query=NULL;
+ result = CERTSVC_SUCCESS;
+ reentry++;
+ goto err;
+ }
+
+err:
+*/
+
+ return CERTSVC_SUCCESS;
+}
+
+void CertSigHandler(int signo)
+{
+ SLOGD("Got Signal %d, exiting now.", signo);
+ if (cert_store_db != NULL) {
+ sqlite3_close(cert_store_db);
+ cert_store_db = NULL;
+ }
+ exit(1);
+}
+
+int CertSvcGetSocketFromSystemd(int* pSockfd)
+{
+ int n = sd_listen_fds(0);
+ int fd;
+
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
+ if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, VCORE_SOCK_PATH, 0)) {
+ LOGD("Get socket from systemd. fd[%d]", fd);
+ *pSockfd = fd;
+ return CERTSVC_SUCCESS;
+ }
+ }
+ return CERTSVC_FAIL;
+}
+
+void CertSvcServerComm()
+{
+ int server_sockfd = 0;
+ int client_sockfd = 0;
+ int read_len = 0;
+ int client_len = 0;
+ struct sockaddr_un clientaddr;
+ int result = CERTSVC_SUCCESS;
+ char *certListBuffer = NULL;
+ char *certBlockBuffer = NULL;
+ size_t bufferLen = 0;
+ size_t blockBufferLen = 0;
+
+ struct timeval timeout;
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+
+ SLOGI("cert-server is starting...");
+
+ VcoreRequestData recv_data;
+ VcoreResponseData send_data;
+
+ if (!CertSvcGetSocketFromSystemd(&server_sockfd)) {
+ SLOGE("Failed to get sockfd from systemd.");
+ return;
+ }
+
+ client_len = sizeof(clientaddr);
+ signal(SIGINT, (void*)CertSigHandler);
+
+/*
+ if (!cert_store_db) {
+ result = initialize_db();
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to initialize database.");
+ result = CERTSVC_IO_ERROR;
+ goto Error_close_exit;
+ }
+
+ if (cert_store_db) {
+ sqlite3_close(cert_store_db);
+ cert_store_db = NULL;
+ }
+ }
+*/
+
+ fd_set fd;
+ struct timeval tv;
+ while (1) {
+ errno = 0;
+
+ FD_ZERO(&fd);
+ FD_SET(server_sockfd, &fd);
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ memset(&recv_data, 0x00, sizeof(VcoreRequestData));
+ memset(&send_data, 0x00, sizeof(VcoreResponseData));
+
+ int ret = select(server_sockfd + 1, &fd, NULL, NULL, &tv);
+ if (ret == 0) { // timeout
+ SLOGD("cert-server timeout. exit.");
+ break;
+ }
+
+ if (ret == -1) {
+ SLOGE("select() error.");
+ break;
+ }
+
+ if ((client_sockfd = accept(server_sockfd, (struct sockaddr*)&clientaddr, (socklen_t*)&client_len)) < 0) {
+ SLOGE("Error in function accept().[socket desc :%d, error no :%d].", client_sockfd, errno);
+ continue;
+ }
+
+ SLOGD("cert-server Accept! client sock[%d]", client_sockfd);
+
+ if (setsockopt (client_sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
+ SLOGE("Error in Set SO_RCVTIMEO Socket Option");
+ send_data.result = CERTSVC_FAIL;
+ goto Error_close_exit;
+ }
+
+ if (setsockopt (client_sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
+ SLOGE("Error in Set SO_SNDTIMEO Socket Option");
+ send_data.result = CERTSVC_FAIL;
+ goto Error_close_exit;
+ }
+
+ SLOGD("Connected to a client...");
+
+ read_len = recv(client_sockfd, (char*)&recv_data, sizeof(recv_data), 0);
+ if (read_len < 0) {
+ SLOGE("Error in function recv().");
+ send_data.result = CERTSVC_FAIL;
+ goto Error_close_exit;
+ }
+
+ if (!cert_store_db) {
+ result = initialize_db();
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to initialize database.");
+ result = CERTSVC_IO_ERROR;
+ goto Error_close_exit;
+ }
+ }
+
+ SLOGD("revc request: reqType=%d", recv_data.reqType);
+
+ switch (recv_data.reqType) {
+ case CERTSVC_EXTRACT_CERT:
+ {
+ send_data.result = getCertificateDetailFromStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.certType,
+ recv_data.gname,
+ send_data.dataBlock,
+ &send_data.dataBlockLen);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_EXTRACT_SYSTEM_CERT:
+ {
+ send_data.result = getCertificateDetailFromSystemStore(
+ cert_store_db,
+ recv_data.gname,
+ send_data.dataBlock,
+ &send_data.dataBlockLen);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_DELETE_CERT:
+ {
+ send_data.result = deleteCertificateFromStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.gname);
+ if (send_data.result == CERTSVC_SUCCESS)
+ send_data.result = update_ca_certificate_file(cert_store_db, NULL, 0);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_GET_CERTIFICATE_STATUS:
+ {
+ send_data.result = getCertificateStatusFromStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.gname,
+ &send_data.certStatus);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_SET_CERTIFICATE_STATUS:
+ {
+ send_data.result = setCertificateStatusToStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.is_root_app,
+ recv_data.gname,
+ recv_data.certStatus);
+ if (send_data.result == CERTSVC_SUCCESS)
+ send_data.result = update_ca_certificate_file(cert_store_db, NULL, 0);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_CHECK_ALIAS_EXISTS:
+ {
+ send_data.result = checkAliasExistsInStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.gname,
+ &send_data.certStatus);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_INSTALL_CERTIFICATE:
+ {
+ send_data.result = installCertificateToStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.gname,
+ recv_data.common_name,
+ recv_data.private_key_gname,
+ recv_data.associated_gname,
+ recv_data.dataBlock,
+ recv_data.dataBlockLen,
+ recv_data.certType);
+
+ if ((send_data.result == CERTSVC_SUCCESS) && ((recv_data.certType == PEM_CRT) || (recv_data.certType == P12_TRUSTED)))
+ send_data.result = update_ca_certificate_file(cert_store_db, recv_data.dataBlock, recv_data.dataBlockLen);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_GET_CERTIFICATE_LIST:
+ case CERTSVC_GET_USER_CERTIFICATE_LIST:
+ case CERTSVC_GET_ROOT_CERTIFICATE_LIST:
+ {
+ send_data.result = getCertificateListFromStore(
+ cert_store_db,
+ recv_data.reqType,
+ recv_data.storeType,
+ recv_data.is_root_app,
+ &certListBuffer,
+ &bufferLen,
+ &send_data.certCount);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ if (bufferLen > 0)
+ result = send(client_sockfd, certListBuffer, bufferLen, 0);
+
+ break;
+ }
+
+ case CERTSVC_GET_CERTIFICATE_ALIAS:
+ {
+ send_data.result = getCertificateAliasFromStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.gname,
+ send_data.common_name);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ break;
+ }
+
+ case CERTSVC_LOAD_CERTIFICATES:
+ {
+ send_data.result = loadCertificatesFromStore(
+ cert_store_db,
+ recv_data.storeType,
+ recv_data.gname,
+ &certBlockBuffer,
+ &blockBufferLen,
+ &send_data.certBlockCount);
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ if (blockBufferLen > 0)
+ result = send(client_sockfd, certBlockBuffer, blockBufferLen, 0);
+ break;
+ }
+
+ default:
+ SLOGE("Input error. Please check request type");
+ break;
+ }
+
+ if (result <= 0) {
+ SLOGE("send failed :%d, errno %d try once", result, errno);
+ //result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ //SLOGE("retry result :%d, errno %d", result, errno);
+ }
+
+ close(client_sockfd);
+ if (cert_store_db) {
+ sqlite3_close(cert_store_db);
+ cert_store_db = NULL;
+ SLOGI("cert_store db was closed");
+ }
+ }
+
+Error_close_exit:
+ close(server_sockfd);
+ if (cert_store_db) {
+ sqlite3_close(cert_store_db);
+ cert_store_db = NULL;
+ }
+
+ if (certListBuffer)
+ free(certListBuffer);
+
+ if (certBlockBuffer)
+ free(certBlockBuffer);
+
+ if (client_sockfd >= 0) {
+ result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
+ close(client_sockfd);
+ }
+ else
+ SLOGE("cannot connect to client socket.");
+
+ SLOGI("CertSvcServerComm done.");
+}
+
+int main(void)
+{
+ SLOGI("cert-server start");
+ CertSvcServerComm();
+ SLOGI("cert-server end");
+
+ return 0;
+}
diff --git a/vcore/src/vcore/Base64.cpp b/vcore/src/vcore/Base64.cpp
index 82398aa..e3a1abe 100644
--- a/vcore/src/vcore/Base64.cpp
+++ b/vcore/src/vcore/Base64.cpp
@@ -20,7 +20,8 @@
#include <openssl/evp.h>
#include <openssl/buffer.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
+
#include <dpl/scoped_free.h>
#include <vcore/Base64.h>
@@ -36,8 +37,8 @@ Base64Encoder::Base64Encoder() :
void Base64Encoder::append(const std::string &data)
{
if (m_finalized) {
- LogWarning("Already finalized.");
- ThrowMsg(Exception::AlreadyFinalized, "Already finalized");
+ WrtLogW("Already finalized.");
+ VcoreThrowMsg(Exception::AlreadyFinalized, "Already finalized");
}
if (!m_b64) {
@@ -49,24 +50,26 @@ void Base64Encoder::append(const std::string &data)
void Base64Encoder::finalize()
{
if (m_finalized) {
- LogWarning("Already finalized.");
- ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+ WrtLogW("Already finalized.");
+ VcoreThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
}
m_finalized = true;
- BIO_flush(m_b64);
+
+ if (BIO_flush(m_b64) != 1)
+ VcoreThrowMsg(Exception::InternalError, "Bio internal error");
}
std::string Base64Encoder::get()
{
if (!m_finalized) {
- LogWarning("Not finalized");
- ThrowMsg(Exception::NotFinalized, "Not finalized");
+ WrtLogW("Not finalized");
+ VcoreThrowMsg(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");
+ WrtLogE("Bio internal error");
+ VcoreThrowMsg(Exception::InternalError, "Bio internal error");
}
if (bptr->length > 0) {
@@ -82,8 +85,8 @@ void Base64Encoder::reset()
m_b64 = BIO_new(BIO_f_base64());
m_bmem = BIO_new(BIO_s_mem());
if (!m_b64 || !m_bmem) {
- LogError("Error during allocation memory in BIO");
- ThrowMsg(Exception::InternalError,
+ WrtLogE("Error during allocation memory in BIO");
+ VcoreThrowMsg(Exception::InternalError,
"Error during allocation memory in BIO");
}
BIO_set_flags(m_b64, BIO_FLAGS_BASE64_NO_NL);
@@ -103,8 +106,8 @@ Base64Decoder::Base64Decoder() :
void Base64Decoder::append(const std::string &data)
{
if (m_finalized) {
- LogWarning("Already finalized.");
- ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+ WrtLogW("Already finalized.");
+ VcoreThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
}
m_input.append(data);
}
@@ -118,8 +121,8 @@ static bool whiteCharacter(char a)
bool Base64Decoder::finalize()
{
if (m_finalized) {
- LogWarning("Already finalized.");
- ThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
+ WrtLogW("Already finalized.");
+ VcoreThrowMsg(Exception::AlreadyFinalized, "Already finalized.");
}
m_finalized = true;
@@ -137,44 +140,44 @@ bool Base64Decoder::finalize()
{
continue;
}
- LogError("Base64 input contains illegal chars: " << m_input[i]);
+ WrtLogE("Base64 input contains illegal chars: %c", m_input[i]);
return false;
}
BIO *b64, *bmem;
size_t len = m_input.size();
- DPL::ScopedFree<char> buffer(static_cast<char*>(malloc(len)));
+ VcoreDPL::ScopedFree<char> buffer(static_cast<char*>(malloc(len)));
if (!buffer) {
- LogError("Error in malloc.");
- ThrowMsg(Exception::InternalError, "Error in malloc.");
+ WrtLogE("Error in malloc.");
+ VcoreThrowMsg(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.");
+ WrtLogE("Couldn't create BIO object.");
+ VcoreThrowMsg(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()));
+ VcoreDPL::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");
+ WrtLogE("Internal error in BIO");
+ VcoreThrowMsg(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");
+ WrtLogE("Internal error in BIO");
+ VcoreThrowMsg(Exception::InternalError, "Internal error in BIO");
}
int readlen = BIO_read(bmem, buffer.Get(), len);
@@ -195,8 +198,8 @@ bool Base64Decoder::finalize()
std::string Base64Decoder::get() const
{
if (!m_finalized) {
- LogWarning("Not finalized.");
- ThrowMsg(Exception::NotFinalized, "Not finalized");
+ WrtLogW("Not finalized.");
+ VcoreThrowMsg(Exception::NotFinalized, "Not finalized");
}
return m_output;
}
diff --git a/vcore/src/vcore/Base64.h b/vcore/src/vcore/Base64.h
index 520662e..b961d98 100644
--- a/vcore/src/vcore/Base64.h
+++ b/vcore/src/vcore/Base64.h
@@ -17,23 +17,20 @@
#define _BASE64_H_
#include <string>
-#include <dpl/noncopyable.h>
-#include <dpl/exception.h>
+#include <vcore/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)
+class Base64Encoder {
+public:
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, InternalError)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, NotFinalized)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized)
};
Base64Encoder();
void append(const std::string &data);
@@ -42,22 +39,23 @@ class Base64Encoder : public DPL::Noncopyable
void reset();
~Base64Encoder();
- private:
+private:
+ Base64Encoder(const Base64Encoder &);
+ const Base64Encoder &operator=(const Base64Encoder &);
+
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)
+class Base64Decoder {
+public:
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, InternalError)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, NotFinalized)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized)
};
Base64Decoder();
void append(const std::string &data);
@@ -69,11 +67,12 @@ class Base64Decoder : public DPL::Noncopyable
bool finalize();
std::string get() const;
void reset();
- ~Base64Decoder()
- {
- }
+ ~Base64Decoder() {}
+
+private:
+ Base64Decoder(const Base64Decoder &);
+ const Base64Decoder &operator=(const Base64Decoder &);
- private:
std::string m_input;
std::string m_output;
bool m_finalized;
diff --git a/vcore/src/vcore/CRL.h b/vcore/src/vcore/CRL.h
index 51915ee..7a52569 100644
--- a/vcore/src/vcore/CRL.h
+++ b/vcore/src/vcore/CRL.h
@@ -26,29 +26,24 @@
#include <list>
#include <string>
-#include <dpl/exception.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>
+#include <vcore/exception.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)
+VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base)
+VCORE_DECLARE_EXCEPTION_TYPE(Base, StorageError)
+VCORE_DECLARE_EXCEPTION_TYPE(Base, InternalError)
+VCORE_DECLARE_EXCEPTION_TYPE(Base, InvalidParameter)
+
} // namespace CRLException
class CRLImpl;
-class CRL : DPL::Noncopyable
-{
+class CRL {
public:
typedef std::list<std::string> StringList;
@@ -67,6 +62,7 @@ public:
bool isRevoked; /**< True when certificate is revoked */
};
+ CRL() = delete;
CRL(CRLCacheInterface *ptr);
virtual ~CRL();
@@ -152,6 +148,9 @@ public:
private:
friend class CachedCRL;
CRLImpl *m_impl;
+
+ CRL(const CRL &);
+ const CRL &operator=(const CRL &);
};
} // namespace ValidationCore
diff --git a/vcore/src/vcore/CRLImpl.cpp b/vcore/src/vcore/CRLImpl.cpp
index b2e18f9..6602e17 100644
--- a/vcore/src/vcore/CRLImpl.cpp
+++ b/vcore/src/vcore/CRLImpl.cpp
@@ -16,7 +16,7 @@
/*!
* @author Piotr Marcinkiewicz(p.marcinkiew@samsung.com)
* @version 0.2
- * @file CRLImpl.h
+ * @file CRLImpl.cpp
* @brief Routines for certificate validation over CRL
*/
@@ -32,9 +32,8 @@
#include <openssl/pem.h>
#include <openssl/x509v3.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/assert.h>
-#include <dpl/exception.h>
#include <dpl/db/orm.h>
#include <dpl/foreach.h>
@@ -42,11 +41,9 @@
#include <vcore/Certificate.h>
#include <vcore/SoupMessageSendSync.h>
#include <vcore/CRLCacheInterface.h>
-#include <tzplatform_config.h>
namespace {
-const char *CRL_LOOKUP_DIR_1 = tzplatform_mkpath(TZ_SYS_SHARE, "cert-svc/ca-certs/code-signing/wac");
-const char *CRL_LOOKUP_DIR_2 = tzplatform_mkpath(TZ_SYS_SHARE, "cert-svc/certs/code-signing/wac");
+const char *CRL_LOOKUP_DIR = "/usr/share/ca-certificates/wac";
} //anonymous namespace
namespace ValidationCore {
@@ -58,7 +55,7 @@ CRL::StringList CRLImpl::getCrlUris(const CertificatePtr &argCert)
if (!result.empty()) {
return result;
}
- LogInfo("No distribution points found. Getting from CA cert.");
+ WrtLogI("No distribution points found. Getting from CA cert.");
X509_STORE_CTX *ctx = createContext(argCert);
X509_OBJECT obj;
@@ -69,7 +66,7 @@ CRL::StringList CRLImpl::getCrlUris(const CertificatePtr &argCert)
&obj);
X509_STORE_CTX_free(ctx);
if (0 >= retVal) {
- LogError("No dedicated CA certificate available");
+ WrtLogE("No dedicated CA certificate available");
return result;
}
CertificatePtr caCert(new Certificate(obj.data.x509));
@@ -82,36 +79,27 @@ CRLImpl::CRLImpl(CRLCacheInterface *ptr)
{
Assert(m_crlCache != NULL);
- LogInfo("CRL storage initialization.");
+ WrtLogI("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.");
- }
+ if (!m_store)
+ VcoreThrowMsg(CRLException::StorageError,
+ "impossible 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.");
+ VcoreThrowMsg(CRLException::StorageError,
+ "impossible 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);
+ bool retVal = X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR, X509_FILETYPE_PEM) == 1;
+ retVal &= X509_LOOKUP_add_dir(m_lookup, CRL_LOOKUP_DIR, 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.");
+ VcoreThrowMsg(CRLException::StorageError,
+ "Failed to add lookup dir for PEM files");
}
- LogInfo("CRL storage initialization complete.");
+ WrtLogI("CRL storage initialization complete.");
}
CRLImpl::~CRLImpl()
@@ -122,7 +110,7 @@ CRLImpl::~CRLImpl()
void CRLImpl::cleanup()
{
- LogInfo("Free CRL storage");
+ WrtLogI("Free CRL storage");
// STORE is responsible for LOOKUP release
// X509_LOOKUP_free(m_lookup);
X509_STORE_free(m_store);
@@ -136,7 +124,7 @@ CRL::RevocationStatus CRLImpl::checkCertificate(const CertificatePtr &argCert)
FOREACH(it, crlUris) {
CRLDataPtr crl = getCRL(*it);
if (!crl) {
- LogDebug("CRL not found for URI: " << *it);
+ WrtLogD("CRL not found for URI: %s", (*it).c_str());
continue;
}
X509_CRL *crlInternal = convertToInternal(crl);
@@ -150,17 +138,17 @@ CRL::RevocationStatus CRLImpl::checkCertificate(const CertificatePtr &argCert)
// If nextUpdate is not set assume it is actual.
retStatus.isCRLValid = true;
}
- LogInfo("CRL valid: " << retStatus.isCRLValid);
+ WrtLogI("CRL valid: %d", 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);
+ WrtLogI("CRL revoked: %d", retStatus.isRevoked);
if (!retStatus.isRevoked && isOutOfDate(crl)) {
- LogDebug("Certificate is not Revoked, but CRL is outOfDate.");
+ WrtLogD("Certificate is not Revoked, but CRL is outOfDate.");
continue;
}
@@ -171,14 +159,11 @@ CRL::RevocationStatus CRLImpl::checkCertificate(const CertificatePtr &argCert)
return retStatus;
}
-CRL::RevocationStatus CRLImpl::checkCertificateChain(CertificateCollection
- certChain)
+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.");
- }
+ if (!certChain.sort())
+ VcoreThrowMsg(CRLException::InvalidParameter,
+ "Certificate list doesn't create chain.");
CRL::RevocationStatus ret;
ret.isCRLValid = true;
@@ -186,25 +171,27 @@ CRL::RevocationStatus CRLImpl::checkCertificateChain(CertificateCollection
const CertificateList &certList = certChain.getChain();
FOREACH(it, certList) {
if (!(*it)->isRootCert()) {
- LogInfo("Certificate common name: " << *((*it)->getCommonName()));
+ WrtLogI("Certificate common name: %s", (*it)->getCommonName().c_str());
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. "
+ WrtLogI("Could not find End Entity certificate. "
"Collection does not form chain.");
return VERIFICATION_STATUS_ERROR;
}
@@ -244,13 +231,13 @@ bool CRLImpl::isOutOfDate(const CRLDataPtr &crl) const {
bool CRLImpl::updateList(const CertificatePtr &argCert,
const CRL::UpdatePolicy updatePolicy)
{
- LogInfo("Update CRL for certificate");
+ WrtLogI("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);
+ WrtLogI("Getting CRL for URI: %s", (*it).c_str());
bool downloaded = false;
@@ -263,24 +250,24 @@ bool CRLImpl::updateList(const CertificatePtr &argCert,
}
if (!!crl && isOutOfDate(crl)) {
- LogDebug("Crl out of date - downloading.");
+ WrtLogD("Crl out of date - downloading.");
crl = downloadCRL(*it);
downloaded = true;
}
if (!crl) {
- LogDebug("Crl not found in cache - downloading.");
+ WrtLogD("Crl not found in cache - downloading.");
crl = downloadCRL(*it);
downloaded = true;
}
if (!crl) {
- LogDebug("Failed to obtain CRL. URL: " << *it);
+ WrtLogD("Failed to obtain CRL. URL: %s", (*it).c_str());
continue;
}
if (!!crl && isOutOfDate(crl)) {
- LogError("CRL out of date. Broken URL: " << *it);
+ WrtLogE("CRL out of date. Broken URL: %s", (*it).c_str());
}
// Make X509 internal structure
@@ -288,7 +275,7 @@ bool CRLImpl::updateList(const CertificatePtr &argCert,
//Check if CRL is signed
if (!verifyCRL(crlInternal, argCert)) {
- LogError("Failed to verify CRL. URI: " << crl->uri);
+ WrtLogE("Failed to verify CRL. URI: %s", (crl->uri).c_str());
X509_CRL_free(crlInternal);
return false;
}
@@ -333,7 +320,7 @@ bool CRLImpl::verifyCRL(X509_CRL *crl,
X509_CRL_get_issuer(crl), &obj);
X509_STORE_CTX_free(ctx);
if (0 >= retVal) {
- LogError("Unknown CRL issuer certificate!");
+ WrtLogE("Unknown CRL issuer certificate!");
return false;
}
@@ -341,19 +328,19 @@ bool CRLImpl::verifyCRL(X509_CRL *crl,
EVP_PKEY *pkey = X509_get_pubkey(obj.data.x509);
X509_OBJECT_free_contents(&obj);
if (!pkey) {
- LogError("Failed to get issuer's public key.");
+ WrtLogE("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.");
+ WrtLogE("Failed to verify CRL.");
return false;
} else if (0 == retVal) {
- LogError("CRL is invalid");
+ WrtLogE("CRL is invalid");
return false;
}
- LogInfo("CRL is valid.");
+ WrtLogI("CRL is valid.");
return true;
}
@@ -362,10 +349,10 @@ 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.");
+ WrtLogI("CRL is in PEM format.");
return true;
}
- LogInfo("CRL is in DER format.");
+ WrtLogI("CRL is in DER format.");
return false;
}
@@ -375,11 +362,10 @@ X509_CRL *CRLImpl::convertToInternal(const CRLDataPtr &crl) const
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");
- }
+ if (!bmem)
+ VcoreThrowMsg(CRLException::InternalError,
+ "Failed to allocate memory in BIO");
+
ret = PEM_read_bio_X509_CRL(bmem, NULL, NULL, NULL);
BIO_free_all(bmem);
} else {
@@ -389,11 +375,10 @@ X509_CRL *CRLImpl::convertToInternal(const CRLDataPtr &crl) const
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");
- }
+
+ if (!ret)
+ VcoreThrowMsg(CRLException::InternalError,
+ "Failed to convert to internal structure");
return ret;
}
@@ -401,9 +386,9 @@ 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.");
- }
+ if (!ctx)
+ VcoreThrowMsg(CRLException::StorageError, "Failed to create new ctx");
+
X509_STORE_CTX_init(ctx, m_store, argCert->getX509(), NULL);
return ctx;
}
@@ -421,7 +406,7 @@ CRLImpl::CRLDataPtr CRLImpl::downloadCRL(const std::string &uri)
&cpath,
&use_ssl))
{
- LogWarning("Error in OCSP_parse_url");
+ WrtLogW("Error in OCSP_parse_url");
return CRLDataPtr();
}
@@ -440,7 +425,7 @@ CRLImpl::CRLDataPtr CRLImpl::downloadCRL(const std::string &uri)
message.setHeader("Host", host);
if (SoupMessageSendSync::REQUEST_STATUS_OK != message.sendSync()) {
- LogWarning("Error in sending network request.");
+ WrtLogW("Error in sending network request.");
return CRLDataPtr();
}
@@ -453,22 +438,21 @@ 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);
+ WrtLogI("CRL not present in database. URI: %s", uri.c_str());
return CRLDataPtr();
}
std::string body = cachedCrl.crl_body;
- LogInfo("CRL found in database.");
+ WrtLogI("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.");
- }
+ if (!decoder.finalize())
+ VcoreThrowMsg(CRLException::StorageError,
+ "Failed to decode base64 format.");
std::string crlBody = decoder.get();
std::unique_ptr<char[]> bodyBuffer(new char[crlBody.length()]);
@@ -482,9 +466,9 @@ 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");
- }
+ if (!crl || !crl->buffer)
+ VcoreThrowMsg(CRLException::InternalError, "CRL buffer is empty");
+
encoder.append(std::string(crl->buffer, crl->length));
encoder.finalize();
std::string b64CRLBody = encoder.get();
diff --git a/vcore/src/vcore/CRLImpl.h b/vcore/src/vcore/CRLImpl.h
index 72d8d43..68475d5 100644
--- a/vcore/src/vcore/CRLImpl.h
+++ b/vcore/src/vcore/CRLImpl.h
@@ -23,14 +23,12 @@
#ifndef _VALIDATION_CORE_ENGINE_CRLIMPL_H_
#define _VALIDATION_CORE_ENGINE_CRLIMPL_H_
-#include <dpl/exception.h>
+#include <string.h>
#include <memory>
-#include <dpl/noncopyable.h>
-#include <dpl/log/log.h>
-
#include <openssl/x509.h>
-#include <vcore/CRL.h>
+#include <dpl/noncopyable.h>
+
#include <vcore/Certificate.h>
#include <vcore/CertificateCollection.h>
#include <vcore/SoupMessageSendBase.h>
@@ -38,18 +36,18 @@
#include <vcore/CRLCacheInterface.h>
#include <vcore/TimeConversion.h>
+#include <vcore/CRL.h>
+
namespace ValidationCore {
-class CRLImpl : DPL::Noncopyable
-{
- protected:
+class CRLImpl : VcoreDPL::Noncopyable {
+protected:
X509_STORE *m_store;
X509_LOOKUP *m_lookup;
CRLCacheInterface *m_crlCache;
- class CRLData : DPL::Noncopyable
- {
- public:
+ class CRLData : VcoreDPL::Noncopyable {
+ public:
//TODO: change to SharedArray when available
char *buffer;
size_t length;
@@ -75,7 +73,6 @@ class CRLImpl : DPL::Noncopyable
~CRLData()
{
- LogInfo("Delete buffer");
delete[] buffer;
}
};
@@ -94,7 +91,8 @@ class CRLImpl : DPL::Noncopyable
bool isOutOfDate(const CRLDataPtr &crl) const;
friend class CachedCRL;
- public:
+
+public:
CRLImpl(CRLCacheInterface *ptr);
~CRLImpl();
diff --git a/vcore/src/vcore/CachedCRL.cpp b/vcore/src/vcore/CachedCRL.cpp
index dfcd04b..bdc5123 100644
--- a/vcore/src/vcore/CachedCRL.cpp
+++ b/vcore/src/vcore/CachedCRL.cpp
@@ -23,7 +23,7 @@
#include <vcore/CachedCRL.h>
#include <dpl/foreach.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/foreach.h>
#include <vcore/CRLImpl.h>
@@ -86,7 +86,7 @@ VerificationStatus CachedCRL::check(const CertificateCollection &certs)
}
if (!allValid) {
// problems with CRL validity
- LogDebug("Some CRLs not valid");
+ WrtLogD("Some CRLs not valid");
}
CRL::RevocationStatus stat;
Try {
@@ -96,24 +96,24 @@ VerificationStatus CachedCRL::check(const CertificateCollection &certs)
return VERIFICATION_STATUS_ERROR;
}
if (stat.isRevoked) {
- LogDebug("Status REVOKED");
+ WrtLogD("Status REVOKED");
return VERIFICATION_STATUS_REVOKED;
}
- LogDebug("Status GOOD");
+ WrtLogD("Status GOOD");
return VERIFICATION_STATUS_GOOD;
}
VerificationStatus CachedCRL::checkEndEntity(CertificateCollection &certs)
{
if (certs.empty()) {
- LogError("Collection empty. This should never happen.");
- LogDebug("Status ERROR");
+ WrtLogE("Collection empty. This should never happen.");
+ WrtLogD("Status ERROR");
return VERIFICATION_STATUS_ERROR;
}
if (!certs.sort()) {
- LogError("Could not find End Entity certificate. "
+ WrtLogE("Could not find End Entity certificate. "
"Collection does not form chain.");
- LogDebug("Status ERROR");
+ WrtLogD("Status ERROR");
return VERIFICATION_STATUS_ERROR;
}
CRLImpl crl(new CRLCacheDAO);
@@ -131,15 +131,15 @@ VerificationStatus CachedCRL::checkEndEntity(CertificateCollection &certs)
}
if (!allValid) {
// problems with CRL validity
- LogDebug("Some CRLs not valid");
+ WrtLogD("Some CRLs not valid");
}
CertificateList::const_iterator iter = certs.begin();
CRL::RevocationStatus stat = crl.checkCertificate(*iter);
if (stat.isRevoked) {
- LogDebug("Status REVOKED");
+ WrtLogD("Status REVOKED");
return VERIFICATION_STATUS_REVOKED;
}
- LogDebug("Status GOOD");
+ WrtLogD("Status GOOD");
return VERIFICATION_STATUS_GOOD;
}
@@ -164,7 +164,7 @@ bool CachedCRL::updateCRLForUri(const std::string &uri, bool useExpiredShift)
}
if (CertificateCacheDAO::getCRLResponse(&cachedCRL)) {
if (now < cachedCRL.next_update_time) {
- LogDebug("Cached CRL still valid for: " << uri);
+ WrtLogD("Cached CRL still valid for: %s", uri.c_str());
return true;
}
}
@@ -172,7 +172,7 @@ bool CachedCRL::updateCRLForUri(const std::string &uri, bool useExpiredShift)
CRLImpl crl(new CRLCacheDAO);
CRLImpl::CRLDataPtr list = crl.downloadCRL(uri);
if (!list) {
- LogWarning("Could not retreive CRL from " << uri);
+ WrtLogW("Could not retreive CRL from %s", uri.c_str());
return false;
}
crl.updateCRL(list);
diff --git a/vcore/src/vcore/CachedOCSP.cpp b/vcore/src/vcore/CachedOCSP.cpp
index c0e3695..48c613f 100644
--- a/vcore/src/vcore/CachedOCSP.cpp
+++ b/vcore/src/vcore/CachedOCSP.cpp
@@ -25,7 +25,7 @@
#include <time.h>
#include <dpl/foreach.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/foreach.h>
#include <vcore/OCSP.h>
@@ -75,9 +75,9 @@ VerificationStatus CachedOCSP::check(const CertificateCollection &certs)
db_status.end_entity_check = false;
if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
- LogDebug("Found cache entry for OCSP");
+ WrtLogD("Found cache entry for OCSP");
if (now < db_status.next_update_time) {
- LogDebug("Cache response valid");
+ WrtLogD("Cache response valid");
return db_status.ocsp_status;
}
}
@@ -109,9 +109,9 @@ VerificationStatus CachedOCSP::checkEndEntity(CertificateCollection &certs)
db_status.end_entity_check = true;
if (CertificateCacheDAO::getOCSPStatus(&db_status)) {
- LogDebug("Found cache entry for OCSP");
+ WrtLogD("Found cache entry for OCSP");
if (now < db_status.next_update_time) {
- LogDebug("Cache response valid");
+ WrtLogD("Cache response valid");
return db_status.ocsp_status;
}
}
@@ -150,7 +150,7 @@ void CachedOCSP::updateCache()
CertificateCollection col;
col.load(db_status->cert_chain);
if (!col.sort()) {
- LogError("Certificate collection does not create chain.");
+ WrtLogE("Certificate collection does not create chain.");
continue;
}
@@ -183,7 +183,7 @@ void CachedOCSP::getCertsForEndEntity(
const CertificateCollection &certs, CertificateList* clst)
{
if (NULL == clst) {
- LogError("NULL pointer");
+ WrtLogE("NULL pointer");
return;
}
diff --git a/vcore/src/vcore/CertStoreType.cpp b/vcore/src/vcore/CertStoreType.cpp
index 4a994b7..d435fb6 100644
--- a/vcore/src/vcore/CertStoreType.cpp
+++ b/vcore/src/vcore/CertStoreType.cpp
@@ -23,46 +23,57 @@
*/
#include <vcore/CertStoreType.h>
+#include <string.h>
+
namespace ValidationCore {
namespace CertStoreId {
Set::Set()
: m_certificateStorage(0)
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
, m_ocspUrl(NULL)
- #endif
+#endif
{}
-void Set::add(Type second) {
+Set::~Set()
+{
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+ delete[] m_ocspUrl;
+#endif
+}
+
+void Set::add(Type second)
+{
m_certificateStorage |= second;
}
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
-void Set::add(std::string ocspUrl) {
+void Set::add(std::string ocspUrl)
+{
- if (strlen(ocspUrl.c_str()) == 0)
- {
- return;
- }
+ if (ocspUrl.length() == 0)
+ return;
- m_ocspUrl = new char[ocspUrl.size() + 1];
- if (m_ocspUrl != NULL) {
- strncpy(m_ocspUrl, ocspUrl.c_str(), ocspUrl.size() + 1);
- }
+ m_ocspUrl = new char[ocspUrl.length() + 1];
+ if (m_ocspUrl)
+ strncpy(m_ocspUrl, ocspUrl.c_str(), ocspUrl.length() + 1);
}
#endif
-bool Set::contains(Type second) const {
+bool Set::contains(Type second) const
+{
return static_cast<bool>(m_certificateStorage & second);
}
-bool Set::isEmpty() const {
+bool Set::isEmpty() const
+{
return m_certificateStorage == 0;
}
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
-char* Set::getOcspUrl() {
- return m_ocspUrl;
+char* Set::getOcspUrl()
+{
+ return m_ocspUrl;
}
#endif
diff --git a/vcore/src/vcore/CertStoreType.h b/vcore/src/vcore/CertStoreType.h
index 409d9b7..c07e0ce 100644
--- a/vcore/src/vcore/CertStoreType.h
+++ b/vcore/src/vcore/CertStoreType.h
@@ -24,7 +24,7 @@
#ifndef _VALIDATION_CORE_CERTSTORETYPE_H_
#define _VALIDATION_CORE_CERTSTORETYPE_H_
-#include <string.h>
+#include <string>
namespace ValidationCore {
namespace CertStoreId {
@@ -35,6 +35,7 @@ const Type TIZEN_DEVELOPER = 1;
// RootCA certificates for author signatures.
const Type TIZEN_TEST = 1 << 1;
const Type TIZEN_VERIFY = 1 << 2;
+const Type TIZEN_STORE = 1 << 3;
// RootCA's visibility level : public
const Type VIS_PUBLIC = 1 << 6;
// RootCA's visibility level : partner
@@ -46,26 +47,26 @@ const Type VIS_PARTNER_MANUFACTURER = 1 << 9;
// RootCA's visibility level : platform
const Type VIS_PLATFORM = 1 << 10;
-class Set
-{
- public:
+class Set {
+public:
Set();
+ virtual ~Set();
void add(Type second);
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
void add(std::string ocspUrl);
char* getOcspUrl();
- #endif
+#endif
- bool contains(Type second) const;
+ bool contains(Type second) const;
bool isEmpty() const;
private:
Type m_certificateStorage;
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
char* m_ocspUrl;
- #endif
+#endif
};
} // namespace CertStoreId
diff --git a/vcore/src/vcore/Certificate.cpp b/vcore/src/vcore/Certificate.cpp
index 45bfba6..55bcd3a 100644
--- a/vcore/src/vcore/Certificate.cpp
+++ b/vcore/src/vcore/Certificate.cpp
@@ -29,7 +29,7 @@
#include <openssl/bn.h>
#include <dpl/assert.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <vcore/Base64.h>
#include <vcore/TimeConversion.h>
@@ -40,11 +40,9 @@ 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.");
- }
+ if (!m_x509)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Internal Openssl error in d2i_X509 function.");
}
Certificate::Certificate(cert_svc_mem_buff &buffer)
@@ -52,11 +50,9 @@ 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.");
- }
+ if (!m_x509)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Internal Openssl error in d2i_X509 function.");
}
Certificate::Certificate(const std::string &der,
@@ -73,7 +69,7 @@ Certificate::Certificate(const std::string &der,
base64.reset();
base64.append(der);
if (!base64.finalize()) {
- LogWarning("Error during decoding");
+ WrtLogW("Error during decoding");
}
tmp = base64.get();
ptr = reinterpret_cast<const unsigned char*>(tmp.c_str());
@@ -84,11 +80,9 @@ Certificate::Certificate(const std::string &der,
}
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.");
- }
+ if (!m_x509)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Internal Openssl error in d2i_X509 function.");
}
Certificate::~Certificate()
@@ -105,11 +99,9 @@ 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");
- }
+ if (!rawDer || size <= 0)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "i2d_X509 failed");
std::string output(reinterpret_cast<char*>(rawDer), size);
OPENSSL_free(rawDer);
@@ -128,7 +120,7 @@ std::string Certificate::getBase64(void) const
bool Certificate::isSignedBy(const CertificatePtr &parent) const
{
if (!parent) {
- LogDebug("Invalid certificate parameter.");
+ WrtLogD("Invalid certificate parameter.");
return false;
}
return 0 == X509_NAME_cmp(X509_get_subject_name(parent->m_x509),
@@ -143,21 +135,15 @@ Certificate::Fingerprint Certificate::getFingerprint(
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 (!X509_digest(m_x509, EVP_md5(), fingerprint, &fingerprintlength))
+ VcoreThrowMsg(Certificate::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!");
- }
+ if (!X509_digest(m_x509, EVP_sha1(), fingerprint, &fingerprintlength))
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "SHA1 digest counting failed");
}
raw.resize(fingerprintlength); // improve performance
@@ -181,30 +167,28 @@ X509_NAME *Certificate::getX509Name(FieldType type) const
Assert("Invalid field type.");
}
- if (!name) {
- LogError("Error during x509 name extraction.");
- ThrowMsg(Exception::OpensslInternalError,
- "Error during x509 name extraction.");
- }
+ if (!name)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Error during x509 name extraction.");
return name;
}
-DPL::String Certificate::getOneLine(FieldType type) const
+std::string Certificate::getOneLine(FieldType type) const
{
X509_NAME *name = getX509Name(type);
static const int MAXB = 1024;
- char buffer[MAXB];
+ char buffer[MAXB] = {0, };
X509_NAME_oneline(name, buffer, MAXB);
- return DPL::FromUTF8String(buffer);
+
+ return std::string(buffer);
}
-DPL::String Certificate::getField(FieldType type,
- int fieldNid) const
+std::string Certificate::getField(FieldType type, int fieldNid) const
{
X509_NAME *subjectName = getX509Name(type);
X509_NAME_ENTRY *subjectEntry = NULL;
- DPL::String output;
+ std::string output;
int entryCount = X509_NAME_entry_count(subjectName);
for (int i = 0; i < entryCount; ++i) {
@@ -229,59 +213,61 @@ DPL::String Certificate::getField(FieldType type,
int nLength = ASN1_STRING_to_UTF8(&pData,
pASN1Str);
- if (nLength < 0) {
- LogError("Reading field error.");
- ThrowMsg(Exception::OpensslInternalError,
- "Reading field error.");
- }
+ if (nLength < 0)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Reading field error.");
- std::string strEntry(reinterpret_cast<char*>(pData),
- nLength);
- output = DPL::FromUTF8String(strEntry);
- OPENSSL_free(pData);
+ if (!pData) {
+ output = std::string();
+ }
+ else {
+ output = std::string(reinterpret_cast<char*>(pData), nLength);
+ OPENSSL_free(pData);
+ }
}
+
return output;
}
-DPL::String Certificate::getCommonName(FieldType type) const
+std::string Certificate::getCommonName(FieldType type) const
{
return getField(type, NID_commonName);
}
-DPL::String Certificate::getCountryName(FieldType type) const
+std::string Certificate::getCountryName(FieldType type) const
{
return getField(type, NID_countryName);
}
-DPL::String Certificate::getStateOrProvinceName(FieldType type) const
+std::string Certificate::getStateOrProvinceName(FieldType type) const
{
return getField(type, NID_stateOrProvinceName);
}
-DPL::String Certificate::getLocalityName(FieldType type) const
+std::string Certificate::getLocalityName(FieldType type) const
{
return getField(type, NID_localityName);
}
-DPL::String Certificate::getOrganizationName(FieldType type) const
+std::string Certificate::getOrganizationName(FieldType type) const
{
return getField(type, NID_organizationName);
}
-DPL::String Certificate::getOrganizationalUnitName(FieldType type) const
+std::string Certificate::getOrganizationalUnitName(FieldType type) const
{
return getField(type, NID_organizationalUnitName);
}
-DPL::String Certificate::getEmailAddres(FieldType type) const
+std::string Certificate::getEmailAddres(FieldType type) const
{
return getField(type, NID_pkcs9_emailAddress);
}
-DPL::String Certificate::getOCSPURL() const
+std::string Certificate::getOCSPURL() const
{
// TODO verify this code
- DPL::String retValue;
+ std::string retValue;
AUTHORITY_INFO_ACCESS *aia = static_cast<AUTHORITY_INFO_ACCESS*>(
X509_get_ext_d2i(m_x509,
NID_info_access,
@@ -301,10 +287,11 @@ DPL::String Certificate::getOCSPURL() const
if (OBJ_obj2nid(ad->method) == NID_ad_OCSP &&
ad->location->type == GEN_URI)
{
- void* data = ASN1_STRING_data(ad->location->d.ia5);
- retValue = DPL::String(DPL::FromUTF8String(
- static_cast<char*>(data)));
-
+ void *data = ASN1_STRING_data(ad->location->d.ia5);
+ if (!data)
+ retValue = std::string();
+ else
+ retValue = std::string(static_cast<char *>(data));
break;
}
}
@@ -312,8 +299,6 @@ DPL::String Certificate::getOCSPURL() const
return retValue;
}
-
-
Certificate::AltNameSet Certificate::getAlternativeNameDNS() const
{
AltNameSet set;
@@ -327,13 +312,16 @@ Certificate::AltNameSet Certificate::getAlternativeNameDNS() const
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);
+ char *temp = reinterpret_cast<char *>(ASN1_STRING_data(namePart->d.dNSName));
+ if (!temp) {
+ set.insert(std::string());
+ }
+ else {
+ set.insert(std::string(temp));
+ WrtLogD("FOUND GEN_DNS: %s", temp);
+ }
} else {
- LogDebug("FOUND GEN TYPE ID: " << namePart->type);
+ WrtLogD("FOUND GEN TYPE ID: %d", namePart->type);
}
}
return set;
@@ -342,54 +330,51 @@ Certificate::AltNameSet Certificate::getAlternativeNameDNS() const
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.");
- }
+ if (!time)
+ VcoreThrowMsg(Certificate::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.");
- }
+ if (asn1TimeToTimeT(time, &output))
+ VcoreThrowMsg(Certificate::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.");
- }
+ if (!time)
+ VcoreThrowMsg(Certificate::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.");
- }
+ if (asn1TimeToTimeT(time, &output))
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Converting ASN1_time to time_t error.");
+
return output;
}
ASN1_TIME* Certificate::getNotAfterTime() const
{
- ASN1_TIME *timeafter = X509_get_notAfter(m_x509);
- if (!timeafter) {
- LogError("Reading Not After error.");
- ThrowMsg(Exception::OpensslInternalError, "Reading Not After error.");
- }
+ ASN1_TIME *timeafter = X509_get_notAfter(m_x509);
+ if (!timeafter)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Reading Not After error.");
- return timeafter;
+ return timeafter;
}
ASN1_TIME* Certificate::getNotBeforeTime() const
{
- ASN1_TIME *timebefore = X509_get_notBefore(m_x509);
- if (!timebefore) {
- LogError("Reading Not Before error.");
- ThrowMsg(Exception::OpensslInternalError, "Reading Not Before error.");
- }
- return timebefore;
+ ASN1_TIME *timebefore = X509_get_notBefore(m_x509);
+ if (!timebefore)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Reading Not Before error.");
+
+ return timebefore;
}
bool Certificate::isRootCert()
@@ -412,7 +397,7 @@ Certificate::getCrlUris() const
NULL,
NULL));
if (!distPoints) {
- LogDebug("No distribution points in certificate.");
+ WrtLogD("No distribution points in certificate.");
return result;
}
@@ -420,7 +405,7 @@ Certificate::getCrlUris() const
for (int i = 0; i < count; ++i) {
DIST_POINT* point = sk_DIST_POINT_value(distPoints, i);
if (!point) {
- LogError("Failed to get distribution point.");
+ WrtLogE("Failed to get distribution point.");
continue;
}
if (point->distpoint != NULL &&
@@ -435,7 +420,7 @@ Certificate::getCrlUris() const
char *crlUri =
reinterpret_cast<char*>(name->d.ia5->data);
if (!crlUri) {
- LogError("Failed to get URI.");
+ WrtLogE("Failed to get URI.");
continue;
}
result.push_back(crlUri);
@@ -453,14 +438,13 @@ long Certificate::getVersion() const
return X509_get_version(m_x509);
}
-DPL::String Certificate::getSerialNumberString() const
+std::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");
- }
+ if (!ai)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Error in X509_get_serialNumber");
+
std::stringstream stream;
stream << std::hex << std::setfill('0');
if (ai->type == V_ASN1_NEG_INTEGER) {
@@ -473,10 +457,11 @@ DPL::String Certificate::getSerialNumberString() const
if (!data.empty()) {
data.erase(--data.end());
}
- return DPL::FromUTF8String(data);
+
+ return data;
}
-DPL::String Certificate::getKeyUsageString() const
+std::string Certificate::getKeyUsageString() const
{
// Extensions were defined in RFC 3280
const char *usage[] = {
@@ -505,66 +490,64 @@ DPL::String Certificate::getKeyUsageString() const
if (!result.empty()) {
result.erase(--result.end());
}
- return DPL::FromUTF8String(result);
+
+ return result;
}
-DPL::String Certificate::getSignatureAlgorithmString() const
+std::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");
- }
+ if (!b.get())
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Error in BIO_new");
+
+ if (i2a_ASN1_OBJECT(b.get(), m_x509->cert_info->signature->algorithm) < 0)
+ VcoreThrowMsg(Certificate::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");
- }
+ if (bptr == 0)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Error in BIO_get_mem_ptr");
+
std::string result(bptr->data, bptr->length);
- return DPL::FromUTF8String(result);
+
+ return result;
}
-DPL::String Certificate::getPublicKeyString() const
+std::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");
- }
+ if (!b.get())
+ VcoreThrowMsg(Certificate::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");
- }
+ if (!pkey)
+ VcoreThrowMsg(Certificate::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");
- }
+ if (bptr == 0)
+ VcoreThrowMsg(Certificate::Exception::OpensslInternalError,
+ "Error in BIO_get_mem_ptr");
+
std::string result(bptr->data, bptr->length);
- return DPL::FromUTF8String(result);
+
+ return result;
}
-int Certificate::isCA() const {
+int Certificate::isCA() const
+{
return X509_check_ca(m_x509);
}
diff --git a/vcore/src/vcore/Certificate.h b/vcore/src/vcore/Certificate.h
index 2687468..e8d2364 100644
--- a/vcore/src/vcore/Certificate.h
+++ b/vcore/src/vcore/Certificate.h
@@ -27,14 +27,12 @@
#include <string>
#include <vector>
#include <ctime>
-
-#include <dpl/exception.h>
-#include <dpl/noncopyable.h>
#include <memory>
-#include <dpl/string.h>
#include <openssl/x509.h>
+#include <vcore/exception.h>
+
#include <cert-service.h>
extern "C" {
@@ -51,11 +49,18 @@ class Certificate;
typedef std::shared_ptr<Certificate> CertificatePtr;
typedef std::list<CertificatePtr> CertificateList;
-class Certificate : public std::enable_shared_from_this<Certificate>
-{
- public:
+class Certificate : public std::enable_shared_from_this<Certificate> {
+public:
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, OpensslInternalError);
+ };
+
typedef std::vector<unsigned char> Fingerprint;
- typedef DPL::String AltName;
+
+ // ascii string
+ typedef std::string AltName;
typedef std::set<AltName> AltNameSet;
enum FingerprintType
@@ -75,13 +80,6 @@ class Certificate : public std::enable_shared_from_this<Certificate>
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);
@@ -107,19 +105,16 @@ class Certificate : public std::enable_shared_from_this<Certificate>
Fingerprint getFingerprint(FingerprintType type) const;
// getName uses deprecated functions. Usage is strongly discouraged.
- DPL::String getOneLine(FieldType type = FIELD_SUBJECT) const;
-
- DPL::String getCommonName(FieldType type = FIELD_SUBJECT) const;
- DPL::String getCountryName(FieldType type = FIELD_SUBJECT) const;
- DPL::String getStateOrProvinceName(
- FieldType type = FIELD_SUBJECT) const;
- DPL::String getLocalityName(FieldType type = FIELD_SUBJECT) const;
- DPL::String getOrganizationName(
- FieldType type = FIELD_SUBJECT) const;
- DPL::String getOrganizationalUnitName(
- FieldType type = FIELD_SUBJECT) const;
- DPL::String getEmailAddres(FieldType type = FIELD_SUBJECT) const;
- DPL::String getOCSPURL() const;
+ // utf8 string
+ std::string getOneLine(FieldType type = FIELD_SUBJECT) const;
+ std::string getCommonName(FieldType type = FIELD_SUBJECT) const;
+ std::string getCountryName(FieldType type = FIELD_SUBJECT) const;
+ std::string getStateOrProvinceName(FieldType type = FIELD_SUBJECT) const;
+ std::string getLocalityName(FieldType type = FIELD_SUBJECT) const;
+ std::string getOrganizationName(FieldType type = FIELD_SUBJECT) const;
+ std::string getOrganizationalUnitName(FieldType type = FIELD_SUBJECT) const;
+ std::string getEmailAddres(FieldType type = FIELD_SUBJECT) const;
+ std::string getOCSPURL() const;
// Openssl supports 9 types of alternative name filed.
@@ -150,13 +145,11 @@ class Certificate : public std::enable_shared_from_this<Certificate>
long getVersion() const;
- DPL::String getSerialNumberString() const;
-
- DPL::String getKeyUsageString() const;
-
- DPL::String getSignatureAlgorithmString() const;
-
- DPL::String getPublicKeyString() const;
+ // utf8 string
+ std::string getSerialNumberString() const;
+ std::string getKeyUsageString() const;
+ std::string getSignatureAlgorithmString() const;
+ std::string getPublicKeyString() const;
/*
* 0 - not CA
@@ -171,11 +164,11 @@ class Certificate : public std::enable_shared_from_this<Certificate>
static std::string FingerprintToColonHex(
const Fingerprint &fingerprint);
- protected:
+protected:
X509_NAME *getX509Name(FieldType type) const;
- DPL::String getField(FieldType type,
- int fieldNid) const;
+ // utf8 string
+ std::string getField(FieldType type, int fieldNid) const;
X509 *m_x509;
};
diff --git a/vcore/src/vcore/CertificateCacheDAO.cpp b/vcore/src/vcore/CertificateCacheDAO.cpp
index 483702c..c01fa7a 100644
--- a/vcore/src/vcore/CertificateCacheDAO.cpp
+++ b/vcore/src/vcore/CertificateCacheDAO.cpp
@@ -26,13 +26,13 @@
#include <vcore/VCorePrivate.h>
#include <dpl/foreach.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_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;
+using namespace VcoreDPL::DB::ORM;
+using namespace VcoreDPL::DB::ORM::vcore;
namespace ValidationCore {
@@ -49,7 +49,7 @@ void CertificateCacheDAO::setOCSPStatus(const std::string& cert_chain,
if (getOCSPStatus(&status)) {
// only need to update data in DB
Equals<OCSPResponseStorage::cert_chain> e1(
- DPL::FromUTF8String(cert_chain));
+ VcoreDPL::FromUTF8String(cert_chain));
Equals<OCSPResponseStorage::end_entity_check> e2(
end_entity_check ? 1 : 0);
@@ -66,7 +66,7 @@ void CertificateCacheDAO::setOCSPStatus(const std::string& cert_chain,
// need to insert data
OCSPResponseStorage::Row row;
- row.Set_cert_chain(DPL::FromUTF8String(cert_chain));
+ row.Set_cert_chain(VcoreDPL::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);
@@ -76,7 +76,7 @@ void CertificateCacheDAO::setOCSPStatus(const std::string& cert_chain,
insert->Execute();
}
transaction.Commit();
- } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ } Catch(VcoreDPL::DB::SqlConnection::Exception::Base) {
ReThrowMsg(Exception::DatabaseError, "Failed to setOCSPStatus");
}
}
@@ -84,12 +84,12 @@ void CertificateCacheDAO::setOCSPStatus(const std::string& cert_chain,
bool CertificateCacheDAO::getOCSPStatus(OCSPCachedStatus* cached_status)
{
if (NULL == cached_status) {
- LogError("NULL pointer");
+ WrtLogE("NULL pointer");
return false;
}
Try {
Equals<OCSPResponseStorage::cert_chain> e1(
- DPL::FromUTF8String(cached_status->cert_chain));
+ VcoreDPL::FromUTF8String(cached_status->cert_chain));
Equals<OCSPResponseStorage::end_entity_check> e2(
cached_status->end_entity_check ? 1 : 0);
@@ -105,10 +105,10 @@ bool CertificateCacheDAO::getOCSPStatus(OCSPCachedStatus* cached_status)
return true;
}
- LogDebug("Cached OCSP status not found");
+ WrtLogD("Cached OCSP status not found");
return false;
}
- Catch(DPL::DB::SqlConnection::Exception::Base) {
+ Catch(VcoreDPL::DB::SqlConnection::Exception::Base) {
ReThrowMsg(Exception::DatabaseError, "Failed to getOCSPStatus");
}
}
@@ -117,7 +117,7 @@ void CertificateCacheDAO::getOCSPStatusList(
OCSPCachedStatusList* cached_status_list)
{
if (NULL == cached_status_list) {
- LogError("NULL pointer");
+ WrtLogE("NULL pointer");
return;
}
Try {
@@ -127,7 +127,7 @@ void CertificateCacheDAO::getOCSPStatusList(
FOREACH(i, list) {
OCSPCachedStatus status;
- status.cert_chain = DPL::ToUTF8String(i->Get_cert_chain());
+ status.cert_chain = VcoreDPL::ToUTF8String(i->Get_cert_chain());
status.ocsp_status = intToVerificationStatus(
*(i->Get_ocsp_status()));
status.end_entity_check =
@@ -137,7 +137,7 @@ void CertificateCacheDAO::getOCSPStatusList(
}
}
- Catch(DPL::DB::SqlConnection::Exception::Base) {
+ Catch(VcoreDPL::DB::SqlConnection::Exception::Base) {
ReThrowMsg(Exception::DatabaseError, "Failed to getOCSPStatusList");
}
}
@@ -155,11 +155,11 @@ void CertificateCacheDAO::setCRLResponse(const std::string& distribution_point,
// only need to update data in DB
VCORE_DB_UPDATE(update, CRLResponseStorage, &ThreadInterface())
Equals<CRLResponseStorage::distribution_point> e1(
- DPL::FromUTF8String(distribution_point));
+ VcoreDPL::FromUTF8String(distribution_point));
CRLResponseStorage::Row row;
update->Where(e1);
- row.Set_crl_body(DPL::FromUTF8String(crl_body));
+ row.Set_crl_body(VcoreDPL::FromUTF8String(crl_body));
row.Set_next_update_time(next_update_time);
update->Values(row);
update->Execute();
@@ -168,14 +168,14 @@ void CertificateCacheDAO::setCRLResponse(const std::string& distribution_point,
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_distribution_point(VcoreDPL::FromUTF8String(distribution_point));
+ row.Set_crl_body(VcoreDPL::FromUTF8String(crl_body));
row.Set_next_update_time(next_update_time);
insert->Values(row);
insert->Execute();
}
transaction.Commit();
- } Catch(DPL::DB::SqlConnection::Exception::Base) {
+ } Catch(VcoreDPL::DB::SqlConnection::Exception::Base) {
ReThrowMsg(Exception::DatabaseError, "Failed to setOCSPStatus");
}
}
@@ -183,27 +183,27 @@ void CertificateCacheDAO::setCRLResponse(const std::string& distribution_point,
bool CertificateCacheDAO::getCRLResponse(CRLCachedData* cached_data)
{
if (NULL == cached_data) {
- LogError("NULL pointer");
+ WrtLogE("NULL pointer");
return false;
}
Try {
VCORE_DB_SELECT(select, CRLResponseStorage, &ThreadInterface())
Equals<CRLResponseStorage::distribution_point> e1(
- DPL::FromUTF8String(cached_data->distribution_point));
+ VcoreDPL::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->crl_body = VcoreDPL::ToUTF8String(row.Get_crl_body());
cached_data->next_update_time = *(row.Get_next_update_time());
return true;
}
- LogDebug("Cached CRL not found");
+ WrtLogD("Cached CRL not found");
return false;
}
- Catch(DPL::DB::SqlConnection::Exception::Base) {
+ Catch(VcoreDPL::DB::SqlConnection::Exception::Base) {
ReThrowMsg(Exception::DatabaseError, "Failed to getCRLResponse");
}
}
@@ -212,7 +212,7 @@ void CertificateCacheDAO::getCRLResponseList(
CRLCachedDataList* cached_data_list)
{
if (NULL == cached_data_list) {
- LogError("NULL pointer");
+ WrtLogE("NULL pointer");
return;
}
Try {
@@ -222,15 +222,15 @@ void CertificateCacheDAO::getCRLResponseList(
FOREACH(i, list) {
CRLCachedData response;
- response.distribution_point = DPL::ToUTF8String(
+ response.distribution_point = VcoreDPL::ToUTF8String(
i->Get_distribution_point());
- response.crl_body = DPL::ToUTF8String(i->Get_crl_body());
+ response.crl_body = VcoreDPL::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) {
+ Catch(VcoreDPL::DB::SqlConnection::Exception::Base) {
ReThrowMsg(Exception::DatabaseError, "Failed to getCRLResponses");
}
}
@@ -245,7 +245,7 @@ void CertificateCacheDAO::clearCertificateCache()
del2->Execute();
transaction.Commit();
}
- Catch(DPL::DB::SqlConnection::Exception::Base) {
+ Catch(VcoreDPL::DB::SqlConnection::Exception::Base) {
ReThrowMsg(Exception::DatabaseError, "Failed to clearUserSettings");
}
}
diff --git a/vcore/src/vcore/CertificateCacheDAO.h b/vcore/src/vcore/CertificateCacheDAO.h
index 59102da..f10ec07 100644
--- a/vcore/src/vcore/CertificateCacheDAO.h
+++ b/vcore/src/vcore/CertificateCacheDAO.h
@@ -52,7 +52,7 @@ class CertificateCacheDAO {
class Exception
{
public:
- DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
DECLARE_EXCEPTION_TYPE(Base, DatabaseError)
};
diff --git a/vcore/src/vcore/CertificateCollection.cpp b/vcore/src/vcore/CertificateCollection.cpp
index 90d1d4e..2f20146 100644
--- a/vcore/src/vcore/CertificateCollection.cpp
+++ b/vcore/src/vcore/CertificateCollection.cpp
@@ -21,13 +21,12 @@
*/
#include <vcore/CertificateCollection.h>
-#include <algorithm>
-
+#include <vcore/Base64.h>
#include <dpl/binary_queue.h>
#include <dpl/foreach.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
-#include <vcore/Base64.h>
+#include <algorithm>
namespace {
@@ -68,18 +67,19 @@ bool CertificateCollection::load(const std::string &buffer)
base64.reset();
base64.append(buffer);
if (!base64.finalize()) {
- LogWarning("Error during chain decoding");
+ WrtLogW("Error during chain decoding");
return false;
}
std::string binaryData = base64.get();
- DPL::BinaryQueue queue;
+ VcoreDPL::BinaryQueue queue;
queue.AppendCopy(binaryData.c_str(), binaryData.size());
int certNum;
queue.FlattenConsume(&certNum, sizeof(int));
CertificateList list;
+ CertificatePtr certPtr;
for (int i = 0; i < certNum; ++i) {
int certSize;
@@ -87,16 +87,16 @@ bool CertificateCollection::load(const std::string &buffer)
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.");
+ VcoreTry {
+ list.push_back(CertificatePtr(new Certificate(std::string(
+ rawDERCert.begin(),
+ rawDERCert.end()))));
+ } VcoreCatch (Certificate::Exception::Base) {
+ WrtLogW("Error during certificate creation.");
return false;
}
- LogDebug("Loading certificate. Certificate common name: " <<
- list.back()->getCommonName());
+
+ WrtLogD("Loading certificate. Certificate common name: %s", list.back()->getCommonName().c_str());
}
load(list);
return true;
@@ -126,11 +126,10 @@ CertificateList CertificateCollection::getCertificateList() const
bool CertificateCollection::isChain() const
{
- if (COLLECTION_SORTED != m_collectionStatus) {
- LogError("You must sort certificates first");
- ThrowMsg(Exception::WrongUsage,
- "You must sort certificates first");
- }
+ if (COLLECTION_SORTED != m_collectionStatus)
+ VcoreThrowMsg(CertificateCollection::Exception::WrongUsage,
+ "You must sort certificate first");
+
return (COLLECTION_SORTED == m_collectionStatus) ? true : false;
}
@@ -144,11 +143,9 @@ bool CertificateCollection::sort()
CertificateList CertificateCollection::getChain() const
{
- if (COLLECTION_SORTED != m_collectionStatus) {
- LogError("You must sort certificates first");
- ThrowMsg(Exception::WrongUsage,
- "You must sort certificates first");
- }
+ if (COLLECTION_SORTED != m_collectionStatus)
+ VcoreThrowMsg(CertificateCollection::Exception::WrongUsage,
+ "You must sort certificates first");
return m_certList;
}
@@ -166,7 +163,7 @@ void CertificateCollection::sortCollection()
// 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)));
+ subTransl.insert(std::make_pair((*it)->getOneLine(), (*it)));
}
// We need one start certificate
sorted.push_back(subTransl.begin()->second);
@@ -175,7 +172,7 @@ void CertificateCollection::sortCollection()
// 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));
+ std::string issuer = sorted.back()->getOneLine(Certificate::FIELD_ISSUER);
auto it = subTransl.find(issuer);
if (it == subTransl.end()) {
break;
@@ -186,13 +183,13 @@ void CertificateCollection::sortCollection()
// 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));
+ issTransl.insert(std::make_pair(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());
+ std::string sub = sorted.front()->getOneLine();
auto it = issTransl.find(sub);
if (it == issTransl.end()) {
break;
@@ -202,7 +199,7 @@ void CertificateCollection::sortCollection()
}
if (!issTransl.empty()) {
- LogWarning("Certificates don't form a valid chain.");
+ WrtLogW("Certificates don't form a valid chain.");
m_collectionStatus = COLLECTION_CHAIN_BROKEN;
return;
}
diff --git a/vcore/src/vcore/CertificateCollection.h b/vcore/src/vcore/CertificateCollection.h
index 953bbfb..9b9a6c4 100644
--- a/vcore/src/vcore/CertificateCollection.h
+++ b/vcore/src/vcore/CertificateCollection.h
@@ -24,8 +24,9 @@
#include <list>
#include <string>
+#include <map>
-#include <dpl/exception.h>
+#include <vcore/exception.h>
#include <vcore/Certificate.h>
@@ -37,14 +38,12 @@ namespace ValidationCore {
* 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)
+class CertificateCollection {
+public:
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, WrongUsage);
};
CertificateCollection();
@@ -152,7 +151,7 @@ class CertificateCollection
*/
CertificatePtr back() const;
- protected:
+protected:
void sortCollection(void);
enum CollectionStatus
diff --git a/vcore/src/vcore/CertificateConfigReader.cpp b/vcore/src/vcore/CertificateConfigReader.cpp
index e98e747..3d67e35 100644
--- a/vcore/src/vcore/CertificateConfigReader.cpp
+++ b/vcore/src/vcore/CertificateConfigReader.cpp
@@ -19,12 +19,13 @@
* @version 1.0
* @brief
*/
-#include "CertificateConfigReader.h"
-#include <cstdlib>
+#include <vcore/CertificateConfigReader.h>
#include <dpl/assert.h>
+#include <cstdlib>
+
namespace {
const std::string XML_EMPTY_NAMESPACE = "";
@@ -39,6 +40,7 @@ const std::string TOKEN_ATTR_URL_NAME = "ocspUrl";
const std::string TOKEN_VALUE_TIZEN_DEVELOPER = "tizen-developer";
const std::string TOKEN_VALUE_TIZEN_TEST = "tizen-test";
const std::string TOKEN_VALUE_TIZEN_VERIFY = "tizen-verify";
+const std::string TOKEN_VALUE_TIZEN_STORE = "tizen-store";
const std::string TOKEN_VALUE_VISIBILITY_PUBLIC = "tizen-public";
const std::string TOKEN_VALUE_VISIBILITY_PARTNER = "tizen-partner";
const std::string TOKEN_VALUE_VISIBILITY_PARTNER_OPERATOR = "tizen-partner-operator";
@@ -61,9 +63,9 @@ int hexCharToInt(char c)
} // anonymous namespace
namespace ValidationCore {
-CertificateConfigReader::CertificateConfigReader() :
- m_certificateDomain(0),
- m_parserSchema(this)
+CertificateConfigReader::CertificateConfigReader()
+ : m_certificateDomain(0)
+ , m_parserSchema(this)
{
m_parserSchema.addBeginTagCallback(
TOKEN_CERTIFICATE_SET,
@@ -96,21 +98,37 @@ CertificateConfigReader::CertificateConfigReader() :
&CertificateConfigReader::tokenEndFingerprintSHA1);
}
+void CertificateConfigReader::initialize(
+ const std::string &file,
+ const std::string &scheme)
+{
+ m_parserSchema.initialize(file, true, SaxReader::VALIDATION_XMLSCHEME, scheme);
+}
+
+void CertificateConfigReader::read(CertificateIdentifier &identificator)
+{
+ m_parserSchema.read(identificator);
+}
+
+void CertificateConfigReader::blankFunction(CertificateIdentifier &)
+{
+}
+
void CertificateConfigReader::tokenCertificateDomain(CertificateIdentifier &)
{
- std::string name = m_parserSchema.getReader().
- attribute(TOKEN_ATTR_NAME, SaxReader::THROW_DISABLE);
+ std::string name = m_parserSchema.getReader().attribute(TOKEN_ATTR_NAME);
if (name.empty()) {
- LogWarning("Invalid fingerprint file. Domain name is mandatory");
- ThrowMsg(Exception::InvalidFile,
- "Invalid fingerprint file. Domain name is mandatory");
+ VcoreThrowMsg(CertificateConfigReader::Exception::InvalidFile,
+ "Invalid fingerprint file. Domain name is mandatory");
} else if (name == TOKEN_VALUE_TIZEN_DEVELOPER) {
m_certificateDomain = CertStoreId::TIZEN_DEVELOPER;
} else if (name == TOKEN_VALUE_TIZEN_TEST) {
m_certificateDomain = CertStoreId::TIZEN_TEST;
} else if (name == TOKEN_VALUE_TIZEN_VERIFY) {
m_certificateDomain = CertStoreId::TIZEN_VERIFY;
+ } else if (name == TOKEN_VALUE_TIZEN_STORE) {
+ m_certificateDomain = CertStoreId::TIZEN_STORE;
} else if (name == TOKEN_VALUE_VISIBILITY_PUBLIC) {
m_certificateDomain = CertStoreId::VIS_PUBLIC;
} else if (name == TOKEN_VALUE_VISIBILITY_PARTNER) {
@@ -121,8 +139,7 @@ void CertificateConfigReader::tokenCertificateDomain(CertificateIdentifier &)
m_certificateDomain = CertStoreId::VIS_PARTNER_MANUFACTURER;
} else if (name == TOKEN_VALUE_VISIBILITY_PLATFORM) {
m_certificateDomain = CertStoreId::VIS_PLATFORM;
- } else {
- LogWarning("This domain will be ignored : " << name);
+ } else {
m_certificateDomain = 0;
}
}
@@ -130,9 +147,9 @@ void CertificateConfigReader::tokenCertificateDomain(CertificateIdentifier &)
void CertificateConfigReader::tokenEndFingerprintSHA1(
CertificateIdentifier &identificator)
{
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
- std::string url = m_parserSchema.getReader().attribute(TOKEN_ATTR_URL_NAME, SaxReader::THROW_DISABLE);
- #endif
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+ std::string url = m_parserSchema.getReader().attribute(TOKEN_ATTR_URL_NAME);
+#endif
std::string text = m_parserSchema.getText();
text += ":"; // add guard at the end of fingerprint
@@ -157,8 +174,8 @@ void CertificateConfigReader::tokenEndFingerprintSHA1(
}
identificator.add(fingerprint, m_certificateDomain);
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
identificator.add(fingerprint, url);
- #endif
+#endif
}
} // namespace ValidationCore
diff --git a/vcore/src/vcore/CertificateConfigReader.h b/vcore/src/vcore/CertificateConfigReader.h
index 4ca7d8e..d61cc86 100644
--- a/vcore/src/vcore/CertificateConfigReader.h
+++ b/vcore/src/vcore/CertificateConfigReader.h
@@ -23,46 +23,33 @@
#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>
+#include <vcore/exception.h>
namespace ValidationCore {
-class CertificateConfigReader
-{
- public:
- class Exception
- {
- public:
- DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
- DECLARE_EXCEPTION_TYPE(Base, InvalidFile)
+class CertificateConfigReader {
+public:
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base);
+ VCORE_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);
- }
+ CertificateConfigReader();
- void read(CertificateIdentifier &identificator)
- {
- m_parserSchema.read(identificator);
- }
+ void initialize(const std::string &file, const std::string &scheme);
+ void read(CertificateIdentifier &identificator);
- private:
- void blankFunction(CertificateIdentifier &)
- {
- }
+private:
+ void blankFunction(CertificateIdentifier &);
void tokenCertificateDomain(CertificateIdentifier &identificator);
void tokenEndFingerprintSHA1(CertificateIdentifier &identificator);
CertStoreId::Type m_certificateDomain;
- ParserSchema<CertificateConfigReader, CertificateIdentifier>
- m_parserSchema;
+ ParserSchema<CertificateConfigReader, CertificateIdentifier> m_parserSchema;
};
} // namespace ValidationCore
diff --git a/vcore/src/vcore/CertificateIdentifier.h b/vcore/src/vcore/CertificateIdentifier.h
index 0090d2c..bbdab2d 100644
--- a/vcore/src/vcore/CertificateIdentifier.h
+++ b/vcore/src/vcore/CertificateIdentifier.h
@@ -27,14 +27,13 @@
#include <map>
#include <dpl/noncopyable.h>
-#include "Certificate.h"
-#include "CertStoreType.h"
+#include <vcore/Certificate.h>
+#include <vcore/CertStoreType.h>
namespace ValidationCore {
-class CertificateIdentifier : public DPL::Noncopyable
-{
+class CertificateIdentifier : public VcoreDPL::Noncopyable {
public:
- typedef std::map<Certificate::Fingerprint, CertStoreId::Set> FingerPrintMap;
+ typedef std::map<Certificate::Fingerprint, CertStoreId::Set> FingerPrintMap;
CertificateIdentifier()
{
@@ -49,13 +48,13 @@ public:
fingerPrintMap[fingerprint].add(domain);
}
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+ #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
void add(const Certificate::Fingerprint &fingerprint,
- std::string ocspUrl)
+ std::string ocspUrl)
{
- fingerPrintMap[fingerprint].add(ocspUrl);
+ fingerPrintMap[fingerprint].add(ocspUrl);
}
- #endif
+ #endif
CertStoreId::Set find(const Certificate::Fingerprint &fingerprint) const
{
@@ -72,7 +71,7 @@ public:
find(certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
}
- private:
+private:
FingerPrintMap fingerPrintMap;
};
} // namespace ValidationCore
diff --git a/vcore/src/vcore/CertificateLoader.cpp b/vcore/src/vcore/CertificateLoader.cpp
index 038e0fc..a934f67 100644
--- a/vcore/src/vcore/CertificateLoader.cpp
+++ b/vcore/src/vcore/CertificateLoader.cpp
@@ -15,7 +15,7 @@
*/
#include <dpl/assert.h>
#include <openssl/x509v3.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/noncopyable.h>
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
@@ -34,7 +34,7 @@ const int MIN_RSA_KEY_LENGTH = 1024;
namespace ValidationCore {
//// COMPARATOR CLASS START ////
-//class CertificateLoaderECDSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
+//class CertificateLoaderECDSA : public CertificateLoader::CertificateLoaderComparator, VcoreDPL::Noncopyable {
//public:
// CertificateLoaderECDSA(const std::string &publicKey)
// : m_ecPublicKey(NULL)
@@ -45,7 +45,7 @@ namespace ValidationCore {
// m_initialized = CertificateLoader::convertBase64NodeToBigNum(publicKey, &m_searchKey);
//
// if(!m_initialized)
-// LogError("Init failed!");
+// WrtLogE("Init failed!");
// }
//
// virtual bool compare(X509 *x509cert){
@@ -60,7 +60,7 @@ namespace ValidationCore {
// return false;
//
// if(m_ecPublicKey->type != EVP_PKEY_EC){
-// LogError("ecPublicKey has wrong type!");
+// WrtLogE("ecPublicKey has wrong type!");
// return false;
// }
//
@@ -97,7 +97,7 @@ namespace ValidationCore {
//// COMPARATOR RSA CLASS START ////
-//class CertificateLoaderRSA : public CertificateLoader::CertificateLoaderComparator, DPL::Noncopyable {
+//class CertificateLoaderRSA : public CertificateLoader::CertificateLoaderComparator, VcoreDPL::Noncopyable {
//public:
// CertificateLoaderRSA(const std::string &m_modulus,const std::string &m_exponent )
// : m_rsaPublicKey(NULL)
@@ -109,7 +109,7 @@ namespace ValidationCore {
// m_initialized_exponent = CertificateLoader::convertBase64NodeToBigNum(m_exponent, &m_exponent_bn);
//
// if(!m_initialized_modulus || !m_initialized_exponent)
-// LogError("Init failed!");
+// WrtLogE("Init failed!");
// }
//
// virtual bool compare(X509 *x509cert){
@@ -124,7 +124,7 @@ namespace ValidationCore {
// return false;
//
// if(m_rsaPublicKey->type != EVP_PKEY_RSA){
-// LogInfo("rsaPublicKey has wrong type!");
+// WrtLogI("rsaPublicKey has wrong type!");
// return false;
// }
//
@@ -133,7 +133,7 @@ namespace ValidationCore {
//
// if (BN_cmp(m_modulus_bn, rsa->n) == 0 &&
// BN_cmp(m_exponent_bn, rsa->e) == 0 ){
-// LogError ("Compare TRUE");
+// WrtLogE ("Compare TRUE");
// return true;
// }
// return false;
@@ -162,7 +162,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
{
(void) m_modulus;
(void) m_exponent;
- LogError("Not implemented.");
+ WrtLogE("Not implemented.");
return UNKNOWN_ERROR;
// if (m_exponent.empty() || m_modulus.empty())
// return WRONG_ARGUMENTS;
@@ -188,7 +188,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificate(
{
(void) storageName;
(void) cmp;
- LogError("Not Implemented");
+ WrtLogE("Not Implemented");
return UNKNOWN_ERROR;
// long int result = OPERATION_SUCCESS;
//
@@ -217,7 +217,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificate(
// {
//
// if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
- // LogError("Extracting Certificate Data failed \n");
+ // WrtLogE("Extracting Certificate Data failed ");
// continue;
// }
//
@@ -226,35 +226,35 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::loadCertificate(
// X509 *x509cert = d2i_X509(NULL, &ptr, certRetrieved.size);
// if(x509cert == NULL){
// certmgr_release_certificate_data(&descriptor);
- // LogError("Error extracting certificate (d2i_X509).");
+ // WrtLogE("Error extracting certificate (d2i_X509).");
// return UNKNOWN_ERROR;
// }
//
- // LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
+ // WrtLogD("The subject of this certificate is %s", (descriptor.mandatory.subject));
// if(cmp->compare(x509cert)){
- // LogDebug("Found match. Coping bytes: " << certRetrieved.size);
+ // WrtLogD("Found match. Coping bytes: %d", certRetrieved.size);
// m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
// certmgr_release_certificate_data(&descriptor);
// X509_free(x509cert);
// break;
// }
//
- // LogDebug("Release");
+ // WrtLogD("Release");
// X509_free(x509cert);
// certmgr_release_certificate_data(&descriptor);
// }
//
// if(ERR_NO_MORE_CERTIFICATES == result){
- // LogError("Certificates for given DN not found\n");
+ // WrtLogE("Certificates for given DN not found");
// return CERTIFICATE_NOT_FOUND;
// }
//
// if(result!= OPERATION_SUCCESS){
- // LogError("Certificate Manager Error\n");
+ // WrtLogE("Certificate Manager Error");
// return UNKNOWN_ERROR;
// }
//
- // LogDebug("Exit");
+ // WrtLogD("Exit");
// return NO_ERROR;
}
@@ -263,7 +263,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
loadCertificateBasedOnSubjectName(const std::string &subjectName)
{
(void) subjectName;
- LogError("Not implemented.");
+ WrtLogE("Not implemented.");
return UNKNOWN_ERROR;
// if(subjectName.empty())
// {
@@ -295,29 +295,29 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// {
//
// if(OPERATION_SUCCESS!=certmgr_extract_certificate_data(&certRetrieved, &descriptor)){
- // LogError("Extracting Certificate Data failed \n");
+ // WrtLogE("Extracting Certificate Data failed ");
// continue;
// }
//
// if(!strcmp(subjectName.c_str(), descriptor.mandatory.subject)){
- // LogDebug("The subject of this certificate is " << descriptor.mandatory.subject);
+ // WrtLogD("The subject of this certificate is %s", descriptor.mandatory.subject);
// m_certificatePtr = CertificatePtr(new Certificate(certRetrieved));
// certmgr_release_certificate_data(&descriptor);
// break;
// }
- // LogDebug("Release");
+ // WrtLogD("Release");
// certmgr_release_certificate_data(&descriptor);
// }
//
// if(ERR_NO_MORE_CERTIFICATES == result) {
- // LogError("Certificates for given DN not found\n");
+ // WrtLogE("Certificates for given DN not found");
// return CERTIFICATE_NOT_FOUND;
// }
// if(result!= OPERATION_SUCCESS){
- // LogError("Certificate Manager Error\n");
+ // WrtLogE("Certificate Manager Error");
// return UNKNOWN_ERROR;
// }
- // LogDebug("Exit");
+ // WrtLogD("Exit");
// return NO_ERROR;
}
@@ -333,7 +333,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// KW memset(&m_cmBuff, 0, sizeof(certmgr_mem_buff));
// KW }
// KW
-// KW LogDebug("IssuerName: " << issuerName << " serialNumber: " << serialNumber);
+// KW WrtLogD("IssuerName: %s , serialNumber: %s", issuerName.c_str(), serialNumber.c_str());
// KW
// KW //used to check status of retrieved certificate
// KW long int result = OPERATION_SUCCESS;
@@ -359,14 +359,14 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// KW certRetrieved.firstFree = 0)
// KW {
// KW
-// KW LogDebug("Extracting certificate from CertMgr");
+// KW WrtLogD("Extracting certificate from CertMgr");
// KW
// KW if( OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor) ){
-// KW LogError("Extracting Certificate Data failed \n");
+// KW WrtLogE("Extracting Certificate Data failed ");
// KW continue;
// KW }
// KW
-// KW LogDebug("Issuer: " << descriptor.mandatory.issuer);
+// KW WrtLogD("Issuer: %s", (descriptor.mandatory.issuer).c_str());
// KW
// KW const unsigned char *ptr = certRetrieved.data;
// KW char *tmp;
@@ -376,13 +376,13 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// KW OPENSSL_free(tmp);
// KW X509_free(x509cert);
// KW
-// KW LogInfo("Certificate number found: " << serialNO);
-// KW LogInfo("Certificate number looking for: " << serialNumber);
+// KW WrtLogI("Certificate number found: %d", serialNO);
+// KW WrtLogI("Certificate number looking for: %d", 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 WrtLogE("The issuer of this certificate is %s", (descriptor.mandatory.issuer).c_str());
// KW
// KW m_cmBuff.data = new unsigned char[certRetrieved.size];
// KW m_cmBuff.firstFree = m_cmBuff.size = certRetrieved.size;
@@ -394,11 +394,11 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// KW }
// KW
// KW if(ERR_NO_MORE_CERTIFICATES == result) {
-// KW LogError("Certificates not found");
+// KW WrtLogE("Certificates not found");
// KW return CERTIFICATE_NOT_FOUND;
// KW }
// KW if(result != OPERATION_SUCCESS){
-// KW LogError("Certificate Manager Error");
+// KW WrtLogE("Certificate Manager Error");
// KW return UNKNOWN_ERROR;
// KW }
// KW return NO_ERROR;
@@ -410,10 +410,10 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
{
(void) curveName;
(void) publicKey;
- LogError("Not implemented.");
+ WrtLogE("Not implemented.");
return UNKNOWN_ERROR;
// if(curveName != OID_CURVE_SECP256R1){
- // LogError("Found field id: " << curveName << " Expected: " << OID_CURVE_SECP256R1);
+ // WrtLogE("Found field id: %s Expected:", curveName.c_str(), OID_CURVE_SECP256R1.c_str());
// return UNSUPPORTED_CERTIFICATE_FIELD;
// }
//
@@ -432,34 +432,34 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// return result;
}
-CertificateLoader::CertificateLoaderResult CertificateLoader::
- loadCertificateFromRawData(const std::string &rawData)
+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.");
+ VcoreTry {
+ m_certificatePtr = CertificatePtr(new Certificate(rawData, Certificate::FORM_BASE64));
+ } VcoreCatch(Certificate::Exception::Base) {
+ WrtLogW("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 (pKey != NULL) {
+ if (pKey->type == EVP_PKEY_RSA) {
+ RSA* pRSA = pKey->pkey.rsa;
- if (pRSA) {
- int keyLength = RSA_size(pRSA);
+ if (pRSA) {
+ int keyLength = RSA_size(pRSA);
- // key Length (modulus) is in bytes
- keyLength <<= 3;
- LogDebug("RSA key length: " << keyLength << " bits");
+ // key Length (modulus) is in bytes
+ keyLength <<= 3;
+ WrtLogD("RSA key length: %d bits", keyLength);
- if (keyLength < MIN_RSA_KEY_LENGTH) {
- LogError(
- "RSA key too short!" << "Has only " << keyLength << " bits");
- return CERTIFICATE_SECURITY_ERROR;
+ if (keyLength < MIN_RSA_KEY_LENGTH) {
+ WrtLogE(
+ "RSA key too short! Has only %d bits", keyLength);
+ return CERTIFICATE_SECURITY_ERROR;
+ }
}
}
}
@@ -483,7 +483,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
//
// if (result != OPERATION_SUCCESS)
// {
-// LogError("Unable to load certificate");
+// WrtLogE("Unable to load certificate");
// return UNKNOWN_ERROR;
// }
//
@@ -512,11 +512,11 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
//
// // key Length (modulus) is in bytes
// keyLength <<= 3;
-// LogDebug("RSA key length: " << keyLength << " bits");
+// WrtLogD("RSA key length: %d bits", keyLength);
//
// if (keyLength < MIN_RSA_KEY_LENGTH)
// {
-// LogError("RSA key too short!" << "Has only " << keyLength << " bits");
+// WrtLogE("RSA key too short! Has only %d bits.", keyLength);
// return CERTIFICATE_SECURITY_ERROR;
// }
// }
@@ -542,7 +542,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
(void) strJ;
(void) strSeed;
(void) strPGenCounter;
- LogError("Not implemented.");
+ WrtLogE("Not implemented.");
return UNKNOWN_ERROR;
// (void)strY;
// (void)strJ;
@@ -578,7 +578,7 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
//
// if (OPERATION_SUCCESS != certmgr_extract_certificate_data(&certRetrieved, &descriptor))
// {
- // LogDebug("unable to retrieve cert from storage");
+ // WrtLogD("unable to retrieve cert from storage");
// continue;
// }
//
@@ -605,9 +605,9 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// BN_cmp(pDSAqBigNum, pDSA->q) == 0 &&
// BN_cmp(pDSAgBigNum, pDSA->g) == 0)
// {
- // LogInfo("DSA Certificate found");
+ // WrtLogI("DSA Certificate found");
// /* TODO load this certificate to m_cmBuff value */
- // LogError("Not implemented!");
+ // WrtLogE("Not implemented!");
//
// EVP_PKEY_free(pKey);
// X509_free(pCertificate);
@@ -639,12 +639,12 @@ CertificateLoader::CertificateLoaderResult CertificateLoader::
// X509_free(pCertificate);
// }
// else
- // LogError("Unable to load certificate");
+ // WrtLogE("Unable to load certificate");
//
// certmgr_release_certificate_data(&descriptor);
// }
//
- // LogError("No DSA certificate with given parameters");
+ // WrtLogE("No DSA certificate with given parameters");
//
// return CERTIFICATE_NOT_FOUND;
}
@@ -654,11 +654,11 @@ bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
{
(void) strNode;
(void) ppBigNum;
- LogError("Not implemented.");
+ WrtLogE("Not implemented.");
return false;
// if (!ppBigNum || *ppBigNum != NULL)
// {
- // LogError("Ptr variable not initialized properly!");
+ // WrtLogE("Ptr variable not initialized properly!");
// return false;
// }
//
@@ -670,7 +670,7 @@ bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
//
// if (!binBuff)
// {
- // LogError("base64 decode failed");
+ // WrtLogE("base64 decode failed");
// return false;
// }
//
@@ -681,7 +681,7 @@ bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
//
// if (!(*ppBigNum))
// {
- // LogError("Conversion from node to bignum failed");
+ // WrtLogE("Conversion from node to bignum failed");
// return false;
// }
//
@@ -692,7 +692,7 @@ bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
// KW {
// KW if (!pBigNum)
// KW {
-// KW LogError("null ptr");
+// KW WrtLogE("null ptr");
// KW return false;
// KW }
// KW
@@ -702,7 +702,7 @@ bool CertificateLoader::convertBase64NodeToBigNum(const std::string& strNode,
// KW // convert bignum to binary format
// KW if (BN_bn2bin(pBigNum, buffer) < 0)
// KW {
-// KW LogError("Conversion from bignum to binary failed");
+// KW WrtLogE("Conversion from bignum to binary failed");
// KW delete []buffer;
// KW return false;
// KW }
diff --git a/vcore/src/vcore/CertificateLoader.h b/vcore/src/vcore/CertificateLoader.h
index de92764..0d4fe04 100644
--- a/vcore/src/vcore/CertificateLoader.h
+++ b/vcore/src/vcore/CertificateLoader.h
@@ -27,7 +27,7 @@
#include <vcore/Certificate.h>
namespace ValidationCore {
-class CertificateLoader : public DPL::Noncopyable
+class CertificateLoader : public VcoreDPL::Noncopyable
{
public:
class CertificateLoaderComparator
diff --git a/vcore/src/vcore/CertificateVerifier.cpp b/vcore/src/vcore/CertificateVerifier.cpp
index ffc0dcc..d683883 100644
--- a/vcore/src/vcore/CertificateVerifier.cpp
+++ b/vcore/src/vcore/CertificateVerifier.cpp
@@ -23,7 +23,7 @@
#include <dpl/assert.h>
#include <dpl/foreach.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
namespace ValidationCore {
@@ -35,7 +35,7 @@ CertificateVerifier::CertificateVerifier(bool enableOcsp, bool enableCrl)
VerificationStatus CertificateVerifier::check(
CertificateCollection &certCollection) const
{
- LogDebug("== Certificate collection validation start ==");
+ WrtLogD("== Certificate collection validation start ==");
Assert(certCollection.isChain() && "Collection must form chain.");
VerificationStatus statusOcsp;
@@ -52,14 +52,14 @@ VerificationStatus CertificateVerifier::check(
} else {
statusCrl = VERIFICATION_STATUS_GOOD;
}
- LogDebug("== Certificate collection validation end ==");
+ WrtLogD("== Certificate collection validation end ==");
return getStatus(statusOcsp, statusCrl);
}
VerificationStatus CertificateVerifier::obtainOcspStatus(
const CertificateCollection &chain) const
{
- LogDebug("== Obtain ocsp status ==");
+ WrtLogD("== Obtain ocsp status ==");
CachedOCSP ocsp;
return ocsp.check(chain);
}
@@ -67,7 +67,7 @@ VerificationStatus CertificateVerifier::obtainOcspStatus(
VerificationStatus CertificateVerifier::obtainCrlStatus(
const CertificateCollection &chain) const
{
- LogDebug("== Obtain crl status ==");
+ WrtLogD("== Obtain crl status ==");
CachedCRL crl;
return crl.check(chain);
}
@@ -79,26 +79,26 @@ VerificationStatus CertificateVerifier::getStatus(
if (ocsp == VERIFICATION_STATUS_REVOKED ||
crl == VERIFICATION_STATUS_REVOKED)
{
- LogDebug("Return status: REVOKED");
+ WrtLogD("Return status: REVOKED");
return VERIFICATION_STATUS_REVOKED;
}
if (ocsp == VERIFICATION_STATUS_GOOD) {
- LogDebug("Return status: GOOD");
+ WrtLogD("Return status: GOOD");
return VERIFICATION_STATUS_GOOD;
}
if (ocsp == VERIFICATION_STATUS_UNKNOWN) {
- LogDebug("Return status: UNKNOWN");
+ WrtLogD("Return status: UNKNOWN");
return VERIFICATION_STATUS_UNKNOWN;
}
if (ocsp == VERIFICATION_STATUS_NOT_SUPPORT) {
- LogDebug("Return status: NOT_SUPPORT");
+ WrtLogD("Return status: NOT_SUPPORT");
return VERIFICATION_STATUS_GOOD;
}
- LogDebug("Return status: ERROR");
+ WrtLogD("Return status: ERROR");
return VERIFICATION_STATUS_ERROR;
}
@@ -125,7 +125,7 @@ VerificationStatus CertificateVerifier::checkEndEntity(
} else {
statusCrl.add(VERIFICATION_STATUS_GOOD);
}
- LogDebug("== Certificate collection validateion end ==");
+ WrtLogD("== Certificate collection validateion end ==");
return getStatus(statusOcsp.convertToStatus(), statusCrl.convertToStatus());
}
diff --git a/vcore/src/vcore/Config.h b/vcore/src/vcore/Config.h
index a810414..8dccbe0 100644
--- a/vcore/src/vcore/Config.h
+++ b/vcore/src/vcore/Config.h
@@ -65,7 +65,7 @@ private:
std::string m_certificateXMLSchemaPath;
};
-typedef DPL::Singleton<Config> ConfigSingleton;
+typedef VcoreDPL::Singleton<Config> ConfigSingleton;
} // namespace ValidationCore
diff --git a/vcore/src/vcore/CryptoHash.cpp b/vcore/src/vcore/CryptoHash.cpp
index 2827b16..7ec4869 100644
--- a/vcore/src/vcore/CryptoHash.cpp
+++ b/vcore/src/vcore/CryptoHash.cpp
@@ -37,42 +37,6 @@ 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()
@@ -87,7 +51,8 @@ Base::~Base()
void Base::Append(const char *buffer)
{
if (m_hasFinal)
- ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+ VcoreThrowMsg(Crypto::Hash::OutOfSequence,
+ "Cannot append hash after final update!");
HashUpdate(buffer, strlen(buffer));
}
@@ -95,7 +60,8 @@ void Base::Append(const char *buffer)
void Base::Append(const char *buffer, size_t bufferSize)
{
if (m_hasFinal)
- ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+ VcoreThrowMsg(Crypto::Hash::OutOfSequence,
+ "Cannot append hash after final update!");
HashUpdate(buffer, bufferSize);
}
@@ -103,7 +69,8 @@ void Base::Append(const char *buffer, size_t bufferSize)
void Base::Append(const std::string &buffer)
{
if (m_hasFinal)
- ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+ VcoreThrowMsg(Crypto::Hash::OutOfSequence,
+ "Cannot append hash after final update!");
HashUpdate(buffer.c_str(), buffer.size());
}
@@ -111,7 +78,8 @@ void Base::Append(const std::string &buffer)
void Base::Append(std::istream &stream)
{
if (m_hasFinal)
- ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+ VcoreThrowMsg(Crypto::Hash::OutOfSequence,
+ "Cannot append hash after final update!");
char buffer[HASH_DIGEST_STREAM_FEED_SIZE];
@@ -128,7 +96,8 @@ void Base::Append(std::istream &stream)
void Base::Append(const void *data, size_t dataSize)
{
if (m_hasFinal)
- ThrowMsg(OutOfSequence, "Cannot append hash after final update!");
+ VcoreThrowMsg(Crypto::Hash::OutOfSequence,
+ "Cannot append hash after final update!");
HashUpdate(data, dataSize);
}
@@ -167,7 +136,8 @@ OpenSSL::OpenSSL(const EVP_MD *evpMd)
EVP_MD_CTX_init(&m_context);
if (EVP_DigestInit(&m_context, evpMd) != 1)
- ThrowMsg(AppendFailed, "EVP_DigestInit failed!");
+ VcoreThrowMsg(Crypto::Hash::AppendFailed,
+ "EVP_DigestInit failed!");
}
OpenSSL::~OpenSSL()
@@ -183,23 +153,27 @@ OpenSSL::~OpenSSL()
void OpenSSL::HashUpdate(const void *data, size_t dataSize)
{
if (m_finalized)
- ThrowMsg(AppendFailed, "OpenSSLHash hash already finalized!");
+ VcoreThrowMsg(Crypto::Hash::AppendFailed,
+ "OpenSSLHash hash already finalized!");
if (EVP_DigestUpdate(&m_context, data, dataSize) != 1)
- ThrowMsg(AppendFailed, "EVP_DigestUpdate failed!");
+ VcoreThrowMsg(Crypto::Hash::AppendFailed,
+ "EVP_DigestUpdate failed!");
}
Hash::Raw OpenSSL::HashFinal()
{
if (m_finalized)
- ThrowMsg(AppendFailed, "OpenSSLHash hash already finalized!");
+ VcoreThrowMsg(Crypto::Hash::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!");
+ VcoreThrowMsg(Crypto::Hash::AppendFailed,
+ "EVP_DigestFinal failed!");
m_finalized = true;
return Raw(hash, hash + hashLength);
diff --git a/vcore/src/vcore/CryptoHash.h b/vcore/src/vcore/CryptoHash.h
index aaed9e0..5611daf 100644
--- a/vcore/src/vcore/CryptoHash.h
+++ b/vcore/src/vcore/CryptoHash.h
@@ -22,32 +22,23 @@
#ifndef _CRYPTO_HASH_H_
#define _CRYPTO_HASH_H_
-#include <dpl/exception.h>
#include <openssl/evp.h>
#include <istream>
#include <string>
#include <vector>
+#include <vcore/exception.h>
+
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)
+VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, OutOfSequence)
+VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, AppendFailed)
class Base
{
diff --git a/vcore/src/vcore/Database.cpp b/vcore/src/vcore/Database.cpp
index 5f03e45..839af32 100644
--- a/vcore/src/vcore/Database.cpp
+++ b/vcore/src/vcore/Database.cpp
@@ -20,5 +20,6 @@
* @brief This file contains the definition of webruntime database
*/
#include <vcore/Database.h>
+#include <mutex>
-DPL::Mutex g_vcoreDbQueriesMutex;
+std::mutex g_vcoreDbQueriesMutex;
diff --git a/vcore/src/vcore/Database.h b/vcore/src/vcore/Database.h
index ca6efa2..f4a5d17 100644
--- a/vcore/src/vcore/Database.h
+++ b/vcore/src/vcore/Database.h
@@ -24,21 +24,21 @@
#include <dpl/db/thread_database_support.h>
#include <dpl/db/sql_connection.h>
-#include <dpl/mutex.h>
#include <dpl/thread.h>
+#include <mutex>
-extern DPL::Mutex g_vcoreDbQueriesMutex;
+extern std::mutex g_vcoreDbQueriesMutex;
#define VCORE_DB_INTERNAL(tlsCommand, InternalType, interface) \
- static DPL::ThreadLocalVariable<InternalType> *tlsCommand ## Ptr = NULL; \
+ static VcoreDPL::ThreadLocalVariable<InternalType> *tlsCommand ## Ptr = NULL; \
{ \
- DPL::Mutex::ScopedLock lock(&g_vcoreDbQueriesMutex); \
+ std::lock_guard<std::mutex> lock(g_vcoreDbQueriesMutex); \
if (!tlsCommand ## Ptr) { \
- static DPL::ThreadLocalVariable<InternalType> tmp; \
+ static VcoreDPL::ThreadLocalVariable<InternalType> tmp; \
tlsCommand ## Ptr = &tmp; \
} \
} \
- DPL::ThreadLocalVariable<InternalType> &tlsCommand = *tlsCommand ## Ptr; \
+ VcoreDPL::ThreadLocalVariable<InternalType> &tlsCommand = *tlsCommand ## Ptr; \
if (tlsCommand.IsNull()) { tlsCommand = InternalType(interface); }
#define VCORE_DB_SELECT(name, type, interface) \
diff --git a/vcore/src/vcore/DeveloperModeValidator.cpp b/vcore/src/vcore/DeveloperModeValidator.cpp
deleted file mode 100644
index a861728..0000000
--- a/vcore/src/vcore/DeveloperModeValidator.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a0c37ba..0000000
--- a/vcore/src/vcore/DeveloperModeValidator.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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/OCSP.cpp b/vcore/src/vcore/OCSP.cpp
index 26f81c3..1e94b17 100644
--- a/vcore/src/vcore/OCSP.cpp
+++ b/vcore/src/vcore/OCSP.cpp
@@ -24,11 +24,12 @@
namespace ValidationCore {
-OCSP::OCSP() :
- m_impl(new OCSPImpl())
+OCSP::OCSP()
+ : m_impl(new OCSPImpl())
{}
-OCSP::~OCSP(){
+OCSP::~OCSP()
+{
delete m_impl;
}
diff --git a/vcore/src/vcore/OCSP.h b/vcore/src/vcore/OCSP.h
index 59c6969..76ac117 100644
--- a/vcore/src/vcore/OCSP.h
+++ b/vcore/src/vcore/OCSP.h
@@ -25,8 +25,6 @@
#include <ctime>
-#include <dpl/noncopyable.h>
-
#include <vcore/Certificate.h>
#include <vcore/CertificateCollection.h>
#include <vcore/VerificationStatus.h>
@@ -35,9 +33,12 @@ namespace ValidationCore {
class OCSPImpl;
-class OCSP : DPL::Noncopyable
-{
+class OCSP {
public:
+
+ OCSP(const OCSP &) = delete;
+ const OCSP &operator=(const OCSP &) = delete;
+
OCSP();
VerificationStatus checkEndEntity(const CertificateCollection &certList);
@@ -82,6 +83,7 @@ public:
virtual ~OCSP();
private:
OCSPImpl *m_impl;
+
};
} // namespace ValidationCore
diff --git a/vcore/src/vcore/OCSPCertMgrUtil.cpp b/vcore/src/vcore/OCSPCertMgrUtil.cpp
index 5db4290..019cd1f 100644
--- a/vcore/src/vcore/OCSPCertMgrUtil.cpp
+++ b/vcore/src/vcore/OCSPCertMgrUtil.cpp
@@ -27,7 +27,8 @@
#include <openssl/pem.h>
#include <openssl/x509.h>
-#include <dpl/log/log.h>
+#include <dpl/assert.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/scoped_resource.h>
#include <string.h>
#include <iostream>
@@ -68,11 +69,11 @@ void getCertFromStore(X509_NAME *subject,
X509 **xcert)
{
if (!xcert || *xcert || !subject) {
- LogError("Invalid input!");
+ WrtLogE("Invalid input!");
return;
}
- typedef DPL::ScopedResource<ContextDeleter> ScopedContext;
+ typedef VcoreDPL::ScopedResource<ContextDeleter> ScopedContext;
int result;
char buffer[MAX_BUF];
@@ -84,43 +85,43 @@ void getCertFromStore(X509_NAME *subject,
ScopedContext ctx(cert_svc_cert_context_init());
if (ctx.Get() == NULL) {
- LogWarning("Error in cert_svc_cert_context_init.");
+ WrtLogW("Error in cert_svc_cert_context_init.");
return;
}
- LogDebug("Search certificate with subject: " << buffer);
+ WrtLogD("Search certificate with subject: %s", buffer);
result = cert_svc_search_certificate(ctx.Get(), SUBJECT_STR, buffer);
- LogDebug("Search finished!");
+ WrtLogD("Search finished!");
if (CERT_SVC_ERR_NO_ERROR != result) {
- LogWarning("Error during certificate search");
+ WrtLogW("Error during certificate search");
return;
}
fileList = ctx.Get()->fileNames;
if (fileList == NULL) {
- LogDebug("No certificate found");
+ WrtLogD("No certificate found");
return;
}
if (fileList->filename == NULL) {
- LogWarning("Empty filename");
+ WrtLogW("Empty filename");
return;
}
- LogDebug("Found cert file: " << fileList->filename);
+ WrtLogD("Found cert file: %s", fileList->filename);
ScopedContext ctx2(cert_svc_cert_context_init());
if (ctx2.Get() == NULL) {
- LogWarning("Error in cert_svc_cert_context_init.");
+ WrtLogW("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");
+ WrtLogW("Error in cert_svc_load_file_to_context");
return;
}
@@ -129,20 +130,18 @@ void getCertFromStore(X509_NAME *subject,
pCertificate = d2i_X509(NULL, &ptr, ctx2.Get()->certBuf->size);
if (pCertificate == NULL) {
- LogWarning("Error during certificate conversion in d2i_X509");
+ WrtLogW("Error during certificate conversion in d2i_X509");
return;
}
*xcert = pCertificate;
if (fileList->next != NULL) {
- LogError("There is more then one certificate with same subject :/");
+ WrtLogE("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);
+ WrtLogE("Additional certificate with same subject: %s", fileList->filename);
}
}
}
diff --git a/vcore/src/vcore/OCSPImpl.cpp b/vcore/src/vcore/OCSPImpl.cpp
index face891..98fc030 100644
--- a/vcore/src/vcore/OCSPImpl.cpp
+++ b/vcore/src/vcore/OCSPImpl.cpp
@@ -22,7 +22,6 @@
* @brief Routines for certificate validation over OCSP
*/
-#include <vcore/OCSP.h>
#include <vcore/OCSPImpl.h>
#include <string.h>
@@ -32,11 +31,11 @@
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
+#include <boost/optional.hpp>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/assert.h>
#include <dpl/foreach.h>
-#include <dpl/scoped_array.h>
#include <dpl/scoped_free.h>
#include <libsoup/soup.h>
@@ -100,21 +99,19 @@ OCSPImpl::OCSPImpl() :
m_bUseDefResponder(false),
m_bSignRequest(false),
m_pSignKey(0)
-{
-}
+{}
SoupWrapper::SoupMessageSendBase::RequestStatus OCSPImpl::sendOcspRequest(
OCSP_REQUEST* argRequest,
- const DPL::OptionalString& argUri)
+ const std::string& 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");
+ VcoreThrowMsg(OCSPImpl::Exception::VerificationError,
+ "OCSP: failed to convert OCSP_REQUEST to mem buffer");
}
Assert(requestSizeInt >= 0);
@@ -127,13 +124,13 @@ SoupWrapper::SoupMessageSendBase::RequestStatus OCSPImpl::sendOcspRequest(
char *cport = 0,*chost = 0,*cpath = 0;
int use_ssl = 0;
- if (!OCSP_parse_url(const_cast<char*>(url.c_str()),
+ if (!OCSP_parse_url(const_cast<char*>(argUri.c_str()),
&chost,
&cport,
&cpath,
&use_ssl))
{
- LogWarning("Error in OCSP_parse_url");
+ WrtLogW("Error in OCSP_parse_url");
return SoupMessageSendBase::REQUEST_STATUS_CONNECTION_ERROR;
}
@@ -148,7 +145,7 @@ SoupWrapper::SoupMessageSendBase::RequestStatus OCSPImpl::sendOcspRequest(
free(chost);
free(cpath);
- m_soupMessage.setHost(url);
+ m_soupMessage.setHost(argUri);
m_soupMessage.setHeader("Host", host);
m_soupMessage.setRequest(std::string("application/ocsp-request"),
buffer);
@@ -163,9 +160,8 @@ ValidationCore::VerificationStatusSet OCSPImpl::validateCertificateList(
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());
+ WrtLogW("No validation will be proceed. OCSP require at"
+ " least 2 certificates in chain. Found only %d", certs.size());
statusSet.add(VERIFICATION_STATUS_ERROR);
return statusSet;
}
@@ -173,7 +169,7 @@ ValidationCore::VerificationStatusSet OCSPImpl::validateCertificateList(
CertificatePtr root = certs.back();
CertStoreId::Set storedSetId = createCertificateIdentifier().find(root);
char* ocspUrl = storedSetId.getOcspUrl();
-
+
if (ocspUrl != NULL)
{
setUseDefaultResponder(true);
@@ -185,10 +181,8 @@ ValidationCore::VerificationStatusSet OCSPImpl::validateCertificateList(
time_t minValidity = 0;
for (++parent; parent != certs.end(); ++iter, ++parent) {
- LogDebug("Certificate validation (CN:" <<
- (*iter)->getOneLine() << ")");
- LogDebug("Parent certificate (CN:" <<
- (*parent)->getOneLine() << ")");
+ WrtLogD("Certificate validation (CN:%s)", (*iter)->getOneLine().c_str());
+ WrtLogD("Parent certificate (CN:%s)", (*parent)->getOneLine().c_str());
statusSet.add(validateCertificate(*iter, *parent));
if ((0 == minValidity || minValidity > m_responseValidity) &&
m_responseValidity > 0)
@@ -227,20 +221,20 @@ VerificationStatus OCSPImpl::validateCertificate(CertificatePtr argCert,
Assert(!!argCert);
Assert(!!argIssuer);
- Try {
- DPL::OptionalString uri;
+ VcoreTry {
+ std::string uri;
if (!m_bUseDefResponder) {
uri = argCert->getOCSPURL();
- if (!uri) {
+ if (uri.empty()) {
return VERIFICATION_STATUS_NOT_SUPPORT;
}
} else {
if (m_strResponderURI.empty()) {
- ThrowMsg(Exception::VerificationError,
- "Default responder is not set");
+ VcoreThrowMsg(OCSPImpl::Exception::VerificationError,
+ "Default responder is not set");
}
- LogWarning("Default responder will be used");
+ WrtLogW("Default responder will be used");
uri = m_strResponderURI;
}
@@ -248,7 +242,7 @@ VerificationStatus OCSPImpl::validateCertificate(CertificatePtr argCert,
// creates a request
CreateRequestResult newRequest = createRequest(argCert, argIssuer);
if (!newRequest.success) {
- ThrowMsg(Exception::VerificationError, "Request creation failed");
+ VcoreThrowMsg(OCSPImpl::Exception::VerificationError, "Request creation failed");
}
// SSLSmartContainer <OCSP_CERTID> certIdCont(certId);
@@ -267,8 +261,8 @@ VerificationStatus OCSPImpl::validateCertificate(CertificatePtr argCert,
OcspResponse response = convertToResponse();
if (!response.first) {
- ThrowMsg(OCSPImpl::Exception::VerificationError,
- "OCSP: failed to convert mem buffer to OCSP_RESPONSE");
+ VcoreThrowMsg(OCSPImpl::Exception::VerificationError,
+ "OCSP: failed to convert mem buffer to OCSP_RESPONSE");
}
SSLSmartContainer <OCSP_RESPONSE> responseCont(response.second);
@@ -277,33 +271,49 @@ VerificationStatus OCSPImpl::validateCertificate(CertificatePtr argCert,
validateResponse(requestCont,
responseCont,
newRequest.ocspCertId);
- } Catch(Exception::ConnectionError) {
- LogWarning("OCSP: ConnectionError");
+ } VcoreCatch(OCSPImpl::Exception::ConnectionError) {
+ WrtLogW("OCSP: ConnectionError");
return VERIFICATION_STATUS_CONNECTION_FAILED;
- } Catch(Exception::CertificateRevoked) {
- LogWarning("OCSP: Revoked");
+ } VcoreCatch(OCSPImpl::Exception::CertificateRevoked) {
+ WrtLogW("OCSP: Revoked");
return VERIFICATION_STATUS_REVOKED;
- } Catch(Exception::CertificateUnknown) {
- LogWarning("OCSP: Unknown");
+ } VcoreCatch(OCSPImpl::Exception::CertificateUnknown) {
+ WrtLogW("OCSP: Unknown");
return VERIFICATION_STATUS_UNKNOWN;
- } Catch(Exception::VerificationError) {
- LogWarning("OCSP: Verification error");
+ } VcoreCatch(OCSPImpl::Exception::VerificationError) {
+ WrtLogW("OCSP: Verification error");
return VERIFICATION_STATUS_VERIFICATION_ERROR;
- } Catch(Exception::Base) {
- LogWarning("OCSP: Error");
+ } VcoreCatch(OCSPImpl::Exception::Base) {
+ WrtLogW("OCSP: Error");
return VERIFICATION_STATUS_ERROR;
}
- LogWarning("OCSP: Good");
+ WrtLogW("OCSP: Good");
return VERIFICATION_STATUS_GOOD;
}
+void OCSPImpl::setDefaultResponder(const char *uri)
+{
+ Assert(uri);
+ m_strResponderURI = std::string(uri);
+}
+
+void OCSPImpl::setUseDefaultResponder(bool value)
+{
+ m_bUseDefResponder = value;
+}
+
+time_t OCSPImpl::getResponseValidity()
+{
+ return m_responseValidity;
+}
+
OCSPImpl::CreateRequestResult OCSPImpl::createRequest(CertificatePtr argCert,
CertificatePtr argIssuer)
{
OCSP_REQUEST* newRequest = OCSP_REQUEST_new();
if (!newRequest) {
- LogWarning("OCSP: Failed to create a request");
+ WrtLogW("OCSP: Failed to create a request");
return CreateRequestResult();
}
@@ -312,14 +322,14 @@ OCSPImpl::CreateRequestResult OCSPImpl::createRequest(CertificatePtr argCert,
OCSP_CERTID* certId = addSerial(argCert, argIssuer);
if (!certId) {
- LogWarning("OCSP: Unable to create a serial id");
+ WrtLogW("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");
+ WrtLogW("OCSP: Unable to create a certificate id");
return CreateRequestResult();
}
@@ -329,7 +339,7 @@ OCSPImpl::CreateRequestResult OCSPImpl::createRequest(CertificatePtr argCert,
if (m_bSignRequest) {
if (!m_pSignCert || !m_pSignKey) {
- LogWarning("OCSP: Unable to sign request if "
+ WrtLogW("OCSP: Unable to sign request if "
"SignCert or SignKey was not set");
return CreateRequestResult();
}
@@ -341,7 +351,7 @@ OCSPImpl::CreateRequestResult OCSPImpl::createRequest(CertificatePtr argCert,
0,
0))
{
- LogWarning("OCSP: Unable to sign request");
+ WrtLogW("OCSP: Unable to sign request");
return CreateRequestResult();
}
}
@@ -367,7 +377,7 @@ void OCSPImpl::setDigestAlgorithmForCertId(OCSP::DigestAlgorithm alg)
if (NULL != foundAlg) {
m_pCertIdDigestAlg = foundAlg;
} else {
- LogDebug("Request for unsupported CertId digest algorithm"
+ WrtLogD("Request for unsupported CertId digest algorithm"
"ignored!");
}
}
@@ -379,7 +389,7 @@ void OCSPImpl::setDigestAlgorithmForRequest(OCSP::DigestAlgorithm alg)
if (NULL != foundAlg) {
m_pRequestDigestAlg = foundAlg;
} else {
- LogDebug("Request for unsupported OCSP request digest algorithm"
+ WrtLogD("Request for unsupported OCSP request digest algorithm"
"ignored!");
}
}
@@ -402,24 +412,24 @@ void OCSPImpl::validateResponse(OCSP_REQUEST* argRequest,
if (result != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
handleInvalidResponse(result);
- ThrowMsg(Exception::VerificationError, "OCSP_response_status failed");
+ VcoreThrowMsg(OCSPImpl::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.");
+ VcoreThrowMsg(OCSPImpl::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");
+ VcoreThrowMsg(OCSPImpl::Exception::VerificationError, "OCSP: Invalid nonce");
}
if (!verifyResponse(basic)) {
- ThrowMsg(Exception::VerificationError,
- "Unable to verify the OCSP responder's certificate");
+ VcoreThrowMsg(OCSPImpl::Exception::VerificationError,
+ "Unable to verify the OCSP responder's certificate");
}
checkRevocationStatus(basicRespCont, argCertId);
@@ -431,7 +441,7 @@ bool OCSPImpl::verifyResponse(OCSP_BASICRESP* basic)
// verify ocsp response
int response = OCSP_basic_verify(basic, NULL, m_pTrustedStore, 0);
if (response <= 0) {
- LogWarning("OCSP verification failed");
+ WrtLogW("OCSP verification failed");
}
return response > 0;
@@ -456,8 +466,8 @@ void OCSPImpl::checkRevocationStatus(OCSP_BASICRESP* basic,
&thisUpdate,
&nextUpdate))
{
- ThrowMsg(Exception::VerificationError,
- "OCSP: Failed to find certificate status.");
+ VcoreThrowMsg(OCSPImpl::Exception::VerificationError,
+ "OCSP: Failed to find certificate status.");
}
if (!OCSP_check_validity(thisUpdate,
@@ -465,27 +475,26 @@ void OCSPImpl::checkRevocationStatus(OCSP_BASICRESP* basic,
MaxValidatyPeriodInSeconds,
MaxAge))
{
- ThrowMsg(Exception::VerificationError,
- "OCSP: Failed to check certificate validate.");
+ VcoreThrowMsg(OCSPImpl::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);
+ WrtLogD("Time of next OCSP update got from server: %d", m_responseValidity);
+ WrtLogD("Expires in: %d", (m_responseValidity - now));
+ WrtLogD("Original: %d", nextUpdate->data);
}
switch (status) {
case V_OCSP_CERTSTATUS_GOOD:
return;
case V_OCSP_CERTSTATUS_REVOKED:
- ThrowMsg(Exception::CertificateRevoked, "Certificate is Revoked");
+ VcoreThrowMsg(OCSPImpl::Exception::CertificateRevoked, "Certificate is Revoked");
case V_OCSP_CERTSTATUS_UNKNOWN:
- ThrowMsg(Exception::CertificateUnknown, "Certificate is Unknown");
+ VcoreThrowMsg(OCSPImpl::Exception::CertificateUnknown, "Certificate is Unknown");
default:
Assert(false && "Invalid status");
}
@@ -512,7 +521,7 @@ OCSPImpl::OcspResponse OCSPImpl::convertToResponse()
BIO_free_all(res_mem_bio);
if (!response) {
- LogWarning("OCSP: Failed to convert OCSP Response to DER format");
+ WrtLogW("OCSP: Failed to convert OCSP Response to DER format");
return std::make_pair(false, static_cast<OCSP_RESPONSE*>(NULL));
}
@@ -523,23 +532,23 @@ void OCSPImpl::handleInvalidResponse(int result)
{
switch (result) {
case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
- LogWarning("OCSP: Server returns "
+ WrtLogW("OCSP: Server returns "
"OCSP_RESPONSE_STATUS_MALFORMEDREQUEST status");
break;
case OCSP_RESPONSE_STATUS_INTERNALERROR:
- LogWarning("OCSP: Server returns "
+ WrtLogW("OCSP: Server returns "
"OCSP_RESPONSE_STATUS_INTERNALERROR status");
break;
case OCSP_RESPONSE_STATUS_TRYLATER:
- LogWarning("OCSP: Server returns "
+ WrtLogW("OCSP: Server returns "
"OCSP_RESPONSE_STATUS_TRYLATER status");
break;
case OCSP_RESPONSE_STATUS_SIGREQUIRED:
- LogWarning("OCSP: Server returns "
+ WrtLogW("OCSP: Server returns "
"OCSP_RESPONSE_STATUS_SIGREQUIRED status");
break;
case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
- LogWarning("OCSP: Server returns "
+ WrtLogW("OCSP: Server returns "
"OCSP_RESPONSE_STATUS_UNAUTHORIZED status");
break;
default:
diff --git a/vcore/src/vcore/OCSPImpl.h b/vcore/src/vcore/OCSPImpl.h
index 11cd647..00f568f 100644
--- a/vcore/src/vcore/OCSPImpl.h
+++ b/vcore/src/vcore/OCSPImpl.h
@@ -36,9 +36,6 @@
#include <openssl/ocsp.h>
#include <libsoup/soup.h>
-#include <dpl/assert.h>
-#include <dpl/exception.h>
-
#include <vcore/scoped_gpointer.h>
#include <vcore/OCSPCertMgrUtil.h>
#include <vcore/CertificateCollection.h>
@@ -48,6 +45,7 @@
#include <vcore/SoupMessageSendBase.h>
#include <vcore/SoupMessageSendSync.h>
#include <vcore/TimeConversion.h>
+#include <vcore/exception.h>
/*
* The WRT MUST NOT allow installation of widgets with revoked signatures.
*
@@ -82,13 +80,13 @@
namespace ValidationCore {
-class OCSPImpl
-{
- public:
+class OCSPImpl {
+public:
+ OCSPImpl();
+
static const char* DEFAULT_RESPONDER_URI_ENV;
VerificationStatus checkEndEntity(const CertificateCollection &certList);
- OCSPImpl();
/**
* Sets digest algorithm for certid in ocsp request
@@ -107,28 +105,28 @@ class OCSPImpl
VerificationStatus validateCertificate(CertificatePtr argCert,
CertificatePtr argIssuer);
- void setDefaultResponder(const char* uri)
- {
- Assert(uri);
- m_strResponderURI = DPL::FromUTF8String(uri);
- }
+ void setDefaultResponder(const char* uri);
- void setUseDefaultResponder(bool value)
- {
- m_bUseDefResponder = value;
- }
+ 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()
- {
- return m_responseValidity;
- }
-
- private:
+ time_t getResponseValidity();
+
+private:
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, ConnectionError)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, CertificateRevoked)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, CertificateUnknown)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, VerificationError)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, RetrieveCertFromStoreError)
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, VerificationNotSupport)
+ };
typedef WRT::ScopedGPointer<SoupSession> ScopedSoupSession;
typedef WRT::ScopedGPointer<SoupMessage> ScopedSoupMessage;
@@ -146,18 +144,6 @@ class OCSPImpl
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;
@@ -165,7 +151,7 @@ class OCSPImpl
SoupWrapper::SoupMessageSendBase::RequestStatus sendOcspRequest(
OCSP_REQUEST* argRequest,
- const DPL::String& argUri);
+ const std::string& argUri);
@@ -220,7 +206,7 @@ class OCSPImpl
time_t m_responseValidity;
bool m_bUseNonce;
bool m_bUseDefResponder;
- DPL::String m_strResponderURI;
+ std::string m_strResponderURI;
bool m_bSignRequest;
EVP_PKEY* m_pSignKey;
CertificatePtr m_pSignCert;
diff --git a/vcore/src/vcore/ParserSchema.h b/vcore/src/vcore/ParserSchema.h
index ed9eb68..8e7b507 100644
--- a/vcore/src/vcore/ParserSchema.h
+++ b/vcore/src/vcore/ParserSchema.h
@@ -25,25 +25,23 @@
#include <map>
#include <string>
-#include <dpl/log/log.h>
-
#include <vcore/SaxReader.h>
+#include <vcore/exception.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)
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, XmlReaderError);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, CertificateLoaderError);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, UnsupportedAlgorithm);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, UnsupportedValue);
}
template<typename ParserType, typename DataType>
-class ParserSchema
-{
- public:
- struct TagDescription
- {
+class ParserSchema {
+public:
+
+ struct TagDescription {
TagDescription(const std::string &tag,
const std::string & xmlNamespace) :
tagName(tag),
@@ -69,27 +67,25 @@ class ParserSchema
}
};
- ParserSchema(ParserType * parser) :
- m_functions(parser)
- {
- }
- virtual ~ParserSchema()
- {
- }
+ ParserSchema(ParserType *parser)
+ : m_functions(parser) {}
+
+ virtual ~ParserSchema() {}
- void initialize(const std::string &filename,
+ void initialize(
+ const std::string &filename,
bool defaultArgs,
SaxReader::ValidationType valType,
const std::string &xmlschema)
{
- Try
+ VcoreTry
{
m_reader.initialize(filename, defaultArgs, valType, xmlschema);
}
- Catch(SaxReader::Exception::Base)
+ VcoreCatch (SaxReader::Exception::Base)
{
- ReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
+ VcoreReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
}
}
@@ -100,7 +96,8 @@ class ParserSchema
void read(DataType &dataContainer)
{
- Try {
+ VcoreTry
+ {
while (m_reader.next()) {
switch (m_reader.type()) {
case SaxReader::NODE_BEGIN:
@@ -113,21 +110,21 @@ class ParserSchema
textNode(dataContainer);
break;
default:
- // LogInfo("Unknown Type Node");
break;
}
}
}
- Catch(SaxReader::Exception::Base)
+ VcoreCatch (SaxReader::Exception::Base)
{
- ReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
+ VcoreReThrowMsg(ParserSchemaException::XmlReaderError, "XmlReaderError");
}
}
typedef void (ParserType::*FunctionPtr)(DataType &data);
typedef std::map<TagDescription, FunctionPtr> FunctionMap;
- void addBeginTagCallback(const std::string &tag,
+ void addBeginTagCallback(
+ const std::string &tag,
const std::string &namespaceUri,
FunctionPtr function)
{
@@ -135,7 +132,8 @@ class ParserSchema
m_beginFunctionMap[desc] = function;
}
- void addEndTagCallback(const std::string &tag,
+ void addEndTagCallback(
+ const std::string &tag,
const std::string &namespaceUri,
FunctionPtr function)
{
@@ -143,24 +141,23 @@ class ParserSchema
m_endFunctionMap[desc] = function;
}
- SaxReader& getReader(void)
+ SaxReader& getReader()
{
return m_reader;
}
- std::string& getText(void)
+ std::string& getText()
{
return m_textNode;
}
- protected:
+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;
}
@@ -173,7 +170,6 @@ class ParserSchema
FunctionPtr fun = m_endFunctionMap[desc];
if (fun == 0) {
- LogDebug("No function found for xml tag: " << m_reader.name());
return;
}
@@ -187,7 +183,6 @@ class ParserSchema
}
ParserType *m_functions;
-
SaxReader m_reader;
FunctionMap m_beginFunctionMap;
FunctionMap m_endFunctionMap;
@@ -195,5 +190,6 @@ class ParserSchema
// 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
index e99436c..188a24e 100644
--- a/vcore/src/vcore/ReferenceValidator.cpp
+++ b/vcore/src/vcore/ReferenceValidator.cpp
@@ -29,7 +29,7 @@
#include <pcrecpp.h>
#include <dpl/errno_string.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
namespace {
@@ -97,7 +97,7 @@ 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.");
+ WrtLogE("Symbol '%c' is out of scope.", a);
throw ERROR_DECODING_URL;
}
@@ -125,7 +125,7 @@ std::string ReferenceValidator::Impl::decodeProcent(const std::string &path) {
}
}
} catch (Result &) {
- LogError("Error while decoding url path: " << path);
+ WrtLogE("Error while decoding url path: %s", path.c_str());
throw ERROR_DECODING_URL;
}
return std::string(output.begin(), output.end());
@@ -138,14 +138,10 @@ ReferenceValidator::Result ReferenceValidator::Impl::dfsCheckDirectories(
{
DIR *dp;
struct dirent *dirp;
- std::string currentDir = m_dirpath;
- if (!directory.empty()) {
- currentDir += "/";
- currentDir += directory;
- }
+ std::string currentDir = m_dirpath + directory;
if ((dp = opendir(currentDir.c_str())) == NULL) {
- LogError("Error opening directory: " << currentDir.c_str());
+ WrtLogE("Error opening directory: %s", currentDir.c_str());
m_errorDescription = currentDir;
return ERROR_OPENING_DIR;
}
@@ -172,7 +168,7 @@ ReferenceValidator::Result ReferenceValidator::Impl::dfsCheckDirectories(
}
if (dirp->d_type == DT_DIR) {
- LogDebug("Open directory: " << (directory + dirp->d_name));
+ WrtLogD("Open directory: %s", (directory + dirp->d_name).c_str());
std::string tmp_directory = directory + dirp->d_name + "/";
Result result = dfsCheckDirectories(referenceSet,
tmp_directory,
@@ -185,14 +181,14 @@ ReferenceValidator::Result ReferenceValidator::Impl::dfsCheckDirectories(
if (referenceSet.end() ==
referenceSet.find(directory + dirp->d_name))
{
- LogDebug("Found file: " << (directory + dirp->d_name));
- LogError("Unknown ERROR_REFERENCE_NOT_FOUND.");
+ WrtLogD("Found file: %s", (directory + dirp->d_name).c_str());
+ WrtLogE("Unknown ERROR_REFERENCE_NOT_FOUND.");
closedir(dp);
m_errorDescription = directory + dirp->d_name;
return ERROR_REFERENCE_NOT_FOUND;
}
} else {
- LogError("Unknown file type.");
+ WrtLogE("Unknown file type.");
closedir(dp);
m_errorDescription = directory + dirp->d_name;
return ERROR_UNSUPPORTED_FILE_TYPE;
@@ -200,9 +196,8 @@ ReferenceValidator::Result ReferenceValidator::Impl::dfsCheckDirectories(
}
if (errno != 0) {
- m_errorDescription = DPL::GetErrnoString();
- LogError("readdir failed. Errno code: " << errno <<
- " Description: " << m_errorDescription);
+ m_errorDescription = VcoreDPL::GetErrnoString();
+ WrtLogE("readdir failed. Errno code: %d, Description: ", errno, m_errorDescription.c_str());
closedir(dp);
return ERROR_READING_DIR;
}
diff --git a/vcore/src/vcore/ReferenceValidator.h b/vcore/src/vcore/ReferenceValidator.h
index d7d964f..b370773 100644
--- a/vcore/src/vcore/ReferenceValidator.h
+++ b/vcore/src/vcore/ReferenceValidator.h
@@ -28,7 +28,7 @@
namespace ValidationCore {
-class ReferenceValidator : DPL::Noncopyable
+class ReferenceValidator : VcoreDPL::Noncopyable
{
public:
enum Result
diff --git a/vcore/src/vcore/RevocationCheckerBase.cpp b/vcore/src/vcore/RevocationCheckerBase.cpp
index 8aa1d62..777da78 100644
--- a/vcore/src/vcore/RevocationCheckerBase.cpp
+++ b/vcore/src/vcore/RevocationCheckerBase.cpp
@@ -28,19 +28,17 @@
#include <dpl/scoped_fclose.h>
-#include <tzplatform_config.h>
-
#include "Certificate.h"
#include "CertificateCollection.h"
namespace {
-const char *DefaultBundlePatch = tzplatform_mkpath(TZ_SYS_ETC, "ssl/certs/ca-certificates.crt");
+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"));
+ VcoreDPL::ScopedFClose fd(fopen(fileName, "rb"));
// no such file, return NULL
if (!fd.Get()) {
diff --git a/vcore/src/vcore/SaxReader.cpp b/vcore/src/vcore/SaxReader.cpp
index 1a0261b..5c49ece 100644
--- a/vcore/src/vcore/SaxReader.cpp
+++ b/vcore/src/vcore/SaxReader.cpp
@@ -20,12 +20,13 @@
* @brief Simple c++ interface for libxml2.
*/
#include <dpl/assert.h>
-#include <dpl/exception.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <vcore/SaxReader.h>
namespace ValidationCore {
+
+
SaxReader::SaxReader() :
m_reader(0)
{
@@ -38,54 +39,49 @@ SaxReader::~SaxReader()
}
}
-void SaxReader::initialize(const std::string &filename,
- bool defaultArgs,
- ValidationType validate,
- const std::string &schema)
+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);
+ WrtLogD("SaxReader opening file: %s", filename.c_str());
- /*
- * 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 (!m_reader) {
+ VcoreThrowMsg(SaxReader::Exception::FileOpeningError,
+ "opening file " << filename << " error");
}
+
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!");
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "Turn on Schema 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!");
+ VcoreThrowMsg(SaxReader::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!");
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "Turn on default arguments failed");
}
}
@@ -99,149 +95,117 @@ bool SaxReader::next()
{
int res = xmlTextReaderRead(m_reader);
- if (0 == xmlTextReaderIsValid(m_reader)) {
- LogWarning("Throw exception file not valid!");
- Throw(Exception::FileNotValid);
- }
+ if (res < 0)
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "xmlTextReaderRead error");
- if (res == 1) {
- return true;
- }
+ if (!xmlTextReaderIsValid(m_reader))
+ VcoreThrowMsg(SaxReader::Exception::FileNotValid,
+ "xmlTextReader is invalid");
- if (res == 0) {
- return false;
- }
- LogError("ParserInternalError");
- Throw(Exception::ParserInternalError);
+ return res ? true : false;
}
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);
- }
+ int res = xmlTextReaderRead(m_reader);
+
+ if (res < 0)
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "xmlTextReaderRead error");
+
+ if (!xmlTextReaderIsValid(m_reader))
+ VcoreThrowMsg(SaxReader::Exception::FileNotValid,
+ "xmlTextReader is invalid");
xmlChar *name = xmlTextReaderName(m_reader);
- if (name == NULL) {
- /*
- * invalid file
- */
- LogWarning("File not Valid");
- Throw(Exception::FileNotValid);
- }
+ if (!name)
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "xmlTextReaderName returns NULL");
- if (token == reinterpret_cast<const char*>(name)) {
- xmlFree(name);
- } else {
- /*
- * we encountered wrong token
- */
+ xmlChar *xmlToken = xmlCharStrdup(token.c_str());
+
+ if (xmlStrcmp(name, xmlToken)) {
xmlFree(name);
- LogWarning("Wrong Token");
- Throw(Exception::WrongToken);
+ xmlFree(xmlToken);
+
+ VcoreThrowMsg(SaxReader::Exception::WrongToken, "Wrong Token");
}
+
+ xmlFree(name);
+ xmlFree(xmlToken);
}
bool SaxReader::isEmpty(void)
{
int ret = xmlTextReaderIsEmptyElement(m_reader);
- if (-1 == ret) {
- LogError("Parser Internal Error");
- Throw(Exception::ParserInternalErrorInEmptyQuery);
- }
- return ret;
+ if (-1 == ret)
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "xmlTextReaderIsEmptyElement error");
+
+ return ret ? true : false;
}
-std::string SaxReader::attribute(const std::string &token,
- ThrowType throwStatus)
+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);
+ if (!attr) {
+ if (throwStatus == THROW_DISABLE) {
+ return std::string();
+ }
+ else {
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "xmlTextReaderGetAttribute error");
+ }
}
- /*
- * cast it to val and return it
- */
- value = reinterpret_cast<const char *>(attr);
+ std::string 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);
+ if (!name)
+ VcoreThrowMsg(SaxReader::Exception::ReadingNameError,
+ "reading name error");
+
+ std::string 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);
+ if (!name) {
+ return std::string();
}
+
+ std::string 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
- */
+ if (!text)
+ VcoreThrowMsg(SaxReader::Exception::ReadingValueError,
+ "reading value error");
+
+ std::string value = reinterpret_cast<const char*>(text);
xmlFree(text);
+
return value;
}
@@ -278,31 +242,20 @@ SaxReader::NodeType SaxReader::type()
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
- */
+ if (!node) {
xmlBufferFree(buff);
- LogError("Parser Internal Error");
- Throw(Exception::ParserInternalError);
+ VcoreThrowMsg(SaxReader::Exception::ParserInternalError,
+ "xmlTextReaderExpand error");
}
- /*
- * 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);
+ int size = xmlNodeDump(buff, node->doc, node, 0, 0);
+ if (size > 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
index 3fd4efc..000ce1c 100644
--- a/vcore/src/vcore/SaxReader.h
+++ b/vcore/src/vcore/SaxReader.h
@@ -26,31 +26,25 @@
#include <string>
#include <libxml/xmlreader.h>
-#include <dpl/exception.h>
+
+#include <vcore/exception.h>
namespace ValidationCore {
-class SaxReader
-{
- public:
+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)
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, FileOpeningError);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, FileNotValid);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, ParserInternalError);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, WrongToken);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, ReadingValueError);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, ReadingNameError);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, UnsupportedType);
};
enum NodeType
@@ -80,7 +74,8 @@ class SaxReader
/*
* initializes parser
*/
- void initialize(const std::string &filename,
+ void initialize(
+ const std::string &filename,
bool defaultArgs = false,
ValidationType validation = VALIDATION_DISABLE,
const std::string &schema = std::string());
@@ -95,8 +90,8 @@ class SaxReader
bool next();
/**
- * Move to next xml node. If next node name is differ from token the exception will
- * be thrown.
+ * Move to next xml node. If next node name is differ from token the exception wiil
+ * be thronw.
*/
void next(const std::string &token);
@@ -108,13 +103,7 @@ class SaxReader
/**
* Read attribute tag.
*/
- std::string attribute(const std::string &token,
- ThrowType throwStatus = THROW_ENABLE);
-
- /**
- * Read xml tag name with namespace.
- */
- // KW std::string fullName();
+ std::string attribute(const std::string &token, ThrowType throwStatus = THROW_ENABLE);
/**
* Read xml tag name without namespace.
@@ -142,7 +131,7 @@ class SaxReader
*/
void dumpNode(std::string &buffer);
- private:
+private:
/*
* internal libxml text reader
*/
diff --git a/vcore/src/vcore/SignatureData.cpp b/vcore/src/vcore/SignatureData.cpp
new file mode 100644
index 0000000..a8a84fa
--- /dev/null
+++ b/vcore/src/vcore/SignatureData.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+#include <vcore/SignatureData.h>
+
+#include <dpl/log/log.h>
+
+namespace ValidationCore {
+
+SignatureData::SignatureData()
+ : m_signatureNumber(-1)
+ , m_certificateSorted(false)
+{}
+
+SignatureData::SignatureData(const std::string &fileName, int fileNumber)
+ : m_signatureNumber(fileNumber)
+ , m_fileName(fileName)
+ , m_certificateSorted(false)
+{}
+
+SignatureData::~SignatureData()
+{}
+
+const ReferenceSet& SignatureData::getReferenceSet() const
+{
+ return m_referenceSet;
+}
+
+void SignatureData::setReference(const ReferenceSet &referenceSet)
+{
+ m_referenceSet = referenceSet;
+}
+
+CertificateList SignatureData::getCertList() const
+{
+ return m_certList;
+}
+
+void SignatureData::setSortedCertificateList(const CertificateList &list)
+{
+ m_certList = list;
+ m_certificateSorted = true;
+}
+
+bool SignatureData::isAuthorSignature() const
+{
+ return m_signatureNumber == -1;
+}
+
+std::string SignatureData::getSignatureFileName() const
+{
+ return m_fileName;
+}
+
+int SignatureData::getSignatureNumber() const
+{
+ return m_signatureNumber;
+}
+
+std::string SignatureData::getRoleURI() const
+{
+ return m_roleURI;
+}
+
+std::string SignatureData::getProfileURI() const
+{
+ return m_profileURI;
+}
+
+bool SignatureData::containObjectReference(const std::string &ref) const
+{
+ std::string rName = "#";
+ rName += ref;
+ return m_referenceSet.end() != m_referenceSet.find(rName);
+}
+
+ObjectList SignatureData::getObjectList() const
+{
+ return m_objectList;
+}
+
+void SignatureData::setStorageType(const CertStoreId::Set &storeIdSet)
+{
+ m_storeIdSet = storeIdSet;
+}
+
+const CertStoreId::Set& SignatureData::getStorageType() const
+{
+ return m_storeIdSet;
+}
+
+CertStoreId::Type SignatureData::getVisibilityLevel() const
+{
+ if (m_storeIdSet.contains(CertStoreId::VIS_PLATFORM))
+ return CertStoreId::VIS_PLATFORM;
+ else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER_MANUFACTURER))
+ return CertStoreId::VIS_PLATFORM;
+ else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER_OPERATOR))
+ return CertStoreId::VIS_PLATFORM;
+ else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER))
+ return CertStoreId::VIS_PARTNER;
+ else if (m_storeIdSet.contains(CertStoreId::VIS_PUBLIC))
+ return CertStoreId::VIS_PUBLIC;
+ else {
+ LogWarning("Visibility level was broken.");
+ return 0;
+ }
+}
+
+const SignatureData::IMEIList& SignatureData::getIMEIList() const
+{
+ return m_imeiList;
+}
+
+const SignatureData::MEIDList& SignatureData::getMEIDList() const
+{
+ return m_meidList;
+}
+
+CertificatePtr SignatureData::getEndEntityCertificatePtr() const
+{
+ if (m_certificateSorted)
+ return m_certList.front();
+
+ return CertificatePtr();
+}
+
+CertificatePtr SignatureData::getRootCaCertificatePtr() const
+{
+ if (m_certificateSorted)
+ return m_certList.back();
+
+ return CertificatePtr();
+}
+
+} // ValidationCore
diff --git a/vcore/src/vcore/SignatureData.h b/vcore/src/vcore/SignatureData.h
index 5afba19..64310e3 100644
--- a/vcore/src/vcore/SignatureData.h
+++ b/vcore/src/vcore/SignatureData.h
@@ -14,7 +14,7 @@
* limitations under the License.
*/
/*
- * @file SignatureData.cpp
+ * @file SignatureData.h
* @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
* @version 1.0
* @brief SignatureData is used to storage data parsed from digsig file.
@@ -26,10 +26,6 @@
#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>
@@ -38,143 +34,39 @@ 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)
- {}
+class SignatureData {
+public:
+ SignatureData();
+ SignatureData(const std::string &fileName, int fileNumber);
- virtual ~SignatureData()
- {}
+ 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 CertStoreId::Type getVisibilityLevel(void) const
- {
- if (m_storeIdSet.contains(CertStoreId::VIS_PLATFORM) == true)
- return CertStoreId::VIS_PLATFORM;
- else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER_MANUFACTURER) == true)
- return CertStoreId::VIS_PLATFORM;
- else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER_OPERATOR) == true)
- return CertStoreId::VIS_PLATFORM;
- else if (m_storeIdSet.contains(CertStoreId::VIS_PARTNER) == true)
- return CertStoreId::VIS_PARTNER;
- else if (m_storeIdSet.contains(CertStoreId::VIS_PUBLIC) == true)
- return CertStoreId::VIS_PUBLIC;
- else {
- LogWarning("Visibility level was broken.");
- return 0;
- }
- }
-
- 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();
- }
+ void setReference(const ReferenceSet &referenceSet);
+ void setSortedCertificateList(const CertificateList &list);
+ void setStorageType(const CertStoreId::Set &storeIdSet);
+
+ const ReferenceSet& getReferenceSet() const;
+ CertificateList getCertList() const;
+ ObjectList getObjectList() const;
+ bool containObjectReference(const std::string &ref) const;
+ bool isAuthorSignature() const;
+ int getSignatureNumber() const;
+ std::string getSignatureFileName() const;
+ std::string getRoleURI() const;
+ std::string getProfileURI() const;
+ const CertStoreId::Set& getStorageType() const;
+ CertStoreId::Type getVisibilityLevel() const;
+ const IMEIList& getIMEIList() const;
+ const MEIDList& getMEIDList() const;
+ CertificatePtr getEndEntityCertificatePtr() const;
+ CertificatePtr getRootCaCertificatePtr() const;
friend class SignatureReader;
- private:
+private:
ReferenceSet m_referenceSet;
CertificateList m_certList;
diff --git a/vcore/src/vcore/SignatureFinder.cpp b/vcore/src/vcore/SignatureFinder.cpp
index cc0a408..0c864b7 100644
--- a/vcore/src/vcore/SignatureFinder.cpp
+++ b/vcore/src/vcore/SignatureFinder.cpp
@@ -20,14 +20,15 @@
* @brief Search for author-signature.xml and signatureN.xml files.
*/
#include <vcore/SignatureFinder.h>
+#include <dpl/log/wrt_log.h>
#include <dirent.h>
#include <errno.h>
#include <istream>
+#include <sstream>
#include <pcrecpp.h>
-#include <dpl/log/log.h>
namespace ValidationCore {
static const char *SIGNATURE_AUTHOR = "author-signature.xml";
@@ -35,7 +36,7 @@ static const char *REGEXP_DISTRIBUTOR_SIGNATURE =
"^(signature)([1-9][0-9]*)(\\.xml)";
class SignatureFinder::Impl {
- public:
+public:
Impl(const std::string& dir)
: m_dir(dir)
, m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
@@ -45,7 +46,7 @@ class SignatureFinder::Impl {
Result find(SignatureFileInfoSet &set);
- private:
+private:
std::string m_dir;
pcrecpp::RE m_signatureRegexp;
};
@@ -59,7 +60,7 @@ SignatureFinder::Result SignatureFinder::Impl::find(SignatureFileInfoSet &set)
* find a dir
*/
if ((dp = opendir(m_dir.c_str())) == NULL) {
- LogError("Error opening directory:" << m_dir);
+ WrtLogE("Error opening directory: %s", m_dir.c_str());
return ERROR_OPENING_DIR;
}
@@ -88,7 +89,7 @@ SignatureFinder::Result SignatureFinder::Impl::find(SignatureFileInfoSet &set)
}
if (errno != 0) {
- LogError("Error in readdir");
+ WrtLogE("Error in readdir");
closedir(dp);
return ERROR_READING_DIR;
}
@@ -101,7 +102,8 @@ SignatureFinder::SignatureFinder(const std::string& dir)
: m_impl(new Impl(dir))
{}
-SignatureFinder::~SignatureFinder(){
+SignatureFinder::~SignatureFinder()
+{
delete m_impl;
}
diff --git a/vcore/src/vcore/SignatureFinder.h b/vcore/src/vcore/SignatureFinder.h
index c1545cc..4809096 100644
--- a/vcore/src/vcore/SignatureFinder.h
+++ b/vcore/src/vcore/SignatureFinder.h
@@ -27,12 +27,10 @@
#include <set>
#include <string>
-#include <dpl/noncopyable.h>
-
namespace ValidationCore {
-class SignatureFileInfo
-{
- public:
+
+class SignatureFileInfo {
+public:
SignatureFileInfo(const std::string &fileName, int num)
: m_fileName(fileName)
, m_fileNumber(num)
@@ -52,15 +50,16 @@ class SignatureFileInfo
{
return m_fileNumber < second.m_fileNumber;
}
- private:
+
+private:
std::string m_fileName;
int m_fileNumber;
};
typedef std::set<SignatureFileInfo> SignatureFileInfoSet;
-class SignatureFinder : DPL::Noncopyable {
- public:
+class SignatureFinder {
+public:
enum Result
{
NO_ERROR,
@@ -69,15 +68,19 @@ class SignatureFinder : DPL::Noncopyable {
ERROR_ISTREAM
};
- SignatureFinder(const std::string& dir);
+ SignatureFinder() = delete;
+ explicit SignatureFinder(const std::string& dir);
virtual ~SignatureFinder();
Result find(SignatureFileInfoSet &set);
- private:
+private:
class Impl;
Impl *m_impl;
+
+ SignatureFinder(const SignatureFinder &);
+ const SignatureFinder &operator=(const SignatureFinder &);
};
} // namespace ValidationCore
diff --git a/vcore/src/vcore/SignatureReader.cpp b/vcore/src/vcore/SignatureReader.cpp
index 80553b6..229c93d 100644
--- a/vcore/src/vcore/SignatureReader.cpp
+++ b/vcore/src/vcore/SignatureReader.cpp
@@ -162,11 +162,9 @@ SignatureReader::SignatureReader() :
m_parserSchema.addBeginTagCallback(TOKEN_OBJECT,
XML_NAMESPACE,
&SignatureReader::tokenObject);
- m_parserSchema.addBeginTagCallback(
- TOKEN_SIGNATURE_PROPERTIES,
- XML_NAMESPACE,
- &SignatureReader::
- tokenSignatureProperties);
+ m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_PROPERTIES,
+ XML_NAMESPACE,
+ &SignatureReader::tokenSignatureProperties);
m_parserSchema.addBeginTagCallback(TOKEN_SIGNATURE_PROPERTY,
XML_NAMESPACE,
&SignatureReader::blankFunction);
@@ -306,11 +304,9 @@ SignatureReader::SignatureReader() :
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_DSA_PGENCOUNTER_COMPONENT,
+ XML_NAMESPACE,
+ &SignatureReader::tokenEndDSAPGenCounterComponent);
m_parserSchema.addEndTagCallback(TOKEN_RSA_KEY_VALUE,
XML_NAMESPACE,
&SignatureReader::tokenEndRSAKeyValue);
@@ -325,46 +321,58 @@ SignatureReader::SignatureReader() :
&SignatureReader::blankFunction);
}
-void SignatureReader::tokenKeyInfo(SignatureData &signatureData)
+
+void SignatureReader::initialize(
+ SignatureData &signatureData,
+ const std::string &xmlscheme)
{
- (void)signatureData;
+ m_parserSchema.initialize(
+ signatureData.getSignatureFileName(),
+ true,
+ SaxReader::VALIDATION_XMLSCHEME,
+ xmlscheme);
}
-void SignatureReader::tokenX509Data(SignatureData &signatureData)
+
+void SignatureReader::read(SignatureData &signatureData)
{
- (void)signatureData;
+ m_parserSchema.read(signatureData);
}
-void SignatureReader::tokenX509Certificate(SignatureData &signatureData)
+
+void SignatureReader::blankFunction(SignatureData &)
{
- (void)signatureData;
}
-void SignatureReader::tokenPublicKey(SignatureData &signatureData)
+
+void SignatureReader::tokenKeyInfo(SignatureData &)
+{
+}
+
+void SignatureReader::tokenX509Data(SignatureData &)
{
- (void)signatureData;
}
-void SignatureReader::tokenNamedCurve(SignatureData &signatureData)
+void SignatureReader::tokenX509Certificate(SignatureData &)
+{
+}
+
+void SignatureReader::tokenPublicKey(SignatureData &)
+{
+}
+
+void SignatureReader::tokenNamedCurve(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);
+ std::string IMEI = m_parserSchema.getReader().attribute(TOKEN_IMEI);
+ std::string MEID = m_parserSchema.getReader().attribute(TOKEN_MEID);
//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;
+ VcoreThrowMsg(SignatureReader::Exception::TargetRestriction,
+ "TargetRestriction should contain exactly one attribute.");
}
if (!IMEI.empty()) {
@@ -375,14 +383,12 @@ void SignatureReader::tokenTargetRestriction(SignatureData &signatureData)
}
}
-void SignatureReader::tokenEndKeyInfo(SignatureData &signatureData)
+void SignatureReader::tokenEndKeyInfo(SignatureData &)
{
- (void)signatureData;
}
-void SignatureReader::tokenEndX509Data(SignatureData &signatureData)
+void SignatureReader::tokenEndX509Data(SignatureData &)
{
- (void)signatureData;
}
void SignatureReader::tokenEndX509Certificate(SignatureData &signatureData)
@@ -391,20 +397,11 @@ void SignatureReader::tokenEndX509Certificate(SignatureData &signatureData)
if (CertificateLoader::NO_ERROR !=
loader.loadCertificateFromRawData(m_parserSchema.getText())) {
fprintf(stderr, "## [validate error]: Certificate could not be loaded\n");
- LogWarning("Certificate could not be loaded!");
- ThrowMsg(ParserSchemaException::CertificateLoaderError,
- "Certificate could not be loaded.");
+ VcoreThrowMsg(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)
{
@@ -413,28 +410,24 @@ void SignatureReader::tokenEndRSAKeyValue(SignatureData &signatureData)
loader.loadCertificateBasedOnExponentAndModulus(m_modulus,
m_exponent)) {
fprintf(stderr, "## [validate error]: Certificate could not be loaded\n");
- LogWarning("Certificate could not be loaded!");
- ThrowMsg(ParserSchemaException::CertificateLoaderError,
- "Certificate could not be loaded.");
+ VcoreThrowMsg(ParserSchemaException::CertificateLoaderError,
+ "Certificate could not be loaded");
}
signatureData.m_certList.push_back(loader.getCertificatePtr());
}
-void SignatureReader::tokenEndKeyModulus(SignatureData &signatureData)
+void SignatureReader::tokenEndKeyModulus(SignatureData &)
{
- (void)signatureData;
m_modulus = m_parserSchema.getText();
}
-void SignatureReader::tokenEndKeyExponent(SignatureData &signatureData)
+void SignatureReader::tokenEndKeyExponent(SignatureData &)
{
- (void)signatureData;
m_exponent = m_parserSchema.getText();
}
-void SignatureReader::tokenEndPublicKey(SignatureData &signatureData)
+void SignatureReader::tokenEndPublicKey(SignatureData &)
{
- (void)signatureData;
m_publicKey = m_parserSchema.getText();
}
@@ -444,8 +437,8 @@ void SignatureReader::tokenEndECKeyValue(SignatureData &signatureData)
if (CertificateLoader::NO_ERROR !=
loader.loadCertificateWithECKEY(m_nameCurveURI, m_publicKey)) {
fprintf(stderr, "## [validate error]: Certificate could not be loaded\n");
- ThrowMsg(ParserSchemaException::CertificateLoaderError,
- "Certificate could not be loaded.");
+ VcoreThrowMsg(ParserSchemaException::CertificateLoaderError,
+ "Certificate could not be loaded");
}
signatureData.m_certList.push_back(loader.getCertificatePtr());
}
@@ -458,60 +451,53 @@ void SignatureReader::tokenEndObject(SignatureData &signatureData)
(!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;
+ VcoreThrowMsg(SignatureReader::Exception::TargetRestriction,
+ "TargetRestriction should contain exactly one ds:Object "
+ "containing zero or more wac:TargetRestriction children.");
}
+
if ((!signatureData.m_imeiList.empty()) ||
(!signatureData.m_meidList.empty())) {
m_targetRestrictionObjectFound = true;
}
+
}
-void SignatureReader::tokenEndDSAPComponent(SignatureData& signatureData)
+void SignatureReader::tokenEndDSAPComponent(SignatureData &)
{
- (void)signatureData;
m_dsaKeyPComponent = m_parserSchema.getText();
}
-void SignatureReader::tokenEndDSAQComponent(SignatureData& signatureData)
+void SignatureReader::tokenEndDSAQComponent(SignatureData &)
{
- (void)signatureData;
m_dsaKeyQComponent = m_parserSchema.getText();
}
-void SignatureReader::tokenEndDSAGComponent(SignatureData& signatureData)
+void SignatureReader::tokenEndDSAGComponent(SignatureData &)
{
- (void)signatureData;
m_dsaKeyGComponent = m_parserSchema.getText();
}
-void SignatureReader::tokenEndDSAYComponent(SignatureData& signatureData)
+void SignatureReader::tokenEndDSAYComponent(SignatureData &)
{
- (void)signatureData;
m_dsaKeyYComponent = m_parserSchema.getText();
}
-void SignatureReader::tokenEndDSAJComponent(SignatureData& signatureData)
+void SignatureReader::tokenEndDSAJComponent(SignatureData &)
{
- (void)signatureData;
m_dsaKeyJComponent = m_parserSchema.getText();
}
-void SignatureReader::tokenEndDSASeedComponent(SignatureData& signatureData)
+void SignatureReader::tokenEndDSASeedComponent(SignatureData &)
{
- (void)signatureData;
m_dsaKeySeedComponent = m_parserSchema.getText();
}
-void SignatureReader::tokenEndDSAPGenCounterComponent(
- SignatureData& signatureData)
+void SignatureReader::tokenEndDSAPGenCounterComponent(SignatureData &)
{
- (void)signatureData;
m_dsaKeyPGenCounter = m_parserSchema.getText();
}
-void SignatureReader::tokenEndDSAKeyValue(SignatureData& signatureData)
+void SignatureReader::tokenEndDSAKeyValue(SignatureData &signatureData)
{
CertificateLoader loader;
@@ -524,9 +510,8 @@ void SignatureReader::tokenEndDSAKeyValue(SignatureData& signatureData)
m_dsaKeySeedComponent,
m_dsaKeyPGenCounter)) {
fprintf(stderr, "## [validate error]: Certificate could not be loaded\n");
- LogWarning("Certificate could not be loaded.");
- ThrowMsg(ParserSchemaException::CertificateLoaderError,
- "Certificate could not be loaded.");
+ VcoreThrowMsg(ParserSchemaException::CertificateLoaderError,
+ "Certificate could not be loaded.");
}
signatureData.m_certList.push_back(loader.getCertificatePtr());
}
@@ -535,9 +520,8 @@ void SignatureReader::tokenRole(SignatureData &signatureData)
{
if (!signatureData.m_roleURI.empty()) {
fprintf(stderr, "## [validate error]: Multiple definition of Role is not allowed\n");
- LogWarning("Multiple definition of Role is not allowed.");
- ThrowMsg(ParserSchemaException::UnsupportedValue,
- "Multiple definition of Role is not allowed.");
+ VcoreThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Multiple definition of Role is not allowed.");
}
signatureData.m_roleURI = m_parserSchema.getReader().attribute(TOKEN_URI);
}
@@ -546,9 +530,8 @@ void SignatureReader::tokenProfile(SignatureData &signatureData)
{
if (!signatureData.m_profileURI.empty()) {
fprintf(stderr, "## [validate error]: Multiple definition of Profile is not allowed\n");
- LogWarning("Multiple definition of Profile is not allowed.");
- ThrowMsg(ParserSchemaException::UnsupportedValue,
- "Multiple definition of Profile is not allowed.");
+ VcoreThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Multiple definition of Profile is not allowed.");
}
signatureData.m_profileURI = m_parserSchema.getReader().attribute(TOKEN_URI);
}
@@ -557,9 +540,8 @@ void SignatureReader::tokenEndIdentifier(SignatureData &signatureData)
{
if (!signatureData.m_identifier.empty()) {
fprintf(stderr, "## [validate error]: Multiple definition of Identifier is not allowed\n");
- LogWarning("Multiple definition of Identifier is not allowed.");
- ThrowMsg(ParserSchemaException::UnsupportedValue,
- "Multiple definition of Identifier is not allowed.");
+ VcoreThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Multiple definition of Identifier is not allowed.");
}
signatureData.m_identifier = m_parserSchema.getText();
}
@@ -570,22 +552,19 @@ void SignatureReader::tokenObject(SignatureData &signatureData)
if (id.empty()) {
fprintf(stderr, "## [validate error]: Unsupported value of Attribute Id in Object tag\n");
- LogWarning("Unsupported value of Attribute Id in Object tag.");
- ThrowMsg(ParserSchemaException::UnsupportedValue,
- "Unsupported value of Attribute Id in Object tag.");
+ VcoreThrowMsg(ParserSchemaException::UnsupportedValue,
+ "Unsupported value of Attribute Id in Object tag.");
}
signatureData.m_objectList.push_back(id);
}
-void SignatureReader::tokenSignatureProperties(SignatureData &signatureData)
+void SignatureReader::tokenSignatureProperties(SignatureData &)
{
- (void)signatureData;
if (++m_signaturePropertiesCounter > 1) {
fprintf(stderr, "## [validate error]: Only one SignatureProperties tag is allowed in Object\n");
- LogWarning("Only one SignatureProperties tag is allowed in Object");
- ThrowMsg(ParserSchemaException::UnsupportedValue,
- "Only one SignatureProperties tag is allowed in Object");
+ VcoreThrowMsg(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
index 2f2f9a8..309a915 100644
--- a/vcore/src/vcore/SignatureReader.h
+++ b/vcore/src/vcore/SignatureReader.h
@@ -22,42 +22,30 @@
#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>
+#include <vcore/exception.h>
+
+#include <map>
namespace ValidationCore {
-class SignatureReader
-{
- public:
- class Exception
- {
- public:
- DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
- DECLARE_EXCEPTION_TYPE(Base, TargetRestrictionException)
+
+class SignatureReader {
+public:
+ class Exception {
+ public:
+ VCORE_DECLARE_EXCEPTION_TYPE(ValidationCore::Exception, Base);
+ VCORE_DECLARE_EXCEPTION_TYPE(Base, TargetRestriction);
};
SignatureReader();
- void initialize(SignatureData &data,
- const std::string &xmlscheme)
- {
- m_parserSchema.initialize(
- data.getSignatureFileName(), true, SaxReader::VALIDATION_XMLSCHEME,
- xmlscheme);
- }
+ void initialize(SignatureData &signatureData, const std::string &xmlscheme);
- void read(SignatureData &data)
- {
- m_parserSchema.read(data);
- }
+ void read(SignatureData &signatureData);
- private:
- void blankFunction(SignatureData &)
- {
- }
+private:
+ void blankFunction(SignatureData &signatureData);
void tokenKeyInfo(SignatureData &signatureData);
void tokenKeyModulus(SignatureData &signatureData);
@@ -70,15 +58,20 @@ class SignatureReader
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);
diff --git a/vcore/src/vcore/SignatureValidator.cpp b/vcore/src/vcore/SignatureValidator.cpp
index 35ffaa3..2a51402 100644
--- a/vcore/src/vcore/SignatureValidator.cpp
+++ b/vcore/src/vcore/SignatureValidator.cpp
@@ -21,15 +21,16 @@
*/
#include <vcore/SignatureValidator.h>
#include <vcore/CertificateCollection.h>
-#include <dpl/log/log.h>
-#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
-#include <vcore/CertificateVerifier.h>
-#endif
#include <vcore/Certificate.h>
#include <vcore/OCSPCertMgrUtil.h>
#include <vcore/ReferenceValidator.h>
#include <vcore/ValidatorFactories.h>
#include <vcore/XmlsecAdapter.h>
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+#include <vcore/CertificateVerifier.h>
+#endif
+
+#include <dpl/log/wrt_log.h>
namespace {
const time_t TIMET_DAY = 60 * 60 * 24;
@@ -41,8 +42,6 @@ const std::string TOKEN_ROLE_DISTRIBUTOR_URI =
const std::string TOKEN_PROFILE_URI =
"http://www.w3.org/ns/widgets-digsig#profile";
-//const char* TIZEN_STORE_CN = "Tizen Store"; //un-used variable
-
} // namespace anonymouse
@@ -56,20 +55,26 @@ static tm _ASN1_GetTimeT(ASN1_TIME* time)
if (time->type == V_ASN1_UTCTIME) /* two digit year */
{
- t.tm_year = (str[i++] - '0') * 10 + (str[++i] - '0');
+ t.tm_year = (str[i] - '0') * 10 + (str[i+1] - '0');
+ i += 2;
if (t.tm_year < 70)
t.tm_year += 100;
}
else if (time->type == V_ASN1_GENERALIZEDTIME) /* four digit year */
{
- t.tm_year = (str[i++] - '0') * 1000 + (str[++i] - '0') * 100 + (str[++i] - '0') * 10 + (str[++i] - '0');
+ t.tm_year =
+ (str[i] - '0') * 1000
+ + (str[i+1] - '0') * 100
+ + (str[i+2] - '0') * 10
+ + (str[i+3] - '0');
+ i += 4;
t.tm_year -= 1900;
}
- t.tm_mon = ((str[i++] - '0') * 10 + (str[++i] - '0')) - 1; // -1 since January is 0 not 1.
- t.tm_mday = (str[i++] - '0') * 10 + (str[++i] - '0');
- t.tm_hour = (str[i++] - '0') * 10 + (str[++i] - '0');
- t.tm_min = (str[i++] - '0') * 10 + (str[++i] - '0');
- t.tm_sec = (str[i++] - '0') * 10 + (str[++i] - '0');
+ t.tm_mon = ((str[i] - '0') * 10 + (str[i+1] - '0')) - 1; // -1 since January is 0 not 1.
+ t.tm_mday = (str[i+2] - '0') * 10 + (str[i+3] - '0');
+ t.tm_hour = (str[i+4] - '0') * 10 + (str[i+5] - '0');
+ t.tm_min = (str[i+6] - '0') * 10 + (str[i+7] - '0');
+ t.tm_sec = (str[i+8] - '0') * 10 + (str[i+9] - '0');
/* Note: we did not adjust the time based on time zone information */
return t;
@@ -93,11 +98,15 @@ public:
bool crlEnable,
bool complianceMode)
: m_complianceModeEnabled(complianceMode)
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
- , m_ocspEnable(ocspEnable)
- , m_crlEnable(crlEnable)
- #endif
- {}
+ {
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+ m_ocspEnable = ocspEnable;
+ m_crlEnable = crlEnable;
+#else
+ (void) ocspEnable;
+ (void) crlEnable;
+#endif
+ }
virtual ~ImplSignatureValidator(){ }
@@ -105,18 +114,18 @@ public:
std::string roleURI = data.getRoleURI();
if (roleURI.empty()) {
- LogWarning("URI attribute in Role tag couldn't be empty.");
+ WrtLogW("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 "
+ WrtLogW("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 "
+ WrtLogW("URI attribute in Role tag does not "
"match with signature filename.");
return false;
}
@@ -125,9 +134,8 @@ public:
bool checkProfileURI(const SignatureData &data) {
if (TOKEN_PROFILE_URI != data.getProfileURI()) {
- LogWarning(
- "Profile tag contains unsupported value in URI attribute(" <<
- data.getProfileURI() << ").");
+ WrtLogW(
+ "Profile tag contains unsupported value in URI attribute( %s ).", (data.getProfileURI()).c_str());
return false;
}
return true;
@@ -138,8 +146,7 @@ public:
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);
+ WrtLogW("Signature does not contain reference for object %s", (*iter).c_str());
return false;
}
}
@@ -177,7 +184,6 @@ SignatureValidator::Result ImplTizenSignatureValidator::check(
{
bool disregard = false;
- DPL::Log::LogSystemSingleton::Instance().SetTag("OSP");
if (!checkRoleURI(data)) {
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -193,14 +199,14 @@ SignatureValidator::Result ImplTizenSignatureValidator::check(
// First step - sort certificate
if (!collection.sort()) {
- LogWarning("Certificates do not form valid chain.");
- return SignatureValidator::SIGNATURE_INVALID;
+ WrtLogW("Certificates do not form valid chain.");
+ return SignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
}
// Check for error
if (collection.empty()) {
- LogWarning("Certificate list in signature is empty.");
- return SignatureValidator::SIGNATURE_INVALID;
+ WrtLogW("Certificate list in signature is empty.");
+ return SignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
}
CertificateList sortedCertificateList = collection.getChain();
@@ -215,50 +221,46 @@ SignatureValidator::Result ImplTizenSignatureValidator::check(
// Is Root CA certificate trusted?
CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
- LogDebug("Is root certificate from TIZEN_DEVELOPER domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
- LogDebug("Is root certificate from TIZEN_TEST domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_TEST));
- LogDebug("Is root certificate from TIZEN_VERIFY domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
- LogDebug("Is root certificate from TIZEN_PUBLIC domain: "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Is root certificate from TIZEN_PARTNER domain: "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Is root certificate from TIZEN_PLATFORM domain: "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
-
- LogDebug("Visibility level is public : "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Visibility level is partner : "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Visibility level is platform : "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+ WrtLogD("Is root certificate from TIZEN_DEVELOPER domain: %d", storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
+ WrtLogD("Is root certificate from TIZEN_TEST domain: %d", storeIdSet.contains(CertStoreId::TIZEN_TEST));
+ WrtLogD("Is root certificate from TIZEN_VERIFY domain: %d", storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
+ WrtLogD("Is root certificate from TIZEN_STORE domain: %d", storeIdSet.contains(CertStoreId::TIZEN_STORE));
+ WrtLogD("Is root certificate from TIZEN_PUBLIC domain: %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Is root certificate from TIZEN_PARTNER domain: %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Is root certificate from TIZEN_PLATFORM domain: %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
- if (data.isAuthorSignature())
- {
- if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
- {
- LogWarning("author-signature.xml has got unrecognized Root CA "
- "certificate. Signature will be disregarded.");
- disregard = true;
- }
- LogDebug("Root CA for author signature is correct.");
+ WrtLogD("Visibility level is public : %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Visibility level is partner : %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Visibility level is platform : %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+
+ if (data.isAuthorSignature())
+ {
+ if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
+ {
+ WrtLogW("author-signature.xml has got unrecognized Root CA "
+ "certificate. Signature will be disregarded.");
+ disregard = true;
+ }
}
else
{
-LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
- //Additional Check for certificate registration
+ WrtLogD("signaturefile name = %s", data.getSignatureFileName().c_str());
+ if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
+ {
+ WrtLogE("distributor has author level siganture! Signature will be disregarded.");
+ return SignatureValidator::SIGNATURE_IN_DISTRIBUTOR_CASE_AUTHOR_CERT;//SIGNATURE_INVALID;
+ }
+
if (data.getSignatureNumber() == 1)
{
if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
{
- LogDebug("Root CA for signature1.xml is correct.");
+ WrtLogD("Root CA for signature1.xml is correct.");
}
else
{
- LogWarning("signature1.xml has got unrecognized Root CA "
+ WrtLogW("signature1.xml has got unrecognized Root CA "
"certificate. Signature will be disregarded.");
disregard = true;
}
@@ -278,7 +280,7 @@ LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
// 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.");
+ WrtLogW("Root CA certificate not found. Chain is incomplete.");
// context.allowBrokenChain = true;
}
@@ -297,44 +299,46 @@ LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
char msg[1024];
t = localtime(&nowTime);
+ if (!t)
+ return SignatureValidator::SIGNATURE_INVALID_CERT_TIME;
memset(&tc, 0, sizeof(tc));
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
- LogDebug("## System's currentTime : " << msg);
+ WrtLogD("## System's currentTime : %s", msg);
fprintf(stderr, "## System's currentTime : %s\n", msg);
tb = _ASN1_GetTimeT(notBeforeTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
- LogDebug("## certificate's notBeforeTime : " << msg);
+ WrtLogD("## certificate's notBeforeTime : %s", msg);
fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
ta = _ASN1_GetTimeT(notAfterTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
- LogDebug("## certificate's notAfterTime : " << msg);
+ WrtLogD("## certificate's notAfterTime : %s", msg);
fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
- if (storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
+ if (storeIdSet.contains(CertStoreId::TIZEN_TEST) || storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
{
- LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
+ WrtLogD("## TIZEN_VERIFY : check certificate Time : FALSE");
fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
- return SignatureValidator::SIGNATURE_INVALID;
+ return SignatureValidator::SIGNATURE_INVALID_CERT_TIME;//SIGNATURE_INVALID;
}
int year = (ta.tm_year - tb.tm_year) / 4;
if(year == 0)
{
- tc.tm_year = tb.tm_year;
+ tc.tm_year = tb.tm_year;
tc.tm_mon = tb.tm_mon + 1;
tc.tm_mday = tb.tm_mday;
if(tc.tm_mon == 12)
{
- tc.tm_year = ta.tm_year;
+ tc.tm_year = ta.tm_year;
tc.tm_mon = ta.tm_mon - 1;
tc.tm_mday = ta.tm_mday;
-
+
if(tc.tm_mon < 0)
{
tc.tm_year = ta.tm_year;
@@ -343,21 +347,21 @@ LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
if(tc.tm_mday == 0)
{
- tc.tm_year = tb.tm_year;
+ tc.tm_year = tb.tm_year;
tc.tm_mon = tb.tm_mon;
tc.tm_mday = tb.tm_mday +1;
}
}
- }
+ }
}
else{
tc.tm_year = tb.tm_year + year;
tc.tm_mon = (tb.tm_mon + ta.tm_mon )/2;
- tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
+ tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
}
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
- LogDebug("## cmp cert with validation time : " << msg);
+ WrtLogD("## cmp cert with validation time : %s", msg);
fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
time_t outCurrent = mktime(&tc);
@@ -376,36 +380,36 @@ LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
struct tm *t;
if (data.isAuthorSignature())
- {
+ {
// time_t 2038 year bug exist. So, notAtter() cann't check...
/*
if (notAfter < nowTime)
{
context.validationTime = notAfter - TIMET_DAY;
- LogWarning("Author certificate is expired. notAfter...");
+ WrtLogW("Author certificate is expired. notAfter...");
}
*/
if (notBefore > nowTime)
{
- LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
+ WrtLogW("Author certificate is expired. notBefore time is greater than system-time.");
t = localtime(&nowTime);
- LogDebug("System's current Year : " << t->tm_year + 1900);
- LogDebug("System's current month : " << t->tm_mon + 1);
- LogDebug("System's current day : " << t->tm_mday);
+ WrtLogD("System's current Year : %d", (t->tm_year + 1900));
+ WrtLogD("System's current month : %d", (t->tm_mon + 1));
+ WrtLogD("System's current day : %d", (t->tm_mday));
t = localtime(&notBefore);
- LogDebug("Author certificate's notBefore Year : " << t->tm_year + 1900);
- LogDebug("Author certificate's notBefore month : " << t->tm_mon + 1);
- LogDebug("Author certificate's notBefore day : " << t->tm_mday);
+ WrtLogD("Author certificate's notBefore Year : %d", (t->tm_year + 1900));
+ WrtLogD("Author certificate's notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Author certificate's notBefore day : %d", (t->tm_mday));
context.validationTime = notBefore + TIMET_DAY;
t = localtime(&context.validationTime);
- LogDebug("Modified current Year : " << t->tm_year + 1900);
- LogDebug("Modified current notBefore month : " << t->tm_mon + 1);
- LogDebug("Modified current notBefore day : " << t->tm_mday);
+ WrtLogD("Modified current Year : %d", (t->tm_year + 1900));
+ WrtLogD("Modified current notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Modified current notBefore day : %d", (t->tm_mday));
}
}
#endif
@@ -414,23 +418,28 @@ LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
// end
- if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
- LogWarning("Installation break - invalid package! >> validate");
- return SignatureValidator::SIGNATURE_INVALID;
- }
-
- data.setReference(context.referenceSet);
- if (!checkObjectReferences(data)) {
- return SignatureValidator::SIGNATURE_INVALID;
- }
-
+ if (!data.isAuthorSignature())
+ {
+ if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
+ WrtLogW("Installation break - invalid package!");
+ return SignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
+ }
+
+ data.setReference(context.referenceSet);
+ if (!checkObjectReferences(data)) {
+ WrtLogW("Failed to check Object References");
+ return SignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
+ }
+
+ (void) widgetContentPath;
/*
ReferenceValidator fileValidator(widgetContentPath);
if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
- LogWarning("Invalid package - file references broken");
- return SignatureValidator::SIGNATURE_INVALID;
+ WrtLogW("Invalid package - file references broken");
+ return SignatureValidator::SIGNATURE_INVALID_NO_HASH_FILE;//SIGNATURE_INVALID;
}
*/
+ }
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
// It is good time to do OCSP check
@@ -442,8 +451,8 @@ LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
coll.load(sortedCertificateList);
if (!coll.sort()) {
- LogDebug("Collection does not contain chain!");
- return SignatureValidator::SIGNATURE_INVALID;
+ WrtLogD("Collection does not contain chain!");
+ return SignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
}
CertificateVerifier verificator(m_ocspEnable, m_crlEnable);
@@ -464,8 +473,8 @@ LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
#endif
if (disregard) {
- LogWarning("Signature is disregard. RootCA is not a member of Tizen.");
- return SignatureValidator::SIGNATURE_DISREGARD;
+ WrtLogW("Signature is disregard. RootCA is not a member of Tizen");
+ return SignatureValidator::SIGNATURE_INVALID_DISTRIBUTOR_CERT;//SIGNATURE_DISREGARD;
}
return SignatureValidator::SIGNATURE_VERIFIED;
}
@@ -474,13 +483,11 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
const std::string &widgetContentPath,
const std::list<std::string>& uriList)
{
- DPL::Log::LogSystemSingleton::Instance().SetTag("OSP");
if(uriList.size() == 0 )
- LogWarning("checkList >> no hash");
+ WrtLogW("checkList >> no hash");
bool disregard = false;
- bool partialHash = false;
-
+
if (!checkRoleURI(data)) {
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -496,13 +503,13 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
// First step - sort certificate
if (!collection.sort()) {
- LogWarning("Certificates do not form valid chain.");
+ WrtLogW("Certificates do not form valid chain.");
return SignatureValidator::SIGNATURE_INVALID;
}
// Check for error
if (collection.empty()) {
- LogWarning("Certificate list in signature is empty.");
+ WrtLogW("Certificate list in signature is empty.");
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -518,50 +525,40 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
// Is Root CA certificate trusted?
CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
- LogDebug("Is root certificate from TIZEN_DEVELOPER domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
- LogDebug("Is root certificate from TIZEN_TEST domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_TEST));
- LogDebug("Is root certificate from TIZEN_VERIFY domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
- LogDebug("Is root certificate from TIZEN_PUBLIC domain: "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Is root certificate from TIZEN_PARTNER domain: "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Is root certificate from TIZEN_PLATFORM domain: "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
-
- LogDebug("Visibility level is public : "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Visibility level is partner : "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Visibility level is platform : "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+ WrtLogD("Is root certificate from TIZEN_DEVELOPER domain: %d", storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
+ WrtLogD("Is root certificate from TIZEN_TEST domain: %d", storeIdSet.contains(CertStoreId::TIZEN_TEST));
+ WrtLogD("Is root certificate from TIZEN_VERIFY domain: %d", storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
+ WrtLogD("Is root certificate from TIZEN_PUBLIC domain: %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Is root certificate from TIZEN_PARTNER domain: %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Is root certificate from TIZEN_PLATFORM domain: %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+
+ WrtLogD("Visibility level is public : %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Visibility level is partner : %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Visibility level is platform : %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
if (data.isAuthorSignature())
{
if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
{
- LogWarning("author-signature.xml has got unrecognized Root CA "
+ WrtLogW("author-signature.xml has got unrecognized Root CA "
"certificate. Signature will be disregarded.");
disregard = true;
}
- LogDebug("Root CA for author signature is correct.");
+ WrtLogD("Root CA for author signature is correct.");
}
else
{
- LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
- //Additional Check for certificate registration
+ WrtLogD("signaturefile name = %s", data.getSignatureFileName().c_str());
if (data.getSignatureNumber() == 1)
{
if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
{
- LogDebug("Root CA for signature1.xml is correct.");
+ WrtLogD("Root CA for signature1.xml is correct.");
}
else
{
- LogWarning("signature1.xml has got unrecognized Root CA "
+ WrtLogW("signature1.xml has got unrecognized Root CA "
"certificate. Signature will be disregarded.");
disregard = true;
}
@@ -581,7 +578,7 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
// 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.");
+ WrtLogW("Root CA certificate not found. Chain is incomplete.");
// context.allowBrokenChain = true;
}
@@ -595,7 +592,7 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
ASN1_TIME* notAfterTime = data.getEndEntityCertificatePtr()->getNotAfterTime();
ASN1_TIME* notBeforeTime = data.getEndEntityCertificatePtr()->getNotBeforeTime();
-
+
if (X509_cmp_time(notBeforeTime, &nowTime) > 0 || X509_cmp_time(notAfterTime, &nowTime) < 0)
{
struct tm *t;
@@ -603,26 +600,28 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
char msg[1024];
t = localtime(&nowTime);
+ if (!t)
+ return SignatureValidator::SIGNATURE_INVALID_CERT_TIME;
memset(&tc, 0, sizeof(tc));
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
- LogDebug("## System's currentTime : " << msg);
+ WrtLogD("## System's currentTime : %s", msg);
fprintf(stderr, "## System's currentTime : %s\n", msg);
tb = _ASN1_GetTimeT(notBeforeTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
- LogDebug("## certificate's notBeforeTime : " << msg);
+ WrtLogD("## certificate's notBeforeTime : %s", msg);
fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
ta = _ASN1_GetTimeT(notAfterTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
- LogDebug("## certificate's notAfterTime : " << msg);
+ WrtLogD("## certificate's notAfterTime : %s", msg);
fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
if (storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
{
- LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
+ WrtLogD("## TIZEN_VERIFY : check certificate Time : FALSE");
fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -633,7 +632,7 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
- LogDebug("## cmp cert with validation time : " << msg);
+ WrtLogD("## cmp cert with validation time : %s", msg);
fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
time_t outCurrent = mktime(&tc);
@@ -656,30 +655,30 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
if (notAfter < nowTime)
{
context.validationTime = notAfter - TIMET_DAY;
- LogWarning("Author certificate is expired. notAfter...");
+ WrtLogW("Author certificate is expired. notAfter...");
}
*/
if (notBefore > nowTime)
{
- LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
+ WrtLogW("Author certificate is expired. notBefore time is greater than system-time.");
t = localtime(&nowTime);
- LogDebug("System's current Year : " << t->tm_year + 1900);
- LogDebug("System's current month : " << t->tm_mon + 1);
- LogDebug("System's current day : " << t->tm_mday);
+ WrtLogD("System's current Year : %d", (t->tm_year + 1900));
+ WrtLogD("System's current month : %d", (t->tm_mon + 1));
+ WrtLogD("System's current day : %d", (t->tm_mday));
t = localtime(&notBefore);
- LogDebug("Author certificate's notBefore Year : " << t->tm_year + 1900);
- LogDebug("Author certificate's notBefore month : " << t->tm_mon + 1);
- LogDebug("Author certificate's notBefore day : " << t->tm_mday);
+ WrtLogD("Author certificate's notBefore Year : %d", (t->tm_year + 1900));
+ WrtLogD("Author certificate's notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Author certificate's notBefore day : %d", (t->tm_mday));
context.validationTime = notBefore + TIMET_DAY;
t = localtime(&context.validationTime);
- LogDebug("Modified current Year : " << t->tm_year + 1900);
- LogDebug("Modified current notBefore month : " << t->tm_mon + 1);
- LogDebug("Modified current notBefore day : " << t->tm_mday);
+ WrtLogD("Modified current Year : %d", (t->tm_year + 1900));
+ WrtLogD("Modified current notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Modified current notBefore day : %d", (t->tm_mday));
}
}
#endif
@@ -690,16 +689,15 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
if(uriList.size() == 0)
{
if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validateNoHash(&context)) {
- LogWarning("Installation break - invalid package! >> validateNoHash");
+ WrtLogW("Installation break - invalid package! >> validateNoHash");
return SignatureValidator::SIGNATURE_INVALID;
}
}
else if(uriList.size() != 0)
{
- partialHash = true;
XmlSecSingleton::Instance().setPartialHashList(uriList);
if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validatePartialHash(&context)) {
- LogWarning("Installation break - invalid package! >> validatePartialHash");
+ WrtLogW("Installation break - invalid package! >> validatePartialHash");
return SignatureValidator::SIGNATURE_INVALID;
}
}
@@ -709,10 +707,11 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
// return SignatureValidator::SIGNATURE_INVALID;
// }
+ (void) widgetContentPath;
/*
ReferenceValidator fileValidator(widgetContentPath);
if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
- LogWarning("Invalid package - file references broken");
+ WrtLogW("Invalid package - file references broken");
return SignatureValidator::SIGNATURE_INVALID;
}
*/
@@ -727,7 +726,7 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
coll.load(sortedCertificateList);
if (!coll.sort()) {
- LogDebug("Collection does not contain chain!");
+ WrtLogD("Collection does not contain chain!");
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -749,7 +748,7 @@ SignatureValidator::Result ImplTizenSignatureValidator::checkList(SignatureData
#endif
if (disregard) {
- LogWarning("Signature is disregard. RootCA is not a member of Tizen.");
+ WrtLogW("Signature is disregard. RootCA is not a member of Tizen.");
return SignatureValidator::SIGNATURE_DISREGARD;
}
return SignatureValidator::SIGNATURE_VERIFIED;
@@ -775,9 +774,9 @@ class ImplWacSignatureValidator : public SignatureValidator::ImplSignatureValida
SignatureValidator::Result ImplWacSignatureValidator::checkList(
- SignatureData &data,
- const std::string &widgetContentPath,
- const std::list<std::string>& uriList)
+ SignatureData & /* data */,
+ const std::string & /* widgetContentPath */,
+ const std::list<std::string>& /* uriList */)
{
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -804,13 +803,13 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
// First step - sort certificate
if (!collection.sort()) {
- LogWarning("Certificates do not form valid chain.");
+ WrtLogW("Certificates do not form valid chain.");
return SignatureValidator::SIGNATURE_INVALID;
}
// Check for error
if (collection.empty()) {
- LogWarning("Certificate list in signature is empty.");
+ WrtLogW("Certificate list in signature is empty.");
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -826,49 +825,43 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
// Is Root CA certificate trusted?
CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
- LogDebug("Is root certificate from TIZEN_DEVELOPER domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
- LogDebug("Is root certificate from TIZEN_TEST domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_TEST));
- LogDebug("Is root certificate from TIZEN_VERIFY domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
- LogDebug("Is root certificate from TIZEN_PUBLIC domain: "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Is root certificate from TIZEN_PARTNER domain: "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Is root certificate from TIZEN_PLATFORM domain: "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
-
- LogDebug("Visibility level is public : "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Visibility level is partner : "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Visibility level is platform : "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+ WrtLogD("Is root certificate from TIZEN_DEVELOPER domain: %d", storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
+ WrtLogD("Is root certificate from TIZEN_TEST domain: %d", storeIdSet.contains(CertStoreId::TIZEN_TEST));
+ WrtLogD("Is root certificate from TIZEN_VERIFY domain: %d", storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
+ WrtLogD("Is root certificate from TIZEN_PUBLIC domain: %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Is root certificate from TIZEN_PARTNER domain: %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Is root certificate from TIZEN_PLATFORM domain: %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
- if (data.isAuthorSignature())
- {
- if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
- {
- LogWarning("author-signature.xml has got unrecognized Root CA "
- "certificate. Signature will be disregarded.");
- disregard = true;
- }
- LogDebug("Root CA for author signature is correct.");
- } else {
- LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
+ WrtLogD("Visibility level is public : %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Visibility level is partner : %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Visibility level is platform : %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+
+ if (data.isAuthorSignature())
+ {
+ if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
+ {
+ WrtLogW("author-signature.xml has got unrecognized Root CA "
+ "certificate. Signature will be disregarded.");
+ disregard = true;
+ }
+ } else {
+ WrtLogD("signaturefile name = %s", data.getSignatureFileName().c_str());
+ if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
+ {
+ WrtLogE("distributor has author level siganture! Signature will be disregarded.");
+ return SignatureValidator::SIGNATURE_INVALID;
+ }
- //Additional Check for certificate registration
if (data.getSignatureNumber() == 1)
{
if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
{
- LogDebug("Root CA for signature1.xml is correct.");
+ WrtLogD("Root CA for signature1.xml is correct.");
}
else
{
- LogWarning("signature1.xml has got unrecognized Root CA "
+ WrtLogW("signature1.xml has got unrecognized Root CA "
"certificate. Signature will be disregarded.");
disregard = true;
}
@@ -888,7 +881,7 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
// 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.");
+ WrtLogW("Root CA certificate not found. Chain is incomplete.");
// context.allowBrokenChain = true;
}
@@ -908,26 +901,28 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
char msg[1024];
t = localtime(&nowTime);
+ if (!t)
+ return SignatureValidator::SIGNATURE_INVALID_CERT_TIME;
memset(&tc, 0, sizeof(tc));
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
- LogDebug("## System's currentTime : " << msg);
+ WrtLogD("## System's currentTime : %s", msg);
fprintf(stderr, "## System's currentTime : %s\n", msg);
tb = _ASN1_GetTimeT(notBeforeTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
- LogDebug("## certificate's notBeforeTime : " << msg);
+ WrtLogD("## certificate's notBeforeTime : %s", msg);
fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
ta = _ASN1_GetTimeT(notAfterTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
- LogDebug("## certificate's notAfterTime : " << msg);
+ WrtLogD("## certificate's notAfterTime : %s", msg);
fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
if (storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
{
- LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
+ WrtLogD("## TIZEN_VERIFY : check certificate Time : FALSE");
fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -938,14 +933,14 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
- LogDebug("## cmp cert with validation time : " << msg);
+ WrtLogD("## cmp cert with validation time : %s", msg);
fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
time_t outCurrent = mktime(&tc);
context.validationTime = outCurrent;
//return SignatureValidator::SIGNATURE_INVALID;
}
-
+
#endif
#if 0
@@ -961,49 +956,52 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
if (notAfter < nowTime)
{
context.validationTime = notAfter - TIMET_DAY;
- LogWarning("Author certificate is expired. notAfter...");
+ WrtLogW("Author certificate is expired. notAfter...");
}
*/
if (notBefore > nowTime)
{
- LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
+ WrtLogW("Author certificate is expired. notBefore time is greater than system-time.");
t = localtime(&nowTime);
- LogDebug("System's current Year : " << t->tm_year + 1900);
- LogDebug("System's current month : " << t->tm_mon + 1);
- LogDebug("System's current day : " << t->tm_mday);
+ WrtLogD("System's current Year : %d", (t->tm_year + 1900));
+ WrtLogD("System's current month : %d", (t->tm_mon + 1));
+ WrtLogD("System's current day : %d", (t->tm_mday));
t = localtime(&notBefore);
- LogDebug("Author certificate's notBefore Year : " << t->tm_year + 1900);
- LogDebug("Author certificate's notBefore month : " << t->tm_mon + 1);
- LogDebug("Author certificate's notBefore day : " << t->tm_mday);
+ WrtLogD("Author certificate's notBefore Year : %d", (t->tm_year + 1900));
+ WrtLogD("Author certificate's notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Author certificate's notBefore day : %d", (t->tm_mday));
context.validationTime = notBefore + TIMET_DAY;
t = localtime(&context.validationTime);
- LogDebug("Modified current Year : " << t->tm_year + 1900);
- LogDebug("Modified current notBefore month : " << t->tm_mon + 1);
- LogDebug("Modified current notBefore day : " << t->tm_mday);
+ WrtLogD("Modified current Year : %d", (t->tm_year + 1900));
+ WrtLogD("Modified current notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Modified current notBefore day : %d", (t->tm_mday));
}
}
#endif
- if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
- LogWarning("Installation break - invalid package!");
- return SignatureValidator::SIGNATURE_INVALID;
- }
+ if (!data.isAuthorSignature())
+ {
+ if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
+ WrtLogW("Installation break - invalid package!");
+ return SignatureValidator::SIGNATURE_INVALID;
+ }
- data.setReference(context.referenceSet);
+ data.setReference(context.referenceSet);
- if (!checkObjectReferences(data)) {
- return SignatureValidator::SIGNATURE_INVALID;
- }
+ if (!checkObjectReferences(data)) {
+ return SignatureValidator::SIGNATURE_INVALID;
+ }
- ReferenceValidator fileValidator(widgetContentPath);
- if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
- LogWarning("Invalid package - file references broken");
- return SignatureValidator::SIGNATURE_INVALID;
- }
+ ReferenceValidator fileValidator(widgetContentPath);
+ if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
+ WrtLogW("Invalid package - file references broken");
+ return SignatureValidator::SIGNATURE_INVALID;
+ }
+ }
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
// It is good time to do OCSP check
@@ -1015,7 +1013,7 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
coll.load(sortedCertificateList);
if (!coll.sort()) {
- LogDebug("Collection does not contain chain!");
+ WrtLogD("Collection does not contain chain!");
return SignatureValidator::SIGNATURE_INVALID;
}
@@ -1037,7 +1035,7 @@ SignatureValidator::Result ImplWacSignatureValidator::check(
#endif
if (disregard) {
- LogWarning("Signature is disregard. RootCA is not a member of Tizen.");
+ WrtLogW("Signature is disregard. RootCA is not a member of Tizen.");
return SignatureValidator::SIGNATURE_DISREGARD;
}
return SignatureValidator::SIGNATURE_VERIFIED;
@@ -1052,7 +1050,7 @@ SignatureValidator::SignatureValidator(
bool complianceMode)
: m_impl(0)
{
- LogDebug( "appType :" << appType );
+ WrtLogD( "appType :%d", appType );
if(appType == TIZEN)
{
diff --git a/vcore/src/vcore/SignatureValidator.h b/vcore/src/vcore/SignatureValidator.h
index 512cd6b..1f3900c 100644
--- a/vcore/src/vcore/SignatureValidator.h
+++ b/vcore/src/vcore/SignatureValidator.h
@@ -22,15 +22,18 @@
#ifndef _VALIDATION_CORE_SIGNATUREVALIDATOR_H_
#define _VALIDATION_CORE_SIGNATUREVALIDATOR_H_
-#include <string>
+#ifndef LOG_TAG
+#undef LOG_TAG
+#define LOG_TAG "OSP"
+#endif
-#include <dpl/noncopyable.h>
+#include <string>
#include <vcore/SignatureData.h>
namespace ValidationCore {
-class SignatureValidator : public DPL::Noncopyable {
+class SignatureValidator {
public:
class ImplSignatureValidator;
@@ -46,9 +49,22 @@ public:
SIGNATURE_INVALID,
SIGNATURE_VERIFIED,
SIGNATURE_DISREGARD, // no ocsp response or ocsp return unknown status
- SIGNATURE_REVOKED
+ SIGNATURE_REVOKED,
+ SIGNATURE_INVALID_CERT_CHAIN, //5, from here, new error enum
+ SIGNATURE_INVALID_DISTRIBUTOR_CERT,
+ SIGNATURE_INVALID_SDK_DEFAULT_AUTHOR_CERT,
+ SIGNATURE_IN_DISTRIBUTOR_CASE_AUTHOR_CERT,
+ SIGNATURE_INVALID_CERT_TIME,
+ SIGNATURE_NO_DEVICE_PROFILE,
+ SIGNATURE_INVALID_DEVICE_UNIQUE_ID,
+ SIGNATURE_INVALID_NO_HASH_FILE,
+ SIGNATURE_INVALID_HASH_SIGNATURE
};
+ SignatureValidator() = delete;
+ SignatureValidator(const SignatureValidator &) = delete;
+ const SignatureValidator &operator=(const SignatureValidator &) = delete;
+
explicit SignatureValidator(
AppType appType,
bool ocspEnable,
diff --git a/vcore/src/vcore/SoupMessageSendAsync.h b/vcore/src/vcore/SoupMessageSendAsync.h
deleted file mode 100644
index 07fcad5..0000000
--- a/vcore/src/vcore/SoupMessageSendAsync.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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
index e7f4742..a361c18 100644
--- a/vcore/src/vcore/SoupMessageSendBase.cpp
+++ b/vcore/src/vcore/SoupMessageSendBase.cpp
@@ -23,7 +23,7 @@
#include <dpl/assert.h>
#include <dpl/foreach.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
namespace SoupWrapper {
@@ -74,7 +74,7 @@ void SoupMessageSendBase::setRetry(int retry) {
SoupMessage* SoupMessageSendBase::createRequest(){
SoupMessage *message;
- LogInfo("Soup message will be send to: " << m_host.c_str());
+ WrtLogI("Soup message will be send to: %s", m_host.c_str());
if (!m_requestBuffer.empty()) {
message = soup_message_new("POST", m_host.c_str());
@@ -83,7 +83,7 @@ SoupMessage* SoupMessageSendBase::createRequest(){
}
if (!message) {
- LogError("Error creating request!");
+ WrtLogE("Error creating request!");
return 0;
}
diff --git a/vcore/src/vcore/SoupMessageSendSync.cpp b/vcore/src/vcore/SoupMessageSendSync.cpp
index e3f3ee4..8c7343c 100644
--- a/vcore/src/vcore/SoupMessageSendSync.cpp
+++ b/vcore/src/vcore/SoupMessageSendSync.cpp
@@ -26,7 +26,7 @@
#include <vconf.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
namespace SoupWrapper {
@@ -43,11 +43,10 @@ SoupMessageSendBase::RequestStatus SoupMessageSendSync::sendSync()
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());
+ WrtLogD("Proxy ptr: %s Proxy addr: %s", (void*)proxy.get(), proxy.get());
for(int tryCount = 0; tryCount < m_tryCount; ++ tryCount){
- LogDebug("Try(" << tryCount << ") to download " << m_host);
+ WrtLogD("Try(%d) to download %s", tryCount, m_host.c_str());
ScopedSoupSession session(soup_session_async_new_with_options(
SOUP_SESSION_ASYNC_CONTEXT,
@@ -63,7 +62,7 @@ SoupMessageSendBase::RequestStatus SoupMessageSendSync::sendSync()
msg.Reset(createRequest());
if (!msg) {
- LogError("Unable to send HTTP request.");
+ WrtLogE("Unable to send HTTP request.");
m_status = STATUS_IDLE;
return REQUEST_STATUS_CONNECTION_ERROR;
}
@@ -80,10 +79,7 @@ SoupMessageSendBase::RequestStatus SoupMessageSendSync::sendSync()
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");
+ WrtLogW("Soup failed with code [%d] message [%s]", msg->status_code, msg->response_body->data);
}
}
diff --git a/vcore/src/vcore/TimeConversion.cpp b/vcore/src/vcore/TimeConversion.cpp
index 98c80f3..803f582 100644
--- a/vcore/src/vcore/TimeConversion.cpp
+++ b/vcore/src/vcore/TimeConversion.cpp
@@ -17,7 +17,7 @@
#include <string.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <dpl/assert.h>
namespace ValidationCore {
@@ -97,12 +97,12 @@ int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm, time_t *res)
const int DATE_BUFFER_LENGTH = 15; // YYYYMMDDHHMMSSZ
if (NULL == res || NULL == tm) {
- LogError("NULL pointer");
+ WrtLogE("NULL pointer");
return -1;
}
if (DATE_BUFFER_LENGTH != tm->length || NULL == tm->data) {
- LogError("Invalid ASN1_GENERALIZEDTIME");
+ WrtLogE("Invalid ASN1_GENERALIZEDTIME");
return -1;
}
@@ -116,7 +116,7 @@ int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm, time_t *res)
&time_s.tm_min,
&time_s.tm_sec) < 6)
{
- LogError("Could not extract time data from ASN1_GENERALIZEDTIME");
+ WrtLogE("Could not extract time data from ASN1_GENERALIZEDTIME");
return -1;
}
diff --git a/vcore/src/vcore/VCore.cpp b/vcore/src/vcore/VCore.cpp
index fe1aa76..7788584 100644
--- a/vcore/src/vcore/VCore.cpp
+++ b/vcore/src/vcore/VCore.cpp
@@ -30,21 +30,13 @@
#include <glib-object.h>
#include <dpl/assert.h>
-#include <dpl/log/log.h>
-
-#include <tzplatform_config.h>
-
-namespace {
+#include <dpl/log/wrt_log.h>
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
-DPL::DB::ThreadDatabaseSupport *threadInterface = NULL;
-const std::string DatabasePath = tzplatform_mkpath(TZ_SYS_DB, ".cert_svc_vcore.db");
-#endif
-
-const std::string FingerprintListPath = tzplatform_mkpath(TZ_SYS_SHARE, "ca-certificates/fingerprint/fingerprint_list.xml");
-const std::string FingerprintListSchemaPath = tzplatform_mkpath(TZ_SYS_SHARE, "ca-certificates/fingerprint/fingerprint_list.xsd");
-
+namespace {
+VcoreDPL::DB::ThreadDatabaseSupport *threadInterface = NULL;
} // namespace anonymous
+#endif
namespace ValidationCore {
@@ -54,24 +46,24 @@ void AttachToThreadRO(void)
Assert(threadInterface);
static bool check = true;
threadInterface->AttachToThread(
- DPL::DB::SqlConnection::Flag::RO);
+ VcoreDPL::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");
+ "Not a valid vcore database version");
}
#endif
}
void AttachToThreadRW(void)
{
-#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
Assert(threadInterface);
static bool check = true;
threadInterface->AttachToThread(
- DPL::DB::SqlConnection::Flag::RW);
+ VcoreDPL::DB::SqlConnection::Flag::RW);
// We can have race condition here but CheckTableExist
// is thread safe and nothing bad will happend.
if (check) {
@@ -89,31 +81,31 @@ void DetachFromThread(void){
#endif
}
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
-DPL::DB::ThreadDatabaseSupport& ThreadInterface(void) {
+VcoreDPL::DB::ThreadDatabaseSupport& ThreadInterface(void) {
Assert(threadInterface);
return *threadInterface;
}
#endif
+
void VCoreInit()
{
-#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
- if (threadInterface) {
- LogDebug("Already Initialized");
- return;
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+ if (threadInterface) {
+ WrtLogD("Already Initialized");
+ return true;
}
- threadInterface = new DPL::DB::ThreadDatabaseSupport(
- DatabasePath.c_str(),
- DPL::DB::SqlConnection::Flag::UseLucene);
+ threadInterface = new VcoreDPL::DB::ThreadDatabaseSupport(
+ CERTSVC_VCORE_DB,
+ VcoreDPL::DB::SqlConnection::Flag::UseLucene);
#endif
SSL_library_init();
- g_type_init();
Config &globalConfig = ConfigSingleton::Instance();
- globalConfig.setXMLConfigPath(FingerprintListPath);
- globalConfig.setXMLSchemaPath(FingerprintListSchemaPath);
+ globalConfig.setXMLConfigPath(std::string(FINGERPRINT_LIST_PATH));
+ globalConfig.setXMLSchemaPath(std::string(FINGERPRINT_LIST_SCHEMA_PATH));
}
void VCoreDeinit()
diff --git a/vcore/src/vcore/VCorePrivate.h b/vcore/src/vcore/VCorePrivate.h
index a2955b1..802d3fa 100644
--- a/vcore/src/vcore/VCorePrivate.h
+++ b/vcore/src/vcore/VCorePrivate.h
@@ -31,7 +31,7 @@
namespace ValidationCore {
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
-DPL::DB::ThreadDatabaseSupport& ThreadInterface(void);
+VcoreDPL::DB::ThreadDatabaseSupport& ThreadInterface(void);
#endif
} // namespace ValidationCore
diff --git a/vcore/src/vcore/ValidatorFactories.cpp b/vcore/src/vcore/ValidatorFactories.cpp
index c068df7..93238c6 100644
--- a/vcore/src/vcore/ValidatorFactories.cpp
+++ b/vcore/src/vcore/ValidatorFactories.cpp
@@ -21,12 +21,12 @@
*/
#include <vcore/ValidatorFactories.h>
-#include <string>
-#include <dpl/log/log.h>
-
#include <vcore/Certificate.h>
#include <vcore/CertificateConfigReader.h>
#include <vcore/Config.h>
+#include <dpl/log/wrt_log.h>
+
+#include <string>
namespace ValidationCore {
@@ -38,12 +38,13 @@ const CertificateIdentifier& createCertificateIdentifier()
CertificateConfigReader reader;
std::string file =
ConfigSingleton::Instance().getXMLConfigPath();
- LogDebug("File with fingerprint list is: " << file);
+ WrtLogD("File with fingerprint list is: %s", file.c_str());
std::string schema =
ConfigSingleton::Instance().getXMLSchemaPath();
- LogDebug("File with fingerprint list schema is: " << schema);
+ WrtLogD("File with fingerprint list schema is: %s", schema.c_str());
reader.initialize(file, schema);
reader.read(certificateIdentifier);
+
initialized = true;
}
return certificateIdentifier;
diff --git a/vcore/src/vcore/WacOrigin.cpp b/vcore/src/vcore/WacOrigin.cpp
index 7ca0174..304f0e8 100644
--- a/vcore/src/vcore/WacOrigin.cpp
+++ b/vcore/src/vcore/WacOrigin.cpp
@@ -113,7 +113,7 @@ void WacOrigin::parse(const char *url)
char *output = NULL;
if (IDNA_SUCCESS !=
idna_to_ascii_lz(m_host.c_str(), &output, IDNA_USE_STD3_ASCII_RULES)) {
- LogError("libidn error");
+ WrtLogE("libidn error");
m_parseFailed = true;
free(output);
return;
@@ -144,7 +144,7 @@ void WacOrigin::setPort()
m_port = PORT_HTTPS;
return;
} else {
- LogDebug("Scheme " << m_scheme << " is not support by WAC2.0");
+ WrtLogD("Scheme %s is not support by WAC2.0 ", m_scheme.c_str());
m_parseFailed = true;
}
}
diff --git a/vcore/src/vcore/WrtSignatureValidator.cpp b/vcore/src/vcore/WrtSignatureValidator.cpp
index 654b05b..81fc201 100644
--- a/vcore/src/vcore/WrtSignatureValidator.cpp
+++ b/vcore/src/vcore/WrtSignatureValidator.cpp
@@ -21,7 +21,6 @@
*/
#include <vcore/WrtSignatureValidator.h>
-#include <dpl/log/log.h>
#include <vcore/CertificateVerifier.h>
#include <vcore/Certificate.h>
#include <vcore/OCSPCertMgrUtil.h>
@@ -29,6 +28,8 @@
#include <vcore/ValidatorFactories.h>
#include <vcore/XmlsecAdapter.h>
+#include <dpl/log/wrt_log.h>
+
namespace {
const time_t TIMET_DAY = 60 * 60 * 24;
@@ -38,6 +39,7 @@ 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
static tm _ASN1_GetTimeT(ASN1_TIME* time)
@@ -50,20 +52,26 @@ static tm _ASN1_GetTimeT(ASN1_TIME* time)
if (time->type == V_ASN1_UTCTIME) /* two digit year */
{
- t.tm_year = (str[i++] - '0') * 10 + (str[++i] - '0');
+ t.tm_year = (str[i] - '0') * 10 + (str[i+1] - '0');
+ i += 2;
if (t.tm_year < 70)
t.tm_year += 100;
}
else if (time->type == V_ASN1_GENERALIZEDTIME) /* four digit year */
{
- t.tm_year = (str[i++] - '0') * 1000 + (str[++i] - '0') * 100 + (str[++i] - '0') * 10 + (str[++i] - '0');
+ t.tm_year =
+ (str[i] - '0') * 1000
+ + (str[i+1] - '0') * 100
+ + (str[i+2] - '0') * 10
+ + (str[i+3] - '0');
+ i += 4;
t.tm_year -= 1900;
}
- t.tm_mon = ((str[i++] - '0') * 10 + (str[++i] - '0')) - 1; // -1 since January is 0 not 1.
- t.tm_mday = (str[i++] - '0') * 10 + (str[++i] - '0');
- t.tm_hour = (str[i++] - '0') * 10 + (str[++i] - '0');
- t.tm_min = (str[i++] - '0') * 10 + (str[++i] - '0');
- t.tm_sec = (str[i++] - '0') * 10 + (str[++i] - '0');
+ t.tm_mon = ((str[i] - '0') * 10 + (str[i+1] - '0')) - 1; // -1 since January is 0 not 1.
+ t.tm_mday = (str[i+2] - '0') * 10 + (str[i+3] - '0');
+ t.tm_hour = (str[i+4] - '0') * 10 + (str[i+5] - '0');
+ t.tm_min = (str[i+6] - '0') * 10 + (str[i+7] - '0');
+ t.tm_sec = (str[i+8] - '0') * 10 + (str[i+9] - '0');
/* Note: we did not adjust the time based on time zone information */
return t;
@@ -82,30 +90,34 @@ public:
bool crlEnable,
bool complianceMode)
: m_complianceModeEnabled(complianceMode)
- #ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
- , m_ocspEnable(ocspEnable)
- , m_crlEnable(crlEnable)
- #endif
- {}
+ {
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+ m_ocspEnable = ocspEnable;
+ m_crlEnable = crlEnable;
+#else
+ (void) ocspEnable;
+ (void) crlEnable;
+#endif
+ }
- virtual ~Impl(){}
+ 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.");
+ WrtLogW("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 "
+ WrtLogW("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 "
+ WrtLogW("URI attribute in Role tag does not "
"match with signature filename.");
return false;
}
@@ -114,9 +126,7 @@ public:
bool checkProfileURI(const SignatureData &data) {
if (TOKEN_PROFILE_URI != data.getProfileURI()) {
- LogWarning(
- "Profile tag contains unsupported value in URI attribute(" <<
- data.getProfileURI() << ").");
+ WrtLogW("Profile tag contains unsupported value in URI attribute (%s).", (data.getProfileURI()).c_str());
return false;
}
return true;
@@ -127,8 +137,7 @@ public:
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);
+ WrtLogW("Signature does not contain reference for object %s", (*iter).c_str());
return false;
}
}
@@ -143,9 +152,8 @@ protected:
};
-class ImplTizen : public WrtSignatureValidator::Impl
-{
- public:
+class ImplTizen : public WrtSignatureValidator::Impl {
+public:
WrtSignatureValidator::Result check(SignatureData &data,
const std::string &widgetContentPath);
@@ -179,14 +187,14 @@ WrtSignatureValidator::Result ImplTizen::check(
// First step - sort certificate
if (!collection.sort()) {
- LogWarning("Certificates do not form valid chain.");
- return WrtSignatureValidator::SIGNATURE_INVALID;
+ WrtLogW("Certificates do not form valid chain.");
+ return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
}
// Check for error
if (collection.empty()) {
- LogWarning("Certificate list in signature is empty.");
- return WrtSignatureValidator::SIGNATURE_INVALID;
+ WrtLogW("Certificate list in signature is empty.");
+ return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
}
CertificateList sortedCertificateList = collection.getChain();
@@ -201,48 +209,44 @@ WrtSignatureValidator::Result ImplTizen::check(
// Is Root CA certificate trusted?
CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
- LogDebug("Is root certificate from TIZEN_DEVELOPER domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
- LogDebug("Is root certificate from TIZEN_TEST domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_TEST));
- LogDebug("Is root certificate from TIZEN_VERIFY domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
- LogDebug("Is root certificate from TIZEN_PUBLIC domain: "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Is root certificate from TIZEN_PARTNER domain: "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Is root certificate from TIZEN_PLATFORM domain: "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
- LogDebug("Visibility level is public : "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Visibility level is partner : "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Visibility level is platform : "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+ WrtLogD("Is root certificate from TIZEN_DEVELOPER domain: %d", storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
+ WrtLogD("Is root certificate from TIZEN_TEST domain: %d", storeIdSet.contains(CertStoreId::TIZEN_TEST));
+ WrtLogD("Is root certificate from TIZEN_VERIFY domain: %d", storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
+ WrtLogD("Is root certificate from TIZEN_PUBLIC domain: %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Is root certificate from TIZEN_PARTNER domain: %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Is root certificate from TIZEN_PLATFORM domain: %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+ WrtLogD("Visibility level is public : %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Visibility level is partner : %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Visibility level is platform : %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
if (data.isAuthorSignature())
{
if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
{
- LogWarning("author-signature.xml has got unrecognized Root CA "
- "certificate. Signature will be disregarded.");
- disregard = true;
+ WrtLogW("author-signature.xml has got unrecognized Root CA "
+ "certificate. Signature will be disregarded.");
+ disregard = true;
}
- LogDebug("Root CA for author signature is correct.");
}
- else
+ else // distributor
{
- LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
+ if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
+ {
+ WrtLogW("distributor has author level siganture! Signature will be disregarded.");
+ return WrtSignatureValidator::SIGNATURE_IN_DISTRIBUTOR_CASE_AUTHOR_CERT;//SIGNATURE_INVALID;
+ }
+ WrtLogD("signaturefile name = %s", data.getSignatureFileName().c_str());
+
if (data.getSignatureNumber() == 1)
{
if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
{
- LogDebug("Root CA for signature1.xml is correct.");
+ WrtLogD("Root CA for signature1.xml is correct.");
}
else
{
- LogWarning("signature1.xml has got unrecognized Root CA "
+ WrtLogW("signature1.xml has got unrecognized Root CA "
"certificate. Signature will be disregarded.");
disregard = true;
}
@@ -262,7 +266,7 @@ WrtSignatureValidator::Result ImplTizen::check(
// 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.");
+ WrtLogW("Root CA certificate not found. Chain is incomplete.");
//context.allowBrokenChain = true;
}
@@ -282,44 +286,46 @@ WrtSignatureValidator::Result ImplTizen::check(
char msg[1024];
t = localtime(&nowTime);
+ if (!t)
+ return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;
memset(&tc, 0, sizeof(tc));
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
- LogDebug("## System's currentTime : " << msg);
+ WrtLogD("## System's currentTime : %s", msg);
fprintf(stderr, "## System's currentTime : %s\n", msg);
tb = _ASN1_GetTimeT(notBeforeTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
- LogDebug("## certificate's notBeforeTime : " << msg);
+ WrtLogD("## certificate's notBeforeTime : %s", msg);
fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
ta = _ASN1_GetTimeT(notAfterTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
- LogDebug("## certificate's notAfterTime : " << msg);
+ WrtLogD("## certificate's notAfterTime : %s", msg);
fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
- if (storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
- {
- LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
+ if (storeIdSet.contains(CertStoreId::TIZEN_TEST) || storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
+ {
+ WrtLogD("## TIZEN_VERIFY : check certificate Time : FALSE");
fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
- return WrtSignatureValidator::SIGNATURE_INVALID;
+ return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;//SIGNATURE_INVALID;
}
int year = (ta.tm_year - tb.tm_year) / 4;
if(year == 0)
{
- tc.tm_year = tb.tm_year;
+ tc.tm_year = tb.tm_year;
tc.tm_mon = tb.tm_mon + 1;
tc.tm_mday = tb.tm_mday;
if(tc.tm_mon == 12)
{
- tc.tm_year = ta.tm_year;
+ tc.tm_year = ta.tm_year;
tc.tm_mon = ta.tm_mon - 1;
tc.tm_mday = ta.tm_mday;
-
+
if(tc.tm_mon < 0)
{
tc.tm_year = ta.tm_year;
@@ -328,21 +334,21 @@ WrtSignatureValidator::Result ImplTizen::check(
if(tc.tm_mday == 0)
{
- tc.tm_year = tb.tm_year;
+ tc.tm_year = tb.tm_year;
tc.tm_mon = tb.tm_mon;
tc.tm_mday = tb.tm_mday +1;
}
}
- }
+ }
}
else{
tc.tm_year = tb.tm_year + year;
tc.tm_mon = (tb.tm_mon + ta.tm_mon )/2;
- tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
+ tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
}
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
- LogDebug("## cmp cert with validation time : " << msg);
+ WrtLogD("## cmp cert with validation time : %s", msg);
fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
time_t outCurrent = mktime(&tc);
@@ -351,7 +357,7 @@ WrtSignatureValidator::Result ImplTizen::check(
fprintf(stderr, "## cmp outCurrent time : %ld\n", outCurrent);
//return WrtSignatureValidator::SIGNATURE_INVALID;
- }
+ }
#endif
@@ -368,30 +374,30 @@ WrtSignatureValidator::Result ImplTizen::check(
if (notAfter < nowTime)
{
context.validationTime = notAfter - TIMET_DAY;
- LogWarning("Author certificate is expired. notAfter...");
+ WrtLogW("Author certificate is expired. notAfter...");
}
*/
if (notBefore > nowTime)
{
- LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
+ WrtLogW("Author certificate is expired. notBefore time is greater than system-time.");
t = localtime(&nowTime);
- LogDebug("System's current Year : " << t->tm_year + 1900);
- LogDebug("System's current month : " << t->tm_mon + 1);
- LogDebug("System's current day : " << t->tm_mday);
+ WrtLogD("System's current Year : %d", (t->tm_year + 1900));
+ WrtLogD("System's current month : %d", (t->tm_mon + 1));
+ WrtLogD("System's current day : %d", (t->tm_mday));
t = localtime(&notBefore);
- LogDebug("Author certificate's notBefore Year : " << t->tm_year + 1900);
- LogDebug("Author certificate's notBefore month : " << t->tm_mon + 1);
- LogDebug("Author certificate's notBefore day : " << t->tm_mday);
+ WrtLogD("Author certificate's notBefore Year : %d", (t->tm_year + 1900));
+ WrtLogD("Author certificate's notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Author certificate's notBefore day : %d", (t->tm_mday));
context.validationTime = notBefore + TIMET_DAY;
t = localtime(&context.validationTime);
- LogDebug("Modified current Year : " << t->tm_year + 1900);
- LogDebug("Modified current notBefore month : " << t->tm_mon + 1);
- LogDebug("Modified current notBefore day : " << t->tm_mday);
+ WrtLogD("Modified current Year : %d", (t->tm_year + 1900));
+ WrtLogD("Modified current notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Modified current notBefore day : %d", (t->tm_mday));
}
}
#endif
@@ -399,22 +405,26 @@ WrtSignatureValidator::Result ImplTizen::check(
//context.allowBrokenChain = true;
// end
- if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
- LogWarning("Installation break - invalid package!");
- return WrtSignatureValidator::SIGNATURE_INVALID;
- }
+ if (!data.isAuthorSignature())
+ {
+ if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
+ WrtLogW("Installation break - invalid package!");
+ return WrtSignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
+ }
- data.setReference(context.referenceSet);
+ data.setReference(context.referenceSet);
- if (!checkObjectReferences(data)) {
- return WrtSignatureValidator::SIGNATURE_INVALID;
- }
+ if (!checkObjectReferences(data)) {
+ WrtLogW("Failed to check Object References");
+ return WrtSignatureValidator::SIGNATURE_INVALID_HASH_SIGNATURE;//SIGNATURE_INVALID;
+ }
- ReferenceValidator fileValidator(widgetContentPath);
- if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
- LogWarning("Invalid package - file references broken");
- return WrtSignatureValidator::SIGNATURE_INVALID;
- }
+ ReferenceValidator fileValidator(widgetContentPath);
+ if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
+ WrtLogW("Invalid package - file references broken");
+ return WrtSignatureValidator::SIGNATURE_INVALID_NO_HASH_FILE;//SIGNATURE_INVALID;
+ }
+ }
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
// It is good time to do OCSP check
@@ -426,8 +436,8 @@ WrtSignatureValidator::Result ImplTizen::check(
coll.load(sortedCertificateList);
if (!coll.sort()) {
- LogDebug("Collection does not contain chain!");
- return WrtSignatureValidator::SIGNATURE_INVALID;
+ WrtLogD("Collection does not contain chain!");
+ return WrtSignatureValidator::SIGNATURE_INVALID_CERT_CHAIN;//SIGNATURE_INVALID;
}
CertificateVerifier verificator(m_ocspEnable, m_crlEnable);
@@ -440,23 +450,23 @@ WrtSignatureValidator::Result ImplTizen::check(
if (result == VERIFICATION_STATUS_UNKNOWN ||
result == VERIFICATION_STATUS_ERROR)
{
- #ifdef _OCSP_POLICY_DISREGARD_UNKNOWN_OR_ERROR_CERTS_
+#ifdef _OCSP_POLICY_DISREGARD_UNKNOWN_OR_ERROR_CERTS_
disregard = true;
- #endif
+#endif
}
}
#endif
if (disregard) {
- LogWarning("Signature is disregard. RootCA is not a member of Tizen");
- return WrtSignatureValidator::SIGNATURE_DISREGARD;
+ WrtLogW("Signature is disregard. RootCA is not a member of Tizen");
+ return WrtSignatureValidator::SIGNATURE_INVALID_DISTRIBUTOR_CERT;//SIGNATURE_DISREGARD;
}
return WrtSignatureValidator::SIGNATURE_VERIFIED;
}
class ImplWac : public WrtSignatureValidator::Impl
{
- public:
+public:
WrtSignatureValidator::Result check(SignatureData &data,
const std::string &widgetContentPath);
@@ -490,13 +500,13 @@ WrtSignatureValidator::Result ImplWac::check(
// First step - sort certificate
if (!collection.sort()) {
- LogWarning("Certificates do not form valid chain.");
+ WrtLogW("Certificates do not form valid chain.");
return WrtSignatureValidator::SIGNATURE_INVALID;
}
// Check for error
if (collection.empty()) {
- LogWarning("Certificate list in signature is empty.");
+ WrtLogW("Certificate list in signature is empty.");
return WrtSignatureValidator::SIGNATURE_INVALID;
}
@@ -512,50 +522,44 @@ WrtSignatureValidator::Result ImplWac::check(
// Is Root CA certificate trusted?
CertStoreId::Set storeIdSet = createCertificateIdentifier().find(root);
- LogDebug("Is root certificate from TIZEN_DEVELOPER domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
- LogDebug("Is root certificate from TIZEN_TEST domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_TEST));
- LogDebug("Is root certificate from TIZEN_VERIFY domain: "
- << storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
- LogDebug("Is root certificate from TIZEN_PUBLIC domain: "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Is root certificate from TIZEN_PARTNER domain: "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Is root certificate from TIZEN_PLATFORM domain: "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
-
- LogDebug("Visibility level is public : "
- << storeIdSet.contains(CertStoreId::VIS_PUBLIC));
- LogDebug("Visibility level is partner : "
- << storeIdSet.contains(CertStoreId::VIS_PARTNER));
- LogDebug("Visibility level is platform : "
- << storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+ WrtLogD("Is root certificate from TIZEN_DEVELOPER domain: %d", storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER));
+ WrtLogD("Is root certificate from TIZEN_TEST domain: %d", storeIdSet.contains(CertStoreId::TIZEN_TEST));
+ WrtLogD("Is root certificate from TIZEN_VERIFY domain: %d", storeIdSet.contains(CertStoreId::TIZEN_VERIFY));
+ WrtLogD("Is root certificate from TIZEN_PUBLIC domain: %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Is root certificate from TIZEN_PARTNER domain: %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Is root certificate from TIZEN_PLATFORM domain: %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
+
+ WrtLogD("Visibility level is public : %d", storeIdSet.contains(CertStoreId::VIS_PUBLIC));
+ WrtLogD("Visibility level is partner : %d", storeIdSet.contains(CertStoreId::VIS_PARTNER));
+ WrtLogD("Visibility level is platform : %d", storeIdSet.contains(CertStoreId::VIS_PLATFORM));
if (data.isAuthorSignature())
{
if (!storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
{
- LogWarning("author-signature.xml has got unrecognized Root CA "
- "certificate. Signature will be disregarded.");
- disregard = true;
+ WrtLogW("author-signature.xml has got unrecognized Root CA "
+ "certificate. Signature will be disregarded.");
+ disregard = true;
}
- LogDebug("Root CA for author signature is correct.");
}
else
{
- LogDebug("signaturefile name = " << data.getSignatureFileName().c_str());
- //Additional Check for certificate registration
+ if (storeIdSet.contains(CertStoreId::TIZEN_DEVELOPER))
+ {
+ WrtLogW("distributor has author level siganture! Signature will be disregarded.");
+ return WrtSignatureValidator::SIGNATURE_INVALID;
+ }
+ WrtLogD("signaturefile name = %s", data.getSignatureFileName().c_str());
if (data.getSignatureNumber() == 1)
{
if (storeIdSet.contains(CertStoreId::VIS_PUBLIC) || storeIdSet.contains(CertStoreId::VIS_PARTNER) || storeIdSet.contains(CertStoreId::VIS_PLATFORM))
{
- LogDebug("Root CA for signature1.xml is correct.");
+ WrtLogD("Root CA for signature1.xml is correct.");
}
else
{
- LogWarning("signature1.xml has got unrecognized Root CA "
+ WrtLogW("signature1.xml has got unrecognized Root CA "
"certificate. Signature will be disregarded.");
disregard = true;
}
@@ -575,7 +579,7 @@ WrtSignatureValidator::Result ImplWac::check(
// 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.");
+ WrtLogW("Root CA certificate not found. Chain is incomplete.");
// context.allowBrokenChain = true;
}
@@ -595,26 +599,28 @@ WrtSignatureValidator::Result ImplWac::check(
char msg[1024];
t = localtime(&nowTime);
+ if (!t)
+ return WrtSignatureValidator::SIGNATURE_INVALID_CERT_TIME;
memset(&tc, 0, sizeof(tc));
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", t->tm_year + 1900, t->tm_mon + 1,t->tm_mday );
- LogDebug("## System's currentTime : " << msg);
+ WrtLogD("## System's currentTime : %s", msg);
fprintf(stderr, "## System's currentTime : %s\n", msg);
tb = _ASN1_GetTimeT(notBeforeTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tb.tm_year + 1900, tb.tm_mon + 1,tb.tm_mday );
- LogDebug("## certificate's notBeforeTime : " << msg);
+ WrtLogD("## certificate's notBeforeTime : %s", msg);
fprintf(stderr, "## certificate's notBeforeTime : %s\n", msg);
ta = _ASN1_GetTimeT(notAfterTime);
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", ta.tm_year + 1900, ta.tm_mon + 1,ta.tm_mday );
- LogDebug("## certificate's notAfterTime : " << msg);
+ WrtLogD("## certificate's notAfterTime : %s", msg);
fprintf(stderr, "## certificate's notAfterTime : %s\n", msg);
if (storeIdSet.contains(CertStoreId::TIZEN_VERIFY))
{
- LogDebug("## TIZEN_VERIFY : check certificate Time : FALSE");
+ WrtLogD("## TIZEN_VERIFY : check certificate Time : FALSE");
fprintf(stderr, "## TIZEN_VERIFY : check certificate Time : FALSE\n");
return WrtSignatureValidator::SIGNATURE_INVALID;
}
@@ -623,16 +629,16 @@ WrtSignatureValidator::Result ImplWac::check(
if(year == 0)
{
- tc.tm_year = tb.tm_year;
+ tc.tm_year = tb.tm_year;
tc.tm_mon = tb.tm_mon + 1;
tc.tm_mday = tb.tm_mday;
if(tc.tm_mon == 12)
{
- tc.tm_year = ta.tm_year;
+ tc.tm_year = ta.tm_year;
tc.tm_mon = ta.tm_mon - 1;
tc.tm_mday = ta.tm_mday;
-
+
if(tc.tm_mon < 0)
{
tc.tm_year = ta.tm_year;
@@ -641,21 +647,21 @@ WrtSignatureValidator::Result ImplWac::check(
if(tc.tm_mday == 0)
{
- tc.tm_year = tb.tm_year;
+ tc.tm_year = tb.tm_year;
tc.tm_mon = tb.tm_mon;
tc.tm_mday = tb.tm_mday +1;
}
}
- }
+ }
}
else{
tc.tm_year = tb.tm_year + year;
tc.tm_mon = (tb.tm_mon + ta.tm_mon )/2;
- tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
+ tc.tm_mday = (tb.tm_mday + ta.tm_mday)/2;
}
snprintf(msg, sizeof(msg), "Year: %d, month: %d, day : %d", tc.tm_year + 1900, tc.tm_mon + 1,tc.tm_mday );
- LogDebug("## cmp cert with validation time : " << msg);
+ WrtLogD("## cmp cert with validation time : %s", msg);
fprintf(stderr, "## cmp cert with validation time : %s\n", msg);
time_t outCurrent = mktime(&tc);
@@ -664,7 +670,7 @@ WrtSignatureValidator::Result ImplWac::check(
context.validationTime = outCurrent;
//return WrtSignatureValidator::SIGNATURE_INVALID;
- }
+ }
#endif
@@ -681,49 +687,53 @@ WrtSignatureValidator::Result ImplWac::check(
if (notAfter < nowTime)
{
context.validationTime = notAfter - TIMET_DAY;
- LogWarning("Author certificate is expired. notAfter...");
+ WrtLogW("Author certificate is expired. notAfter...");
}
*/
if (notBefore > nowTime)
{
- LogWarning("Author certificate is expired. notBefore time is greater than system-time.");
+ WrtLogW("Author certificate is expired. notBefore time is greater than system-time.");
t = localtime(&nowTime);
- LogDebug("System's current Year : " << t->tm_year + 1900);
- LogDebug("System's current month : " << t->tm_mon + 1);
- LogDebug("System's current day : " << t->tm_mday);
+ WrtLogD("System's current Year : %d", (t->tm_year + 1900));
+ WrtLogD("System's current month : %d", (t->tm_mon + 1));
+ WrtLogD("System's current day : %d", (t->tm_mday));
t = localtime(&notBefore);
- LogDebug("Author certificate's notBefore Year : " << t->tm_year + 1900);
- LogDebug("Author certificate's notBefore month : " << t->tm_mon + 1);
- LogDebug("Author certificate's notBefore day : " << t->tm_mday);
+ WrtLogD("Author certificate's notBefore Year : %d", (t->tm_year + 1900));
+ WrtLogD("Author certificate's notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Author certificate's notBefore day : %d", (t->tm_mday));
context.validationTime = notBefore + TIMET_DAY;
t = localtime(&context.validationTime);
- LogDebug("Modified current Year : " << t->tm_year + 1900);
- LogDebug("Modified current notBefore month : " << t->tm_mon + 1);
- LogDebug("Modified current notBefore day : " << t->tm_mday);
+ WrtLogD("Modified current Year : %d", (t->tm_year + 1900));
+ WrtLogD("Modified current notBefore month : %d", (t->tm_mon + 1));
+ WrtLogD("Modified current notBefore day : %d", (t->tm_mday));
}
}
#endif
- if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
- LogWarning("Installation break - invalid package!");
- return WrtSignatureValidator::SIGNATURE_INVALID;
- }
- data.setReference(context.referenceSet);
+ if (!data.isAuthorSignature())
+ {
+ if (XmlSec::NO_ERROR != XmlSecSingleton::Instance().validate(&context)) {
+ WrtLogW("Installation break - invalid package!");
+ return WrtSignatureValidator::SIGNATURE_INVALID;
+ }
- if (!checkObjectReferences(data)) {
- return WrtSignatureValidator::SIGNATURE_INVALID;
- }
+ data.setReference(context.referenceSet);
- ReferenceValidator fileValidator(widgetContentPath);
- if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
- LogWarning("Invalid package - file references broken");
- return WrtSignatureValidator::SIGNATURE_INVALID;
- }
+ if (!checkObjectReferences(data)) {
+ return WrtSignatureValidator::SIGNATURE_INVALID;
+ }
+
+ ReferenceValidator fileValidator(widgetContentPath);
+ if (ReferenceValidator::NO_ERROR != fileValidator.checkReferences(data)) {
+ WrtLogW("Invalid package - file references broken");
+ return WrtSignatureValidator::SIGNATURE_INVALID;
+ }
+ }
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
// It is good time to do OCSP check
@@ -735,7 +745,7 @@ WrtSignatureValidator::Result ImplWac::check(
coll.load(sortedCertificateList);
if (!coll.sort()) {
- LogDebug("Collection does not contain chain!");
+ WrtLogD("Collection does not contain chain!");
return WrtSignatureValidator::SIGNATURE_INVALID;
}
@@ -757,7 +767,7 @@ WrtSignatureValidator::Result ImplWac::check(
#endif
if (disregard) {
- LogWarning("Signature is disregard. RootCA is not a member of Tizen.");
+ WrtLogW("Signature is disregard. RootCA is not a member of Tizen.");
return WrtSignatureValidator::SIGNATURE_DISREGARD;
}
return WrtSignatureValidator::SIGNATURE_VERIFIED;
@@ -778,7 +788,8 @@ WrtSignatureValidator::WrtSignatureValidator(
m_impl = new ImplWac(ocspEnable,crlEnable,complianceMode);
}
-WrtSignatureValidator::~WrtSignatureValidator() {
+WrtSignatureValidator::~WrtSignatureValidator()
+{
delete m_impl;
}
diff --git a/vcore/src/vcore/WrtSignatureValidator.h b/vcore/src/vcore/WrtSignatureValidator.h
index 5ff8752..04a8434 100644
--- a/vcore/src/vcore/WrtSignatureValidator.h
+++ b/vcore/src/vcore/WrtSignatureValidator.h
@@ -24,14 +24,13 @@
#include <string>
-#include <dpl/noncopyable.h>
-
#include <vcore/SignatureData.h>
namespace ValidationCore {
-class WrtSignatureValidator : public DPL::Noncopyable {
+class WrtSignatureValidator {
public:
+
class Impl;
enum AppType
@@ -46,9 +45,22 @@ public:
SIGNATURE_INVALID,
SIGNATURE_VERIFIED,
SIGNATURE_DISREGARD, // no ocsp response or ocsp return unknown status
- SIGNATURE_REVOKED
+ SIGNATURE_REVOKED,
+ SIGNATURE_INVALID_CERT_CHAIN, //5, from here, new error enum
+ SIGNATURE_INVALID_DISTRIBUTOR_CERT,
+ SIGNATURE_INVALID_SDK_DEFAULT_AUTHOR_CERT,
+ SIGNATURE_IN_DISTRIBUTOR_CASE_AUTHOR_CERT,
+ SIGNATURE_INVALID_CERT_TIME,
+ SIGNATURE_NO_DEVICE_PROFILE,
+ SIGNATURE_INVALID_DEVICE_UNIQUE_ID,
+ SIGNATURE_INVALID_NO_HASH_FILE,
+ SIGNATURE_INVALID_HASH_SIGNATURE
};
+ WrtSignatureValidator() = delete;
+ WrtSignatureValidator(const WrtSignatureValidator &) = delete;
+ const WrtSignatureValidator &operator=(const WrtSignatureValidator &) = delete;
+
explicit WrtSignatureValidator(
AppType appType,
bool ocspEnable,
@@ -63,6 +75,7 @@ public:
private:
Impl *m_impl;
+
};
} // namespace ValidationCore
diff --git a/vcore/src/vcore/XmlsecAdapter.cpp b/vcore/src/vcore/XmlsecAdapter.cpp
index c1d4529..93fc498 100644
--- a/vcore/src/vcore/XmlsecAdapter.cpp
+++ b/vcore/src/vcore/XmlsecAdapter.cpp
@@ -39,7 +39,7 @@
#include <xmlsec/errors.h>
#include <dpl/assert.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <vcore/XmlsecAdapter.h>
@@ -78,7 +78,7 @@ void* XmlSec::fileOpenCallback(const char *filename)
{
std::string path = s_prefixPath + filename;
- // LogDebug("Xmlsec opening: " << path);
+ // WrtLogD("Xmlsec opening: %s", path);
return new FileWrapper(xmlFileOpen(path.c_str()),false);
}
@@ -100,7 +100,7 @@ int XmlSec::fileReadCallback(void *context,
int XmlSec::fileCloseCallback(void *context)
{
- //LogDebug("Xmlsec closing: ");
+ //WrtLogD("Xmlsec closing: ");
FileWrapper *fw = static_cast<FileWrapper*>(context);
int output = 0;
if (!(fw->released)) {
@@ -126,21 +126,21 @@ void XmlSec::fileExtractPrefix(XmlSecContext *context)
}
}
-void LogDebugPrint(const char* file, int line, const char* func,
- const char* errorObject, const char* errorSubject,
+void LogDebugPrint(const char* file, int line, const char* func,
+ const char* errorObject, const char* errorSubject,
int reason, const char* msg)
{
char total[1024];
- snprintf(total, sizeof(total), "[%s(%d)] : [%s] : [%s] : [%s]", func, line, errorObject, errorSubject, msg);
+ snprintf(total, sizeof(total), "[%s:%d][%s] : [%s] : [%s] : [%s]", file, line, func, errorObject, errorSubject, msg);
if(reason != 256)
{
fprintf(stderr, "## [validate error]: %s\n", total);
- LogError(" " << total);
+ WrtLogE(" %s", total);
}
else
{
- LogDebug(" " << total);
+ WrtLogD(" %s", total);
}
}
@@ -158,13 +158,13 @@ XmlSec::XmlSec() :
#endif
if (xmlSecInit() < 0) {
- LogError("Xmlsec initialization failed.");
+ WrtLogE("Xmlsec initialization failed.");
ThrowMsg(Exception::InternalError, "Xmlsec initialization failed.");
}
if (xmlSecCheckVersion() != 1) {
xmlSecShutdown();
- LogError("Loaded xmlsec library version is not compatible.");
+ WrtLogE("Loaded xmlsec library version is not compatible.");
ThrowMsg(Exception::InternalError,
"Loaded xmlsec library version is not compatible.");
}
@@ -172,7 +172,7 @@ XmlSec::XmlSec() :
#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
xmlSecShutdown();
- LogError(
+ WrtLogE(
"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.");
@@ -183,14 +183,14 @@ XmlSec::XmlSec() :
if (xmlSecCryptoAppInit(NULL) < 0) {
xmlSecShutdown();
- LogError("Crypto initialization failed.");
+ WrtLogE("Crypto initialization failed.");
ThrowMsg(Exception::InternalError, "Crypto initialization failed.");
}
if (xmlSecCryptoInit() < 0) {
xmlSecCryptoAppShutdown();
xmlSecShutdown();
- LogError("Xmlsec-crypto initialization failed.");
+ WrtLogE("Xmlsec-crypto initialization failed.");
ThrowMsg(Exception::InternalError,
"Xmlsec-crypto initialization failed.");
}
@@ -238,7 +238,7 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
int size, res = -1;
fileExtractPrefix(context);
- LogDebug("Prefix path: " << s_prefixPath);
+ WrtLogD("Prefix path: %s", s_prefixPath.c_str());
xmlSecIOCleanupCallbacks();
@@ -251,7 +251,7 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
/* load file */
doc = xmlParseFile(context->signatureFile.c_str());
if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)) {
- LogWarning("Unable to parse file " << context->signatureFile);
+ WrtLogW("Unable to parse file %s", (context->signatureFile).c_str());
goto done;
}
@@ -259,14 +259,14 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
node = xmlSecFindNode(xmlDocGetRootElement(
doc), xmlSecNodeSignature, xmlSecDSigNs);
if (node == NULL) {
- LogWarning("Start node not found in " << context->signatureFile);
+ WrtLogW("Start node not found in %s", (context->signatureFile).c_str());
goto done;
}
/* create signature context */
dsigCtx = xmlSecDSigCtxCreate(mngr);
if (dsigCtx == NULL) {
- LogError("Failed to create signature context.");
+ WrtLogE("Failed to create signature context.");
goto done;
}
@@ -276,14 +276,14 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
}
if (context->validationTime) {
- LogDebug("Setting validation time.");
+ WrtLogD("Setting validation time.");
dsigCtx->keyInfoReadCtx.certsVerificationTime = context->validationTime;
}
if( m_noHash == true || m_partialHash == true ) {
- LogDebug("SignatureEx start >> ");
+ WrtLogD("SignatureEx start >> ");
if( m_pList == NULL ) {
- LogWarning("## [validate]: uriList does not exist" );
+ WrtLogW("## [validate]: uriList does not exist" );
fprintf(stderr, "## [validate]: uriList does not exist\n");
res = xmlSecDSigCtxVerifyEx(dsigCtx, node, 1, NULL);
} else {
@@ -292,7 +292,7 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
if(m_pList == NULL)
{
- LogWarning("## [validate]: uriList does not exist" );
+ WrtLogW("## [validate]: uriList does not exist" );
fprintf(stderr, "## [validate]: uriList does not exist\n");
res = -1;
goto done;
@@ -300,7 +300,7 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
n = m_pList->size();
- char* pList[n];
+ char* pList[n + 1];
std::list<std::string>::const_iterator itr = m_pList->begin();
std::string tmpString;
char* uri = NULL;
@@ -327,17 +327,17 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
}
if(res < 0) {
- LogError("SignatureEx verify error.");
+ WrtLogE("SignatureEx verify error.");
fprintf(stderr, "## [validate error]: SignatureEx verify error\n");
res = -1;
goto done;
}
} else {
- LogDebug("Signature start >> ");
+ WrtLogD("Signature start >> ");
/* Verify signature */
if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
- LogError("Signature verify error.");
+ WrtLogE("Signature verify error.");
fprintf(stderr, "## [validate error]: Signature verify error\n");
res = -1;
goto done;
@@ -346,25 +346,24 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
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!");
+ WrtLogW("XMLSEC_KEYINFO_FLAGS_ALLOW_BROKEN_CHAIN was set to true!");
+ WrtLogW("Signature contains broken chain!");
context->errorBrokenChain = true;
}
/* print verification result to stdout */
if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
- LogDebug("Signature is OK");
+ WrtLogD("Signature is OK");
res = 0;
} else {
- LogDebug("Signature is INVALID");
+ WrtLogD("Signature is INVALID");
res = -1;
goto done;
}
if (dsigCtx->c14nMethod && dsigCtx->c14nMethod->id &&
dsigCtx->c14nMethod->id->name) {
- // LogInfo("Canonicalization method: " <<
- // reinterpret_cast<const char *>(dsigCtx->c14nMethod->id->name));
+ // WrtLogI("Canonicalization method: %s", (reinterpret_cast<const char *>(dsigCtx->c14nMethod->id->name)).c_str());
}
size = xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences));
@@ -380,12 +379,9 @@ XmlSec::Result XmlSec::validateFile(XmlSecContext *context,
reinterpret_cast<const char *>(dsigRefCtx->digestMethod->id
->name);
std::string strDigest(pDigest);
- /*LogInfo("reference digest method: " <<
- reinterpret_cast<const char *>(dsigRefCtx->digestMethod
- ->id
- ->name));*/
+ /*WrtLogI("reference digest method: %s" (reinterpret_cast<const char *>(dsigRefCtx->digestMethod->id->name)).c_str());*/
if (strDigest == DIGEST_MD5) {
- LogWarning("MD5 digest method used! Please use sha");
+ WrtLogW("MD5 digest method used! Please use sha");
res = -1;
break;
}
@@ -422,7 +418,7 @@ void XmlSec::loadDERCertificateMemory(XmlSecContext *context,
int size = i2d_X509(context->certificatePtr->getX509(), &derCertificate);
if (!derCertificate) {
- LogError("Failed during x509 conversion to der format.");
+ WrtLogE("Failed during x509 conversion to der format.");
ThrowMsg(Exception::InternalError,
"Failed during x509 conversion to der format.");
}
@@ -433,7 +429,7 @@ void XmlSec::loadDERCertificateMemory(XmlSecContext *context,
xmlSecKeyDataFormatDer,
xmlSecKeyDataTypeTrusted) < 0) {
OPENSSL_free(derCertificate);
- LogError("Failed to load der certificate from memory.");
+ WrtLogE("Failed to load der certificate from memory.");
ThrowMsg(Exception::InternalError,
"Failed to load der certificate from memory.");
}
@@ -448,7 +444,7 @@ void XmlSec::loadPEMCertificateFile(XmlSecContext *context,
context->certificatePath.c_str(),
xmlSecKeyDataFormatPem,
xmlSecKeyDataTypeTrusted) < 0) {
- LogError("Failed to load PEM certificate from file.");
+ WrtLogE("Failed to load PEM certificate from file.");
ThrowMsg(Exception::InternalError,
"Failed to load PEM certificate from file.");
}
@@ -463,19 +459,19 @@ XmlSec::Result XmlSec::validate(XmlSecContext *context)
xmlSecErrorsSetCallback(LogDebugPrint);
if (!m_initialized) {
- LogError("XmlSec is not initialized.");
+ WrtLogE("XmlSec is not initialized.");
ThrowMsg(Exception::InternalError, "XmlSec is not initialized");
}
AutoPtr<xmlSecKeysMngr> mngr(xmlSecKeysMngrCreate());
if (!mngr.get()) {
- LogError("Failed to create keys manager.");
+ WrtLogE("Failed to create keys manager.");
ThrowMsg(Exception::InternalError, "Failed to create keys manager.");
}
if (xmlSecCryptoAppDefaultKeysMngrInit(mngr.get()) < 0) {
- LogError("Failed to initialize keys manager.");
+ WrtLogE("Failed to initialize keys manager.");
ThrowMsg(Exception::InternalError, "Failed to initialize keys manager.");
}
context->referenceSet.clear();
diff --git a/vcore/src/vcore/XmlsecAdapter.h b/vcore/src/vcore/XmlsecAdapter.h
index 3deba63..3c8d94f 100644
--- a/vcore/src/vcore/XmlsecAdapter.h
+++ b/vcore/src/vcore/XmlsecAdapter.h
@@ -32,7 +32,7 @@
#include <vcore/SignatureData.h>
namespace ValidationCore {
-class XmlSec : public DPL::Noncopyable
+class XmlSec : public VcoreDPL::Noncopyable
{
public:
@@ -97,7 +97,7 @@ class XmlSec : public DPL::Noncopyable
class Exception
{
public:
- DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(VcoreDPL::Exception, Base)
DECLARE_EXCEPTION_TYPE(Base, InternalError)
};
@@ -137,7 +137,7 @@ class XmlSec : public DPL::Noncopyable
static void fileExtractPrefix(XmlSecContext *context);
};
-typedef DPL::Singleton<XmlSec> XmlSecSingleton;
+typedef VcoreDPL::Singleton<XmlSec> XmlSecSingleton;
} // namespace ValidationCore
diff --git a/vcore/src/vcore/api.cpp b/vcore/src/vcore/api.cpp
index 34ee76b..cb6797f 100644
--- a/vcore/src/vcore/api.cpp
+++ b/vcore/src/vcore/api.cpp
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 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.
@@ -45,15 +45,12 @@
#include <openssl/evp.h>
#include <openssl/bio.h>
-#include <dlog.h>
-
#include <dpl/foreach.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <cert-svc/cinstance.h>
#include <cert-svc/ccert.h>
#include <cert-svc/cpkcs12.h>
-#include <cert-svc/cpkcs12.h>
#include <cert-svc/cprimitives.h>
#include <vcore/Base64.h>
@@ -61,7 +58,7 @@
#include <vcore/CertificateCollection.h>
#include <vcore/pkcs12.h>
-#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
+#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
#include <cert-svc/ccrl.h>
#include <cert-svc/cocsp.h>
#include <vcore/OCSP.h>
@@ -72,7 +69,15 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
+#define START_CERT "-----BEGIN CERTIFICATE-----"
+#define END_CERT "-----END CERTIFICATE-----"
+#define START_TRUSTED "-----BEGIN TRUSTED CERTIFICATE-----"
+#define END_TRUSTED "-----END TRUSTED CERTIFICATE-----"
+
+#ifndef LOG_TAG
#define LOG_TAG "CERT_SVC"
+#endif
+
using namespace ValidationCore;
namespace {
@@ -243,15 +248,14 @@ public:
}
auto certPtr = iter->second;
-
- DPL::String result;
- switch(field) {
+ std::string result;
+ switch (field) {
case CERTSVC_SUBJECT:
result = certPtr->getOneLine();
break;
case CERTSVC_ISSUER:
result = certPtr->getOneLine(Certificate::FIELD_ISSUER);
- break;
+ break;
case CERTSVC_SUBJECT_COMMON_NAME:
result = certPtr->getCommonName();
break;
@@ -283,12 +287,12 @@ public:
result = certPtr->getOrganizationalUnitName(Certificate::FIELD_ISSUER);
break;
case CERTSVC_VERSION:
- {
- std::stringstream stream;
- stream << (certPtr->getVersion()+1);
- result = DPL::FromUTF8String(stream.str());
- break;
- }
+ {
+ std::stringstream stream;
+ stream << (certPtr->getVersion()+1);
+ result = stream.str();
+ break;
+ }
case CERTSVC_SERIAL_NUMBER:
result = certPtr->getSerialNumberString();
break;
@@ -311,9 +315,8 @@ public:
buffer->privateInstance = cert.privateInstance;
return CERTSVC_SUCCESS;
}
- std::string output = DPL::ToUTF8String(result);
- char *cstring = new char[output.size()+1];
+ char *cstring = new char[result.size()+1];
if (cstring == NULL) {
buffer->privateHandler = NULL;
buffer->privateLength = 0;
@@ -321,10 +324,10 @@ public:
return CERTSVC_BAD_ALLOC;
}
- strncpy(cstring, output.c_str(), output.size()+1);
+ strncpy(cstring, result.c_str(), result.size()+1);
buffer->privateHandler = cstring;
- buffer->privateLength = output.size();
+ buffer->privateLength = result.size();
buffer->privateInstance = cert.privateInstance;
m_allocatedStringSet.insert(cstring);
@@ -466,7 +469,7 @@ public:
fieldId = SUBJECT_COMMONNAME;
break;
default:
- LogError("Not implemented!");
+ WrtLogE("Not implemented!");
return CERTSVC_WRONG_ARGUMENT;
}
@@ -474,16 +477,16 @@ public:
cert_svc_cert_context_final);
if (ctx.get() == NULL) {
- LogWarning("Error in cert_svc_cert_context_init.");
+ WrtLogW("Error in cert_svc_cert_context_init.");
return CERTSVC_FAIL;
}
- LogDebug("Match string: " << value);
+ WrtLogD("Match string: %s", value);
result = cert_svc_search_certificate(ctx.get(), fieldId, const_cast<char*>(value));
- LogDebug("Search finished!");
+ WrtLogD("Search finished!");
if (CERT_SVC_ERR_NO_ERROR != result) {
- LogWarning("Error during certificate search");
+ WrtLogW("Error during certificate search");
return CERTSVC_FAIL;
}
@@ -498,7 +501,7 @@ public:
ScopedCertCtx ctx2(cert_svc_cert_context_init(),
cert_svc_cert_context_final);
if (ctx2.get() == NULL) {
- LogWarning("Error in cert_svc_cert_context_init.");
+ WrtLogW("Error in cert_svc_cert_context_init.");
return CERTSVC_FAIL;
}
@@ -506,7 +509,7 @@ public:
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");
+ WrtLogW("Error in cert_svc_load_file_to_context");
return CERTSVC_FAIL;
}
int certId = addCert(CertificatePtr(new Certificate(*(ctx2.get()->certBuf))));
@@ -980,34 +983,34 @@ public:
int getVisibility(CertSvcCertificate certificate, int* visibility)
{
int ret = CERTSVC_FAIL;
- xmlChar *xmlPathCertificateSet = (xmlChar*) "CertificateSet";
- xmlChar *xmlPathCertificateDomain = (xmlChar*) "CertificateDomain";// name=\"tizen-platform\"";
+ //xmlChar *xmlPathCertificateSet = (xmlChar*) "CertificateSet"; /*unused variable*/
+ //xmlChar *xmlPathCertificateDomain = (xmlChar*) "CertificateDomain";// name=\"tizen-platform\""; /*unused variable*/
xmlChar *xmlPathDomainPlatform = (xmlChar*) "tizen-platform";
xmlChar *xmlPathDomainPublic = (xmlChar*) "tizen-public";
xmlChar *xmlPathDomainPartner = (xmlChar*) "tizen-partner";
xmlChar *xmlPathDomainDeveloper = (xmlChar*) "tizen-developer";
- xmlChar *xmlPathFingerPrintSHA1 = (xmlChar*) "FingerprintSHA1";
+ //xmlChar *xmlPathFingerPrintSHA1 = (xmlChar*) "FingerprintSHA1"; /*unused variable*/
- CertificatePtr certPtr = m_certificateMap[0];
- if(certPtr == NULL)
- {
- LOGE("Invalid Parameter. certificate is not initialized");
+ auto iter = m_certificateMap.find(certificate.privateHandler);
+ if (iter == m_certificateMap.end()) {
return CERTSVC_FAIL;
- }
+ }
+ CertificatePtr certPtr = iter->second;
+
std::string fingerprint = Certificate::FingerprintToColonHex(certPtr->getFingerprint(Certificate::FINGERPRINT_SHA1));
/* load file */
- xmlDocPtr doc = xmlParseFile(tzplatform_mkpath(TZ_SYS_SHARE, "ca-certificates/fingerprint/fingerprint_list.xml"));
+ xmlDocPtr doc = xmlParseFile(FINGERPRINT_LIST_PATH);
if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL))
{
- LOGE("Failed to prase fingerprint_list.xml\n");
+ WrtLogE("Failed to prase fingerprint_list.xml");
return CERTSVC_IO_ERROR;
}
xmlNodePtr curPtr = xmlFirstElementChild(xmlDocGetRootElement(doc));
if(curPtr == NULL)
{
- LOGE("Can not find root");
+ WrtLogE("Can not find root");
ret = CERTSVC_IO_ERROR;
goto out;
}
@@ -1017,7 +1020,7 @@ public:
xmlAttr* attr = curPtr->properties;
if(!attr->children || !attr->children->content)
{
- LOGE("Failed to get fingerprints from list");
+ WrtLogE("Failed to get fingerprints from list");
ret = CERTSVC_FAIL;
goto out;
}
@@ -1026,18 +1029,18 @@ public:
xmlNodePtr FpPtr = xmlFirstElementChild(curPtr);
if(FpPtr == NULL)
{
- LOGE("Could not find fingerprint");
+ WrtLogE("Could not find fingerprint");
ret = CERTSVC_FAIL;
goto out;
}
- LOGD("Retrieve level : %s", strLevel);
+ WrtLogD("Retrieve level : %s", strLevel);
while(FpPtr)
{
xmlChar *content = xmlNodeGetContent(FpPtr);
if(xmlStrcmp(content, (xmlChar*)fingerprint.c_str()) == 0)
{
- LOGD("fingerprint : %s are %s", content, strLevel);
+ WrtLogD("fingerprint : %s are %s", content, strLevel);
if(!xmlStrcmp(strLevel, xmlPathDomainPlatform))
{
*visibility = CERTSVC_VISIBILITY_PLATFORM;
@@ -1092,6 +1095,31 @@ out:
return c_certsvc_pkcs12_import(path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
}
+ inline int pkcsNameIsUniqueInStore(
+ CertStoreType storeType,
+ CertSvcString pfxIdString,
+ int *is_unique)
+ {
+ int result = c_certsvc_pkcs12_alias_exists_in_store(storeType, pfxIdString.privateHandler, is_unique);
+ return result;
+ }
+
+ inline int getCertDetailFromStore(CertStoreType storeType,
+ CertSvcString gname,
+ char** certBuffer,
+ size_t* certSize)
+ {
+ return c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname.privateHandler, certBuffer, certSize);
+ }
+
+ inline int pkcsDeleteCertFromStore(
+ CertStoreType storeType,
+ CertSvcString gname
+ )
+ {
+ return c_certsvc_pkcs12_delete_certificate_from_store(storeType, gname.privateHandler);
+ }
+
inline int getPkcsIdList(
CertSvcInstance &instance,
CertSvcStringList *handler)
@@ -1175,6 +1203,180 @@ out:
return c_certsvc_pkcs12_delete(pfxIdString.privateHandler);
}
+ inline int pkcsImportToStore(
+ CertStoreType storeType,
+ CertSvcString path,
+ CertSvcString pass,
+ CertSvcString pfxIdString)
+ {
+ return c_certsvc_pkcs12_import_from_file_to_store(storeType, path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
+ }
+
+ inline int pkcsGetAliasNameForCertInStore(CertStoreType storeType,
+ CertSvcString gname,
+ char **alias)
+ {
+ return c_certsvc_pkcs12_get_certificate_alias_from_store(storeType, gname.privateHandler, alias);
+ }
+
+ inline int pkcsSetCertStatusToStore(CertStoreType storeType,
+ int is_root_app,
+ CertSvcString gname,
+ CertStatus status)
+ {
+ return c_certsvc_pkcs12_set_certificate_status_to_store(storeType, is_root_app, gname.privateHandler, status);
+ }
+
+ inline int pkcsGetCertStatusFromStore(
+ CertStoreType storeType,
+ CertSvcString gname,
+ int *status)
+ {
+ return c_certsvc_pkcs12_get_certificate_status_from_store(storeType, gname.privateHandler, status);
+ }
+
+ inline int getCertFromStore(CertSvcInstance instance,
+ CertStoreType storeType,
+ char *gname,
+ CertSvcCertificate *certificate)
+ {
+ return certsvc_get_certificate(instance, storeType, gname, certificate);
+ }
+
+ inline int freePkcsIdListFromStore(
+ CertSvcStoreCertList** certList)
+ {
+ return c_certsvc_pkcs12_free_aliases_loaded_from_store(certList);
+ }
+
+ inline int getPkcsIdListFromStore(
+ CertStoreType storeType,
+ int is_root_app,
+ CertSvcStoreCertList** certList,
+ int* length)
+ {
+ return c_certsvc_pkcs12_get_certificate_list_from_store(storeType, is_root_app, certList, length);
+ }
+
+ inline int getPkcsIdEndUserListFromStore(
+ CertStoreType storeType,
+ CertSvcStoreCertList** certList,
+ int* length)
+ {
+ return c_certsvc_pkcs12_get_end_user_certificate_list_from_store(storeType, certList, length);
+ }
+
+ inline int getPkcsIdRootListFromStore(
+ CertStoreType storeType,
+ CertSvcStoreCertList** certList,
+ int* length)
+ {
+ return c_certsvc_pkcs12_get_root_certificate_list_from_store(storeType, certList, length);
+ }
+
+ inline int getPkcsPrivateKeyFromStore(
+ CertStoreType storeType,
+ CertSvcString gname,
+ char **certBuffer,
+ size_t *certSize)
+ {
+ return c_certsvc_pkcs12_private_key_load_from_store(storeType, gname.privateHandler, certBuffer, certSize);
+ }
+
+ inline int getPkcsCertificateListFromStore(
+ CertSvcInstance &instance,
+ CertStoreType storeType,
+ CertSvcString &pfxIdString,
+ CertSvcCertificateList *handler)
+ {
+ char **certs;
+ gsize i, ncerts;
+ std::vector<CertificatePtr> certPtrVector;
+ std::vector<int> listId;
+ char *certBuffer = NULL;
+ size_t certLength = 0;
+ CertSvcString Alias;
+ char* header = NULL;
+ char* trailer = NULL;
+ const char* headEnd = NULL;
+ const char* tailEnd = NULL;
+ int length = 0;
+ int result;
+
+ result = c_certsvc_pkcs12_load_certificates_from_store(storeType, pfxIdString.privateHandler, &certs, &ncerts);
+ if (result != CERTSVC_SUCCESS) {
+ WrtLogE("Unable to load certificates from store.");
+ return result;
+ }
+
+ for (i = 0; i < ncerts; i++) {
+ Alias.privateHandler = certs[i];
+ Alias.privateLength = strlen(certs[i]);
+ result = certsvc_pkcs12_get_certificate_info_from_store(instance, storeType, Alias, &certBuffer, &certLength);
+ if (result != CERTSVC_SUCCESS || !certBuffer) {
+ WrtLogE("Failed to get certificate buffer.");
+ return CERTSVC_FAIL;
+ }
+
+ header = strstr(certBuffer, START_CERT);
+ headEnd = START_CERT;
+ if (!header) {
+ // START_CERT not found. let's find START_TRUSTED.
+ header = strstr(certBuffer, START_TRUSTED);
+ headEnd = START_TRUSTED;
+ }
+
+ if (header) {
+ // START_something found. let's find END_CERT first.
+ trailer = strstr(header, END_CERT);
+ tailEnd = END_CERT;
+ }
+
+ if (!trailer) {
+ // END_CERT not found. let's find END_TRUSTED.
+ trailer = strstr(header, END_TRUSTED);
+ tailEnd = END_TRUSTED;
+ }
+
+ if (!trailer) {
+ WrtLogE("Failed the get the certificate.");
+ return CERTSVC_FAIL;
+ }
+
+ length = ((1 + strlen(header)) - (strlen(headEnd) + strlen(tailEnd) + 1));
+ std::string tmpBuffer(certBuffer);
+ tmpBuffer = tmpBuffer.substr(strlen(headEnd),length);
+ std::string binary(tmpBuffer.c_str(), length);
+ Certificate::FormType formType = Certificate::FORM_BASE64;
+ certPtrVector.push_back(CertificatePtr(new Certificate(binary, formType)));
+ free(certBuffer);
+ certBuffer = NULL;
+ }
+
+ 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 bool checkValidStoreType(CertStoreType storeType)
+ {
+ if (storeType >= VPN_STORE && storeType <= ALL_STORE)
+ return true;
+ else
+ return false;
+ }
+
private:
int m_certificateCounter;
std::map<int, CertificatePtr> m_certificateMap;
@@ -1186,7 +1388,7 @@ private:
std::map<int, std::vector<std::string> > m_stringListMap;
std::set<char *> m_allocatedStringSet;
-
+
#ifdef TIZEN_FEATURE_CERT_SVC_OCSP_CRL
CertSvcCrlCacheWrite m_crlWrite;
CertSvcCrlCacheRead m_crlRead;
@@ -1205,7 +1407,6 @@ int certsvc_instance_new(CertSvcInstance *instance) {
if (init) {
SSL_library_init(); // required by message verification
OpenSSL_add_all_digests();
- g_type_init(); // required by libsoup/ocsp
init = 0;
}
try {
@@ -1488,14 +1689,14 @@ int certsvc_pkcs12_dup_evp_pkey(
&size);
if (result != CERTSVC_SUCCESS) {
- LogError("Error in certsvc_pkcs12_private_key_dup");
+ WrtLogE("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");
+ WrtLogE("Error in BIO_write");
BIO_free_all(b);
certsvc_pkcs12_private_key_free(buffer);
return CERTSVC_FAIL;
@@ -1511,8 +1712,7 @@ int certsvc_pkcs12_dup_evp_pkey(
return CERTSVC_SUCCESS;
}
- LogError("Result is null. Openssl REASON code is: "
- << ERR_GET_REASON(ERR_peek_last_error()));
+ WrtLogE("Result is null. Openssl REASON code is: %d", ERR_GET_REASON(ERR_peek_last_error()));
return CERTSVC_FAIL;
}
@@ -1691,7 +1891,7 @@ int certsvc_certificate_get_visibility(CertSvcCertificate certificate, int* visi
return impl(certificate.privateInstance)->getVisibility(certificate, visibility);
} catch (...)
{
- LOGE("exception occur");
+ WrtLogE("exception occur");
}
return CERTSVC_FAIL;
}
@@ -1717,6 +1917,368 @@ int certsvc_pkcs12_import_from_file(CertSvcInstance instance,
return CERTSVC_FAIL;
}
+int certsvc_get_certificate(CertSvcInstance instance,
+ CertStoreType storeType,
+ char *gname,
+ CertSvcCertificate *certificate)
+{
+ int result = CERTSVC_SUCCESS;
+ char* certBuffer = NULL;
+ std::string fileName;
+ size_t length = 0;
+ FILE* fp_write = NULL;
+ BIO* pBio = NULL;
+ X509* x509Struct = NULL;
+
+ try {
+ result = c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname, &certBuffer, &length);
+ if (result != CERTSVC_SUCCESS) {
+ WrtLogE("Failed to get certificate buffer from store.");
+ return result;
+ }
+
+ pBio = BIO_new(BIO_s_mem());
+ if (pBio == NULL) {
+ WrtLogE("Failed to allocate memory.");
+ result = CERTSVC_BAD_ALLOC;
+ }
+
+ length = BIO_write(pBio, (const void*) certBuffer, length);
+ if (length < 1) {
+ WrtLogE("Failed to load cert into bio.");
+ result = CERTSVC_BAD_ALLOC;
+ }
+
+ x509Struct = PEM_read_bio_X509(pBio, NULL, 0, NULL);
+ if (x509Struct != NULL) {
+ CertificatePtr cert(new Certificate(x509Struct));
+ certificate->privateInstance = instance;
+ certificate->privateHandler = impl(instance)->addCert(cert);
+ if (certBuffer!=NULL) free(certBuffer);
+ }
+ else {
+ fileName.append(CERTSVC_PKCS12_STORAGE_DIR);
+ fileName.append(gname);
+ if (!(fp_write = fopen(fileName.c_str(), "w"))) {
+ WrtLogE("Failed to open the file for writing, [%s].", fileName.c_str());
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ if (fwrite(certBuffer, sizeof(char), (size_t)length, fp_write) != (size_t)length) {
+ WrtLogE("Fail to write certificate.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ fclose(fp_write);
+ result = certsvc_certificate_new_from_file(instance, fileName.c_str(), certificate);
+ if (result != CERTSVC_SUCCESS) {
+ WrtLogE("Failed to construct certificate from buffer.");
+ goto error;
+ }
+ unlink(fileName.c_str());
+ }
+ result = CERTSVC_SUCCESS;
+ } catch (std::bad_alloc &) {
+ return CERTSVC_BAD_ALLOC;
+ } catch (...) {}
+
+error:
+ if (x509Struct) X509_free(x509Struct);
+ if (pBio) BIO_free(pBio);
+ return result;
+}
+
+int certsvc_pkcs12_check_alias_exists_in_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString pfxIdString,
+ int *is_unique)
+{
+ if (pfxIdString.privateHandler == NULL || pfxIdString.privateLength<=0) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+
+ return impl(instance)->pkcsNameIsUniqueInStore(storeType, pfxIdString, is_unique);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_free_certificate_list_loaded_from_store(CertSvcInstance instance,
+ CertSvcStoreCertList** certList)
+{
+ if (*certList == NULL) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ try {
+ return impl(instance)->freePkcsIdListFromStore(certList);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_certificate_list_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ int is_root_app,
+ CertSvcStoreCertList** certList,
+ int* length)
+{
+ if (*certList != NULL) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+
+ return impl(instance)->getPkcsIdListFromStore(storeType, is_root_app, certList, length);
+ } catch (...) {}
+
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_end_user_certificate_list_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcStoreCertList** certList,
+ int* length)
+{
+ if (*certList != NULL) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+
+ return impl(instance)->getPkcsIdEndUserListFromStore(storeType, certList, length);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_root_certificate_list_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcStoreCertList** certList,
+ int* length)
+{
+ if (*certList != NULL) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+
+ return impl(instance)->getPkcsIdRootListFromStore(storeType, certList, length);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_certificate_info_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ char** certBuffer,
+ size_t* certSize)
+{
+ if (*certBuffer != NULL) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+
+ return impl(instance)->getCertDetailFromStore(storeType, gname, certBuffer, certSize);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_delete_certificate_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname)
+{
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->pkcsDeleteCertFromStore(storeType, gname);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString path,
+ CertSvcString password,
+ CertSvcString pfxIdString)
+{
+ try {
+ if (path.privateHandler != NULL) {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->pkcsImportToStore(storeType, path, password, pfxIdString);
+ }
+ else
+ return CERTSVC_FAIL;
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_alias_name_for_certificate_in_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ char **alias)
+{
+ if (gname.privateHandler == NULL || gname.privateLength<=0) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->pkcsGetAliasNameForCertInStore(storeType, gname, alias);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_set_certificate_status_to_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ int is_root_app,
+ CertSvcString gname,
+ CertStatus status)
+{
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->pkcsSetCertStatusToStore(storeType, is_root_app, gname, status);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_certificate_status_from_store(
+ CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ int *status)
+{
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->pkcsGetCertStatusFromStore(storeType, gname, status);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_get_certificate_from_store(CertSvcInstance instance,
+ CertStoreType storeType,
+ char *gname,
+ CertSvcCertificate *certificate)
+{
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->getCertFromStore(instance, storeType, gname, certificate);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_load_certificate_list_from_store(
+ CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString pfxIdString,
+ CertSvcCertificateList *certificateList)
+{
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->getPkcsCertificateListFromStore(instance, storeType, pfxIdString, certificateList);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_private_key_dup_from_store(
+ CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ char **certBuffer,
+ size_t *certSize)
+{
+ try {
+ if (!impl(instance)->checkValidStoreType(storeType)) {
+ WrtLogE("Invalid input parameter.");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+ return impl(instance)->getPkcsPrivateKeyFromStore(storeType, gname, certBuffer, certSize);
+ } catch (...) {}
+ return CERTSVC_FAIL;
+}
+
+int certsvc_pkcs12_dup_evp_pkey_from_store(
+ CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString gname,
+ EVP_PKEY** pkey)
+{
+ char *buffer = NULL;
+ size_t size;
+
+ int result = certsvc_pkcs12_private_key_dup_from_store(instance, storeType, gname, &buffer, &size);
+ if (result != CERTSVC_SUCCESS) {
+ WrtLogE("Error in certsvc_pkcs12_private_key_dup");
+ return result;
+ }
+
+ BIO *b = BIO_new(BIO_s_mem());
+ if ((int)size != BIO_write(b, buffer, size)) {
+ WrtLogE("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;
+
+ WrtLogE("Result is null. Openssl REASON code is: %d", ERR_GET_REASON(ERR_peek_last_error()));
+ return CERTSVC_FAIL;
+}
+
int certsvc_pkcs12_get_id_list(
CertSvcInstance instance,
CertSvcStringList *pfxIdStringList)
@@ -1771,7 +2333,7 @@ int certsvc_pkcs12_private_key_dup(
void certsvc_pkcs12_private_key_free(
char *buffer)
{
- delete[] buffer;
+ free(buffer);
}
int certsvc_pkcs12_delete(
@@ -1783,3 +2345,4 @@ int certsvc_pkcs12_delete(
} catch (...) {}
return CERTSVC_FAIL;
}
+
diff --git a/vcore/src/vcore/cert-svc-client.c b/vcore/src/vcore/cert-svc-client.c
new file mode 100644
index 0000000..1935518
--- /dev/null
+++ b/vcore/src/vcore/cert-svc-client.c
@@ -0,0 +1,582 @@
+/**
+ * Copyright (c) 2015 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 cert-svc-client.c
+ * @author Madhan A K (madhan.ak@samsung.com)
+ * Kyungwook Tak (k.tak@samsung.com)
+ * @version 1.0
+ * @brief cert-svc client interface for cert-server.
+ */
+
+#include <sys/stat.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cert-service-debug.h>
+
+#include <cert-svc-client.h>
+
+void initialize_res_data(VcoreResponseData *pData)
+{
+ memset(pData->dataBlock, 0, VCORE_MAX_RECV_DATA_SIZE);
+ memset(pData->common_name, 0, VCORE_MAX_FILENAME_SIZE * 2 + 1);
+ pData->dataBlockLen = 0;
+ pData->certStatus = 0;
+ pData->result = 0;
+ pData->certList = NULL;
+ pData->certCount = 0;
+ pData->certBlockList = NULL;
+ pData->certBlockCount = 0;
+}
+
+void initialize_req_data(VcoreRequestData *pData)
+{
+ memset(pData->gname, 0, VCORE_MAX_FILENAME_SIZE+1);
+ memset(pData->common_name, 0, VCORE_MAX_FILENAME_SIZE+1);
+ memset(pData->private_key_gname, 0, VCORE_MAX_FILENAME_SIZE+1);
+ memset(pData->associated_gname, 0, VCORE_MAX_FILENAME_SIZE+1);
+ memset(pData->dataBlock, 0, VCORE_MAX_SEND_DATA_SIZE);
+ pData->certStatus = 0;
+ pData->storeType = -1;
+ pData->reqType = -1;
+ pData->dataBlockLen = -1;
+ pData->is_root_app = -1;
+}
+
+int _recv_fixed_lenghth(int sockfd, char *buff, int length)
+{
+ int offset = 0;
+ int remaining = length;
+ int read_len = 0;
+ while(remaining > 0) {
+ read_len = recv(sockfd, buff + offset, remaining, 0);
+ if(read_len <= 0)
+ return offset;
+ remaining -= read_len;
+ offset += read_len;
+ }
+ return offset;
+}
+
+VcoreRequestData* set_request_data(
+ int reqType,
+ CertStoreType storeType,
+ int is_root_app,
+ const char *pGroupName,
+ const char *common_name,
+ const char *private_key_gname,
+ const char *associated_gname,
+ const char *pData,
+ size_t dataLen,
+ CertType certType,
+ int certStatus)
+{
+ VcoreRequestData* pReqData = (VcoreRequestData*)malloc(sizeof(VcoreRequestData));
+ if (!pReqData) {
+ LOGE("Failed to malloc VcoreRequestData");
+ return NULL;
+ }
+ initialize_req_data(pReqData);
+
+ pReqData->reqType = reqType;
+ pReqData->storeType = (CertStoreType) storeType;
+ pReqData->dataBlockLen = dataLen;
+ pReqData->certType = certType;
+ pReqData->certStatus = certStatus;
+ pReqData->is_root_app = is_root_app;
+
+ if (pGroupName) {
+ if (strlen(pGroupName) > VCORE_MAX_FILENAME_SIZE) {
+ LOGE("The data name is too long");
+ free(pReqData);
+ return NULL;
+ }
+ strncpy(pReqData->gname, pGroupName, VCORE_MAX_FILENAME_SIZE);
+ pReqData->gname[strlen(pGroupName)] = '\0';
+ }
+
+ if (common_name) {
+ if (strlen(common_name) > VCORE_MAX_FILENAME_SIZE) {
+ LOGE("The length of the path specified is too long");
+ free(pReqData);
+ return NULL;
+ }
+ strncpy(pReqData->common_name, common_name, VCORE_MAX_FILENAME_SIZE);
+ pReqData->common_name[strlen(common_name)] = '\0';
+ }
+
+ if (private_key_gname) {
+ if (strlen(private_key_gname) > VCORE_MAX_FILENAME_SIZE) {
+ LOGE("The private key gname is too long");
+ free(pReqData);
+ return NULL;
+ }
+ strncpy(pReqData->private_key_gname, private_key_gname, VCORE_MAX_FILENAME_SIZE);
+ pReqData->private_key_gname[strlen(private_key_gname)] = '\0';
+ }
+
+ if (associated_gname) {
+ if (strlen(associated_gname) > VCORE_MAX_FILENAME_SIZE) {
+ LOGE("The associated gname is too long");
+ free(pReqData);
+ return NULL;
+ }
+ strncpy(pReqData->associated_gname, associated_gname, VCORE_MAX_FILENAME_SIZE);
+ pReqData->associated_gname[strlen(associated_gname)] = '\0';
+ }
+
+ if (dataLen != 0 && pData != NULL) {
+ if (dataLen > VCORE_MAX_SEND_DATA_SIZE) {
+ LOGE("The data length is too long [%d]", dataLen);
+ free(pReqData);
+ return NULL;
+ }
+ memcpy(pReqData->dataBlock, pData, dataLen);
+ }
+ return pReqData;
+}
+
+
+VcoreResponseData cert_svc_client_comm(VcoreRequestData* pClientData) {
+
+ int sockfd = 0;
+ int clientLen = 0;
+ int tempSockLen = 0;
+ int read_len = 0;
+ int i = 0;
+ struct sockaddr_un clientaddr;
+ VcoreResponseData recvData;
+ initialize_res_data(&recvData);
+
+ if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ LOGE("Error in function socket()..");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_exit;
+ }
+
+ tempSockLen = strlen(VCORE_SOCK_PATH);
+ bzero(&clientaddr, sizeof(clientaddr));
+ clientaddr.sun_family = AF_UNIX;
+ strncpy(clientaddr.sun_path, VCORE_SOCK_PATH, tempSockLen);
+ clientaddr.sun_path[tempSockLen] = '\0';
+ clientLen = sizeof(clientaddr);
+
+ struct timeval timeout;
+ timeout.tv_sec = 10;
+ timeout.tv_usec = 0;
+
+ if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
+ LOGE("Error in Set SO_RCVTIMEO Socket Option");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+
+ if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
+ LOGE("Error in Set SO_SNDTIMEO Socket Option");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+
+ if (connect(sockfd, (struct sockaddr*)&clientaddr, clientLen) < 0) {
+ LOGE("Error in function connect()..");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+
+ if (write(sockfd, (char*)pClientData, sizeof(VcoreRequestData)) < 0) {
+ LOGE("Error in function write()..");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+
+ read_len = _recv_fixed_lenghth(sockfd, (char*)&recvData, sizeof(recvData));
+ if (read_len < 0) {
+ LOGE("Error in function read()..");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+
+ if(recvData.certCount > 0) {
+ recvData.certList = (VcoreCertResponseData *) malloc(recvData.certCount * sizeof(VcoreCertResponseData));
+ if (!recvData.certList) {
+ LOGE("Failed to allocate memory");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+ memset(recvData.certList, 0x00, recvData.certCount * sizeof(VcoreCertResponseData));
+ for(i=0; i<recvData.certCount; i++) {
+ read_len = _recv_fixed_lenghth(sockfd, (char*)(recvData.certList + i), sizeof(VcoreCertResponseData));
+ if (read_len < 0) {
+ LOGE("Error in function read()..");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+ }
+ }
+
+ if(recvData.certBlockCount > 0) {
+ recvData.certBlockList = (ResponseCertBlock *) malloc(recvData.certBlockCount * sizeof(ResponseCertBlock));
+ if (!recvData.certBlockList) {
+ LOGE("Failed to allocate memory");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+ memset(recvData.certBlockList, 0x00, recvData.certBlockCount * sizeof(ResponseCertBlock));
+ for(i=0; i<recvData.certBlockCount; i++) {
+ read_len = _recv_fixed_lenghth(sockfd, (char*)(recvData.certBlockList + i), sizeof(ResponseCertBlock));
+ if (read_len < 0) {
+ LOGE("Error in function read()..");
+ recvData.result = VCORE_SOCKET_ERROR;
+ goto Error_close_exit;
+ }
+ }
+ }
+
+Error_close_exit:
+ close(sockfd);
+ if (recvData.result == VCORE_SOCKET_ERROR) {
+ free(recvData.certList);
+ recvData.certList = NULL;
+ recvData.certCount = 0;
+
+ free(recvData.certBlockList);
+ recvData.certBlockList = NULL;
+ recvData.certBlockCount = 0;
+ }
+
+Error_exit:
+ return recvData;
+}
+
+int vcore_client_install_certificate_to_store(
+ CertStoreType storeType,
+ const char *gname,
+ const char *common_name,
+ const char *private_key_gname,
+ const char *associated_gname,
+ const char *certData,
+ size_t certSize,
+ CertType certType)
+{
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ initialize_res_data(&recvData);
+
+ if (!gname && !certData) {
+ LOGE("Invalid input argument.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ pSendData = set_request_data(
+ CERTSVC_INSTALL_CERTIFICATE,
+ storeType,
+ DISABLED,
+ gname,
+ common_name,
+ private_key_gname,
+ associated_gname,
+ certData,
+ certSize,
+ certType, 0);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+ free(pSendData);
+ return recvData.result;
+}
+
+int vcore_client_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, const char* gname, CertStatus status) {
+
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ initialize_res_data(&recvData);
+
+ if (gname == NULL) {
+ LOGE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ pSendData = set_request_data(CERTSVC_SET_CERTIFICATE_STATUS, storeType, is_root_app, gname, NULL, NULL, NULL, NULL, 0, 0, status);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+ free(pSendData);
+
+ return recvData.result;
+}
+
+int vcore_client_get_certificate_status_from_store(CertStoreType storeType, const char* gname, int *status) {
+
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ initialize_res_data(&recvData);
+
+ if (gname == NULL) {
+ LOGE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ pSendData = set_request_data(CERTSVC_GET_CERTIFICATE_STATUS, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+ free(pSendData);
+ *status = recvData.certStatus;
+ return recvData.result;
+}
+
+int vcore_client_check_alias_exist_in_store(CertStoreType storeType, const char* alias, int *status) {
+
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ initialize_res_data(&recvData);
+
+ if (alias == NULL) {
+ LOGE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ pSendData = set_request_data(CERTSVC_CHECK_ALIAS_EXISTS, storeType, DISABLED,alias, NULL, NULL, NULL, NULL, 0, 0, 0);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+ free(pSendData);
+ *status = recvData.certStatus;
+ return recvData.result;
+}
+
+int vcore_client_get_certificate_from_store(CertStoreType storeType, const char* gname, char** certData, size_t* certSize, CertType certType) {
+
+ char* outData = NULL;
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+
+ if (!gname || !certData || !certSize) {
+ LOGE("Invalid input argument.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ initialize_res_data(&recvData);
+
+ if (storeType == SYSTEM_STORE) /* for extracting certificate from system store */
+ pSendData = set_request_data(CERTSVC_EXTRACT_SYSTEM_CERT, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, certType, 0);
+ else /* for extracting certificate from other stores */
+ pSendData = set_request_data(CERTSVC_EXTRACT_CERT, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, certType, 0);
+
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+ if (recvData.result < 0) {
+ LOGE("An error occurred from server side err[%d]", recvData.result);
+ free(pSendData);
+ return recvData.result;
+ }
+ free(pSendData);
+
+ if (recvData.dataBlockLen > 0 && recvData.dataBlockLen <= VCORE_MAX_RECV_DATA_SIZE) {
+ outData = (char*)malloc(recvData.dataBlockLen + 1);
+ memset(outData, 0x00, recvData.dataBlockLen +1);
+ memcpy(outData, recvData.dataBlock, recvData.dataBlockLen);
+ *certData = outData;
+ *certSize = recvData.dataBlockLen;
+ }
+ else {
+ LOGE("revcData length is wrong : %d", recvData.dataBlockLen);
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ return recvData.result;
+}
+
+int vcore_client_delete_certificate_from_store(CertStoreType storeType, const char* gname) {
+
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ initialize_res_data(&recvData);
+
+ if (gname == NULL) {
+ LOGE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ pSendData = set_request_data(CERTSVC_DELETE_CERT, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+ free(pSendData);
+ return recvData.result;
+}
+
+int _vcore_client_get_certificate_list_from_store(int reqType, CertStoreType storeType, int is_root_app,
+ CertSvcStoreCertList** certList, int* length)
+{
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ CertSvcStoreCertList* curr = NULL;
+ CertSvcStoreCertList* prev = NULL;
+ VcoreCertResponseData* cert = NULL;
+ int tmplen = 0;
+ int i=0;
+ initialize_res_data(&recvData);
+
+
+ pSendData = set_request_data(reqType, storeType, is_root_app, NULL, NULL, NULL, NULL, NULL, 0, 0, 0);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+
+ if(recvData.certCount > 0) {
+ for(i=0; i<recvData.certCount; i++) {
+ cert = recvData.certList + i ;
+ curr = (CertSvcStoreCertList*) malloc(sizeof(CertSvcStoreCertList));
+ memset(curr, 0x00, sizeof(CertSvcStoreCertList));
+
+ tmplen = strlen(cert->gname);
+ curr->gname = (char*) malloc (sizeof(char) * (tmplen+ 1));
+ memset(curr->gname, 0x00, tmplen + 1);
+ memcpy(curr->gname, cert->gname, tmplen);
+
+ tmplen = strlen(cert->title);
+ curr->title = (char*) malloc (sizeof(char) * (tmplen+ 1));
+ memset(curr->title, 0x00, tmplen + 1);
+ memcpy(curr->title, cert->title, tmplen);
+
+ curr->status = cert->status;
+ curr->storeType = cert->storeType;
+
+ if(prev == NULL) {
+ *certList = curr;
+ }else {
+ prev->next = curr;
+ }
+ prev = curr;
+ }
+ }
+
+ *length = recvData.certCount;
+
+ LOGI("get_certificate_list_from_store: result=%d", recvData.result);
+ if(recvData.certList != NULL)
+ free(recvData.certList);
+ free(pSendData);
+ return recvData.result;
+}
+
+int vcore_client_get_certificate_list_from_store(CertStoreType storeType, int is_root_app,
+ CertSvcStoreCertList** certList, int* length)
+{
+ return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_CERTIFICATE_LIST, storeType, is_root_app,
+ certList, length);
+}
+
+int vcore_client_get_root_certificate_list_from_store(CertStoreType storeType,
+ CertSvcStoreCertList** certList, int* length)
+{
+ return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_ROOT_CERTIFICATE_LIST, storeType, 0,
+ certList, length);
+}
+
+int vcore_client_get_end_user_certificate_list_from_store(CertStoreType storeType,
+ CertSvcStoreCertList** certList, int* length)
+{
+ return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_USER_CERTIFICATE_LIST, storeType, 0,
+ certList, length);
+}
+
+int vcore_client_get_certificate_alias_from_store(CertStoreType storeType, const char *gname, char **alias)
+{
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ initialize_res_data(&recvData);
+
+ if (gname == NULL) {
+ LOGE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ pSendData = set_request_data(CERTSVC_GET_CERTIFICATE_ALIAS, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+
+ *alias = strndup(recvData.common_name, sizeof(recvData.common_name));
+ free(pSendData);
+ return recvData.result;
+}
+
+int vcore_client_load_certificates_from_store(CertStoreType storeType, const char *gname, char ***certs, int *ncerts)
+{
+ VcoreRequestData* pSendData = NULL;
+ VcoreResponseData recvData;
+ ResponseCertBlock* cert = NULL;
+ int i=0;
+ initialize_res_data(&recvData);
+
+ pSendData = set_request_data(CERTSVC_LOAD_CERTIFICATES, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
+ if (pSendData == NULL) {
+ LOGE("Failed to set request data");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ recvData = cert_svc_client_comm(pSendData);
+
+ *ncerts = recvData.certBlockCount;
+ *certs = (char**)malloc((recvData.certBlockCount+1) * sizeof(char *));
+ (*certs)[recvData.certBlockCount] = NULL;
+ LOGD("vcore_client_load_certificates_from_store. result=%d, ncerts=%d", recvData.result, *ncerts);
+ if(recvData.certBlockCount > 0) {
+ for(i=0; i<recvData.certBlockCount; i++) {
+ cert = recvData.certBlockList + i ;
+ (*certs)[i] = strndup(cert->dataBlock, cert->dataBlockLen);
+ LOGD("vcore_client_load_certificates_from_store. cert=%s", (*certs)[i]);
+ }
+ }
+
+ if(recvData.certBlockList != NULL)
+ free(recvData.certBlockList);
+ free(pSendData);
+ return recvData.result;
+
+}
diff --git a/vcore/src/vcore/cert-svc-client.h b/vcore/src/vcore/cert-svc-client.h
new file mode 100644
index 0000000..9c5b595
--- /dev/null
+++ b/vcore/src/vcore/cert-svc-client.h
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2015 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 cert-svc-client.h
+ * @author Madhan A K (madhan.ak@samsung.com)
+ * @version 1.0
+ * @brief cert-svc client interface for cert-svc server present in secure-storage module.
+ */
+
+#ifndef CERT_SVC_CLIENT_H_
+#define CERT_SVC_CLIENT_H_
+
+#include <cert-svc/cerror.h>
+#include <cert-svc/ccert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VCORE_MAX_FILENAME_SIZE 128
+#define VCORE_MAX_RECV_DATA_SIZE 8192 //4096, internal buffer = 4KB*2. /*Note:system store cert size is bigger than 4KB*/
+#define VCORE_MAX_SEND_DATA_SIZE 8192 //4096, internal buffer = 4KB*2.
+#define VCORE_MAX_GROUP_ID_SIZE 32
+#define VCORE_MAX_APPID_SIZE 32
+#define VCORE_MAX_PASSWORD_SIZE 32
+#define VCORE_SOCKET_ERROR (-0x01C10000) // TIZEN_ERROR_CONNECTION /*Connection error*/
+#define VCORE_SOCK_PATH "/tmp/CertSocket"
+#define VCORE_PKEY_TEMP_PATH "/tmp/tmpData"
+
+typedef enum {
+ CERTSVC_EXTRACT_CERT,
+ CERTSVC_EXTRACT_SYSTEM_CERT,
+ CERTSVC_DELETE_CERT,
+ CERTSVC_INSTALL_CERTIFICATE,
+ CERTSVC_GET_CERTIFICATE_STATUS,
+ CERTSVC_SET_CERTIFICATE_STATUS,
+ CERTSVC_CHECK_ALIAS_EXISTS,
+ CERTSVC_GET_CERTIFICATE_LIST,
+ CERTSVC_GET_CERTIFICATE_ALIAS,
+ CERTSVC_GET_USER_CERTIFICATE_LIST,
+ CERTSVC_GET_ROOT_CERTIFICATE_LIST,
+ CERTSVC_LOAD_CERTIFICATES,
+} VcoreRequestType;
+
+typedef struct {
+ VcoreRequestType reqType;
+ CertStoreType storeType;
+ char gname[VCORE_MAX_FILENAME_SIZE * 2 + 1]; /* for gname */
+ char common_name[VCORE_MAX_FILENAME_SIZE * 2 + 1]; /* for common_name */
+ char private_key_gname[VCORE_MAX_FILENAME_SIZE * 2 + 1]; /* for private_key_gname */
+ char associated_gname[VCORE_MAX_FILENAME_SIZE * 2 + 1]; /* for associated_gname */
+ char dataBlock[VCORE_MAX_SEND_DATA_SIZE]; /* for cert & key buffer */
+ size_t dataBlockLen;
+ int certStatus;
+ int is_root_app;
+ CertType certType;
+} VcoreRequestData;
+
+typedef struct {
+ char gname[VCORE_MAX_FILENAME_SIZE * 2 + 1];
+ char title[VCORE_MAX_FILENAME_SIZE * 2 + 1];
+ int status;
+ CertStoreType storeType;
+} VcoreCertResponseData;
+
+
+typedef struct {
+ char dataBlock[VCORE_MAX_RECV_DATA_SIZE];
+ size_t dataBlockLen;
+} ResponseCertBlock;
+
+typedef struct {
+ char dataBlock[VCORE_MAX_RECV_DATA_SIZE];
+ size_t dataBlockLen;
+ int certStatus;
+ char common_name[VCORE_MAX_FILENAME_SIZE* 2 + 1]; /*for common_name*/
+ int result;
+ int certCount;
+ VcoreCertResponseData* certList;
+ int certBlockCount;
+ ResponseCertBlock* certBlockList; // array
+} VcoreResponseData;
+
+
+
+int vcore_client_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, const char* gname, CertStatus status);
+int vcore_client_get_certificate_status_from_store(CertStoreType storeType, const char* gname, int *status);
+int vcore_client_check_alias_exist_in_store(CertStoreType storeType, const char* alias, int *status);
+int vcore_client_install_certificate_to_store(CertStoreType storeType, const char *gname, const char *common_name, const char *private_key_gname, const char *associated_gname, const char *dataBlock, size_t dataBlockLen, CertType certType);
+int vcore_client_get_certificate_from_store(CertStoreType storeType, const char* gname, char** certData, size_t* certSize, CertType certType);
+int vcore_client_delete_certificate_from_store(CertStoreType storeType, const char* gname);
+VcoreResponseData cert_svc_client_comm(VcoreRequestData* client_data);
+int vcore_client_get_certificate_list_from_store(CertStoreType storeType, int is_root_app, CertSvcStoreCertList** certList, int* length);
+int vcore_client_get_root_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, int* length);
+int vcore_client_get_end_user_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, int* length);
+int vcore_client_get_certificate_alias_from_store(CertStoreType storeType, const char *gname, char **alias);
+int vcore_client_load_certificates_from_store(CertStoreType storeType, const char *gname, char ***certs, int *ncerts);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/vcore/src/vcore/exception.cpp b/vcore/src/vcore/exception.cpp
new file mode 100644
index 0000000..20d359f
--- /dev/null
+++ b/vcore/src/vcore/exception.cpp
@@ -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 exception.cpp
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation of exception system
+ */
+#include <vcore/exception.h>
+
+#include <dpl/log/vcore_log.h>
+
+#include <stddef.h>
+#include <cstdio>
+
+namespace ValidationCore {
+Exception* Exception::m_lastException = NULL;
+unsigned int Exception::m_exceptionCount = 0;
+void (*Exception::m_terminateHandler)() = NULL;
+
+void LogUnhandledException(const std::string &str)
+{
+ // Logging to dlog
+ VcoreLogD("%s", str.c_str());
+}
+
+void LogUnhandledException(const std::string &str,
+ const char *filename,
+ int line,
+ const char *function)
+{
+ // Logging to dlog
+ VcoreLogE("[%s:%d][%s]%s", filename, line, function, str.c_str());
+}
+} // namespace ValidationCore
diff --git a/vcore/src/vcore/exception.h b/vcore/src/vcore/exception.h
new file mode 100644
index 0000000..dae719e
--- /dev/null
+++ b/vcore/src/vcore/exception.h
@@ -0,0 +1,390 @@
+/*
+ * 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 exception.h
+ * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief Header file for base exception
+ */
+#ifndef ValidationCore_EXCEPTION_H
+#define ValidationCore_EXCEPTION_H
+
+#include <string>
+#include <cstring>
+#include <cstdio>
+#include <exception>
+#include <cstdlib>
+#include <sstream>
+
+namespace ValidationCore {
+void LogUnhandledException(const std::string &str);
+void LogUnhandledException(const std::string &str,
+ const char *filename,
+ int line,
+ const char *function);
+}
+
+namespace ValidationCore {
+class Exception {
+private:
+ static unsigned int m_exceptionCount;
+ static Exception* m_lastException;
+ static void (*m_terminateHandler)();
+
+ static void AddRef(Exception* exception)
+ {
+ if (!m_exceptionCount) {
+ m_terminateHandler = std::set_terminate(&TerminateHandler);
+ }
+
+ ++m_exceptionCount;
+ m_lastException = exception;
+ }
+
+ static void UnRef(Exception* e)
+ {
+ if (m_lastException == e) {
+ m_lastException = NULL;
+ }
+
+ --m_exceptionCount;
+
+ if (!m_exceptionCount) {
+ std::set_terminate(m_terminateHandler);
+ m_terminateHandler = NULL;
+ }
+ }
+
+ static void TerminateHandler()
+ {
+ if (m_lastException != NULL) {
+ DisplayKnownException(*m_lastException);
+ abort();
+ } else {
+ DisplayUnknownException();
+ abort();
+ }
+ }
+
+ Exception *m_reason;
+ std::string m_path;
+ std::string m_function;
+ int m_line;
+
+protected:
+ std::string m_message;
+ std::string m_className;
+
+public:
+ static std::string KnownExceptionToString(const Exception &e)
+ {
+ std::ostringstream message;
+ message <<
+ "\033[1;5;31m\n=== Unhandled DPL exception occurred ===\033[m\n\n";
+ message << "\033[1;33mException trace:\033[m\n\n";
+ message << e.DumpToString();
+ message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+ return message.str();
+ }
+
+ static std::string UnknownExceptionToString()
+ {
+ std::ostringstream message;
+ message <<
+ "\033[1;5;31m\n=== Unhandled non-DPL exception occurred ===\033[m\n\n";
+ message << "\033[1;31m\n=== Will now abort ===\033[m\n";
+
+ return message.str();
+ }
+
+ static void DisplayKnownException(const Exception& e)
+ {
+ LogUnhandledException(KnownExceptionToString(e).c_str());
+ }
+
+ static void DisplayUnknownException()
+ {
+ LogUnhandledException(UnknownExceptionToString().c_str());
+ }
+
+ Exception(const Exception &other)
+ {
+ // Deep copy
+ if (other.m_reason != NULL) {
+ m_reason = new Exception(*other.m_reason);
+ } else {
+ m_reason = NULL;
+ }
+
+ m_message = other.m_message;
+ m_path = other.m_path;
+ m_function = other.m_function;
+ m_line = other.m_line;
+
+ m_className = other.m_className;
+
+ AddRef(this);
+ }
+
+ const Exception &operator =(const Exception &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ // Deep copy
+ if (other.m_reason != NULL) {
+ m_reason = new Exception(*other.m_reason);
+ } else {
+ m_reason = NULL;
+ }
+
+ m_message = other.m_message;
+ m_path = other.m_path;
+ m_function = other.m_function;
+ m_line = other.m_line;
+
+ m_className = other.m_className;
+
+ AddRef(this);
+
+ return *this;
+ }
+
+ Exception(const char *path,
+ const char *function,
+ int line,
+ const std::string &message) :
+ m_reason(NULL),
+ m_path(path),
+ m_function(function),
+ m_line(line),
+ m_message(message)
+ {
+ AddRef(this);
+ }
+
+ Exception(const char *path,
+ const char *function,
+ int line,
+ const Exception &reason,
+ const std::string &message) :
+ m_reason(new Exception(reason)),
+ m_path(path),
+ m_function(function),
+ m_line(line),
+ m_message(message)
+ {
+ AddRef(this);
+ }
+
+ virtual ~Exception() throw()
+ {
+ if (m_reason != NULL) {
+ delete m_reason;
+ m_reason = NULL;
+ }
+
+ UnRef(this);
+ }
+
+ void Dump() const
+ {
+ // Show reason first
+ if (m_reason != NULL) {
+ m_reason->Dump();
+ }
+
+ // Afterward, dump exception
+ const char *file = strchr(m_path.c_str(), '/');
+
+ if (file == NULL) {
+ file = m_path.c_str();
+ } else {
+ ++file;
+ }
+
+ printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+ file, m_line,
+ m_function.c_str(),
+ m_className.c_str(),
+ m_message.empty() ? "<EMPTY>" : m_message.c_str());
+ }
+
+ std::string DumpToString() const
+ {
+ std::string ret;
+ if (m_reason != NULL) {
+ ret = m_reason->DumpToString();
+ }
+
+ const char *file = strchr(m_path.c_str(), '/');
+
+ if (file == NULL) {
+ file = m_path.c_str();
+ } else {
+ ++file;
+ }
+
+ char buf[1024];
+ snprintf(buf,
+ sizeof(buf),
+ "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n",
+ file,
+ m_line,
+ m_function.c_str(),
+ m_className.c_str(),
+ m_message.empty() ? "<EMPTY>" : m_message.c_str());
+
+ buf[sizeof(buf) - 1] = '\n';
+ ret += buf;
+
+ return ret;
+ }
+
+ Exception *GetReason() const
+ {
+ return m_reason;
+ }
+
+ std::string GetPath() const
+ {
+ return m_path;
+ }
+
+ std::string GetFunction() const
+ {
+ return m_function;
+ }
+
+ int GetLine() const
+ {
+ return m_line;
+ }
+
+ std::string GetMessage() const
+ {
+ return m_message;
+ }
+
+ std::string GetClassName() const
+ {
+ return m_className;
+ }
+};
+} // namespace ValidationCore
+
+#define VcoreTry try
+
+#define VcoreThrow(ClassName) \
+ throw ClassName(__FILE__, __FUNCTION__, __LINE__)
+
+#define VcoreThrowMsg(ClassName, Message) \
+ do \
+ { \
+ std::ostringstream dplLoggingStream; \
+ dplLoggingStream << Message; \
+ throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \
+ } while (0)
+
+#define VcoreReThrow(ClassName) \
+ throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception)
+
+#define VcoreReThrowMsg(ClassName, Message) \
+ throw ClassName(__FILE__, \
+ __FUNCTION__, \
+ __LINE__, \
+ _rethrown_exception, \
+ Message)
+
+#define VcoreCatch(ClassName) \
+ catch (const ClassName &_rethrown_exception)
+
+#define VCORE_DECLARE_EXCEPTION_TYPE(BaseClass, Class) \
+ class Class : public BaseClass { \
+ public: \
+ Class(const char *path, \
+ const char *function, \
+ int line, \
+ const std::string & message = std::string()) \
+ : BaseClass(path, function, line, message) { \
+ \
+ BaseClass::m_className = #Class; \
+ } \
+ \
+ Class(const char *path, \
+ const char *function, \
+ int line, \
+ const ValidationCore::Exception & reason, \
+ const std::string & message = std::string()) \
+ : BaseClass(path, function, line, reason, message) { \
+ BaseClass::m_className = #Class; \
+ } \
+ };
+
+#define VCORE_UNHANDLED_EXCEPTION_HANDLER_BEGIN try
+
+#define VCORE_UNHANDLED_EXCEPTION_HANDLER_END \
+ catch (const ValidationCore::Exception &exception) \
+ { \
+ std::ostringstream msg; \
+ msg << ValidationCore::Exception::KnownExceptionToString(exception); \
+ ValidationCore::LogUnhandledException(msg.str(), \
+ __FILE__, \
+ __LINE__, \
+ __FUNCTION__); \
+ abort(); \
+ } \
+ catch (std::exception& e) \
+ { \
+ std::ostringstream msg; \
+ msg << e.what(); \
+ msg << "\n"; \
+ msg << ValidationCore::Exception::UnknownExceptionToString(); \
+ ValidationCore::LogUnhandledException(msg.str(), \
+ __FILE__, \
+ __LINE__, \
+ __FUNCTION__); \
+ abort(); \
+ } \
+ catch (...) \
+ { \
+ std::ostringstream msg; \
+ msg << ValidationCore::Exception::UnknownExceptionToString(); \
+ ValidationCore::LogUnhandledException(msg.str(), \
+ __FILE__, \
+ __LINE__, \
+ __FUNCTION__); \
+ abort(); \
+ }
+
+namespace ValidationCore {
+namespace CommonException {
+/**
+ * Internal exception definitions
+ *
+ * These should normally not happen.
+ * Usually, exception trace with internal error includes
+ * important messages.
+ */
+VCORE_DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from
+ // underlying libraries or
+ // kernel
+}
+}
+
+#endif // ValidationCore_EXCEPTION_H
diff --git a/vcore/src/vcore/pkcs12.c b/vcore/src/vcore/pkcs12.c
deleted file mode 100755
index 1239dda..0000000
--- a/vcore/src/vcore/pkcs12.c
+++ /dev/null
@@ -1,946 +0,0 @@
-/**
- * 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
-#define _CERT_SVC_VERIFY_PKCS12
-
-#include <cert-service.h>
-#include "cert-service-util.h"
-#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>
-#include <dlfcn.h>
-#include <cert-service-debug.h>
-#include <tzplatform_config.h>
-#include <tizen.h>
-
-#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
-
-#define CERTSVC_PKCS12_STORAGE_DIR tzplatform_mkpath(TZ_SYS_SHARE, "cert-svc/pkcs12")
-#define CERTSVC_PKCS12_STORAGE_FILE "storage"
-#define CERTSVC_PKCS12_STORAGE_PATH tzplatform_mkpath3(TZ_SYS_SHARE,"cert-svc/pkcs12", CERTSVC_PKCS12_STORAGE_FILE)
-#define MAX_PASSWORD_SIZE 32
-#define MAX_SEND_DATA_SIZE 4096 // internal buffer = 4KB
-
-typedef enum
-{
- SSA_PARAM_ERROR = TIZEN_ERROR_SYSTEM_CLASS | 0x01, /** < Invalid parameters */
- SSA_AUTHENTICATION_ERROR = TIZEN_ERROR_SYSTEM_CLASS | 0x02, /** < Authentication error */
- SSA_TZ_ERROR = TIZEN_ERROR_SYSTEM_CLASS | 0x03, /** < Trust zone error */
- SSA_SOCKET_ERROR = TIZEN_ERROR_CONNECTION, /** < Connection error */
- SSA_PERMISSION_ERROR = TIZEN_ERROR_PERMISSION_DENIED, /** < Permission denied */
- SSA_SECURITY_SERVER_ERROR = TIZEN_ERROR_SYSTEM_CLASS | 0x04,/** < Security server error */
- SSA_CIPHER_ERROR = TIZEN_ERROR_SYSTEM_CLASS | 0x05, /** < Encryption / Decryption error */
- SSA_IO_ERROR = TIZEN_ERROR_IO_ERROR, /** < I/O error */
- SSA_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /** < Out of memory */
- SSA_UNKNOWN_ERROR = TIZEN_ERROR_UNKNOWN, /** < Unknown error */
-} ssa_error_e;
-
-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[] = "secure-storage::pkcs12";
-
-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;
- char* data = NULL;
- char* tempfilepath = NULL;
-
- trial = 0U;
- try_again:
- ++trial;
- result = generate_random_filepath(&tempfilepath);
- if(result != CERTSVC_SUCCESS)
- return result;
- if(with_secure_storage)
- exists = (access(*tempfilepath, F_OK) == 0 || ssm_getinfo(*filepath, &sfi, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP) == 0);
- else
- exists = (access(*tempfilepath, F_OK) == 0);
-
- if(!exists) {
- *filepath = tempfilepath;
- }
- else {
- if(data){
- free(data);
- data = NULL;
- }
- free(tempfilepath);
- 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 = 0;
- struct stat st;
- int wr_res;
- void* dlHandle = NULL;
- GKeyFile *keyfile;
- gchar *bare;
- gchar *pkvalue;
- gchar **cvaluev;
- gsize i, n;
- gchar *data;
- gsize length;
- static int initFlag = 0;
- const char appInfo[] = "certsvcp12";
- int readLen = 0;
- char fileBuffer[4096] = {0,};
-
- 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;
- }
-
-#ifdef TIZEN_FEATURE_OSP_DISABLE
- LOGD("TIZEN_FEAT_OSP_DISABLE is 1");
-#endif
-
-#ifndef TIZEN_FEATURE_OSP_DISABLE
- LOGD("TIZEN_FEAT_OSP_DISABLE is 0");
-#endif
-
-#ifndef TIZEN_FEATURE_OSP_DISABLE
- dlHandle = dlopen("/usr/lib/osp/libosp-appfw.so", RTLD_LAZY);
- if (!dlHandle)
- {
- LOGD("Failed to open so with reason : %s", dlerror());
- goto free_keyfile;
- }
-#endif
- result = PKCS12_parse(container, password, &key, &cert, &certv);
- PKCS12_free(container);
- if (result == 0)
- {
- LOGD("Failed to parse PKCS12");
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
-#define _CERT_SVC_VERIFY_PKCS12
-#ifdef _CERT_SVC_VERIFY_PKCS12
-
- if (certv == NULL)
- {
- char* pSubject = NULL;
- char* pIssuerName = NULL;
- int isSelfSigned = 0;
-
- pSubject = X509_NAME_oneline(cert->cert_info->subject, NULL, 0);
- if (!pSubject)
- {
- LOGD("Failed to get subject name");
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- pIssuerName = X509_NAME_oneline(cert->cert_info->issuer, NULL, 0);
- if (!pIssuerName)
- {
- LOGD("Failed to get issuer name");
- free(pSubject);
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- if (strcmp((const char*)pSubject, (const char*)pIssuerName) == 0)
- {
- //self signed..
- //isSelfSigned = 1;
-
- EVP_PKEY* pKey = X509_get_pubkey(cert);
- if (!pKey)
- {
- LOGD("Failed to get public key");
- result = CERTSVC_FAIL;
- free(pSubject);
- free(pIssuerName);
- goto free_keyfile;
- }
-
- if (X509_verify(cert, pKey) <= 0)
- {
- LOGD("P12 verification failed");
- result = CERTSVC_FAIL;
- EVP_PKEY_free(pKey);
- free(pSubject);
- free(pIssuerName);
- goto free_keyfile;
- }
- LOGD("P12 verification Success");
- EVP_PKEY_free(pKey);
- }
- else
- {
- //isSelfSigned = 0;
- int res = 0;
- X509_STORE_CTX *cert_ctx = NULL;
- X509_STORE *cert_store = NULL;
-
- cert_store = X509_STORE_new();
- if (!cert_store)
- {
- LOGD("Memory allocation failed");
- free(pSubject);
- free(pIssuerName);
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- res = X509_STORE_load_locations(cert_store, NULL, tzplatform_mkpath(TZ_SYS_ETC, "ssl/certs/"));
- if (res != 1)
- {
- LOGD("P12 load certificate store failed");
- free(pSubject);
- free(pIssuerName);
- X509_STORE_free(cert_store);
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- res = X509_STORE_set_default_paths(cert_store);
- if (res != 1)
- {
- LOGD("P12 load certificate store path failed");
- free(pSubject);
- free(pIssuerName);
- X509_STORE_free(cert_store);
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- // initialize store and store context
- cert_ctx = X509_STORE_CTX_new();
- if (cert_ctx == NULL)
- {
- LOGD("Memory allocation failed");
- free(pSubject);
- free(pIssuerName);
- X509_STORE_free(cert_store);
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- // construct store context
- if (!X509_STORE_CTX_init(cert_ctx, cert_store, cert, NULL))
- {
- LOGD("Memory allocation failed");
- free(pSubject);
- free(pIssuerName);
- X509_STORE_free(cert_store);
- X509_STORE_CTX_free(cert_ctx);
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- res = X509_verify_cert(cert_ctx);
- if (res != 1)
- {
- LOGD("P12 verification failed");
- free(pSubject);
- free(pIssuerName);
- X509_STORE_free(cert_store);
- X509_STORE_CTX_free(cert_ctx);
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
- X509_STORE_free(cert_store);
- X509_STORE_CTX_free(cert_ctx);
- LOGD("P12 verification Success");
- }
- free(pSubject);
- free(pIssuerName);
- }
- else if (certv != NULL)
- {
- // Cert Chain
- int res = 0;
- X509_STORE_CTX *cert_ctx = NULL;
- X509_STORE *cert_store = NULL;
-
- cert_store = X509_STORE_new();
- if (!cert_store)
- {
- LOGD("Memory allocation failed");
- result = CERTSVC_FAIL;
- goto free_keyfile;
- }
-
- res = X509_STORE_load_locations(cert_store, NULL, tzplatform_mkpath(TZ_SYS_SHARE, "cert-svc/certs/ssl/"));
- if (res != 1)
- {
- LOGD("P12 load certificate store failed");
- result = CERTSVC_FAIL;
- X509_STORE_free(cert_store);
- goto free_keyfile;
- }
-
- res = X509_STORE_set_default_paths(cert_store);
- if (res != 1)
- {
- LOGD("P12 load certificate path failed");
- result = CERTSVC_FAIL;
- X509_STORE_free(cert_store);
- goto free_keyfile;
- }
-
- // initialize store and store context
- cert_ctx = X509_STORE_CTX_new();
- if (cert_ctx == NULL)
- {
- LOGD("Memory allocation failed");
- result = CERTSVC_FAIL;
- X509_STORE_free(cert_store);
- goto free_keyfile;
- }
-
- // construct store context
- if (!X509_STORE_CTX_init(cert_ctx, cert_store, cert, NULL))
- {
- LOGD("Memory allocation failed");
- result = CERTSVC_FAIL;
- X509_STORE_free(cert_store);
- X509_STORE_CTX_free(cert_ctx);
- goto free_keyfile;
- }
-
- X509_STORE_CTX_trusted_stack(cert_ctx, certv);
-
- res = X509_verify_cert(cert_ctx);
- if (res != 1)
- {
- LOGD("P12 verification failed");
- result = CERTSVC_FAIL;
- X509_STORE_free(cert_store);
- X509_STORE_CTX_free(cert_ctx);
- goto free_keyfile;
- }
-
- LOGD("P12 verification Success");
- X509_STORE_free(cert_store);
- X509_STORE_CTX_free(cert_ctx);
- }
-#endif //_CERT_SVC_VERIFY_PKCS12
- 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);
- if(result == 0) {
- result = CERTSVC_FAIL;
- fclose(stream);
- free(unique);
- goto clean_cert_chain_and_pkey;
- }
-
- fseek(stream, 0, SEEK_SET);
-
- readLen = fread(fileBuffer, sizeof(char), 4096, stream);
- fclose(stream);
- if(readLen <= 0){
- free(unique);
- result = CERTSVC_FAIL;
- SLOGE("failed to read key file");
- 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;
- }
- unlink(unique);
-
- 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 < (unsigned int)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;
-
- SECURE_LOGD("( %s, %s)", path, password);
-#ifndef TIZEN_FEATURE_OSP_DISABLE
-
- typedef int (*InsertPkcs12FuncPointer)(const char*, const char*);
- typedef void (*InitAppInfoPointer)(const char*, const char*);
-
- InsertPkcs12FuncPointer pInsertPkcs12FuncPointer = NULL;
- InitAppInfoPointer pInit = NULL;
-
-
- pInsertPkcs12FuncPointer = (InsertPkcs12FuncPointer)dlsym(dlHandle, "InsertPkcs12Content");
- if (dlerror() != NULL)
- {
- LOGD("Failed to find InsertPkcs12Content symbol : %s", dlerror());
- result = CERTSVC_FAIL;
- goto free_data;
- }
-
- if(initFlag == 0)
- {
- pInit = (InitAppInfoPointer)dlsym(dlHandle, "InitWebAppInfo");
- if (dlerror() != NULL)
- {
- LOGD("Failed to find InitWebAppInfo symbol : %s", dlerror());
- result = CERTSVC_FAIL;
- goto free_data;
- }
-
- pInit(appInfo, NULL);
- initFlag = 1;
- }
-
- int errCode = pInsertPkcs12FuncPointer(path, password);
- if (errCode != 0)
- {
- LOGD("dlHandle is not able to call function");
- c_certsvc_pkcs12_delete(alias);
- result = CERTSVC_FAIL;
- goto free_data;
- }
-#endif
- 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);
-#ifndef TIZEN_FEATURE_OSP_DISABLE
- if(dlHandle){
- dlclose(dlHandle);
- }
-#endif
- 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);
-}
-
-static void _delete_from_osp_cert_mgr(const char* path);
-
-static void
-_delete_from_osp_cert_mgr(const char* path)
-{
-
- typedef int (*RemoveUserCertificatePointer)(unsigned char*, int);
- typedef void (*InitAppInfoPointer)(const char*, const char*);
-
- static int initFlag = 0;
-
- unsigned char* pCertBuffer = NULL;
- int certBufferLen = 0;
- const char appInfo[] = "certsvcp12";
-
- RemoveUserCertificatePointer pRemoveUserCertificatePointer = NULL;
- InitAppInfoPointer pInit = NULL;
- void* dlHandle = dlopen("/usr/lib/osp/libosp-appfw.so", RTLD_LAZY);
- if (!dlHandle)
- {
- LOGD("Failed to open so with reason : %s", dlerror());
- goto end_of_func;
- }
-
- pRemoveUserCertificatePointer = (RemoveUserCertificatePointer)dlsym(dlHandle, "RemoveUserCertificate");
- if (dlerror() != NULL)
- {
- LOGD("Failed to find RemoveUserCertificate symbol : %s", dlerror());
- goto end_of_func;
- }
-
- if(initFlag == 0)
- {
- pInit = (InitAppInfoPointer)dlsym(dlHandle, "InitWebAppInfo");
- if (dlerror() != NULL)
- {
- LOGD("Failed to find InitWebAppInfo symbol : %s", dlerror());
- goto end_of_func;
- }
-
- pInit(appInfo, NULL);
- initFlag = 1;
- }
-
- int result = certsvc_load_file_to_buffer(path, &pCertBuffer, &certBufferLen);
- if (result != 0 )
- {
- LOGD("certsvc_load_file_to_buffer Failed.");
- goto end_of_func;
- }
- int errCode = pRemoveUserCertificatePointer(pCertBuffer, certBufferLen);
- if (errCode != 0)
- {
- LOGD("dlHandle is not able to call function");
- goto end_of_func;
- }
-
-end_of_func:
-
- if(dlHandle){
- dlclose(dlHandle);
- }
- return;
-}
-
-
-int certsvc_load_file_to_buffer(const char* filePath, unsigned char** certBuf, int* length)
-{
- int ret = CERT_SVC_ERR_NO_ERROR;
- FILE* fp_in = NULL;
- unsigned long int fileSize = 0;
-
- /* get file size */
- if((ret = cert_svc_get_file_size(filePath, &fileSize)) != CERT_SVC_ERR_NO_ERROR) {
- SECURE_SLOGE("[ERR][%s] Fail to get file size, [%s]\n", __func__, filePath);
- return CERT_SVC_ERR_FILE_IO;
- }
- /* open file and write to buffer */
- if(!(fp_in = fopen(filePath, "rb"))) {
- SECURE_SLOGE("[ERR][%s] Fail to open file, [%s]\n", __func__, filePath);
- return CERT_SVC_ERR_FILE_IO;
- }
-
- if(!(*certBuf = (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(*certBuf, 0x00, (fileSize + 1));
- if(fread(*certBuf, sizeof(unsigned char), fileSize, fp_in) != fileSize) {
- SECURE_SLOGE("[ERR][%s] Fail to read file, [%s]\n", __func__, filePath);
- ret = CERT_SVC_ERR_FILE_IO;
- goto err;
- }
-
- *length = fileSize;
-
-err:
- if(fp_in != NULL)
- fclose(fp_in);
- return ret;
-}
-
-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;
- }
- }
-
- _delete_from_osp_cert_mgr(certs[0]);
- 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;
-}
-
-
-int cert_svc_get_file_size(const char* filepath, unsigned long int* length)
-{
- int ret = CERT_SVC_ERR_NO_ERROR;
- FILE* fp_in = NULL;
-
- if(!(fp_in = fopen(filepath, "r"))) {
- SECURE_SLOGE("[ERR][%s] Fail to open file, [%s]\n", __func__, filepath);
- ret = CERT_SVC_ERR_FILE_IO;
- goto err;
- }
-
- fseek(fp_in, 0L, SEEK_END);
- (*length) = ftell(fp_in);
-
-err:
- if(fp_in != NULL)
- fclose(fp_in);
-
- return ret;
-}
diff --git a/vcore/src/vcore/pkcs12.cpp b/vcore/src/vcore/pkcs12.cpp
new file mode 100644
index 0000000..027af07
--- /dev/null
+++ b/vcore/src/vcore/pkcs12.cpp
@@ -0,0 +1,1465 @@
+/**
+ * Copyright (c) 2015 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.
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+#include <openssl/sha.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <db-util.h>
+
+#include <ss_manager.h>
+
+#include <cert-service.h>
+#include <cert-service-util.h>
+#include <cert-service-debug.h>
+#include <cert-svc/cerror.h>
+#include <cert-svc-client.h>
+
+#include <vcore/utils.h>
+#include <pkcs12.h>
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define START_CERT "-----BEGIN CERTIFICATE-----"
+#define END_CERT "-----END CERTIFICATE-----"
+#define START_TRUSTED "-----BEGIN TRUSTED CERTIFICATE-----"
+#define END_TRUSTED "-----END TRUSTED CERTIFICATE-----"
+#define START_KEY "-----BEGIN PRIVATE KEY-----"
+#define END_KEY "-----END PRIVATE KEY-----"
+
+#define CERTSVC_PKCS12_STORAGE_FILE "storage"
+
+#define CERTSVC_PKCS12_STORAGE_PATH CERTSVC_PKCS12_STORAGE_DIR "/" CERTSVC_PKCS12_STORAGE_FILE
+
+#define MAX_BUFFER_SIZE 16;
+#define _CERT_SVC_VERIFY_PKCS12
+
+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[] = "secure-storage::pkcs12";
+
+sqlite3 *cert_store_db = NULL;
+
+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) {
+ result = close(result);
+ if(result == -1)
+ SLOGD("Failed to close, errno : %d", errno);
+ 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) {
+ unsigned trial = 0x00U;
+ int result;
+ ssm_file_info_t sfi;
+ int exists = 1;
+
+ for (; trial < 0xFFU; ++trial) {
+ result = generate_random_filepath(filepath);
+ if(result != CERTSVC_SUCCESS)
+ return result;
+
+ exists = (access(*filepath, F_OK) == 0);
+
+ if (with_secure_storage)
+ exists |= (ssm_getinfo(*filepath, &sfi, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP) == 0);
+
+ /* find unique filename */
+ if(!exists)
+ return CERTSVC_SUCCESS;
+
+ free(*filepath);
+ }
+
+ return CERTSVC_FAIL;
+}
+
+static char *bare_filename(char *filepath) {
+ char *needle;
+ if(!filepath)
+ return NULL;
+ needle = strrchr(filepath, '/');
+ if(!needle)
+ return NULL;
+ return *(++needle) ? needle : NULL;
+}
+
+int read_from_file(const char *fileName, char **certBuffer, int *length) {
+
+ int result = CERTSVC_SUCCESS;
+ FILE *fp_out = NULL;
+ int certLength = 0;
+ struct stat st;
+
+ if (stat(fileName, &st) == -1) {
+ SLOGE("Certificate does not exist in disable folder.");
+ result = CERTSVC_FAIL;
+ goto err;
+ }
+
+ if (!(fp_out = fopen(fileName, "rb"))) {
+ SLOGE("Fail to open file for reading, [%s].", fileName);
+ result = CERTSVC_FAIL;
+ goto err;
+ }
+
+ fseek(fp_out, 0L, SEEK_END);
+ certLength = ftell(fp_out);
+ if (certLength < 1) {
+ SLOGE("Fail to get certificate length.");
+ result = CERT_SVC_ERR_FILE_IO;
+ goto err;
+ }
+
+ *certBuffer = (char*)malloc(sizeof(char) * ((int)certLength + 1));
+ if (*certBuffer == NULL) {
+ SLOGE("Fail to allocate memory");
+ result = CERTSVC_BAD_ALLOC;
+ goto err;
+ }
+
+ memset(*certBuffer, 0x00, certLength+1);
+ rewind (fp_out);
+ if (fread(*certBuffer, sizeof(char), (size_t)certLength, fp_out) != (size_t)certLength) {
+ SLOGE("Fail to read file, [%s]", fileName);
+ result = CERTSVC_IO_ERROR;
+ goto err;
+ }
+ *length = certLength;
+
+err:
+ if (fp_out != NULL) {
+ fclose(fp_out);
+ fp_out = NULL;
+ }
+ return result;
+}
+
+int open_db(sqlite3 **db_handle, const char *db_path) {
+
+ int result = -1;
+ sqlite3 *handle;
+
+ if (access(db_path, F_OK) == 0) {
+ result = db_util_open(db_path, &handle, 0);
+ if (result != SQLITE_OK) {
+ SLOGE("connect to db [%s] failed!", db_path);
+ return CERTSVC_FAIL;
+ }
+ *db_handle = handle;
+ return CERTSVC_SUCCESS;
+ }
+ SLOGD("%s DB does not exists. Create one!!", db_path);
+
+ result = db_util_open(db_path, &handle, 0);
+ if (result != SQLITE_OK) {
+ SLOGE("connect to db [%s] failed!", db_path);
+ return CERTSVC_FAIL;
+ }
+ *db_handle = handle;
+ return CERTSVC_SUCCESS;
+}
+
+int initialize_db() {
+
+ int result = CERTSVC_SUCCESS;
+ if (cert_store_db == NULL) {
+ result = open_db(&cert_store_db, CERTSVC_SYSTEM_STORE_DB);
+ if (result != CERTSVC_SUCCESS)
+ SLOGE("Certsvc store DB creation failed");
+ }
+ return result;
+}
+
+int execute_select_query(char *query, sqlite3_stmt **stmt) {
+
+ int result = CERTSVC_SUCCESS;
+ sqlite3_stmt *stmts = NULL;
+
+ if (cert_store_db != NULL) {
+ sqlite3_close(cert_store_db);
+ cert_store_db = NULL;
+ }
+
+ result = initialize_db();
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to initialise database.");
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ result = sqlite3_prepare_v2(cert_store_db, query, strlen(query), &stmts, NULL);
+ if (result != SQLITE_OK) {
+ SLOGE("sqlite3_prepare_v2 failed [%s].", query);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ *stmt = stmts;
+ result = CERTSVC_SUCCESS;
+
+error:
+ return result;
+}
+
+int c_certsvc_pkcs12_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, char* gname, CertStatus status) {
+
+ return vcore_client_set_certificate_status_to_store(storeType, is_root_app, gname, status);
+}
+
+int c_certsvc_pkcs12_get_certificate_buffer_from_store(CertStoreType storeType, char* gname, char** certBuffer, size_t* certSize) {
+
+ return vcore_client_get_certificate_from_store(storeType, gname, certBuffer, certSize, PEM_CRT);
+}
+
+int c_certsvc_pkcs12_get_certificate_status_from_store(CertStoreType storeType, const gchar *gname, int *status) {
+
+ return vcore_client_get_certificate_status_from_store(storeType, gname, status);
+}
+
+int c_certsvc_pkcs12_alias_exists_in_store(CertStoreType storeType, const gchar *alias, gboolean *exists) {
+
+ return vcore_client_check_alias_exist_in_store(storeType, alias, exists);
+}
+
+int c_certsvc_pkcs12_private_key_load_from_store(CertStoreType storeType, const gchar *gname, char **certBuffer, size_t *certSize) {
+
+ return vcore_client_get_certificate_from_store(storeType, gname, certBuffer, certSize, (CertType)P12_PKEY);
+}
+
+int c_certsvc_pkcs12_delete_certificate_from_store(CertStoreType storeType, const char* gname) {
+
+ int result = CERTSVC_SUCCESS;
+
+ result = vcore_client_delete_certificate_from_store(storeType, gname);
+ if(result == CERTSVC_SUCCESS)
+ SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Uninstall, Result=Succeed");
+ else
+ SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Uninstall, Result=Failed");
+
+ return result;
+}
+
+int c_certsvc_pkcs12_get_certificate_alias_from_store(CertStoreType storeType, const gchar *gname, char **alias) {
+
+ return vcore_client_get_certificate_alias_from_store(storeType, gname, alias);
+}
+
+int c_certsvc_pkcs12_load_certificates_from_store(CertStoreType storeType, const gchar *gname, gchar ***certs, gsize *ncerts) {
+ return vcore_client_load_certificates_from_store(storeType, gname, (char ***)certs, (int *)ncerts);
+}
+
+int c_certsvc_pkcs12_free_aliases_loaded_from_store(CertSvcStoreCertList** certList) {
+ int result = CERTSVC_SUCCESS;
+ CertSvcStoreCertList* tmpNode = NULL;
+
+ while (*certList!=NULL) {
+ tmpNode = *certList;
+ if(tmpNode->title != NULL) { free(tmpNode->title); }
+ if(tmpNode->gname != NULL) { free(tmpNode->gname); }
+ (*certList) = (*certList)->next;
+ free(tmpNode);
+ }
+
+ if (cert_store_db != NULL) {
+ sqlite3_close(cert_store_db);
+ cert_store_db = NULL;
+ }
+ certList = NULL;
+ return result;
+}
+
+int c_certsvc_pkcs12_get_root_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, int* length) {
+ return vcore_client_get_root_certificate_list_from_store(storeType, certList, length);
+}
+
+int c_certsvc_pkcs12_get_end_user_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, int* length) {
+ return vcore_client_get_end_user_certificate_list_from_store(storeType, certList, length);
+}
+
+int c_certsvc_pkcs12_get_certificate_list_from_store(CertStoreType storeType, int is_root_app, CertSvcStoreCertList** certList, int* length) {
+ return vcore_client_get_certificate_list_from_store(storeType, is_root_app, certList, length);
+}
+
+int install_pem_file_format_to_store(CertStoreType storeType, const char* certBuffer, int certLength, \
+ const gchar *alias, const char* path, char *private_key_gname, gchar *associated_gname, CertType decideCert) {
+
+ int result = CERTSVC_SUCCESS;
+ int readCount = 0;
+ char* fileName = NULL;
+ char* commonName = NULL;
+ char *unique = NULL;
+ BIO* pBio = NULL;
+ X509* x509Struct = NULL;
+ struct stat dirST;
+
+ if (!certBuffer || !certLength) {
+ SLOGE("Invalid argument. certBuffer is input cert.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ if (decideCert == PEM_CRT) {
+ result = unique_filename(&unique, FALSE);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Fail to generate unique filename.");
+ return result;
+ }
+ }
+ else
+ unique = (char*)path;
+
+ if (unique == NULL) {
+ SLOGE("Failed to get unique file name.");
+ return result;
+ }
+
+ /* Get common name from buffer or from file */
+ if (stat(path, &dirST) != -1) {
+ result = get_common_name(path, NULL, &commonName);
+ if (result != CERTSVC_SUCCESS) {
+ pBio = BIO_new(BIO_s_mem());
+ if (pBio == NULL) {
+ SLOGE("Failed to allocate memory.");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ }
+
+ readCount = BIO_write(pBio, (const void*) certBuffer, certLength);
+ if (readCount < 1) {
+ SLOGE("Failed to load cert into bio.");
+ result = CERTSVC_BAD_ALLOC;
+ goto error;
+ }
+
+ x509Struct = PEM_read_bio_X509(pBio, NULL, 0, NULL);
+ if (x509Struct == NULL) {
+ SLOGE("Failed to create x509 structure.");
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ result = get_common_name(NULL, x509Struct, &commonName);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("CommonName is NULL");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ }
+ }
+
+ /* storing the certificate to key-manager */
+ fileName = bare_filename(unique);
+ if ((decideCert == P12_END_USER) && (private_key_gname != NULL))
+ result = vcore_client_install_certificate_to_store(storeType, fileName, alias, private_key_gname, fileName, certBuffer, certLength, decideCert);
+ else if ((decideCert == P12_TRUSTED) || (decideCert == P12_INTERMEDIATE))
+ result = vcore_client_install_certificate_to_store(storeType, fileName, commonName, NULL, associated_gname, certBuffer, certLength, decideCert);
+ else
+ result = vcore_client_install_certificate_to_store(storeType, fileName, commonName, NULL, fileName, certBuffer, certLength, decideCert);
+
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to intall certificate. result[%d]", result);
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ SLOGD("Success to add certificate in store.");
+
+error:
+ if (commonName)
+ free(commonName);
+ return result;
+}
+
+int install_crt_file(
+ const char *path,
+ CertStoreType storeType,
+ const gchar *alias,
+ char *private_key_gname,
+ gchar *associated_gname,
+ CertType decideCert)
+{
+ int result = CERTSVC_SUCCESS;
+ int fileSize = 0;
+ int certLength = 0;
+ const char* header = NULL;
+ const char* trailer = NULL;
+ char* fileContent = NULL;
+ const char* tmpBuffer = NULL;
+ char* certBuffer = NULL;
+ const char* tailEnd = NULL;
+
+ if (read_from_file(path, &fileContent, &fileSize)!=CERTSVC_SUCCESS)
+ {
+ SLOGE("Failed to read the file. [%s]",path);
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ tmpBuffer = fileContent;
+ if (decideCert == PEM_CRT)
+ header = strstr(tmpBuffer, START_CERT);
+ else if (decideCert == P12_END_USER)
+ header = strstr(tmpBuffer, START_CERT);
+ else if ((decideCert == P12_TRUSTED)||(decideCert == P12_INTERMEDIATE))
+ header = strstr(tmpBuffer, START_TRUSTED);
+ else {
+ SLOGE("Invalid cert.");
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ if (header != NULL) {
+ /* Supports installation of only one certificate present in a CRT file */
+ if (decideCert == PEM_CRT) {
+ trailer = strstr(header, END_CERT);
+ tailEnd = END_CERT;
+ }
+ else if (decideCert == P12_END_USER) {
+ trailer = strstr(header, END_CERT);
+ tailEnd = END_CERT;
+ }
+ else if ((decideCert == P12_TRUSTED)||(decideCert == P12_INTERMEDIATE)) {
+ trailer = strstr(header, END_TRUSTED);
+ tailEnd = END_TRUSTED;
+ }
+ else {
+ SLOGE("Invalid certificate passed.");
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ if (trailer != NULL) {
+ tmpBuffer = trailer;
+ certLength = ((int)(trailer - header) + strlen(tailEnd));
+ certBuffer = (char*) malloc(sizeof(char) * (certLength+2));
+ if (certBuffer == NULL) {
+ result = CERTSVC_BAD_ALLOC;
+ SLOGE("Fail to allocate memory.");
+ goto error;
+ }
+
+ memset(certBuffer, 0x00, certLength+2);
+ memcpy(certBuffer, header, certLength);
+ certBuffer[certLength] = '\0';
+
+ result = install_pem_file_format_to_store(storeType, certBuffer, certLength, alias, \
+ path, private_key_gname, associated_gname, decideCert);
+ if (result != CERTSVC_SUCCESS) {
+ result = CERTSVC_FAIL;
+ SLOGE("Fail to install certificate[%s]", path);
+ }
+ }
+ }
+ else {
+ SLOGE("Invalid file type passed.");
+ result = CERT_SVC_ERR_INVALID_CERTIFICATE;
+ }
+
+error:
+ if (certBuffer)
+ free(certBuffer);
+ if (fileContent)
+ free(fileContent);
+ return result;
+}
+
+int handle_crt_pem_file_installation(CertStoreType storeType, const char *path, const gchar *alias) {
+
+ int result = CERTSVC_SUCCESS;
+
+ if ((strstr(path, ".crt")) != NULL || (strstr(path, ".pem")) != NULL) {
+ SLOGD("certificate extention is .crt/.pem file");
+
+ /* Installs CRT and PEM files. We will passing NULL for private_key_gname and associated_gname parameter in
+ * install_crt_file(). Which means that there is no private key involved in the certificate which we are
+ * installing and there are no other certificates related with the current certificate which is installed */
+ result = install_crt_file(path, storeType, alias, NULL, NULL, PEM_CRT);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to install the certificate.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ }
+ else {
+ SLOGE("Invalid certificate passed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ SLOGD("Success to install the certificate.");
+
+error:
+ return result;
+}
+
+int verify_cert_details(X509** cert, STACK_OF(X509) **certv) {
+
+ int result = CERTSVC_SUCCESS;
+ char* pSubject = NULL;
+ char* pIssuerName = NULL;
+ X509_STORE_CTX *cert_ctx = NULL;
+ X509_STORE *cert_store = NULL;
+ int res = 0;
+
+#ifdef _CERT_SVC_VERIFY_PKCS12
+ if (*certv == NULL) {
+ pSubject = X509_NAME_oneline((*cert)->cert_info->subject, NULL, 0);
+ if (!pSubject) {
+ SLOGE("Failed to get subject name");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ pIssuerName = X509_NAME_oneline((*cert)->cert_info->issuer, NULL, 0);
+ if (!pIssuerName) {
+ SLOGE("Failed to get issuer name");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ if (strcmp((const char*)pSubject, (const char*)pIssuerName) == 0) {
+ /*self signed.. */
+ EVP_PKEY* pKey = NULL;
+ pKey = X509_get_pubkey(*cert);
+ if (!pKey) {
+ SLOGE("Failed to get public key");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ if (X509_verify(*cert, pKey) <= 0) {
+ SLOGE("P12 verification failed");
+ EVP_PKEY_free(pKey);
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+ SLOGD("P12 verification Success");
+ EVP_PKEY_free(pKey);
+ }
+ else {
+ cert_store = X509_STORE_new();
+ if (!cert_store) {
+ SLOGE("Memory allocation failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ res = X509_STORE_load_locations(cert_store, NULL, "/opt/etc/ssl/certs/");
+ if (res != 1) {
+ SLOGE("P12 load certificate store failed");
+ X509_STORE_free(cert_store);
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ res = X509_STORE_set_default_paths(cert_store);
+ if (res != 1) {
+ SLOGE("P12 load certificate store path failed");
+ X509_STORE_free(cert_store);
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ /* initialise store and store context */
+ cert_ctx = X509_STORE_CTX_new();
+ if (cert_ctx == NULL) {
+ SLOGE("Memory allocation failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ /* construct store context */
+ if (!X509_STORE_CTX_init(cert_ctx, cert_store, *cert, NULL)) {
+ SLOGE("Memory allocation failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+#ifdef P12_VERIFICATION_NEEDED
+ res = X509_verify_cert(cert_ctx);
+ if (res != 1) {
+ SLOGE("P12 verification failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+ SLOGD("P12 verification Success");
+#endif
+ }
+ }
+ else if (*certv != NULL) {
+ /* Cert Chain */
+ cert_store = X509_STORE_new();
+ if (!cert_store) {
+ SLOGE("Memory allocation failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ res = X509_STORE_load_locations(cert_store, NULL, CERTSVC_SSL_CERTS_DIR);
+ if (res != 1) {
+ SLOGE("P12 load certificate store failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ res = X509_STORE_set_default_paths(cert_store);
+ if (res != 1) {
+ SLOGE("P12 load certificate path failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ /* initialise store and store context */
+ cert_ctx = X509_STORE_CTX_new();
+ if (cert_ctx == NULL) {
+ SLOGE("Memory allocation failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ /* construct store context */
+ if (!X509_STORE_CTX_init(cert_ctx, cert_store, *cert, NULL)) {
+ SLOGE("Memory allocation failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+
+ X509_STORE_CTX_trusted_stack(cert_ctx, *certv);
+#ifdef P12_VERIFICATION_NEEDED
+ res = X509_verify_cert(cert_ctx);
+ if (res != 1) {
+ SLOGE("P12 verification failed");
+ result = CERTSVC_FAIL;
+ goto free_memory;
+ }
+ SLOGD("P12 verification Success");
+#endif
+ }
+#endif //_CERT_SVC_VERIFY_PKCS12
+
+free_memory:
+ if (pSubject != NULL) { free(pSubject); }
+ if (pIssuerName != NULL) { free(pIssuerName); }
+ if (cert_store != NULL) { X509_STORE_free(cert_store); }
+ if (cert_ctx) { X509_STORE_CTX_free(cert_ctx); }
+ return result;
+}
+
+int c_certsvc_pkcs12_import_from_file_to_store(CertStoreType storeTypes, const char *path, const char *password, const gchar *alias) {
+
+ int result = CERTSVC_SUCCESS;
+ int readLen = 0;
+ int tmpLen = 0;
+ int nicerts = 0, i = 0, n = 0, ncerts = 0, wr_res;
+ CertStoreType storeType = NONE_STORE;
+ FILE* stream = NULL;
+ PKCS12* container = NULL;
+ EVP_PKEY* key = NULL;
+ X509* cert = NULL;
+ STACK_OF(X509) *certv = NULL;
+ gchar* bare = NULL;
+ gchar* pkvalue = NULL;
+ gchar** cvaluev = NULL;
+ gchar **certs = NULL;
+ char* tmpPkValue = NULL;
+ char* unique = NULL;
+ char fileBuffer[4096] = {0,};
+ int loopCount = 0;
+ CertType decideCert = INVALID_DATA;
+ gboolean exists = FALSE;
+
+ if ((!alias) || (strlen(alias) < 1) || (!path) || (strlen(path) < 1)) {
+ SLOGE("Invalid input parameter.");
+ SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Failed");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ while(1) {
+ /* Iteration only possible from VPN_STORE till SYSTEM_STORE */
+ if (loopCount == (MAX_STORE_ENUMS-1)) break;
+
+ /* User should not install any form of certificates inside SYSTEM_STORE */
+ if (((1 << loopCount) & storeTypes) == SYSTEM_STORE) {
+ SLOGE("Not a valid store type installing certificate, store type passed [%d].", (1 << loopCount));
+ SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Failed");
+ return CERTSVC_INVALID_STORE_TYPE;
+ }
+
+ /* Iterating over all the stores */
+ if ((1 << loopCount) & storeTypes) {
+ storeType = NONE_STORE;
+ storeType = (CertStoreType) (1 << loopCount);
+ SLOGD("Processing store type : [%s]", (storeType == VPN_STORE)? "VPN" : (storeType == WIFI_STORE)? "WIFI" : "EMAIL");
+
+ /* check if the alias exists before installing certificate */
+ result = c_certsvc_pkcs12_alias_exists_in_store(storeType, alias, &exists);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failure to access database.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ if (exists!=CERTSVC_TRUE) {
+ SLOGE("Alias exist in store [%s].", (storeType == VPN_STORE)? "VPN" : (storeType == WIFI_STORE)? "WIFI" : "EMAIL");
+ result = CERTSVC_DUPLICATED_ALIAS;
+ goto error;
+ }
+
+ /* Logic for handling crt/pem cert installation */
+ /* Check if the input file is a PEM/CRT, since a PFX cert can also be opened without a password */
+ if (password == NULL && ((strstr(path, ".pfx") == NULL) || (strstr(path, ".p12")))) {
+ result = handle_crt_pem_file_installation(storeType, path, alias);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGE("Failed to install PEM/CRT file to store.");
+ result = CERTSVC_FAIL;
+ }
+ loopCount++;
+ continue;
+ }
+
+ /* Logic for handling .pfx/.p12 cert installation */
+ if ((stream = fopen(path, "rb")) == NULL) {
+ SLOGE("Unable to open the file for reading [%s].", path);
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ if (container == NULL) {
+ container = d2i_PKCS12_fp(stream, NULL);
+ fclose(stream);
+ if (container == NULL) {
+ SLOGE("Failed to parse the input file passed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+ }
+
+ /* To ensure when the code re-enters, we should clean up */
+ if (key==NULL && cert==NULL && certv==NULL) {
+ result = PKCS12_parse(container, password, &key, &cert, &certv);
+ PKCS12_free(container);
+ if (result == CERTSVC_FAIL) {
+ SLOGE("Failed to parse the file passed.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ result = verify_cert_details(&cert, &certv);
+ if (result == CERTSVC_FAIL) {
+ SLOGE("Failed to verify p12 certificate.");
+ goto error;
+ }
+ }
+
+ nicerts = 0;
+ nicerts = certv ? sk_X509_num(certv) : 0;
+ if (cvaluev != NULL) {
+ for (i = 0; i < n; i++)
+ g_free(cvaluev[i]);
+ if (cvaluev) free(cvaluev);
+ cvaluev = NULL;
+ }
+
+ n = 0;
+ cvaluev = (gchar **)calloc(1 + nicerts, sizeof(gchar *));
+ if (unique != NULL) { free(unique); unique = NULL; }
+ result = unique_filename(&unique, FALSE);
+ if (result != CERTSVC_SUCCESS || !unique) {
+ SLOGE("Unique filename generation failed.");
+ goto error;
+ }
+
+ if ((stream = fopen(unique, "w+")) == NULL) {
+ SLOGE("Unable to open the file for writing [%s].",unique);
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ result = PEM_write_PrivateKey(stream, key, NULL, NULL, 0, NULL, NULL);
+ if (result == 0) {
+ SLOGE("Writing the private key contents failed.");
+ result = CERTSVC_FAIL;
+ fclose(stream);
+ goto error;
+ }
+
+ fseek(stream, 0, SEEK_SET);
+ memset(fileBuffer, 0, (sizeof(char)*4096));
+ readLen=0;
+ readLen = fread(fileBuffer, sizeof(char), 4096, stream);
+ fclose(stream);
+ if (readLen <= 0){
+ SLOGE("Failed to read key file");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ bare = bare_filename(unique);
+ if (bare) {
+ pkvalue = g_strdup(bare);
+ tmpLen = strlen((const char*)pkvalue);
+ tmpPkValue = (char*)malloc(sizeof(char) * (tmpLen + 1));
+ memset(tmpPkValue, 0x00, tmpLen+1);
+ memcpy(tmpPkValue, pkvalue, tmpLen);
+ }
+
+ decideCert = P12_PKEY;
+ result = vcore_client_install_certificate_to_store(storeType, tmpPkValue, NULL, NULL, NULL, fileBuffer, readLen, decideCert);
+ if (result != CERTSVC_SUCCESS) {
+ SLOGD("Failed to store the private key contents.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ unlink(unique);
+ if (unique!=NULL) { free(unique); unique=NULL; }
+ result = unique_filename(&unique, FALSE);
+ if (result != CERTSVC_SUCCESS || !unique) {
+ SLOGE("Unique filename generation failed.");
+ goto error;
+ }
+
+ if ((stream = fopen(unique, "w")) == NULL) {
+ SLOGE("Unable to open the file for writing [%s].", unique);
+ result = CERTSVC_IO_ERROR;
+ goto error;
+ }
+
+ result = PEM_write_X509(stream, cert);
+ fclose(stream);
+ if (result == 0) {
+ SLOGE("Failed to write contents to file.");
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ bare = bare_filename(unique);
+ if (bare)
+ cvaluev[n++] = g_strdup(bare);
+
+ wr_res = -1;
+ decideCert = P12_END_USER;
+ wr_res = install_crt_file(unique, storeType, alias, tmpPkValue, NULL, decideCert);
+ if (wr_res != CERTSVC_SUCCESS) {
+ result = CERTSVC_FAIL;
+ SLOGE("Failed to install the end user certificate.");
+ goto error;
+ }
+
+ unlink(unique);
+ for (i=nicerts; i>0; i--) {
+ result = unique_filename(&unique, FALSE);
+ if (result != CERTSVC_SUCCESS || !unique) {
+ SLOGE("Unique filename generation failed.");
+ goto error;
+ }
+
+ if ((stream = fopen(unique, "w")) == NULL) {
+ result = CERTSVC_IO_ERROR;
+ SLOGE("Unable to open the file for writing.");
+ goto error;
+ }
+
+ result = PEM_write_X509_AUX(stream, sk_X509_value(certv, i-1));
+ fclose(stream);
+ if (result == 0) {
+ result = CERTSVC_FAIL;
+ SLOGE("Unable to extract the certificates.");
+ goto error;
+ }
+
+ wr_res = -1;
+ if (i==nicerts)
+ decideCert = P12_INTERMEDIATE;
+ else
+ decideCert = P12_TRUSTED;
+ wr_res = install_crt_file(unique, storeType, alias, NULL, cvaluev[0], decideCert);
+ if (wr_res != CERTSVC_SUCCESS) {
+ result = CERTSVC_FAIL;
+ goto error;
+ }
+
+ unlink(unique);
+ bare = bare_filename(unique);
+ if (bare)
+ cvaluev[n++] = g_strdup(bare);
+ }
+ }
+ loopCount++;
+ }
+
+error:
+ /* if any certificate parsing/installation fails in middle,
+ * the below logic will delete the chain installed in DB */
+ if (result != CERTSVC_SUCCESS) {
+ SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Failed");
+ if (nicerts > 0) {
+ nicerts = 0; i = 0;
+ /* cvaluev[0] holds the end user certificate identifier which will be associated
+ * to chain certs. Pull the cert chain based on end user cert and delete one by one. */
+ if (c_certsvc_pkcs12_load_certificates_from_store(storeType, cvaluev[0], &certs, (gsize *)&ncerts) != CERTSVC_SUCCESS) {
+ SLOGE("Unable to load certificates from store.");
+ return result;
+ }
+
+ for (i=0; i<ncerts; i++) {
+ if (certs[i] != NULL) {
+ SLOGD("file to delete : %s",certs[i]);
+ c_certsvc_pkcs12_delete_certificate_from_store(storeType, (char *)certs[i]);
+ }
+ }
+
+ if (certs[i] != NULL) {
+ for (i=0; i<ncerts; i++)
+ g_free(certs[i]);
+ }
+ }
+ }
+ else
+ SLOG(LOG_INFO, "MDM_LOG_USER", "Object=certificate, AccessType=Install, Result=Succeed");
+
+ if (key != NULL) EVP_PKEY_free(key);
+ if (cert != NULL) X509_free(cert);
+ if (certv != NULL) sk_X509_free(certv);
+ if (pkvalue != NULL) free(pkvalue);
+ if (tmpPkValue != NULL) free(tmpPkValue);
+ if (unique != NULL) free(unique);
+ return result;
+}
+
+
+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 = 0;
+ struct stat st;
+ int wr_res;
+ GKeyFile *keyfile;
+ gchar *bare;
+ gchar *pkvalue;
+ gchar **cvaluev;
+ gsize i, n;
+ gchar *data;
+ gsize length;
+ int readLen = 0;
+ char fileBuffer[4096] = {0,};
+
+ 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)
+ {
+ SLOGD("Failed to parse PKCS12");
+ result = CERTSVC_FAIL;
+ goto free_keyfile;
+ }
+
+ result = verify_cert_details(&cert, &certv);
+ if (result == CERTSVC_FAIL)
+ {
+ SLOGE("Failed to parse the file passed.");
+ 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);
+ if(result == 0) {
+ result = CERTSVC_FAIL;
+ fclose(stream);
+ free(unique);
+ goto clean_cert_chain_and_pkey;
+ }
+
+ fseek(stream, 0, SEEK_SET);
+
+ readLen = fread(fileBuffer, sizeof(char), 4096, stream);
+ fclose(stream);
+ if(readLen <= 0){
+ free(unique);
+ result = CERTSVC_FAIL;
+ SLOGE("failed to read key file");
+ 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;
+ SLOGE("ssm_write_file failed : %d", wr_res);
+ goto clean_cert_chain_and_pkey;
+ }
+ unlink(unique);
+
+ 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, 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_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 < (unsigned int)nicerts; i++) {
+ 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_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;
+
+ SLOGD("( %s, %s)", path, password);
+
+ 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 = (gchar **)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;
+ char *spkp;
+ int result;
+ ssm_file_info_t sfi;
+
+ 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);
+ g_key_file_free(keyfile);
+
+ if(error && error->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND) {
+ *count = 0;
+ return CERTSVC_SUCCESS;
+ }
+
+ if(error)
+ return CERTSVC_FAIL;
+
+ if(asprintf(&spkp, "%s/%s", CERTSVC_PKCS12_STORAGE_DIR, pkey) == -1) {
+ spkp = NULL;
+ result = CERTSVC_BAD_ALLOC;
+ goto out;
+ }
+
+ if(ssm_getinfo(spkp, &sfi, SSM_FLAG_DATA, CERTSVC_PKCS12_UNIX_GROUP) != 0) {
+ //result = CERTSVC_FAIL;
+ goto out;
+ }
+
+ if((*buffer = (char *)malloc(sfi.originSize))) {
+ result = CERTSVC_BAD_ALLOC;
+ goto out;
+ }
+
+ 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;
+ }
+
+out:
+ free(spkp);
+ g_free(pkey);
+
+ return result;
+}
+
+void c_certsvc_pkcs12_private_key_free(char *buffer) {
+ free(buffer);
+}
+
+int certsvc_load_file_to_buffer(const char* filePath, unsigned char** certBuf, int* length)
+{
+ int ret = CERT_SVC_ERR_NO_ERROR;
+ FILE* fp_in = NULL;
+ unsigned long int fileSize = 0;
+
+ /* get file size */
+ if((ret = cert_svc_get_file_size(filePath, &fileSize)) != CERT_SVC_ERR_NO_ERROR) {
+ SLOGE("[ERR][%s] Fail to get file size, [%s]", __func__, filePath);
+ return CERT_SVC_ERR_FILE_IO;
+ }
+ /* open file and write to buffer */
+ if(!(fp_in = fopen(filePath, "rb"))) {
+ SLOGE("[ERR][%s] Fail to open file, [%s]", __func__, filePath);
+ return CERT_SVC_ERR_FILE_IO;
+ }
+
+ if(!(*certBuf = (unsigned char*)malloc(sizeof(unsigned char) * (unsigned int)(fileSize + 1)))) {
+ SLOGE("[ERR][%s] Fail to allocate memory.", __func__);
+ ret = CERT_SVC_ERR_MEMORY_ALLOCATION;
+ goto err;
+ }
+ memset(*certBuf, 0x00, (fileSize + 1));
+ if(fread(*certBuf, sizeof(unsigned char), fileSize, fp_in) != fileSize) {
+ SLOGE("[ERR][%s] Fail to read file, [%s]", __func__, filePath);
+ ret = CERT_SVC_ERR_FILE_IO;
+ goto err;
+ }
+
+ *length = fileSize;
+
+err:
+ if(fp_in != NULL)
+ fclose(fp_in);
+ return ret;
+}
+
+int c_certsvc_pkcs12_delete(const gchar *alias) {
+ gchar **certs;
+ gsize ncerts;
+ char *pkey = NULL;
+ char *spkp = NULL;
+ int result;
+ GKeyFile *keyfile = NULL;
+ 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;
+}
+
+
+int cert_svc_get_file_size(const char* filepath, unsigned long int* length)
+{
+ int ret = CERT_SVC_ERR_NO_ERROR;
+ FILE* fp_in = NULL;
+
+ if(!(fp_in = fopen(filepath, "r"))) {
+ SLOGE("[ERR][%s] Fail to open file, [%s]", __func__, filepath);
+ ret = CERT_SVC_ERR_FILE_IO;
+ goto err;
+ }
+
+ fseek(fp_in, 0L, SEEK_END);
+ (*length) = ftell(fp_in);
+
+err:
+ if(fp_in != NULL)
+ fclose(fp_in);
+
+ return ret;
+}
diff --git a/vcore/src/vcore/pkcs12.h b/vcore/src/vcore/pkcs12.h
index c7ae668..1b6c8ab 100644
--- a/vcore/src/vcore/pkcs12.h
+++ b/vcore/src/vcore/pkcs12.h
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 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.
@@ -23,23 +23,261 @@
#define _PKCS12_H_
#include <glib.h>
+#include <cert-svc/ccert.h>
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ * Checks if the alias exist in the user store or not.
+ *
+ * @param[in] Alias Logical name for certificate bundle identification (can't be empty).
+ * @param[out] exists A Boolean value which states if the alias exists or not.
+ * @return CERTSVC_SUCCESS, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT.
+ */
int c_certsvc_pkcs12_alias_exists(const gchar *alias, gboolean *exists);
+
+/**
+ * To import the p12/pfx file to user store.
+ *
+ * @param[in] path Path to file.
+ * @param[in] password Password for opening the file.
+ * @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_DUPLICATED_ALIAS, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
+ */
int c_certsvc_pkcs12_import(const char *path, const char *password, const gchar *alias);
+
+/**
+ * To import the p12/pfx/crt/pem file to specified store (WIFI_STORE/VPN_STORE/EMAIL_STORE).
+ *
+ * @param[in] storeType Refers to WIFI_STORE / VPN_STORE / EMAIL_STORE / ALL_STORE.
+ * @param[in] path Path to file.
+ * @param[in] password Password for opening the file.
+ * @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_DUPLICATED_ALIAS, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
+ */
+int c_certsvc_pkcs12_import_from_file_to_store(CertStoreType storeType, const char *path, const char *password, const gchar *alias);
+
+/**
+ * To get the list of certificate information present in a store. User will be getting
+ * the information in a linked list where every list will contain Alias, Path to certificate,
+ * Certificate status of all the certificates present in the specified store.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] is_root_app If set to ENABLED, can get all the certs without any restriction (should be used only by master application).
+ * If set to DISABLED, only certs which are enabled by master application can only be retrieved.
+ * @param[out] certList Linked-list having all the information about each certificate present in a store.
+ * @param[out] length provides the length of the linked list.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
+ */
+int c_certsvc_pkcs12_get_certificate_list_from_store(CertStoreType storeType, int is_root_app, CertSvcStoreCertList** certList, int* length);
+
+/**
+ * To set the status for a specified certificate in a particular store to enabled / disabled.
+ * The gname is the key for accessing the certificate.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @param[in] is_root_app Set as ENABLED/DISABLED. Enabled, if used by master application is changing the status. Disabled, should be used by other applications.
+ * @param[in] status Allows to set the status of the certificate to enabled / disabled.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
+ */
+int c_certsvc_pkcs12_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, char* gname, CertStatus status);
+
+/**
+ * To get the status (enabled/disabled) for the specified certificate in a particular store.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @param[out] status Returns the status of the certificate. It will be set Disable=0, Enable=1, Fail=-1.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_ALIAS_DOES_NOT_EXIST, CERTSVC_IO_ERROR
+ */
+int c_certsvc_pkcs12_get_certificate_status_from_store(CertStoreType storeType, const gchar *gname, int *status);
+
+/**
+ * To get the encoded form of the specified certificate from the specified store.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @param[out] certBuffer Which will be having the encoded value of the certificate requested.
+ * @param[out] certSize Which will be having the size of the buffer.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
+ */
+int c_certsvc_pkcs12_get_certificate_buffer_from_store(CertStoreType storeType, char* gname, char** certBuffer, size_t* certSize);
+
+/**
+ * To delete the certificate from the specified store (VPN_STORE, WIFI_STORE, EMAIL_STORE, SYSTEM_STORE, ALL_STORE).
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Referred as group name, is the key for accessing the certificate.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_INVALID_STORE_TYPE.
+ */
+int c_certsvc_pkcs12_delete_certificate_from_store(CertStoreType storeType, const char* gname);
+
+/**
+ * To free the certificate list which got generated from
+ * c_certsvc_pkcs12_get_certificate_list_from_store() function.
+ *
+ * @param[in] certList Linked-list having all the information about each certificate present in a store.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL.
+ */
+int c_certsvc_pkcs12_free_aliases_loaded_from_store(CertSvcStoreCertList** certList);
+
+/**
+ * Checks if the alias exist in the user store or not.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] Alias Logical name for certificate bundle identification (can't be empty).
+ * @param[out] exists A Boolean value which states if the alias exists or not.
+ * @return CERTSVC_SUCCESS, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT.
+ */
+int c_certsvc_pkcs12_alias_exists_in_store(CertStoreType storeType, const gchar *alias, gboolean *exists);
+
+/**
+ * Function to get the size of the file passed.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[in] gname Refers to unique name referring to the certificate.
+ * @param[out] certs Provides the list of certificates matching the unique name provided.
+ * @param[out] ncerts Provides the number of certs in certs.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
+ */
+int c_certsvc_pkcs12_load_certificates_from_store(CertStoreType storeType, const gchar *gname, gchar ***certs, gsize *ncerts);
+
+/**
+ * To load the private key for the specified certificate mapped by an Alias.
+ *
+ * @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @param[out] pkey Will hold the private key value of the certificate.
+ * @param[out] count Will hold the siz of the private key buffer.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
+ */
+int c_certsvc_pkcs12_private_key_load_from_store(CertStoreType storeType, const gchar *gname, char **pkey, gsize *count);
+
+/**
+ * Gets the alias name for the gname passed.
+ *
+ * @param[in] instance CertSvcInstance object.
+ * @param[in] gname Certificate identification of pfx/pkcs file.
+ * @param[out] alias Alias name for the given gname.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
+ */
+int c_certsvc_pkcs12_get_certificate_alias_from_store(CertStoreType storeType, const gchar *gname, char **alias);
+
+/**
+ * To get the list of only end user certificate information present in a store. User will be getting
+ * the information in a linked list where every list will contain Alias, Path to certificate,
+ * Certificate status of all the certificates present in the specified store.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[out] certList Linked-list having all the information about each certificate present in a store.
+ * @param[out] length provides the length of the linked list.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
+ */
+int c_certsvc_pkcs12_get_end_user_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, int* length);
+
+/**
+ * To get the list of only root/trusted certificate information present in a store. User will be getting
+ * the information in a linked list where every list will contain Alias, Path to certificate,
+ * Certificate status of all the certificates present in the specified store.
+ *
+ * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
+ * @param[out] certList Linked-list having all the information about each certificate present in a store.
+ * @param[out] length provides the length of the linked list.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
+ */
+int c_certsvc_pkcs12_get_root_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, int* length);
+
+/**
+ * Function to load all the alias list present in the user store.
+ *
+ * @param[out] aliases Which holds all the list of aliases present in the store.
+ * @param[out] naliases Provides the number of aliases present in the store.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR.
+ */
int c_certsvc_pkcs12_aliases_load(gchar ***aliases, gsize *naliases);
+
+/**
+ * To free all the aliases which were loaded previously from
+ * c_certsvc_pkcs12_aliases_load() function.
+ *
+ * @param[in] aliases Which holds all the list of aliases present in the store.
+ */
void c_certsvc_pkcs12_aliases_free(gchar **aliases);
+
+/**
+ * TO check if the p12/pfx file is protected by password or not.
+ *
+ * @param[in] filePath Where the file is located.
+ * @param[out] passworded A boolean value to state if the file is protected by password or not.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT.
+ */
int c_certsvc_pkcs12_has_password(const char *filepath, gboolean *passworded);
+
+/**
+ * To load all the certificates matching the given alias.
+ *
+ * @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @param[out] certificates The pointer holding all the certificates buffer in memory.
+ * @param[out] ncertificates Holds the number of certificates returned.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT.
+ */
int c_certsvc_pkcs12_load_certificates(const gchar *alias, gchar ***certificates, gsize *ncertificates);
+
+/**
+ * To free the certificates from memory which was loaded by
+ * c_certsvc_pkcs12_load_certificates() functon.
+ *
+ * @param[in] certs A pointer holding all the certificates in memory.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR.
+ */
void c_certsvc_pkcs12_free_certificates(gchar **certs);
+
+/**
+ * To load the private key for the specified certificate mapped by an Alias.
+ *
+ * @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @param[out] pkey Will hold the private key value of the certificate.
+ * @param[out] count Will hold the siz of the private key buffer.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
+ */
int c_certsvc_pkcs12_private_key_load(const gchar *alias, char **pkey, gsize *count);
+
+/**
+ * To free the private key buffer previously loaded by
+ * c_certsvc_pkcs12_private_key_load() function.
+ *
+ * @param[in] buffer Holding the private key values.
+ */
void c_certsvc_pkcs12_private_key_free(char *buffer);
+
+/**
+ * Function to delete the certificate present in the user store.
+ *
+ * @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
+ */
int c_certsvc_pkcs12_delete(const gchar *alias);
//static void _delete_from_osp_cert_mgr(const char* path);
+
+/**
+ * Function to load the file to buffer.
+ *
+ * @param[in] filePath Which points to the location where the file is present.
+ * @param[out] certBuf Which will hold the certificate information.
+ * @param[out] length Which will hold the file size.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERT_SVC_ERR_FILE_IO, CERT_SVC_ERR_MEMORY_ALLOCATION.
+ */
int certsvc_load_file_to_buffer(const char* filePath, unsigned char** certBuf, int* length);
+
+/**
+ * Function to get the size of the file passed.
+ *
+ * @param[in] filepath Which points to the location where the file is present.
+ * @param[out] length Which will hold the file size.
+ * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
+ */
int cert_svc_get_file_size(const char* filepath, unsigned long int* length);
#ifdef __cplusplus
diff --git a/vcore/src/vcore/scoped_gpointer.h b/vcore/src/vcore/scoped_gpointer.h
index 78772df..aec26a9 100644
--- a/vcore/src/vcore/scoped_gpointer.h
+++ b/vcore/src/vcore/scoped_gpointer.h
@@ -45,10 +45,10 @@ struct ScopedGPointerPolicy
};
template <typename Class>
-class ScopedGPointer : public DPL::ScopedResource<ScopedGPointerPolicy>
+class ScopedGPointer : public VcoreDPL::ScopedResource<ScopedGPointerPolicy>
{
typedef ScopedGPointerPolicy Policy;
- typedef DPL::ScopedResource<Policy> BaseType;
+ typedef VcoreDPL::ScopedResource<Policy> BaseType;
public:
explicit ScopedGPointer(typename Policy::Type pointer =
diff --git a/vcore/src/vcore/utils.c b/vcore/src/vcore/utils.c
new file mode 100644
index 0000000..db26653
--- /dev/null
+++ b/vcore/src/vcore/utils.c
@@ -0,0 +1,156 @@
+#include <cert-service.h>
+#include <cert-service-debug.h>
+#include <cert-svc/cerror.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils.h"
+
+void _copy_field(const unsigned char *in, unsigned char **out)
+{
+ size_t in_len = strlen((const char *)(in));
+
+ *out = (unsigned char *)malloc(sizeof(unsigned char) * (in_len + 1));
+ if (!(*out)) {
+ LOGE("Failed to allocate memory.");
+ return;
+ }
+
+ memcpy(*out, in, in_len + 1);
+}
+
+char *get_complete_path(const char *str1, const char *str2)
+{
+ size_t str1_len = strlen(str1);
+ char *result = NULL;
+ int as_result;
+
+ if (str1[str1_len - 1] != '/')
+ as_result = asprintf(&result, "%s/%s", str1, str2);
+ else
+ as_result = asprintf(&result, "%s%s", str1, str2);
+
+ if (as_result < 0)
+ return NULL;
+
+ return result;
+}
+
+
+int get_common_name(const char *path, struct x509_st *x509Struct, char **commonName)
+{
+ int result = CERTSVC_SUCCESS;
+ const unsigned char* data = NULL;
+ CERT_CONTEXT* context = NULL;
+ unsigned char *_commonName = NULL;
+ unsigned char *tmpSubjectStr = NULL;
+ cert_svc_name_fld_data *certFieldData = NULL;
+
+ if (!path && !x509Struct) {
+ LOGE("Invalid input parameter.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ /* If x509Struct is empty, we need to read the certificate and construct the x509 structure */
+ if (!x509Struct) {
+ context = cert_svc_cert_context_init();
+ if (!context) {
+ LOGE("Failed to allocate memory.");
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ result = cert_svc_load_file_to_context(context, path);
+ if (result != CERT_SVC_ERR_NO_ERROR) {
+ LOGE("Failed to load file into context.");
+ result = CERTSVC_FAIL;
+ goto err;
+ }
+
+ if (!context->certBuf || !context->certBuf->data) {
+ LOGE("Empty certificate buffer.");
+ result = CERTSVC_FAIL;
+ goto err;
+ }
+
+ data = context->certBuf->data;
+ d2i_X509(&x509Struct, &data, context->certBuf->size);
+
+ if (!x509Struct) {
+ LOGE("[ERR][%s] Fail to construct X509 structure.", __func__);
+ result = CERT_SVC_ERR_INVALID_CERTIFICATE;
+ goto err;
+ }
+ }
+
+ /* At this point we assume that we have the x509Struct filled with information */
+ tmpSubjectStr = (unsigned char *)X509_NAME_oneline((x509Struct->cert_info->subject), NULL, 0);
+ if (!tmpSubjectStr) {
+ LOGE("[ERR][%s] Fail to parse certificate.", __func__);
+ result = CERTSVC_FAIL;
+ goto err;
+ }
+
+ certFieldData = (cert_svc_name_fld_data *)malloc(sizeof(cert_svc_name_fld_data));
+ if (!certFieldData) {
+ LOGE("Failed to allocate memory.");
+ result = CERTSVC_BAD_ALLOC;
+ goto err;
+ }
+
+ certFieldData->commonName = NULL;
+ certFieldData->organizationName = NULL;
+ certFieldData->organizationUnitName = NULL;
+ certFieldData->emailAddress = NULL;
+
+ result = cert_svc_util_parse_name_fld_data(tmpSubjectStr, certFieldData);
+ if (result != CERT_SVC_ERR_NO_ERROR) {
+ LOGE("[ERR][%s] Fail to parse cert_svc_name_fld_data.", __func__);
+ result = CERTSVC_FAIL;
+ goto err;
+ }
+
+ result = CERTSVC_SUCCESS;
+
+ if (certFieldData->commonName)
+ _copy_field(certFieldData->commonName, &_commonName);
+ else if (certFieldData->organizationName)
+ _copy_field(certFieldData->organizationName, &_commonName);
+ else if (certFieldData->organizationUnitName)
+ _copy_field(certFieldData->organizationUnitName, &_commonName);
+ else if (certFieldData->emailAddress)
+ _copy_field(certFieldData->emailAddress, &_commonName);
+
+ if (!_commonName) {
+ LOGE("Failed to get common name");
+ result = CERTSVC_FAIL;
+ goto err;
+ }
+
+ *commonName = (char *)_commonName;
+ LOGD("Success to get common name for title. commonname[%s]", *commonName);
+
+err:
+ if (x509Struct)
+ X509_free(x509Struct);
+
+ if (context)
+ cert_svc_cert_context_final(context);
+
+ if (tmpSubjectStr)
+ OPENSSL_free(tmpSubjectStr);
+
+ if (certFieldData) {
+ free(certFieldData->countryName);
+ free(certFieldData->localityName);
+ free(certFieldData->stateOrProvinceName);
+ free(certFieldData->organizationName);
+ free(certFieldData->organizationUnitName);
+ free(certFieldData->commonName);
+ free(certFieldData->emailAddress);
+ free(certFieldData);
+ }
+
+ return result;
+}
diff --git a/vcore/src/vcore/utils.h b/vcore/src/vcore/utils.h
new file mode 100644
index 0000000..2752b51
--- /dev/null
+++ b/vcore/src/vcore/utils.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <openssl/x509.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *get_complete_path(const char *str1, const char *str2);
+int get_common_name(const char *path, struct x509_st *x509Struct, char **commonName);
+
+#ifdef __cplusplus
+}
+#endif