From: Dariusz Michaluk Date: Wed, 22 Jan 2020 15:50:52 +0000 (+0100) Subject: Merge branch 'tizen' into yaca X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87b774852b010bd6b01f16ba6972cd19268ba637;hp=dbb976c82c7fdf1b57697826f86d5d501f712ec1;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git Merge branch 'tizen' into yaca Change-Id: I3c62439feb7a3460c01f10c4af072f7a1c64fdd1 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 01ce9fb..26b21d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2015 Samsung Electronics Co., Ltd All Rights Reserved +# Copyright (c) 2012-2020 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. @@ -15,6 +15,7 @@ # @file CMakeLists.txt # @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) # @author Pawel Polawski (p.polawski@partner.samsung.com) +# @author Piotr Sawicki (p.sawicki2@partner.samsung.com) # @brief # @@ -34,7 +35,7 @@ INCLUDE(FindPkgConfig) ############################# compiler flags ################################## SET(CMAKE_C_FLAGS "-g") -SET(CMAKE_CXX_FLAGS "-g -std=c++0x") +SET(CMAKE_CXX_FLAGS "-g -std=c++14") SET(CMAKE_C_FLAGS_PROFILING "-O0 -pg") SET(CMAKE_CXX_FLAGS_PROFILING "-O0 -pg") SET(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb") @@ -64,6 +65,8 @@ IF(BUILD_ALL_TESTS) SET(BUILD_CYNARA ON) SET(BUILD_WEB ON) SET(BUILD_YACA ON) + SET(BUILD_NETHER ON) + SET(BUILD_ODE ON) ENDIF(BUILD_ALL_TESTS) # If supported for the target machine, emit position-independent code,suitable @@ -83,6 +86,7 @@ ADD_DEFINITIONS("-Wextra") # Generate even more extra warni ADD_DEFINITIONS("-Wno-variadic-macros") # Inhibit variadic macros warnings (needed for ORM) ADD_DEFINITIONS("-Wno-deprecated") # No warnings about deprecated features ADD_DEFINITIONS("-Wno-deprecated-declarations") # No warnings about deprecated features +ADD_DEFINITIONS("-Wno-implicit-fallthrough") # No warnings about switc() statements, often done on purpose ADD_DEFINITIONS("-DCYNARA_DB_DIR=\"${CYNARA_DB_DIR}\"") ADD_DEFINITIONS("-DAPP_USER=\"${APP_USER}\"") diff --git a/README b/README index c94a739..ea2b291 100644 --- a/README +++ b/README @@ -15,6 +15,8 @@ security-manager security-manager-tests cynara cynara-test +ode + ode-tests There are also inner-tests for testing complex security-tests framework mechanisms with binary: diff --git a/packaging/security-tests.spec b/packaging/security-tests.spec index 9809e03..76d554c 100644 --- a/packaging/security-tests.spec +++ b/packaging/security-tests.spec @@ -16,6 +16,7 @@ BuildRequires: pkgconfig(key-manager) BuildRequires: key-manager-initial-values BuildRequires: util-linux BuildRequires: pkgconfig(yaca) +BuildRequires: pkgconfig(ode) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(dbus-1) @@ -23,7 +24,7 @@ BuildRequires: pkgconfig(libpcrecpp) BuildRequires: pkgconfig(libxml-2.0) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(libwebappenc) -BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(openssl1.1) BuildRequires: cynara-devel BuildRequires: libcynara-creds-dbus-devel BuildRequires: libcynara-creds-gdbus-devel @@ -34,9 +35,12 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(libgum) >= 1.0.5 BuildRequires: pkgconfig(security-privilege-manager) BuildRequires: pkgconfig(libsystemd) +BuildRequires: openssl1.1 Requires: perf Requires: gdb Requires: diffutils +Requires: iproute2 +Requires: toybox-symlinks-ping %global ckm_test_dir %{?TZ_SYS_SHARE:%TZ_SYS_SHARE/ckm-test/}%{!?TZ_SYS_SHARE:/usr/share/ckm-test/} %global ckm_rw_data_dir %{?TZ_SYS_DATA:%TZ_SYS_DATA/ckm/}%{!?TZ_SYS_DATA:/opt/data/ckm/} @@ -52,6 +56,9 @@ Security tests repository - for tests that can't be kept together with code. export LDFLAGS+="-Wl,--rpath=%{_prefix}/lib" cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \ +%if "%{_with_emulator}" == "1" + -DEMULATOR="ON" \ +%endif %if %{tz_backend_enabled} == ON -DTZ_BACKEND="ON" \ %endif @@ -92,6 +99,10 @@ echo "security-tests postinst done ..." /usr/bin/security-tests.sh /usr/bin/security-tests-all.sh /usr/bin/test-performance-check.sh +/usr/bin/setup-nether-tests-nns.sh +/usr/bin/teardown-nether-tests-nns.sh +/usr/bin/setup-nether-tests-dns.sh +/usr/bin/teardown-nether-tests-dns.sh /etc/dbus-1/system.d/security-tests.conf @@ -110,6 +121,8 @@ echo "security-tests postinst done ..." %caps(cap_mac_admin=ep) /usr/bin/ckm-privileged-tests %caps(cap_mac_admin=ep) /usr/bin/ckm-integration-tests /usr/bin/yaca-test +/usr/bin/nether-tests +/usr/bin/ode-tests %{ckm_test_dir}/* /etc/security-tests /usr/lib/security-tests/cynara-tests/plugins/single-policy/* diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 471c28e..aadbe67 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved +# Copyright (c) 2011-2017 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. @@ -110,3 +110,11 @@ ENDIF(BUILD_WEB) IF(BUILD_YACA) ADD_SUBDIRECTORY(yaca) ENDIF(BUILD_YACA) + +IF(BUILD_NETHER) + ADD_SUBDIRECTORY(nether-tests) +ENDIF(BUILD_NETHER) + +IF(BUILD_ODE) + ADD_SUBDIRECTORY(ode) +ENDIF(BUILD_ODE) diff --git a/src/ckm/CMakeLists.txt b/src/ckm/CMakeLists.txt index 7a13769..97f1239 100644 --- a/src/ckm/CMakeLists.txt +++ b/src/ckm/CMakeLists.txt @@ -29,6 +29,10 @@ ENDIF (DEFINED SECURITY_MDFPP_STATE_ENABLED) ADD_DEFINITIONS("-DCKM_TEST_DIR=\"${CKM_TEST_DIR}\"") ADD_DEFINITIONS("-DCKM_RW_DATA_DIR=\"${CKM_RW_DATA_DIR}\"") +OPTION("TZ_BACKEND" OFF) +IF(TZ_BACKEND) + ADD_DEFINITIONS("-DTZ_BACKEND") +ENDIF(TZ_BACKEND) OPTION("TZ_BACKEND" OFF) IF(TZ_BACKEND) @@ -37,7 +41,7 @@ ENDIF(TZ_BACKEND) PKG_CHECK_MODULES(CKM_TEST_COMMON_DEP REQUIRED - openssl + openssl1.1 key-manager libtzplatform-config ) diff --git a/src/ckm/keys/pkcs12.tgz b/src/ckm/keys/pkcs12.tgz deleted file mode 100644 index 0dfe5e2..0000000 Binary files a/src/ckm/keys/pkcs12.tgz and /dev/null differ diff --git a/src/ckm/keys/pkcs12/HOWTO.txt b/src/ckm/keys/pkcs12/HOWTO.txt new file mode 100644 index 0000000..b1af637 --- /dev/null +++ b/src/ckm/keys/pkcs12/HOWTO.txt @@ -0,0 +1,131 @@ +This guideline explains how src/resource/pkcs.p12 is generated. + + +The certificate chain looks as follows (arrow denotes the signing): + +SERVER <-- CA_INT <-- CA + +That is the CA is a root CA, CA_INT is an intermediate/1st level CA, +and SERVER is a final/2nd level CA. + + +Files: +- ca.key, CA's private key used to sign CA_INT certificate +- ca.crt, CA's certificate used to verify a certificate chain (it's + the last certificate in the chain) +- ca-int.key, CA_INT's private key used to sign SERVER certificate +- ca-int.csr, CA_INT's certificate signing request (to be signed with + ca.key) +- ca-int.crt, CA_INT's certificate signed by CA +- server.key, SERVER's private key used to sign client certificates +- server.csr, SERVER's certificate signing request (to be signed with + ca-int.key) +- server.crt, SERVER's certificate signed by CA_INT +- chain.pem, chain of CA, CA_INT and SERVER certificates in PEM format + (can be used for validation) + + +Keys should be left untouched. In case they are lost they can be +regenerated with: + + openssl genrsa -out ca.key 1024 (or any other lenght) + + +Certificate signing requests + + Each certificate must have a different Common Name (CN). The command + for CSR generation will prompt you for it (and for other fields). + + +Openssl ca setup + + Openssl 1.1.1 requires root and intermediate CA certficates (that is + all 3 of above) to have a 'CA' set to 'true' in basicConstraints + extension. It applies to trusted certificates as well. The 'openssl + ca' tool allows that with proper configuration. Modifications in + /etc/ssl/openssl.cnf in [ CA_default ] section: + - set 'x509_extensions' to 'v3_ca' to add the v3 CA extension, + - set 'policy' to 'policy_anything' to get rid of strict CSR field + matching rules. + + Before 'openssl ca' can be used you have to provide a proper + directory structure for it. By default it needs a following hierarchy + in ./demoCA (paths can be modified in /etc/ssl/openssl.cnf): + - demoCA/ + - private/ + - cakey.pem - The private key used to sign the certificate. For + ca-int.csr it will be ca.key. + - cacert.pem - The certificate of the signing CA. For ca-int.csr it + will be ca.crt. + - index.txt - Empty file (touch index.txt) + - serial - A file with serial number (echo 1000 > serial) + + +Certificate generation + +- CA: + + Generate a self signed certificate (root ca): + + openssl req -key ca.key -new -x509 -days 3650 -sha256 -out ca.crt + +- CA_INT: + + Generate a signing request: + + openssl req -new -key ca.key -out ca-int.csr + + Sign the certificate using CA: + + openssl ca -days 3650 -notext -md sha256 -in ca-int.csr -out \ + ca-int.crt + +- SERVER: + + Generate a signing request: + + openssl req -new -key ca-int.key -out server.csr + + Sign the certificate using CA_INT: + + openssl ca -days 3650 -notext -md sha256 -in server.csr -out \ + server.crt + + +Export server private key, certificate and the rest of the chain to +pkcs12: + + cat ca.crt ca-int.crt > chain.pem + + openssl pkcs12 -export -out pkcs.p12 -inkey server.key -in server.crt \ + -certfile chain.pem + + +Useful commands + +- Display certificate info + + openssl x509 -in ca.crt -text -noout + +- Display csr info + + openssl req -in ca-int.csr -text -noout + +- Display pkcs12 contents in PEM format + + openssl pkcs12 -in pkcs.p12 -info + +- Display certificate purpose + + openssl x509 -in ca.crt -purpose + +- Sign a client's certificate with server one: + + openssl req -new -key server.key -out client.csr + openssl x509 -req -in client.csr -CA server.crt -CAkey server.key \ + -CAcreateserial -out client.crt -days 3650 + +- Verify a certficate against a local chain + + openssl verify -CAfile chain.pem client.crt + diff --git a/src/ckm/keys/pkcs12/ca-int.crt b/src/ckm/keys/pkcs12/ca-int.crt new file mode 100644 index 0000000..dea0763 --- /dev/null +++ b/src/ckm/keys/pkcs12/ca-int.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAiCgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYsxCzAJBgNVBAYTAlBM +MQ8wDQYDVQQIDAZQb2xhbmQxDzANBgNVBAcMBldhcnNhdzEQMA4GA1UECgwHU2Ft +c3VuZzEMMAoGA1UECwwDS1NGMRMwEQYDVQQDDAptLmthcnBpdWsyMSUwIwYJKoZI +hvcNAQkBFhZtLmthcnBpdWsyQHNhbXN1bmcuY29tMB4XDTE5MDYxMzExNTQ0OFoX +DTI5MDYxMDExNTQ0OFowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3Rh +dGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwR +Y2EtaW50QHRlc3RtZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOEp +AxNNreF+HPTPznNdeUpcwXfJf5sDjfC9p648jDbiwu8fyEpWQyg1XnhoGc3ZST7o +u3c3oJq89rw5L8c4vxG6QHXE3NHzZOFpvu+tpyIcfoToBRUiKEmpt60SmixA9VVX +C9pUGRyUnjDI4Wuv2ZNw04lYgIGE9jdSMA+dSKYfAgMBAAGjUzBRMB0GA1UdDgQW +BBSvHyNEVaNf2+iZ79oCpVmniojtLzAfBgNVHSMEGDAWgBSIkmgdQrVdA6+R4OHY +kc1mlXOu7jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAEo7oCMW +gApPBjArw/AyPWw4vxLH6U7/kxJFThVu5b1/6bwEpE8hHK9FRuCZKw1ydegyuuO8 +7JgshhHGBlDECa3INdshCk2xi02SDjWZhxJU8r0eIrji2PxqBI3fEpF2067K2DUS +vA1tUP253JYcln+xHxbZDUtzaoXM7LmN9tWx +-----END CERTIFICATE----- diff --git a/src/ckm/keys/pkcs12/ca-int.csr b/src/ckm/keys/pkcs12/ca-int.csr new file mode 100644 index 0000000..ecd6d3e --- /dev/null +++ b/src/ckm/keys/pkcs12/ca-int.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBoTCCAQoCAQAwYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx +ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRY2Et +aW50QHRlc3RtZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOEpAxNN +reF+HPTPznNdeUpcwXfJf5sDjfC9p648jDbiwu8fyEpWQyg1XnhoGc3ZST7ou3c3 +oJq89rw5L8c4vxG6QHXE3NHzZOFpvu+tpyIcfoToBRUiKEmpt60SmixA9VVXC9pU +GRyUnjDI4Wuv2ZNw04lYgIGE9jdSMA+dSKYfAgMBAAGgADANBgkqhkiG9w0BAQsF +AAOBgQC8b7cVVV4z5Bp/XxowzlfhMGL17EE2vgMwpCNNQ+fOpPrrEwmhyg0I4R5+ +iXrnxELVI/cqBUpS84ZHBlNgQAS8F9Wx6AU0yEUBcNqJiMjUreA56VZAfGb+/Sv+ +t6ZQrYtof38aaHfMxhYlCsZzuKGNWvQsLAgxvlBQgHEW9xsqHQ== +-----END CERTIFICATE REQUEST----- diff --git a/src/ckm/keys/pkcs12/ca-int.key b/src/ckm/keys/pkcs12/ca-int.key new file mode 100644 index 0000000..0b3b26e --- /dev/null +++ b/src/ckm/keys/pkcs12/ca-int.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXwIBAAKBgQDhKQMTTa3hfhz0z85zXXlKXMF3yX+bA43wvaeuPIw24sLvH8hK +VkMoNV54aBnN2Uk+6Lt3N6CavPa8OS/HOL8RukB1xNzR82Thab7vraciHH6E6AUV +IihJqbetEposQPVVVwvaVBkclJ4wyOFrr9mTcNOJWICBhPY3UjAPnUimHwIDAQAB +AoGBAMvEP+JCVHBTn4T2Y5IIL/JaS0RK+M6iwtvx50RJy2MIiP27N5n+wzwqQFqb +a27di+oA2Vck4pXnGSxyXIjhFBgWdLmryJM44DSVlWanb5n2A1GW291MGA8bGR/H +TCbsuaEm3Z2ggFighQAp2Zuao2lKuMDOgOzpu+0k7lqtfsqxAkEA8ZHC7ocrlRtM +EzafCi1htuwl9t02Do1q+wn8u5kbKPJ7q4ZNm/sUECfHBE7SbwxNxIEWKuZ5U8V4 +A42VPnO9gwJBAO6cT4IdILqxfxNPd97DY+rT64O/mPIJGC3cmDonf4kc+RuaqbT+ +D9WKp1cwmoeaJDrWbWFWi3cjBrrLd6JxzjUCQQC7s8Heq6Mesd4z065SLx8NDoMV +RZ+aQSJOO91oOzhSYc/cYHfvanGVeAL5AvIaHVpUBOWfogPGJtrxD9NWeoJXAkEA +n4CLwZ15AHOgT6dCqP2R8Crjd3l/YuPjbtzUQaOfpGdiuiokIaHnscZy4FzUH6tR +ZqdqDLROnEAkwn86pLNQtQJBAOAsXPLUpVuJEtPZB1CNLdFkRqkqgFNPnGSIUnTp ++f5H8AHCb1tX/QllL3s6phZ9qds0qrwNxQzgiVATXZyRov4= +-----END RSA PRIVATE KEY----- diff --git a/src/ckm/keys/pkcs12/ca.crt b/src/ckm/keys/pkcs12/ca.crt new file mode 100644 index 0000000..301187d --- /dev/null +++ b/src/ckm/keys/pkcs12/ca.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAk+gAwIBAgIJAOMDgLjsxef2MA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD +VQQGEwJQTDEPMA0GA1UECAwGUG9sYW5kMQ8wDQYDVQQHDAZXYXJzYXcxEDAOBgNV +BAoMB1NhbXN1bmcxDDAKBgNVBAsMA0tTRjETMBEGA1UEAwwKbS5rYXJwaXVrMjEl +MCMGCSqGSIb3DQEJARYWbS5rYXJwaXVrMkBzYW1zdW5nLmNvbTAeFw0xNDExMTMx +MTExNDFaFw0yNDExMTAxMTExNDFaMIGLMQswCQYDVQQGEwJQTDEPMA0GA1UECAwG +UG9sYW5kMQ8wDQYDVQQHDAZXYXJzYXcxEDAOBgNVBAoMB1NhbXN1bmcxDDAKBgNV +BAsMA0tTRjETMBEGA1UEAwwKbS5rYXJwaXVrMjElMCMGCSqGSIb3DQEJARYWbS5r +YXJwaXVrMkBzYW1zdW5nLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +9VvZ3lG1y9a56vUr8s6a44VgSl8mCkIqxt1ds8lJ1GhNuEqtiL+yEq8DDfxulnI6 +xpnmQxFsKy+M14dNNjfAQ9cGiT0aJ8cLVZIRct3phmrUpse3iHpcuR/jwTSJkbwY +druBloGujhF3FDXX2gVHMZ/j+uePP86Q4cjS80CpORcCAwEAAaNQME4wHQYDVR0O +BBYEFIiSaB1CtV0Dr5Hg4diRzWaVc67uMB8GA1UdIwQYMBaAFIiSaB1CtV0Dr5Hg +4diRzWaVc67uMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAXTvQ6fhZ +SZhfd1DsNx+85ikyvPnSAffOWghJjJA2BMaHdKvoSJTHgBn29BmQSz0kSUM4GOM3 +ikD3aSEaqGJWXVUXxAx8vTe8qFfqr9RE0WsBmPPuWa2fwUaq2ttW5Je4UBs/9jiA +2UqgKbtqxvacHpGFoM86QxgV+52AA+Bwfzw= +-----END CERTIFICATE----- diff --git a/src/ckm/keys/pkcs12/ca.key b/src/ckm/keys/pkcs12/ca.key new file mode 100644 index 0000000..234a51a --- /dev/null +++ b/src/ckm/keys/pkcs12/ca.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQD1W9neUbXL1rnq9SvyzprjhWBKXyYKQirG3V2zyUnUaE24Sq2I +v7ISrwMN/G6WcjrGmeZDEWwrL4zXh002N8BD1waJPRonxwtVkhFy3emGatSmx7eI +ely5H+PBNImRvBh2u4GWga6OEXcUNdfaBUcxn+P6548/zpDhyNLzQKk5FwIDAQAB +AoGAR+4WkBuqTUj1FlGsAbHaLKt0UDlWwJknS0eoacWwFEpDxqx19WolfV67aYVA +snBolMKXg7/+0yZMhv8Ofr+XaHkPQplVVn9BwT0rmtEovJXwx+poRP9Bm3emglj/ +iYd8EkaXDlIXCtewtQW9JEIctWppntHj3TvA/h7FCXPN6SkCQQD/N7sn5S1gBkVh +dyXQKoyKsZDb7hMIS1q6cKwYCMf2UrsD1/lnr7xXkvORdL213MfueO8g0WkuKfRY +bDD6WGX1AkEA9hxiOlsgvermqLJkOlJffbSaM8n/6wtnM0HV+Vd9NfSBOmxFDXPO +vrvdgiDPENhbqTJSQVDsfzHilTpK7lEvWwJBAJLxHoOg0tg3pBiyxgWtic+M3q+R +ykl7QViY6KzJ2X98MIrM/Z7yMollZXE4+sVLwZ0O6fdGOr3GkBWc7TImVUUCQQC7 +pf6bQfof9Ce0fnf/I+ldHkPost7nJsWkBlGQkM2OQwP5OK4ZyK/dK76DxmI7FMwm +oJCo7nuzq6R4ZX7WYJ47AkBavxBDo/e9/0Vk5yrloGKW3f8RQXBJLcCkVUGyyJ3D +3gu/nafW4hzjSJniTjC1fOj0eb0OSg1JAvqHTYAnUsI7 +-----END RSA PRIVATE KEY----- diff --git a/src/ckm/keys/pkcs12/chain.pem b/src/ckm/keys/pkcs12/chain.pem new file mode 100644 index 0000000..b4b75e6 --- /dev/null +++ b/src/ckm/keys/pkcs12/chain.pem @@ -0,0 +1,51 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAk+gAwIBAgIJAOMDgLjsxef2MA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD +VQQGEwJQTDEPMA0GA1UECAwGUG9sYW5kMQ8wDQYDVQQHDAZXYXJzYXcxEDAOBgNV +BAoMB1NhbXN1bmcxDDAKBgNVBAsMA0tTRjETMBEGA1UEAwwKbS5rYXJwaXVrMjEl +MCMGCSqGSIb3DQEJARYWbS5rYXJwaXVrMkBzYW1zdW5nLmNvbTAeFw0xNDExMTMx +MTExNDFaFw0yNDExMTAxMTExNDFaMIGLMQswCQYDVQQGEwJQTDEPMA0GA1UECAwG +UG9sYW5kMQ8wDQYDVQQHDAZXYXJzYXcxEDAOBgNVBAoMB1NhbXN1bmcxDDAKBgNV +BAsMA0tTRjETMBEGA1UEAwwKbS5rYXJwaXVrMjElMCMGCSqGSIb3DQEJARYWbS5r +YXJwaXVrMkBzYW1zdW5nLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +9VvZ3lG1y9a56vUr8s6a44VgSl8mCkIqxt1ds8lJ1GhNuEqtiL+yEq8DDfxulnI6 +xpnmQxFsKy+M14dNNjfAQ9cGiT0aJ8cLVZIRct3phmrUpse3iHpcuR/jwTSJkbwY +druBloGujhF3FDXX2gVHMZ/j+uePP86Q4cjS80CpORcCAwEAAaNQME4wHQYDVR0O +BBYEFIiSaB1CtV0Dr5Hg4diRzWaVc67uMB8GA1UdIwQYMBaAFIiSaB1CtV0Dr5Hg +4diRzWaVc67uMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAXTvQ6fhZ +SZhfd1DsNx+85ikyvPnSAffOWghJjJA2BMaHdKvoSJTHgBn29BmQSz0kSUM4GOM3 +ikD3aSEaqGJWXVUXxAx8vTe8qFfqr9RE0WsBmPPuWa2fwUaq2ttW5Je4UBs/9jiA +2UqgKbtqxvacHpGFoM86QxgV+52AA+Bwfzw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICtzCCAiCgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwgYsxCzAJBgNVBAYTAlBM +MQ8wDQYDVQQIDAZQb2xhbmQxDzANBgNVBAcMBldhcnNhdzEQMA4GA1UECgwHU2Ft +c3VuZzEMMAoGA1UECwwDS1NGMRMwEQYDVQQDDAptLmthcnBpdWsyMSUwIwYJKoZI +hvcNAQkBFhZtLmthcnBpdWsyQHNhbXN1bmcuY29tMB4XDTE5MDYxMzExNTQ0OFoX +DTI5MDYxMDExNTQ0OFowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3Rh +dGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwR +Y2EtaW50QHRlc3RtZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOEp +AxNNreF+HPTPznNdeUpcwXfJf5sDjfC9p648jDbiwu8fyEpWQyg1XnhoGc3ZST7o +u3c3oJq89rw5L8c4vxG6QHXE3NHzZOFpvu+tpyIcfoToBRUiKEmpt60SmixA9VVX +C9pUGRyUnjDI4Wuv2ZNw04lYgIGE9jdSMA+dSKYfAgMBAAGjUzBRMB0GA1UdDgQW +BBSvHyNEVaNf2+iZ79oCpVmniojtLzAfBgNVHSMEGDAWgBSIkmgdQrVdA6+R4OHY +kc1mlXOu7jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAEo7oCMW +gApPBjArw/AyPWw4vxLH6U7/kxJFThVu5b1/6bwEpE8hHK9FRuCZKw1ydegyuuO8 +7JgshhHGBlDECa3INdshCk2xi02SDjWZhxJU8r0eIrji2PxqBI3fEpF2067K2DUS +vA1tUP253JYcln+xHxbZDUtzaoXM7LmN9tWx +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjDCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwYTELMAkGA1UEBhMCQVUx +EzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEaMBgGA1UEAwwRY2EtaW50QHRlc3RtZS5jb20wHhcNMTkwNjEzMTIw +NzU5WhcNMjkwNjEwMTIwNzU5WjBhMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29t +ZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRowGAYD +VQQDDBFzZXJ2ZXJAdGVzdG1lLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAw4Jj7q00Gt8G55TPvZwhEL4Q74mEb0gvUy+ZQDAQpgUpfd79FAV1rKjvn5gC +DZuUCWvPYReTe0OMbb30iVDyHss6MEzhBjOFNxZybZbDULKDWxZTckC6GWZpmOJY +xuv2Kl/iRgYEvfyfLr2g1pL7PpLZDkcoHzc+BouQxEU+3nkCAwEAAaNTMFEwHQYD +VR0OBBYEFE8OYEtgOx9klZOaDcNJF6nkfeE6MB8GA1UdIwQYMBaAFK8fI0RVo1/b +6Jnv2gKlWaeKiO0vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEA +pkpwMYqyEFl1fPGHbub4ieDxm9U+KSkMOoB3pB5atqvP4LJj7sGQL6qnRYiL5er3 +cyBaIQdKt/NqWR4LKrLGPsfIbtDesRAP8HfG5ZfxiRr4Z4PhdMzO4XVSihuoGUoh +DfQkQRjWw60PKpc9uQypCcHY5yWu/b+lPL5ydXKyU5o= +-----END CERTIFICATE----- diff --git a/src/ckm/keys/pkcs12/server.crt b/src/ckm/keys/pkcs12/server.crt new file mode 100644 index 0000000..40b6b69 --- /dev/null +++ b/src/ckm/keys/pkcs12/server.crt @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICjDCCAfWgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwYTELMAkGA1UEBhMCQVUx +EzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEaMBgGA1UEAwwRY2EtaW50QHRlc3RtZS5jb20wHhcNMTkwNjEzMTIw +NzU5WhcNMjkwNjEwMTIwNzU5WjBhMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29t +ZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRowGAYD +VQQDDBFzZXJ2ZXJAdGVzdG1lLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +gYEAw4Jj7q00Gt8G55TPvZwhEL4Q74mEb0gvUy+ZQDAQpgUpfd79FAV1rKjvn5gC +DZuUCWvPYReTe0OMbb30iVDyHss6MEzhBjOFNxZybZbDULKDWxZTckC6GWZpmOJY +xuv2Kl/iRgYEvfyfLr2g1pL7PpLZDkcoHzc+BouQxEU+3nkCAwEAAaNTMFEwHQYD +VR0OBBYEFE8OYEtgOx9klZOaDcNJF6nkfeE6MB8GA1UdIwQYMBaAFK8fI0RVo1/b +6Jnv2gKlWaeKiO0vMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEA +pkpwMYqyEFl1fPGHbub4ieDxm9U+KSkMOoB3pB5atqvP4LJj7sGQL6qnRYiL5er3 +cyBaIQdKt/NqWR4LKrLGPsfIbtDesRAP8HfG5ZfxiRr4Z4PhdMzO4XVSihuoGUoh +DfQkQRjWw60PKpc9uQypCcHY5yWu/b+lPL5ydXKyU5o= +-----END CERTIFICATE----- diff --git a/src/ckm/keys/pkcs12/server.csr b/src/ckm/keys/pkcs12/server.csr new file mode 100644 index 0000000..11fc7f9 --- /dev/null +++ b/src/ckm/keys/pkcs12/server.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBoTCCAQoCAQAwYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx +ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vy +dmVyQHRlc3RtZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMOCY+6t +NBrfBueUz72cIRC+EO+JhG9IL1MvmUAwEKYFKX3e/RQFdayo75+YAg2blAlrz2EX +k3tDjG299IlQ8h7LOjBM4QYzhTcWcm2Ww1Cyg1sWU3JAuhlmaZjiWMbr9ipf4kYG +BL38ny69oNaS+z6S2Q5HKB83PgaLkMRFPt55AgMBAAGgADANBgkqhkiG9w0BAQsF +AAOBgQCY3jWaE33hy1JVni9bLCUYwOz6VJVV8d1WWpSf7CpIgrXUQFPOIfO71jlf +Vn99iYCUIodq+9M9dyeNoU1mkAp2LpG3Y3DjePpIyM3zLLEM/CmQ9ZbuS/zKl5fO +KoItsRl0uFJEEEHw7lWxdRuIvzix5SFxTApiMPktjtCs/9eAew== +-----END CERTIFICATE REQUEST----- diff --git a/src/ckm/keys/pkcs12/server.key b/src/ckm/keys/pkcs12/server.key new file mode 100644 index 0000000..a1197d7 --- /dev/null +++ b/src/ckm/keys/pkcs12/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDDgmPurTQa3wbnlM+9nCEQvhDviYRvSC9TL5lAMBCmBSl93v0U +BXWsqO+fmAINm5QJa89hF5N7Q4xtvfSJUPIeyzowTOEGM4U3FnJtlsNQsoNbFlNy +QLoZZmmY4ljG6/YqX+JGBgS9/J8uvaDWkvs+ktkORygfNz4Gi5DERT7eeQIDAQAB +AoGAARIqx/js6yTDnesjxC8hwzy3TQic0Bs+Hx+IoGBjBvXKR2U8T6rD/UEjpuUn +RbnPcsnDZg3CAg/ZqhQ7TbFC0kPo+S6+wKsZGDWUUvnpMkdcZUqXel8GFhdnmeIh +22vYthP4TCbolxwXlwvuhu0PLZWhRO/Z+g37T3QENexqGv0CQQDmqJ9PDoUj5eUR +wWEqEPraoU6ARBUUX5EhmTT9g9/BXnhwumIOksDHcBqNUwNOlKCUlWfBOelO93Ys +PRW3QyejAkEA2P0tW/8iU4j+0a6DV+TUYFDTjD29y8KPw0Aj59591xD5eIPK3IgU +91vnmtvU/QR26PnMOx4OAPk9a7BtN62zMwJAIFV0950edtjMUr/cAgydTbadDYf9 +uHxpGN+kOQGahT3b/llyU36o/YwufK8tYH+fPxTulXyrwwEXlL3/ZFBKpwJAeLGS +Wlp2WGqZ+j2MdwYkDxLGKHprKHwnBN6XWjCKZGbfrGX6H2Jd7xyinaNrO/UQwxO2 +wqc7+NSpkk3G4jJuuwJAODYlk2Q+djE4jkjDc4xiqsQGBQlI2dlgzjRjIF4HWiLx +bIrI0uCCbGItx++hlvmDx7G8anBmIFfBWIaKdX0aWw== +-----END RSA PRIVATE KEY----- diff --git a/src/ckm/privileged/CMakeLists.txt b/src/ckm/privileged/CMakeLists.txt index c83e5b2..705562c 100644 --- a/src/ckm/privileged/CMakeLists.txt +++ b/src/ckm/privileged/CMakeLists.txt @@ -26,6 +26,9 @@ SET(EIV_KEY_TO_BE_IMPORTED "KeyOne16BytesLen") SET(EIV_PLAIN_MESSAGE "ShortTestMessage") SET(EIV_MESSAGE_ENCRYPTION_IV "abcdefghijklmnop") +SET(EIV_TEST_ASYM_XML_FILENAME "encrypted_initial_values_asym.xml") +SET(EIV_TEST_ASYM_XML ${CMAKE_CURRENT_SOURCE_DIR}/${EIV_TEST_ASYM_XML_FILENAME}) + # encrypt ShortTestMessage using the imported key and 'abcdefghijklmnop' IV EXECUTE_PROCESS( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/aes_128_cbc_encrypt.sh ${EIV_KEY_TO_BE_IMPORTED} ${EIV_MESSAGE_ENCRYPTION_IV} @@ -38,18 +41,39 @@ IF(NOT ${EIV_ENCRYPTION_RESULT} STREQUAL "0") MESSAGE(FATAL_ERROR "Encryption failed: ${EIV_ENCRYPTION_STDERR}") ENDIF(NOT ${EIV_ENCRYPTION_RESULT} STREQUAL "0") +SET(EIV_FILES ${EIV_TEST_XML} ${EIV_TEST_ASYM_XML}) + # prepare initial values xml target -ADD_CUSTOM_COMMAND(OUTPUT ${EIV_TEST_XML} - COMMAND echo -n ${EIV_KEY_TO_BE_IMPORTED} > /tmp/key +ADD_CUSTOM_COMMAND(OUTPUT ${EIV_FILES} COMMAND echo -n THIS/STRING/MUST/BE/REPLACED/IN/REAL/DEVICE= | base64 --decode > /tmp/encryption_key - COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/key -k /tmp/encryption_key -n TEI_0 -t Key -s AES -b hardware -x ${EIV_TEST_XML} + + COMMAND echo -n ${EIV_KEY_TO_BE_IMPORTED} > /tmp/key + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/key -k /tmp/encryption_key -n TEI_0 -t Key -s AES -b hardware > ${EIV_TEST_XML} + + COMMAND openssl genpkey -algorithm RSA -outform DER > /tmp/prvkey + COMMAND openssl rsa -in /tmp/prvkey -inform DER -pubout -outform DER > /tmp/pubkey + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/prvkey -k /tmp/encryption_key -n TEI_RSA_PRV -t Key -s RSA_PRV > ${EIV_TEST_ASYM_XML} + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/pubkey -k /tmp/encryption_key -n TEI_RSA_PUB -t Key -s RSA_PUB -x ${EIV_TEST_ASYM_XML} + + COMMAND openssl genpkey -algorithm RSA -outform PEM > /tmp/prvkey.pem + COMMAND openssl pkcs8 -topk8 -inform PEM -in /tmp/prvkey.pem -outform DER -nocrypt -out /tmp/prvkey + COMMAND openssl rsa -in /tmp/prvkey -inform DER -pubout -outform DER > /tmp/pubkey + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/prvkey -k /tmp/encryption_key -n TEI_RSA_PKCS8_PRV -t Key -s RSA_PRV -x ${EIV_TEST_ASYM_XML} + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/pubkey -k /tmp/encryption_key -n TEI_RSA_PKCS8_PUB -t Key -s RSA_PUB -x ${EIV_TEST_ASYM_XML} + + COMMAND openssl genpkey -genparam -algorithm DSA -pkeyopt dsa_paramgen_bits:1024 -pkeyopt dsa_paramgen_q_bits:160 > /tmp/params.pem + COMMAND openssl genpkey -paramfile /tmp/params.pem -outform DER > /tmp/prvkey + COMMAND openssl dsa -in /tmp/prvkey -inform DER -pubout -outform DER > /tmp/pubkey + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/prvkey -k /tmp/encryption_key -n TEI_DSA_PRV -t Key -s DSA_PRV -x ${EIV_TEST_ASYM_XML} + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/ckm_initial_values -d /tmp/pubkey -k /tmp/encryption_key -n TEI_DSA_PUB -t Key -s DSA_PUB -x ${EIV_TEST_ASYM_XML} + COMMENT "Generating encrypted initial values test xml" VERBATIM ) -ADD_CUSTOM_TARGET(TARGET_EIV_TEST_XML DEPENDS ${EIV_TEST_XML}) +ADD_CUSTOM_TARGET(TARGET_EIV_TEST_XML DEPENDS ${EIV_FILES}) -INSTALL(FILES ${EIV_TEST_XML} DESTINATION ${CKM_TEST_DIR}) +INSTALL(FILES ${EIV_FILES} DESTINATION ${CKM_TEST_DIR}) # ckm-tests PKG_CHECK_MODULES(CKM_DEP @@ -90,6 +114,7 @@ TARGET_COMPILE_DEFINITIONS(${TARGET_CKM_PRIVILEGED_TESTS} PRIVATE EIV_ENCRYPTED_MESSAGE_HEX="${EIV_ENCRYPTED_MESSAGE_HEX}" PRIVATE EIV_MESSAGE_ENCRYPTION_IV="${EIV_MESSAGE_ENCRYPTION_IV}" PRIVATE EIV_TEST_XML_FILENAME="${EIV_TEST_XML_FILENAME}" + PRIVATE EIV_TEST_ASYM_XML_FILENAME="${EIV_TEST_ASYM_XML_FILENAME}" ) INSTALL(TARGETS ${TARGET_CKM_PRIVILEGED_TESTS} DESTINATION bin) diff --git a/src/ckm/privileged/aes_128_cbc_encrypt.sh b/src/ckm/privileged/aes_128_cbc_encrypt.sh index 69a74ee..baad9a8 100755 --- a/src/ckm/privileged/aes_128_cbc_encrypt.sh +++ b/src/ckm/privileged/aes_128_cbc_encrypt.sh @@ -1,4 +1,5 @@ -#!/bin/bash -e +#!/bin/bash +set -euo pipefail if [ "$#" -ne 2 ] then diff --git a/src/ckm/privileged/capi-access_control.cpp b/src/ckm/privileged/capi-access_control.cpp index f0328ed..db28b1c 100644 --- a/src/ckm/privileged/capi-access_control.cpp +++ b/src/ckm/privileged/capi-access_control.cpp @@ -37,6 +37,16 @@ const char* TEST_ALIAS2 = "test-alias2"; const char* TEST_ALIAS3 = "test-alias3"; const char* TEST_DATA = "dsflsdkghkslhglrtghierhgilrehgidsafasdffsgfdgdgfdgfdgfdgfdggf"; +const char* RSA_PUB_KEY_PEM = + "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2b1bXDa+S8/MGWnMkru4\n" + "T4tUddtZNi0NVjQn9RFH1NMa220GsRhRO56F77FlSVFKfSfVZKIiWg6C+DVCkcLf\n" + "zXJ/Z0pvwOQYBAqVMFjV6efQGN0JzJ1Unu7pPRiZl7RKGEI+cyzzrcDyrLLrQ2W7\n" + "0ZySkNEOv6Frx9JgC5NExuYY4lk2fQQa38JXiZkfyzif2em0px7mXbyf5LjccsKq\n" + "v1e+XLtMsL0ZefRcqsP++NzQAI8fKX7WBT+qK0HJDLiHrKOTWYzx6CwJ66LD/vvf\n" + "j55xtsKDLVDbsotvf8/m6VLMab+vqKk11TP4tq6yo0mwyTADvgl1zowQEO9I1W6o\n" + "zQIDAQAB\n" + "-----END PUBLIC KEY-----"; void allow_access_deprecated(const char* alias, const char* accessor, ckmc_access_right_e accessRights) { @@ -889,3 +899,156 @@ RUNNER_TEST(T3145_control_deprecated_remove_allowed, RemoveDataEnv) check_remove_allowed(aliasWithLabel(APP_LABEL_1, TEST_ALIAS).c_str()); } } + +RUNNER_TEST(utc_ckmc_get_key_alias_info_list_p) +{ + ckmc_alias_info_list_s* ppalias_list = NULL; + + int ret = ckmc_get_key_alias_info_list(&ppalias_list); + ckmc_alias_info_list_all_free(ppalias_list); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_DB_ALIAS_UNKNOWN, "Expected CKMC_ERROR_DB_ALIAS_UNKNOWN, returned: " << CKMCErrorToString(ret)); +} + +RUNNER_TEST(utc_ckmc_get_key_alias_info_list_n) +{ + int ret = ckmc_get_key_alias_info_list(NULL); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_INVALID_PARAMETER, "Expected invalid parameter error, returned: " << CKMCErrorToString(ret)); +} + +RUNNER_TEST(utc_ckmc_get_cert_alias_info_list_p) +{ + ckmc_alias_info_list_s* ppalias_list = NULL; + + int ret = ckmc_get_cert_alias_info_list(&ppalias_list); + ckmc_alias_info_list_all_free(ppalias_list); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_DB_ALIAS_UNKNOWN, "Expected CKMC_ERROR_DB_ALIAS_UNKNOWN, returned: " << CKMCErrorToString(ret)); +} + +RUNNER_TEST(utc_ckmc_get_cert_alias_info_list_n) +{ + int ret = ckmc_get_cert_alias_info_list(NULL); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_INVALID_PARAMETER, "Expected invalid parameter error, returned: " << CKMCErrorToString(ret)); +} + + +RUNNER_TEST(utc_ckmc_get_data_alias_info_list_p1) +{ + ckmc_alias_info_list_s* ppalias_list = NULL; + + int ret = ckmc_get_data_alias_info_list(&ppalias_list); + ckmc_alias_info_list_all_free(ppalias_list); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_DB_ALIAS_UNKNOWN, "Expected CKMC_ERROR_DB_ALIAS_UNKNOWN, returned: " << CKMCErrorToString(ret)); +} + + +RUNNER_TEST(utc_ckmc_get_data_alias_info_list_p2, RemoveDataEnv) +{ + ScopedAccessProvider ap(APP_LABEL_1, APP_1, GROUP_1); + save_data(TEST_ALIAS, TEST_DATA); + + ckmc_alias_info_list_s* ppalias_list = NULL; + + int ret = ckmc_get_data_alias_info_list(&ppalias_list); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, returned: " << CKMCErrorToString(ret)); + + char* alias = NULL; + ret = ckmc_alias_info_get_alias(ppalias_list->info, &alias); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Failed to get alias, returned: " << CKMCErrorToString(ret)); + RUNNER_ASSERT_MSG(ppalias_list->next == NULL, "More elements returned"); + std::string aliasOrig = std::string(APP_LABEL_1) + " " + std::string(TEST_ALIAS); + RUNNER_ASSERT_MSG(strcmp(alias, aliasOrig.c_str()) == 0, "Invalid aliast returned : " << alias); + + ckmc_alias_info_list_all_free(ppalias_list); + +} + + +RUNNER_TEST(utc_ckmc_get_data_alias_info_list_n) +{ + int ret = ckmc_get_data_alias_info_list(NULL); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_INVALID_PARAMETER, "Expected invalid parameter error, returned: " << CKMCErrorToString(ret)); +} + +RUNNER_TEST(utc_ckmc_alias_info_get_alias_p) +{ + ckmc_alias_info_list_s *ppalias_list, *tmp; + ckmc_key_s test_key; + ckmc_policy_s test_policy; + int ret; + char* current_alias; + const char* alias = "utc_ckmc_alias_info_get_alias_p_test_alias"; + bool foundAlias = false; + + test_key.raw_key = (unsigned char *)RSA_PUB_KEY_PEM; + test_key.key_size = strlen(RSA_PUB_KEY_PEM); + test_key.key_type = CKMC_KEY_RSA_PUBLIC; + test_key.password = NULL; + + test_policy.password = NULL; + test_policy.extractable = true; + + ret = ckmc_save_key(alias, test_key, test_policy); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, got " << CKMCErrorToString(ret)); + + ret = ckmc_get_key_alias_info_list(&ppalias_list); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, got " << CKMCErrorToString(ret)); + + tmp = ppalias_list; + + while (tmp) { + ret = ckmc_alias_info_get_alias(tmp->info, ¤t_alias); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, got " << CKMCErrorToString(ret)); + if (strstr(current_alias, alias)) { + foundAlias = true; + break; + } + tmp = tmp->next; + } + ckmc_alias_info_list_all_free(ppalias_list); + ckmc_remove_key(alias); + RUNNER_ASSERT_MSG(foundAlias == true, "Expected to find alias, but alias not found"); +} + +RUNNER_TEST(utc_ckmc_alias_info_is_password_protected_p) +{ + ckmc_alias_info_list_s *ppalias_list, *tmp; + ckmc_key_s test_key; + ckmc_policy_s test_policy; + int ret; + char* current_alias; + const char* alias = "utc_ckmc_alias_info_get_alias_p_test_alias"; + bool foundAlias = false; + + test_key.raw_key = (unsigned char *)RSA_PUB_KEY_PEM; + test_key.key_size = strlen(RSA_PUB_KEY_PEM); + test_key.key_type = CKMC_KEY_RSA_PUBLIC; + test_key.password = NULL; + + test_policy.password = NULL; + test_policy.extractable = true; + + ret = ckmc_save_key(alias, test_key, test_policy); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, got " << CKMCErrorToString(ret)); + + ret = ckmc_get_key_alias_info_list(&ppalias_list); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, got " << CKMCErrorToString(ret)); + + tmp = ppalias_list; + + while (tmp) { + ret = ckmc_alias_info_get_alias(tmp->info, ¤t_alias); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, got " << CKMCErrorToString(ret)); + if (strstr(current_alias, alias)) { + foundAlias = true; + bool is_password_protected; + ret = ckmc_alias_info_is_password_protected(tmp->info, &is_password_protected); + RUNNER_ASSERT_MSG(ret == CKMC_ERROR_NONE, "Expected no error, got " << CKMCErrorToString(ret)); + RUNNER_ASSERT(is_password_protected == false); + break; + } + tmp = tmp->next; + } + ckmc_alias_info_list_all_free(ppalias_list); + ckmc_remove_key(alias); + RUNNER_ASSERT(foundAlias == true); +} diff --git a/src/ckm/privileged/initial-values.cpp b/src/ckm/privileged/initial-values.cpp index ab3629b..e8988de 100644 --- a/src/ckm/privileged/initial-values.cpp +++ b/src/ckm/privileged/initial-values.cpp @@ -63,40 +63,36 @@ std::string XML_3_EXPECTED_KEY_2_RSA = aliasWithLabel(ckmc_owner_id_system, " std::string XML_3_EXPECTED_CERT_1 = aliasWithLabel(ckmc_owner_id_system, "test3-cert1"); std::string XML_3_EXPECTED_DATA_1 = aliasWithLabel(ckmc_owner_id_system, "test3-data1"); -std::string format_src_path(const char *file) +auto format_dest_path(const char *file) { - return std::string(CKM_TEST_DIR) + std::string(file); + return std::string(CKM_RW_DATA_DIR "/initial_values/") + file; } -std::string format_dest_path(const char *file) -{ - return std::string(CKM_RW_DATA_DIR) + std::string( "/initial_values/") + std::string(file); +void test_not_exists(const char *file) { + const auto name = format_dest_path(file); + const bool file_exists = access(name.c_str(), F_OK) != -1; + RUNNER_ASSERT_MSG(!file_exists, "File " << name << " exists"); } -void copy_file(const std::string &from, const std::string &to) +void copy_file(const char *file) { - std::ifstream infile(from, std::ios_base::binary); - RUNNER_ASSERT_MSG(infile, "Input file " << from << " does not exist."); - std::ofstream outfile(to, std::ios_base::binary); - RUNNER_ASSERT_MSG(outfile, "Output file " << to << " does not exist. Reinstall key-manager."); + const auto src = std::string(CKM_TEST_DIR) + file; + const auto dest = format_dest_path(file); + std::ifstream infile(src, std::ios_base::binary); + RUNNER_ASSERT_MSG(infile, "Input file " << src << " does not exist."); + std::ofstream outfile(dest, std::ios_base::binary); + RUNNER_ASSERT_MSG(outfile, "Output file " << dest << " does not exist. Reinstall key-manager."); outfile << infile.rdbuf(); } -void restart_key_manager() +void restart_key_manager(const std::initializer_list files_to_copy = {}) { stop_service(MANAGER); + for (const auto f : files_to_copy) + copy_file(f); start_service(MANAGER); } -void test_exists(const std::string& name, bool expected) { - bool file_exists = (access( name.c_str(), F_OK ) != -1); - RUNNER_ASSERT_MSG(file_exists == expected, - "File " << name << " status: " << file_exists << - " while expected: " << expected); -} - -} - int hexToBin(char h) { if (h >= '0' && h <= '9') return h - '0'; @@ -117,6 +113,8 @@ CKM::RawBuffer hexToBin(std::string &hex) { return output; } +} // namespace + RUNNER_TEST_GROUP_INIT(T60_INITIAL_VALUES); RUNNER_TEST(T6001_init) @@ -128,19 +126,10 @@ RUNNER_TEST(T6001_init) // restart the key-manager // check XML file doesn't exist - copy_file(format_src_path(XML_1_okay), format_dest_path(XML_1_okay)); - copy_file(format_src_path(XML_2_okay), format_dest_path(XML_2_okay)); - copy_file(format_src_path(XML_3_wrong), format_dest_path(XML_3_wrong)); - - test_exists(format_dest_path(XML_1_okay), true); - test_exists(format_dest_path(XML_2_okay), true); - test_exists(format_dest_path(XML_3_wrong), true); - - restart_key_manager(); - - test_exists(format_dest_path(XML_1_okay), false); - test_exists(format_dest_path(XML_2_okay), false); - test_exists(format_dest_path(XML_3_wrong), false); + const auto files = {XML_1_okay, XML_2_okay, XML_3_wrong}; + restart_key_manager(files); + for (const auto f : files) + test_not_exists(f); } RUNNER_TEST(T6010_PARSE_XML_FILE_AT_STARTUP) @@ -269,8 +258,7 @@ RUNNER_TEST_TZ_BACKEND(T7000_Encrypted_initial_values, RemoveDataEnv<0>) std::string messageHex = EIV_ENCRYPTED_MESSAGE_HEX; std::string iv = EIV_MESSAGE_ENCRYPTION_IV; - copy_file(format_src_path(EIV_TEST_XML_FILENAME), format_dest_path(EIV_TEST_XML_FILENAME)); - restart_key_manager(); + restart_key_manager({EIV_TEST_XML_FILENAME}); CKM::CryptoAlgorithm algo; CKM::RawBuffer messageBin = hexToBin(messageHex); @@ -285,6 +273,44 @@ RUNNER_TEST_TZ_BACKEND(T7000_Encrypted_initial_values, RemoveDataEnv<0>) RUNNER_ASSERT_MSG(std::string(decrypted.begin(), decrypted.end()) == EIV_PLAIN_MESSAGE, "Data does not match"); } +RUNNER_TEST_TZ_BACKEND(T7010_Encrypted_initial_values_asymmetric, RemoveDataEnv<0>) +{ + restart_key_manager({EIV_TEST_ASYM_XML_FILENAME}); + constexpr char testDataStr[] = "test-data"; + const CKM::RawBuffer testData(testDataStr, testDataStr+sizeof(testDataStr)-1); + CKM::RawBuffer encrypted, decrypted, signature; + CKM::CryptoAlgorithm algoRsa; + algoRsa.setParam(CKM::ParamName::ALGO_TYPE, CKM::AlgoType::RSA_OAEP); + + auto mgr = CKM::Manager::create(); + int temp; + + #define MGR(OP, ...) do { RUNNER_ASSERT_MSG(CKM_API_SUCCESS == (temp = mgr->OP(__VA_ARGS__)), "Failed to " #OP " " << CKM::APICodeToString(temp)); } while (0) + + const auto rsaCrypt = [&](auto pub, auto prv) { + MGR(encrypt, algoRsa, pub, CKM::Password(), testData, encrypted); + RUNNER_ASSERT_MSG(testData != encrypted, "Data not encrypted"); + MGR(decrypt, algoRsa, prv, CKM::Password(), encrypted, decrypted); + RUNNER_ASSERT_MSG(testData == decrypted, "Data does not match"); + }; + + rsaCrypt("/System TEI_RSA_PUB", "/System TEI_RSA_PRV"); + rsaCrypt("/System TEI_RSA_PKCS8_PUB", "/System TEI_RSA_PKCS8_PRV"); + + const auto sign = [&](auto prv, auto pub, auto hash, auto pad) { + MGR(createSignature, prv, CKM::Password(), testData, hash, pad, signature); + MGR(verifySignature, pub, CKM::Password(), testData, signature, hash, pad); + }; + + constexpr auto rsaHashAlgo = CKM::HashAlgorithm::SHA512; + constexpr auto rsaPaddingAlgo = CKM::RSAPaddingAlgorithm::X931; + sign("/System TEI_RSA_PRV", "/System TEI_RSA_PUB", rsaHashAlgo, rsaPaddingAlgo); + sign("/System TEI_RSA_PKCS8_PRV", "/System TEI_RSA_PKCS8_PUB", rsaHashAlgo, rsaPaddingAlgo); + sign("/System TEI_DSA_PRV", "/System TEI_DSA_PUB", CKM::HashAlgorithm::SHA1, CKM::RSAPaddingAlgorithm::NONE); + + #undef MGR +} + /* TODO * - RW/RO location support (files removal, flag handling) * - item overwrite diff --git a/src/ckm/resource/pkcs.p12 b/src/ckm/resource/pkcs.p12 index 4548d51..3dff3d6 100644 Binary files a/src/ckm/resource/pkcs.p12 and b/src/ckm/resource/pkcs.p12 differ diff --git a/src/ckm/test-certs.cpp b/src/ckm/test-certs.cpp index ff137b1..5642a86 100644 --- a/src/ckm/test-certs.cpp +++ b/src/ckm/test-certs.cpp @@ -40,15 +40,15 @@ enum RawCertificateID { TEST_LEAF, // TEST_LEAF, signed by TEST_IM_CA, expires 2035 // third party - DIGICERT_ROOT_CA, // DIGICERT_ROOT_CA, (root CA), expires 10 Nov 2031 - DIGICERT_IM_CA, // DIGICERT_IM_CA, signed by DIGICERT_ROOT_CA, - // expires 22 Oct 2028 - FACEBOOK_COM, // FACEBOOK_COM, *.facebook.com - signed by DIGICERT_IM_CA, - // expires 22 Mar 2019 + BALTIMORE_CYBER_TRUST_ROOT, // Baltimore CyberTrust Root, (root CA), expires May 13, 2025 + MS_IT_TLS_CA_5, // Microsoft IT TLS CA 5, signed by Baltimore CyberTrust Root, + // expires May 20, 2024 + MICROSOFT_COM, // www.microsoft.com - signed by Microsoft IT TLS CA 5, + // expires October 22, 2021 // ocsp available chain on third party - MICROSOFT_IM_CA, // MICROSOFT_IM_CA, signed by Baltimore CyberTrust Root, expires 20 May 2024 - BING_COM, // BING, signed by MICROSOFT_IM_CA, expires 10 Jul 2019 + MS_IT_TLS_CA_2, // Microsoft IT TLS CA 2, signed by Baltimore CyberTrust Root, expires 20 May 2024 + BING_COM, // BING, signed by Microsoft IT TLS CA 2, expires 30 Apr 2021 // footer - last element in the set NO_CERT @@ -85,11 +85,11 @@ RawCertificateID toRawCertificateID(certificateID id) case certificateID::TEST_IM_CA: return RawCertificateID::TEST_IM_CA; case certificateID::TEST_LEAF: return RawCertificateID::TEST_LEAF; - case certificateID::THIRD_PARTY_ROOT_CA: return RawCertificateID::DIGICERT_ROOT_CA; - case certificateID::THIRD_PARTY_IM_CA: return RawCertificateID::DIGICERT_IM_CA; - case certificateID::THIRD_PARTY_LEAF: return RawCertificateID::FACEBOOK_COM; + case certificateID::THIRD_PARTY_ROOT_CA: return RawCertificateID::BALTIMORE_CYBER_TRUST_ROOT; + case certificateID::THIRD_PARTY_IM_CA: return RawCertificateID::MS_IT_TLS_CA_5; + case certificateID::THIRD_PARTY_LEAF: return RawCertificateID::MICROSOFT_COM; - case certificateID::OCSP_AVAILABLE_IM: return RawCertificateID::MICROSOFT_IM_CA; + case certificateID::OCSP_AVAILABLE_IM: return RawCertificateID::MS_IT_TLS_CA_2; case certificateID::OCSP_AVAILABLE_LEAF: return RawCertificateID::BING_COM; case certificateID::NO_CERT: return RawCertificateID::NO_CERT; @@ -186,85 +186,164 @@ CertMap initializeTestCerts() cm[RawCertificateID::TEST_LEAF].certPtr = createCert(raw_base64); } - // BING.COM, signed by MICROSOFT_IM_CA, expires 10 Jul 2019 + // BING, signed by Microsoft IT TLS CA 2, expires 30 Apr 2021 { std::string raw_base64( "-----BEGIN CERTIFICATE-----\n" - "MIIMAjCCCeqgAwIBAgITLQAAMpnXBx230XCKQgAAAAAymTANBgkqhkiG9w0BAQsF\n" + "MIIN+jCCC+KgAwIBAgITIAAGDxuOsc5CY0aDQgAAAAYPGzANBgkqhkiG9w0BAQsF\n" "ADCBizELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT\n" "B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEVMBMGA1UE\n" - "CxMMTWljcm9zb2Z0IElUMR4wHAYDVQQDExVNaWNyb3NvZnQgSVQgVExTIENBIDUw\n" - "HhcNMTcwNzIwMTc0NzA4WhcNMTkwNzEwMTc0NzA4WjAXMRUwEwYDVQQDEwx3d3cu\n" - "YmluZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6jsg+/7Dl\n" - "IrdgFOcaDlK3RQ9sIgkJsgpj+ZxAbIe3ziyimIxjVlHX87pqgXcNhaYNbCFD0iPm\n" - "+aUfbv4GDTLR+AIr8eSegqxZ+CBToYM67NhpVYra1KAvY4XgqxorO4FB9IWYJRqh\n" - "I3SZeZ3lLK5t9XuUMicG8l52nJfpPdXXvBca2wUCq8FHEObG81vJzESA0htLLPTj\n" - "dUWBQnXPiW5bqzlGHzzv8ISV6jtDLNNa5JRlhSlXho+6pCedhNF7MP4yTaantPvA\n" - "ELLRWX13VhjgoCcRCCu0s8rxW5DuVWl2Pb2iw35MFnNWlcoVwq0AjAfGA+xEba/W\n" - "Lid6qfkQctYjAgMBAAGjggfQMIIHzDAdBgNVHQ4EFgQUCYflhSl4MCAls91+3Gzt\n" - "pSmoA3AwCwYDVR0PBAQDAgSwMB8GA1UdIwQYMBaAFAj+JZ906ocEwry7jqg4XzPG\n" - "0WxlMIGsBgNVHR8EgaQwgaEwgZ6ggZuggZiGS2h0dHA6Ly9tc2NybC5taWNyb3Nv\n" - "ZnQuY29tL3BraS9tc2NvcnAvY3JsL01pY3Jvc29mdCUyMElUJTIwVExTJTIwQ0El\n" - "MjA1LmNybIZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9tc2NvcnAvY3Js\n" - "L01pY3Jvc29mdCUyMElUJTIwVExTJTIwQ0ElMjA1LmNybDCBhQYIKwYBBQUHAQEE\n" - "eTB3MFEGCCsGAQUFBzAChkVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL21z\n" - "Y29ycC9NaWNyb3NvZnQlMjBJVCUyMFRMUyUyMENBJTIwNS5jcnQwIgYIKwYBBQUH\n" - "MAGGFmh0dHA6Ly9vY3NwLm1zb2NzcC5jb20wPgYJKwYBBAGCNxUHBDEwLwYnKwYB\n" - "BAGCNxUIh9qGdYPu2QGCyYUbgbWeYYX062CBXYTS30KC55N6AgFkAgEQMB0GA1Ud\n" - "JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATBNBgNVHSAERjBEMEIGCSsGAQQBgjcq\n" - "ATA1MDMGCCsGAQUFBwIBFidodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL21z\n" - "Y29ycC9jcHMwJwYJKwYBBAGCNxUKBBowGDAKBggrBgEFBQcDAjAKBggrBgEFBQcD\n" - "ATCCBW0GA1UdEQSCBWQwggVgggx3d3cuYmluZy5jb22CEGRpY3QuYmluZy5jb20u\n" - "Y26CEyoucGxhdGZvcm0uYmluZy5jb22CCiouYmluZy5jb22CCGJpbmcuY29tghZp\n" - "ZW9ubGluZS5taWNyb3NvZnQuY29tghMqLndpbmRvd3NzZWFyY2guY29tghljbi5p\n" - "ZW9ubGluZS5taWNyb3NvZnQuY29tghEqLm9yaWdpbi5iaW5nLmNvbYINKi5tbS5i\n" - "aW5nLm5ldIIOKi5hcGkuYmluZy5jb22CGGVjbi5kZXYudmlydHVhbGVhcnRoLm5l\n" - "dIINKi5jbi5iaW5nLm5ldIINKi5jbi5iaW5nLmNvbYIQc3NsLWFwaS5iaW5nLmNv\n" - "bYIQc3NsLWFwaS5iaW5nLm5ldIIOKi5hcGkuYmluZy5uZXSCDiouYmluZ2FwaXMu\n" - "Y29tgg9iaW5nc2FuZGJveC5jb22CFmZlZWRiYWNrLm1pY3Jvc29mdC5jb22CG2lu\n" - "c2VydG1lZGlhLmJpbmcub2ZmaWNlLm5ldIIOci5iYXQuYmluZy5jb22CECouci5i\n" - "YXQuYmluZy5jb22CEiouZGljdC5iaW5nLmNvbS5jboIPKi5kaWN0LmJpbmcuY29t\n" - "gg4qLnNzbC5iaW5nLmNvbYIQKi5hcHBleC5iaW5nLmNvbYIWKi5wbGF0Zm9ybS5j\n" - "bi5iaW5nLmNvbYINd3AubS5iaW5nLmNvbYIMKi5tLmJpbmcuY29tgg9nbG9iYWwu\n" - "YmluZy5jb22CEXdpbmRvd3NzZWFyY2guY29tgg5zZWFyY2gubXNuLmNvbYIRKi5i\n" - "aW5nc2FuZGJveC5jb22CGSouYXBpLnRpbGVzLmRpdHUubGl2ZS5jb22CDyouZGl0\n" - "dS5saXZlLmNvbYIYKi50MC50aWxlcy5kaXR1LmxpdmUuY29tghgqLnQxLnRpbGVz\n" - "LmRpdHUubGl2ZS5jb22CGCoudDIudGlsZXMuZGl0dS5saXZlLmNvbYIYKi50My50\n" - "aWxlcy5kaXR1LmxpdmUuY29tghUqLnRpbGVzLmRpdHUubGl2ZS5jb22CCzNkLmxp\n" - "dmUuY29tghNhcGkuc2VhcmNoLmxpdmUuY29tghRiZXRhLnNlYXJjaC5saXZlLmNv\n" - "bYIVY253ZWIuc2VhcmNoLmxpdmUuY29tggxkZXYubGl2ZS5jb22CDWRpdHUubGl2\n" - "ZS5jb22CEWZhcmVjYXN0LmxpdmUuY29tgg5pbWFnZS5saXZlLmNvbYIPaW1hZ2Vz\n" - "LmxpdmUuY29tghFsb2NhbC5saXZlLmNvbS5hdYIUbG9jYWxzZWFyY2gubGl2ZS5j\n" - "b22CFGxzNGQuc2VhcmNoLmxpdmUuY29tgg1tYWlsLmxpdmUuY29tghFtYXBpbmRp\n" - "YS5saXZlLmNvbYIObG9jYWwubGl2ZS5jb22CDW1hcHMubGl2ZS5jb22CEG1hcHMu\n" - "bGl2ZS5jb20uYXWCD21pbmRpYS5saXZlLmNvbYINbmV3cy5saXZlLmNvbYIcb3Jp\n" - "Z2luLmNud2ViLnNlYXJjaC5saXZlLmNvbYIWcHJldmlldy5sb2NhbC5saXZlLmNv\n" - "bYIPc2VhcmNoLmxpdmUuY29tghJ0ZXN0Lm1hcHMubGl2ZS5jb22CDnZpZGVvLmxp\n" - "dmUuY29tgg92aWRlb3MubGl2ZS5jb22CFXZpcnR1YWxlYXJ0aC5saXZlLmNvbYIM\n" - "d2FwLmxpdmUuY29tghJ3ZWJtYXN0ZXIubGl2ZS5jb22CE3dlYm1hc3RlcnMubGl2\n" - "ZS5jb22CFXd3dy5sb2NhbC5saXZlLmNvbS5hdYIUd3d3Lm1hcHMubGl2ZS5jb20u\n" - "YXUwDQYJKoZIhvcNAQELBQADggIBADTpW/UWeupk40OP6k4yxihKStswxwqPAfMR\n" - "mx4XyqmTAawAKRNM+6EZth1BQdPdOplwRTvs69kkmUHJH+ZjYXBezEACWkzEiNUQ\n" - "nzkRWajdSQIz08Ubj/mBD6U8xLYD+NXgiB0xNWabd8aiPsqPaj6I3qkNw4JvtgtH\n" - "ZQG1zlwC5/Lu6yV3DM3sKpQMyBmOnX6nVUiS0MTOzLgZOQzRk07nO7EXWGcKTmDB\n" - "jE8cqv5IA/jQ6gtaxCI5pDxfXK4ct7oQyoChfxOXcEDKMmMndFmg9ch5c4an/FRM\n" - "2cgzDfjR01A71LNUpLUdOjNV0T+ZEStqEpdyDFfjrHGDtzLyqEz3iyvvQFyjmlGh\n" - "6OtZXwjCPpnVSrKCmfJKio0kUxyq+6t5tZAQbPVgFKiMrVnU+sgvmNVip1toijyz\n" - "8vMVCkwJ2G++7xjJukoELMxZ50W4/SAMZLy1Asx02NBwYCu9+CTQPVnmPe7rmxhl\n" - "QRBOfDNa1+5jwRHY64YudEzKhWR1uqS3ABd/fk+TL86yuNYGAgxnOm1FtOGieRgV\n" - "iV3+NzC+bDbuUOtmbD/GvDGmRwJRcCTHL7jBmkHePh2ABY93NE/IbkaDP6l1Kw98\n" - "AfqkzSUxhqHXuThe7KIoX9/0zv4AA1WZFis1QvAG7dpl9eio6vCdC/73HvBAlqRL\n" - "+7Mb1uu0\n" + "CxMMTWljcm9zb2Z0IElUMR4wHAYDVQQDExVNaWNyb3NvZnQgSVQgVExTIENBIDIw\n" + "HhcNMTkwNDMwMjA0ODAwWhcNMjEwNDMwMjA0ODAwWjAXMRUwEwYDVQQDEwx3d3cu\n" + "YmluZy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhIlPb0iP7\n" + "xRmUScK43QI7Ci/lvfMumWhRFAHcFzjIDHs74sq0B+ze8HW5PR6LWRe/d3yR5dC8\n" + "7gQs0qXGitzsP9vWJcpwKV273tlnWiEfgZx5tvNCFdHOqoYoHL3a8zed/JkGTEeX\n" + "ukGEX0TeBgCjcVTj5qRxJhjlWxs3AcB/q4f4vi3QG80TbSU2UO0lkvhvfs73C1jq\n" + "i7Zspia/YsMqcQ6X+APAZ+4guKjQr5q32tzj2FGtJO6ZmZuNV9Wwb32891UhwZ3D\n" + "2PrIcnCNlIQ1/Fah6im7Vc67qO2x/++r7gO7PtR8byCFnFuNUVQxhSIkCkj6FvPx\n" + "cYefok0wJ0VRAgMBAAGjggnIMIIJxDCCAfQGCisGAQQB1nkCBAIEggHkBIIB4AHe\n" + "AHUA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFqcApGzAAABAMA\n" + "RjBEAiAiASIs5j19VcTLbxcOGHQlIl62d3iy1FY8dnNq+6lebQIgchbSq2Qh78zs\n" + "mmucyslucBycij/FYUe3F1lNpJiB9KsAdgBVgdTCFpA2AUrqC5tXPFPwwOQ4eHAl\n" + "CBcvo6odBxPTDAAAAWpwCkgDAAAEAwBHMEUCIQDx6RqcvDdfIY9qdAuaRFBVvSHN\n" + "ttpAzie3KP9AAiGvBwIgSMvjse/hJusDoRFnSTtX96ierTaqzQH4oDLLnW/Gwc0A\n" + "dQBc3EOS/uarRUSxXprUVuYQN/vV+kfcoXOUsl7m9scOygAAAWpwCkbmAAAEAwBG\n" + "MEQCICbYF6Lv93BFrwLguzmas/5gQ87fzRHkTaMxDSD7PlhRAiA/DXOeTcHaiUPQ\n" + "WsKbJ/7x9EWKvVisqtQMnYk6cBxbBwB2AESUZS6w7s6vxEAH2Kj+KMDa5oK+2Msx\n" + "tT/TM5a1toGoAAABanAKRtoAAAQDAEcwRQIgardRfR7bxwSGF212a603dXYz6O5z\n" + "YHpPks8/RR/AMzQCIQD4VYDD+2zVDHEjz8elkKEzhgzTdOMtc1yYhCU+eHAGkjAn\n" + "BgkrBgEEAYI3FQoEGjAYMAoGCCsGAQUFBwMCMAoGCCsGAQUFBwMBMD4GCSsGAQQB\n" + "gjcVBwQxMC8GJysGAQQBgjcVCIfahnWD7tkBgsmFG4G1nmGF9OtggV2E0t9CgueT\n" + "egIBZAIBHTCBhQYIKwYBBQUHAQEEeTB3MFEGCCsGAQUFBzAChkVodHRwOi8vd3d3\n" + "Lm1pY3Jvc29mdC5jb20vcGtpL21zY29ycC9NaWNyb3NvZnQlMjBJVCUyMFRMUyUy\n" + "MENBJTIwMi5jcnQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLm1zb2NzcC5jb20w\n" + "HQYDVR0OBBYEFDcHtZt8HkKSRO8ETiTkCLixB9PaMAsGA1UdDwQEAwIEsDCCBW0G\n" + "A1UdEQSCBWQwggVgggx3d3cuYmluZy5jb22CEGRpY3QuYmluZy5jb20uY26CEyou\n" + "cGxhdGZvcm0uYmluZy5jb22CCiouYmluZy5jb22CCGJpbmcuY29tghZpZW9ubGlu\n" + "ZS5taWNyb3NvZnQuY29tghMqLndpbmRvd3NzZWFyY2guY29tghljbi5pZW9ubGlu\n" + "ZS5taWNyb3NvZnQuY29tghEqLm9yaWdpbi5iaW5nLmNvbYINKi5tbS5iaW5nLm5l\n" + "dIIOKi5hcGkuYmluZy5jb22CGGVjbi5kZXYudmlydHVhbGVhcnRoLm5ldIINKi5j\n" + "bi5iaW5nLm5ldIINKi5jbi5iaW5nLmNvbYIQc3NsLWFwaS5iaW5nLmNvbYIQc3Ns\n" + "LWFwaS5iaW5nLm5ldIIOKi5hcGkuYmluZy5uZXSCDiouYmluZ2FwaXMuY29tgg9i\n" + "aW5nc2FuZGJveC5jb22CFmZlZWRiYWNrLm1pY3Jvc29mdC5jb22CG2luc2VydG1l\n" + "ZGlhLmJpbmcub2ZmaWNlLm5ldIIOci5iYXQuYmluZy5jb22CECouci5iYXQuYmlu\n" + "Zy5jb22CEiouZGljdC5iaW5nLmNvbS5jboIPKi5kaWN0LmJpbmcuY29tgg4qLnNz\n" + "bC5iaW5nLmNvbYIQKi5hcHBleC5iaW5nLmNvbYIWKi5wbGF0Zm9ybS5jbi5iaW5n\n" + "LmNvbYINd3AubS5iaW5nLmNvbYIMKi5tLmJpbmcuY29tgg9nbG9iYWwuYmluZy5j\n" + "b22CEXdpbmRvd3NzZWFyY2guY29tgg5zZWFyY2gubXNuLmNvbYIRKi5iaW5nc2Fu\n" + "ZGJveC5jb22CGSouYXBpLnRpbGVzLmRpdHUubGl2ZS5jb22CDyouZGl0dS5saXZl\n" + "LmNvbYIYKi50MC50aWxlcy5kaXR1LmxpdmUuY29tghgqLnQxLnRpbGVzLmRpdHUu\n" + "bGl2ZS5jb22CGCoudDIudGlsZXMuZGl0dS5saXZlLmNvbYIYKi50My50aWxlcy5k\n" + "aXR1LmxpdmUuY29tghUqLnRpbGVzLmRpdHUubGl2ZS5jb22CCzNkLmxpdmUuY29t\n" + "ghNhcGkuc2VhcmNoLmxpdmUuY29tghRiZXRhLnNlYXJjaC5saXZlLmNvbYIVY253\n" + "ZWIuc2VhcmNoLmxpdmUuY29tggxkZXYubGl2ZS5jb22CDWRpdHUubGl2ZS5jb22C\n" + "EWZhcmVjYXN0LmxpdmUuY29tgg5pbWFnZS5saXZlLmNvbYIPaW1hZ2VzLmxpdmUu\n" + "Y29tghFsb2NhbC5saXZlLmNvbS5hdYIUbG9jYWxzZWFyY2gubGl2ZS5jb22CFGxz\n" + "NGQuc2VhcmNoLmxpdmUuY29tgg1tYWlsLmxpdmUuY29tghFtYXBpbmRpYS5saXZl\n" + "LmNvbYIObG9jYWwubGl2ZS5jb22CDW1hcHMubGl2ZS5jb22CEG1hcHMubGl2ZS5j\n" + "b20uYXWCD21pbmRpYS5saXZlLmNvbYINbmV3cy5saXZlLmNvbYIcb3JpZ2luLmNu\n" + "d2ViLnNlYXJjaC5saXZlLmNvbYIWcHJldmlldy5sb2NhbC5saXZlLmNvbYIPc2Vh\n" + "cmNoLmxpdmUuY29tghJ0ZXN0Lm1hcHMubGl2ZS5jb22CDnZpZGVvLmxpdmUuY29t\n" + "gg92aWRlb3MubGl2ZS5jb22CFXZpcnR1YWxlYXJ0aC5saXZlLmNvbYIMd2FwLmxp\n" + "dmUuY29tghJ3ZWJtYXN0ZXIubGl2ZS5jb22CE3dlYm1hc3RlcnMubGl2ZS5jb22C\n" + "FXd3dy5sb2NhbC5saXZlLmNvbS5hdYIUd3d3Lm1hcHMubGl2ZS5jb20uYXUwgawG\n" + "A1UdHwSBpDCBoTCBnqCBm6CBmIZLaHR0cDovL21zY3JsLm1pY3Jvc29mdC5jb20v\n" + "cGtpL21zY29ycC9jcmwvTWljcm9zb2Z0JTIwSVQlMjBUTFMlMjBDQSUyMDIuY3Js\n" + "hklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL21zY29ycC9jcmwvTWljcm9z\n" + "b2Z0JTIwSVQlMjBUTFMlMjBDQSUyMDIuY3JsME0GA1UdIARGMEQwQgYJKwYBBAGC\n" + "NyoBMDUwMwYIKwYBBQUHAgEWJ2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kv\n" + "bXNjb3JwL2NwczAfBgNVHSMEGDAWgBSRnjtEbD1XnEJ3KjTXT9HMSpcs2jAdBgNV\n" + "HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggIBAA1g\n" + "NJF5ks5Qrg0/qeOXQbcO3SCs+HKTKxVL8QdaTL3s5gsmWQzcYNS671DmN4lEob2g\n" + "WWZKyKAzQbjDOcf9ndxX4+i+PaCw5K3uONbMOwnuOCwRvDy8YEoCb3OzKFX4sjzh\n" + "1HVL/ljKHUPT+9ap/SpYserNxixibqF2LZYx+9hwr1bcx9GWrg3CoFUFgSZqRQ14\n" + "eiK94iM5kzJLKynKPhez+UOwS5VRev1mxh5nD9hBPzXHHqI9mNWu/lyr7KPUMigi\n" + "QfKKZuqV6W3i1H3BoJi1uDkL3SJo1F39XN3AyGSAZWS9RNn5JzEQQGiJRjrz/PE1\n" + "vTg1BlbsPdKa4gGZGdGBWcj2eXZc+GbLpTy3qWlmJrEn2KGLeomyndlftRPFrBUH\n" + "/5Mio5OeSawjlacBV25fKaoZ1BPc3i+HGKd5ctddCy6kJsgdMD221zGvf/0uW25Z\n" + "ImzDeH7KkOcGbzyWJwBzDgra0RP+qRgK3aYPSWI81OLlnHJ2VOix/UU63NCK2fO/\n" + "URzE8KxoHrgRGXCE52viHv6ksL7QXWelbERU7GEpcZU1suPhDohn4CrfrCYCjpa5\n" + "Ys6ci7Rren82SsXJBfNrgm2U4lxWfzWj+2Ay6yATbdoOPntue8cbbMoTzoNMHQXD\n" + "2DpjtFPs8/RVOFQb0IFVluCrTAnHmI8tTtsmzg6z\n" "-----END CERTIFICATE-----\n"); cm[RawCertificateID::BING_COM].raw_base64 = raw_base64; cm[RawCertificateID::BING_COM].certPtr = createCert(raw_base64); } - // MICROSOFT_IM_CA, expires 20 May 2024 + // Microsoft IT TLS CA 2, signed by Baltimore CyberTrust Root, expires 20 May 2024 { std::string raw_base64( "-----BEGIN CERTIFICATE-----\n" + "MIIFtDCCBJygAwIBAgIQDywQyVsGwJN/uNRJ+D6FaTANBgkqhkiG9w0BAQsFADBa\n" + "MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl\n" + "clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE2\n" + "MDUyMDEyNTE1N1oXDTI0MDUyMDEyNTE1N1owgYsxCzAJBgNVBAYTAlVTMRMwEQYD\n" + "VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy\n" + "b3NvZnQgQ29ycG9yYXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UE\n" + "AxMVTWljcm9zb2Z0IElUIFRMUyBDQSAyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\n" + "MIICCgKCAgEAnqoVwRuhY1/mURjFFrsR3AtNm5EKukBJK9zWBgvFd1ksNEJFC06o\n" + "yRbwKPMflpW/HtOfzIeBliGk57MwZq18bgASr70sPUWuoD917HUgBfxBYoF8zA7Z\n" + "Ie5zAHODFboJL7Fg/apgbQs/GiZZNCi0QkQUWzw0nTUmVSNQ0mz6pCu95Dv1WMsL\n" + "GyPGfdN9zD3Q/QEDyJ695QgjRIxYA1DUE+54ti2k6r0ycKFQYkyWwZ25HD1h2kYt\n" + "3ovW85vF6y7tjTqUEcLbgKUCB81/955hdLLsbFd6f9o2PkU8xuOc3U+bUedvv6Sb\n" + "tvGjBEZeFyH8/CaQhzlsKMH0+OPOFv/bMqcLarPw1V1sOV1bl4W9vi2278niblzI\n" + "bEHt7nN888p4KNIwqCcXaGhbtS4tjn3NKI6v1d2XRyxIvCJDjgoZ09zF39Pyoe92\n" + "sSRikZh7xns4tQEQ8BCs4o5NBSx8UxEsgyzNSskWGEWqsIjt+7+A1skDDZv6k2o8\n" + "VCHNbTLFKS7d72wMI4ErpzVsBIicxaG2ezuMBBuqThxIiJ+G9zfoP9lxim/9rvJA\n" + "xbh3nujA1VJfkOYTJIojEAYCxR3QjEoGdapJmBle97AfqEBnwoJsu2wav8h9v+po\n" + "DL4h6dRzRUxY1DHypcFlXGoHu/REQgFLq2IN30/AhQLN90Pj9TT2RQECAwEAAaOC\n" + "AUIwggE+MB0GA1UdDgQWBBSRnjtEbD1XnEJ3KjTXT9HMSpcs2jAfBgNVHSMEGDAW\n" + "gBTlnVkwgkdYzKz6CFQ2hns6tQRN8DASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1Ud\n" + "DwEB/wQEAwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUF\n" + "BwMJMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln\n" + "aWNlcnQuY29tMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0\n" + "LmNvbS9PbW5pcm9vdDIwMjUuY3JsMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsG\n" + "AQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA0GCSqGSIb3DQEB\n" + "CwUAA4IBAQBsf+pqb89rW8E0rP/cDuB9ixMX4C9OWQ7EA7n0BSllR64ZmuhU9mTV\n" + "2L0G4HEiGXvOmt15i99wJ0ho2/dvMxm1ZeufkAfMuEc5fQ9RE5ENgNR2UCuFB2Bt\n" + "bVmaKUAWxscN4GpXS4AJv+/HS0VXs5Su19J0DA8Bg+lo8ekCl4dq2G1m1WsCvFBI\n" + "oLIjd4neCLlGoxT2jA43lj2JpQ/SMkLkLy9DXj/JHdsqJDR5ogcij4VIX8V+bVD0\n" + "NCw7kQa6Ulq9Zo0jDEq1at4zSeH4mV2PMM3LwIXBA2xo5sda1cnUWJo3Pq4uMgcL\n" + "e0t+fCut38NMkTl8F0arflspaqUVVUov\n" + "-----END CERTIFICATE-----\n"); + cm[RawCertificateID::MS_IT_TLS_CA_2].raw_base64 = raw_base64; + cm[RawCertificateID::MS_IT_TLS_CA_2].certPtr = createCert(raw_base64); + + } + + // Baltimore CyberTrust Root, (root CA), expires May 13, 2025 + { + std::string raw_base64 = std::string( + "-----BEGIN CERTIFICATE-----\n" + "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n" + "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n" + "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n" + "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n" + "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n" + "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n" + "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n" + "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n" + "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n" + "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n" + "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n" + "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n" + "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n" + "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n" + "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n" + "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n" + "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n" + "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n" + "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n" + "-----END CERTIFICATE-----\n"); + cm[RawCertificateID::BALTIMORE_CYBER_TRUST_ROOT].raw_base64 = raw_base64; + cm[RawCertificateID::BALTIMORE_CYBER_TRUST_ROOT].certPtr = createCert(raw_base64); + } + + // Microsoft IT TLS CA 5, signed by Baltimore CyberTrust Root, expires May 20, 2024 + { + std::string raw_base64 = std::string( + "-----BEGIN CERTIFICATE-----\n" "MIIFtDCCBJygAwIBAgIQCIjNUl8ZJERNFKWCkd65UjANBgkqhkiG9w0BAQsFADBa\n" "MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl\n" "clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE2\n" @@ -297,119 +376,66 @@ CertMap initializeTestCerts() "TlHk/R4RFsyeANmXGpfjZceGNRtTdr4y0SxBSUujPpMMW3dXBzA8NYuM0WmiJ/pV\n" "6KudEB7RF9+6bInTyVvXC5SIqdi0ldeO\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::MICROSOFT_IM_CA].raw_base64 = raw_base64; - cm[RawCertificateID::MICROSOFT_IM_CA].certPtr = createCert(raw_base64); - - } - - // DIGICERT_ROOT_CA, (root CA), expires 10 Nov 2031 - { - std::string raw_base64 = std::string( - "-----BEGIN CERTIFICATE-----\n" - "MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\n" - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" - "d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n" - "ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\n" - "MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n" - "LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\n" - "RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n" - "+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\n" - "PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\n" - "xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\n" - "Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\n" - "hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\n" - "EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\n" - "MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\n" - "FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\n" - "nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\n" - "eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\n" - "hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\n" - "Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\n" - "vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n" - "+OkuE6N36B9K\n" - "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::DIGICERT_ROOT_CA].raw_base64 = raw_base64; - cm[RawCertificateID::DIGICERT_ROOT_CA].certPtr = createCert(raw_base64); - } - - // DIGICERT_IM_CA, signed by DIGICERT_ROOT_CA, expires 22 Oct 2028 - { - std::string raw_base64 = std::string( - "-----BEGIN CERTIFICATE-----\n" - "MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs\n" - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" - "d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n" - "ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL\n" - "MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n" - "LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy\n" - "YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2\n" - "4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC\n" - "Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1\n" - "itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn\n" - "4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X\n" - "sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft\n" - "bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA\n" - "MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\n" - "NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy\n" - "dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" - "L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG\n" - "BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ\n" - "UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D\n" - "aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd\n" - "aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH\n" - "E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly\n" - "/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu\n" - "xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF\n" - "0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae\n" - "cPUeybQ=\n" - "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::DIGICERT_IM_CA].raw_base64 = raw_base64; - cm[RawCertificateID::DIGICERT_IM_CA].certPtr = createCert(raw_base64); + cm[RawCertificateID::MS_IT_TLS_CA_5].raw_base64 = raw_base64; + cm[RawCertificateID::MS_IT_TLS_CA_5].certPtr = createCert(raw_base64); } - // FACEBOOK_COM, *.facebook.com - signed by DIGICERT_IM_CA, expires 22 Mar 2019 + // www.microsoft.com - signed by Microsoft IT TLS CA 5, expires October 22, 2021 { std::string raw_base64 = std::string( "-----BEGIN CERTIFICATE-----\n" - "MIIGsjCCBZqgAwIBAgIQCzw7YBoY9Z7itrsFYF7ywDANBgkqhkiG9w0BAQsFADBw\n" - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" - "d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz\n" - "dXJhbmNlIFNlcnZlciBDQTAeFw0xNzEyMTUwMDAwMDBaFw0xOTAzMjIxMjAwMDBa\n" - "MGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRMwEQYDVQQHEwpN\n" - "ZW5sbyBQYXJrMRcwFQYDVQQKEw5GYWNlYm9vaywgSW5jLjEXMBUGA1UEAwwOKi5m\n" - "YWNlYm9vay5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASIA87IjqqM6JBX\n" - "puN20BXCVsDjoP9wnF2rSV60qC130oLTrgfOQ3Uk1dv1R6LFCx4gs2pJUu6iDKBS\n" - "/b+BXOUbo4IEGDCCBBQwHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjsw\n" - "HQYDVR0OBBYEFMD9dPV9y8Yn8QPTYqJF14QcFSEIMIHHBgNVHREEgb8wgbyCDiou\n" - "ZmFjZWJvb2suY29tgg4qLnh4LmZiY2RuLm5ldIILKi5mYnNieC5jb22CDioueHou\n" - "ZmJjZG4ubmV0gg4qLmZhY2Vib29rLm5ldIIOKi54eS5mYmNkbi5uZXSCDyoubWVz\n" - "c2VuZ2VyLmNvbYIGZmIuY29tggsqLmZiY2RuLm5ldIIIKi5mYi5jb22CECoubS5m\n" - "YWNlYm9vay5jb22CDW1lc3Nlbmdlci5jb22CDGZhY2Vib29rLmNvbTAOBgNVHQ8B\n" - "Af8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGA1UdHwRu\n" - "MGwwNKAyoDCGLmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWhhLXNlcnZl\n" - "ci1nNi5jcmwwNKAyoDCGLmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWhh\n" - "LXNlcnZlci1nNi5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEF\n" - "BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwgYMG\n" - "CCsGAQUFBwEBBHcwdTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu\n" - "Y29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln\n" - "aUNlcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAA\n" - "MIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWY\n" - "BPkb37jjd80OyA3cEAAAAWBXnEHoAAAEAwBHMEUCIBC3Rn4i2bhLyR344u3vl7be\n" - "vxoi+WPJBhGT+j1gJmg5AiEAwQ3rzH1mmMSYNYKtVNDZMo+l6e8Z35t+X9NDR7Du\n" - "gWAAdwCHdb/nWXz4jEOZX73zbv9WjUdWNv9KtWDBtOr/XqCDDwAAAWBXnEL7AAAE\n" - "AwBIMEYCIQCRjvvPARW3J1ENmo2Nz1cxisa1BcbDuqvSrfuXkz8btAIhAPmllqgF\n" - "8JjlVHUChiFzghsKVBeTxRagi55tgsAciaoZAHUAu9nfvB+KcbWTlCOXqpJ7RzhX\n" - "lQqrUugakJZkNo4e0YUAAAFgV5xCUgAABAMARjBEAiBY6qdNgMoQAqVTl3zRrTmy\n" - "+X/1f/esBUczsb3MWdZ1ZgIgXdxZNTrDBgyTzxgbVRObkqU3tZZdaiwsw4WI0xI0\n" - "BtQwDQYJKoZIhvcNAQELBQADggEBAGu0uxZD+IRXXlFWLPvknRkXA7J08NyVKG70\n" - "M2vDi2xF2YB8qlZgoxW8YiiV86IpwtOhYLZinSO0iCBDQmTf627LTPfuDcF6qOuO\n" - "WFTvj1IbplPvGWIu5tNBiFWNQxFAIL2Rf+5vmIe+YezUHTLGGqwRtFa2ImS17IMk\n" - "YjZ90LYXXO5qb1RKkFJtAvEBTbJsv8kr+J6Rx+YNJy17LnBX+MbWiyBbvUQoM3sY\n" - "MmcWmcaQmECz9ZHWYjZeufSHbHKG6KDYLU8x6DyhgtxK2rsoIMlNnJkNHaLjw+b8\n" - "7VCYa+EMWppvVuNyXOk9Jkbx7Q3SEoodT77kkHUX0bF2OkZy6cc=\n" + "MIIJHzCCBwegAwIBAgITLQAMNxVixB2TlAh/aAAAAAw3FTANBgkqhkiG9w0BAQsF\n" + "ADCBizELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT\n" + "B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEVMBMGA1UE\n" + "CxMMTWljcm9zb2Z0IElUMR4wHAYDVQQDExVNaWNyb3NvZnQgSVQgVExTIENBIDUw\n" + "HhcNMTkxMDIxMjIwNDA0WhcNMjExMDIxMjIwNDA0WjCBiDELMAkGA1UEBhMCVVMx\n" + "CzAJBgNVBAgTAldBMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv\n" + "ZnQgQ29ycG9yYXRpb24xHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEa\n" + "MBgGA1UEAxMRd3d3Lm1pY3Jvc29mdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" + "DwAwggEKAoIBAQDTEK1CzUwdArEOb/vDOqds7/vQ1yGQtAYaZYNBch27Kw3/XKnf\n" + "td3NVj7tYe7MhI1U+bknxhSx7m4ti7Pzt6mxQiTZ/KegYhxosd3sOEikXgJVzECv\n" + "h0Mvd6adrvi00cUeQz0dlkUkuxMAjiFs+FX7Ogf4xt8ub4hKZPGB85vDnQQ0OHVh\n" + "L9IuUbYHhmh8EoDEdR+og+lj7u5OKt3YEWntgbnfV1d66U59kfp5Dg4T/zFjqz/l\n" + "U3KGBWgj0YoxH8KGfuq2YfFQsm7Q4MDJnR2PNUbwwrK5JldcRn27o5SVZxaB55bs\n" + "dyHWL0GbG5JoIIWg8pGJXKYGfARDEVjWijBPAgMBAAGjggR7MIIEdzCCAXwGCisG\n" + "AQQB1nkCBAIEggFsBIIBaAFmAHYA9lyUL9F3MCIUVBgIMJRWjuNNExkzv98MLyAL\n" + "zE7xZOMAAAFt8GJxcQAABAMARzBFAiEAldKDzhaLTJ1PpTpE7TmrRp+nDwoEZbW5\n" + "JOfrPKoR6PsCIBOqc6bzu7MnferBbxkUKwS67LpFTJgxYk6RV98m5fK2AHUAVYHU\n" + "whaQNgFK6gubVzxT8MDkOHhwJQgXL6OqHQcT0wwAAAFt8GJyzQAABAMARjBEAiBa\n" + "JqHGYrk+yh3ccuelsJxqLbhE3DJuSBZxe+xEpiabhQIgRdcckht/x8uG6tSrRKg5\n" + "0GdwnWlFKMBDT50rQjIPflMAdQB9PvL4j/+IVWgkwsDKnlKJeSvFDngJfy5ql2iZ\n" + "fiLw1wAAAW3wYnG7AAAEAwBGMEQCIGToqXolvHTes1f0QwV9RSvEE5HVwX6jn70+\n" + "KaExl0+BAiBosObeHSU867FO1Aw5dw+R01ZZ1fudHxDwuXgLvqFmQzAnBgkrBgEE\n" + "AYI3FQoEGjAYMAoGCCsGAQUFBwMCMAoGCCsGAQUFBwMBMD4GCSsGAQQBgjcVBwQx\n" + "MC8GJysGAQQBgjcVCIfahnWD7tkBgsmFG4G1nmGF9OtggV2E0t9CgueTegIBZAIB\n" + "HTCBhQYIKwYBBQUHAQEEeTB3MFEGCCsGAQUFBzAChkVodHRwOi8vd3d3Lm1pY3Jv\n" + "c29mdC5jb20vcGtpL21zY29ycC9NaWNyb3NvZnQlMjBJVCUyMFRMUyUyMENBJTIw\n" + "NS5jcnQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLm1zb2NzcC5jb20wHQYDVR0O\n" + "BBYEFParvwUeQbdw6ZH4GpVu9gwrCfuVMAsGA1UdDwQEAwIEsDCBmQYDVR0RBIGR\n" + "MIGOghN3d3dxYS5taWNyb3NvZnQuY29tghF3d3cubWljcm9zb2Z0LmNvbYIYc3Rh\n" + "dGljdmlldy5taWNyb3NvZnQuY29tghFpLnMtbWljcm9zb2Z0LmNvbYINbWljcm9z\n" + "b2Z0LmNvbYIRYy5zLW1pY3Jvc29mdC5jb22CFXByaXZhY3kubWljcm9zb2Z0LmNv\n" + "bTCBrAYDVR0fBIGkMIGhMIGeoIGboIGYhktodHRwOi8vbXNjcmwubWljcm9zb2Z0\n" + "LmNvbS9wa2kvbXNjb3JwL2NybC9NaWNyb3NvZnQlMjBJVCUyMFRMUyUyMENBJTIw\n" + "NS5jcmyGSWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvbXNjb3JwL2NybC9N\n" + "aWNyb3NvZnQlMjBJVCUyMFRMUyUyMENBJTIwNS5jcmwwTQYDVR0gBEYwRDBCBgkr\n" + "BgEEAYI3KgEwNTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5taWNyb3NvZnQuY29t\n" + "L3BraS9tc2NvcnAvY3BzMB8GA1UdIwQYMBaAFAj+JZ906ocEwry7jqg4XzPG0Wxl\n" + "MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOC\n" + "AgEAdWMaW3NOP5Yr47Sow1UZNLMmDlxNjz+8DcHiflQfKsImOvs/UflUrMGXG7rH\n" + "57NbJZ9nYpSTHWxSJfKsGPc3pgc5R1sxZxDb6lBuXEN9NvhJMmPwBkyKJAAnjYN6\n" + "yCNZP4X6dBOONW8uopknF+CRHDZdSiMaFiE4fVCe0LrO90b4ROPsRV8zHn57i1B1\n" + "69n1cqsLXrMHvK0Xnu7rwrvvd5BbOaqm7DrgwJYUk0UciNEfcyN2dNRcCxofWQdV\n" + "GQqvagqtjyDCm/EJ6DJ2kWllGHjauc8IkMaUeCedTYphChEckXoRBZikZtyL0oZj\n" + "67iKht6mm4fST+x0Zuu5wdzUoCTQsNTHV0GSbcVIRcgmaNiwP+0+lrRocUrj2h/7\n" + "2IQN8Pe/+CrDeVJNlKA9gWNl+t1F/r3CKWnkENyNUCTggiCSojdY9Rkj1rTieP6M\n" + "SBUZBWf3MB5XIuaLOTO0/whM831krxNG/k0mdCpDtdKvCKIcARrkKM9A3TxtVpOd\n" + "8f9kifcGaPqTQYr8fxhrNB864qsCG17o8ZckBKW8FY5H/jSQAZb1qbwsTbBMXJIr\n" + "0lAPwH7LIAHJJyslG0X3Mp0ARumGWqVwiHOCaLXO1iSQX0wW4yo+lGxWONvOIoad\n" + "2Ned/fxM675fEVC+r+DI6BKbt9ChfIXiXeULqOZC3yp2Fo8=\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::FACEBOOK_COM].raw_base64 = raw_base64; - cm[RawCertificateID::FACEBOOK_COM].certPtr = createCert(raw_base64); + cm[RawCertificateID::MICROSOFT_COM].raw_base64 = raw_base64; + cm[RawCertificateID::MICROSOFT_COM].certPtr = createCert(raw_base64); } return cm; diff --git a/src/ckm/unprivileged/CMakeLists.txt b/src/ckm/unprivileged/CMakeLists.txt index 6efdfbe..14a8973 100644 --- a/src/ckm/unprivileged/CMakeLists.txt +++ b/src/ckm/unprivileged/CMakeLists.txt @@ -23,6 +23,7 @@ SET(CKM_SOURCES capi-testcases.cpp encryption-decryption-env.cpp encryption-decryption.cpp + sign-verify.cpp main.cpp ) diff --git a/src/ckm/unprivileged/capi-testcases.cpp b/src/ckm/unprivileged/capi-testcases.cpp index 95d2a32..0e0cfca 100644 --- a/src/ckm/unprivileged/capi-testcases.cpp +++ b/src/ckm/unprivileged/capi-testcases.cpp @@ -779,11 +779,8 @@ RUNNER_TEST(T3044_remove_bin_data_C_API) RUNNER_TEST(T3045_save_big_data_C_API, RemoveDataEnv) { -#ifdef TZ_BACKEND + // We don't know which backend will be used const size_t BIG_SIZE = 100000; -#else - const size_t BIG_SIZE = 5000000; -#endif std::vector big_data(BIG_SIZE); std::ifstream is("/dev/urandom", std::ifstream::binary); diff --git a/src/ckm/unprivileged/encryption-decryption.cpp b/src/ckm/unprivileged/encryption-decryption.cpp index 76f1c92..c183c81 100644 --- a/src/ckm/unprivileged/encryption-decryption.cpp +++ b/src/ckm/unprivileged/encryption-decryption.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2019 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. @@ -22,12 +22,12 @@ #include #include -#include -#include +#include #include #include #include +#include #include #include #include @@ -57,24 +57,6 @@ EncryptionError apiEncrypt(ckmc_param_list_h params, return g_api->encrypt(params, key_alias, password, decrypted, ppencrypted); } -// Policy backend to use in subsequent operations (global for each test case) -PolicyBackend g_backend = PolicyBackend::DEFAULT; - -class testBackend { -public: - testBackend(PolicyBackend backend){ - m_backend = g_backend; - g_backend = backend; - } - - virtual ~testBackend(){ - //restore in destructor - g_backend = m_backend; - } -private: - PolicyBackend m_backend; -}; - inline CKM::Password _tostring(const char *str) { return (str == nullptr) ? Password() : Password(str); @@ -127,167 +109,184 @@ struct KeyAliasPair Alias pub; }; -class EncEnv : public RemoveDataEnv { -public: - EncEnv() : m_dbu(NULL) {} - ~EncEnv() { delete m_dbu; } - - void init(const std::string& str) { - RemoveDataEnv::init(str); - m_dbu = new ScopedDBUnlock(UID, "db-pass"); // unlock user's database +struct SyncEnv { + void init(const std::string&) { + g_api = &g_syncApi; } void finish() { - delete m_dbu; - m_dbu = NULL; - RemoveDataEnv::finish(); - g_api = NULL; - } - - ScopedDBUnlock* m_dbu; -}; - -struct SyncEnv : public EncEnv { - void init(const std::string& str) { - EncEnv::init(str); - g_api = &g_syncApi; + g_api = nullptr; } static std::string suffix() { return "_sync"; } }; -struct AsyncEnv : public EncEnv { - void init(const std::string& str) { - EncEnv::init(str); +struct AsyncEnv { + void init(const std::string&) { g_api = &g_asyncApi; } + void finish() { + g_api = nullptr; + } + static std::string suffix() { return "_async"; } }; -struct AlgoBase { - ckmc_algo_type_e m_type; - size_t m_keyLen; - - AlgoBase(ckmc_algo_type_e type, size_t keyLen) : m_type(type), m_keyLen(keyLen) {} - - virtual KeyAliasPair keyGen(const char* pass = nullptr, const char* suffix = nullptr) = 0; +struct Algo { + ckmc_algo_type_e type; + size_t keyLen; }; -typedef std::shared_ptr AlgoBasePtr; +std::unordered_map> g_symKeys; +std::unordered_map> g_asymKeys; -template -AlgoBasePtr createAlgo(ckmc_algo_type_e type, size_t keyLen) { - return AlgoBasePtr(new T(type, keyLen)); -} +enum KeyIdx { + PRIMARY = 0, + PASSWORD_PROTECTED = 1, -struct AlgoAes : public AlgoBase { - AlgoAes(ckmc_algo_type_e type, size_t keyLen) : AlgoBase(type, keyLen) {} - KeyAliasPair keyGen(const char* pass = nullptr, const char* suffix = nullptr); + KEY_IDX_MAX }; -KeyAliasPair AlgoAes::keyGen(const char* pass, const char* suffix) -{ - KeyAliasPair aliases; - std::ostringstream oss; - std::string ownerId = getOwnerIdFromSelf(); - CharPtr passPtr(nullptr, free); - if (pass) - passPtr.reset(strdup(pass)); +RawBufferPtr PLAIN_DATA; +RawBufferPtr BIG_DATA; +ckmc_raw_buffer_s* DEFAULT_IV; +ckmc_raw_buffer_s* IV11; +ckmc_raw_buffer_s* IV12; +ckmc_raw_buffer_s* IV15; +ckmc_raw_buffer_s* IV17; +ckmc_raw_buffer_s* IV128; +ckmc_raw_buffer_s* AAD32; +ckmc_raw_buffer_s* AAD64; - oss << "aes_" << static_cast(m_type) << "_" << m_keyLen << "_key_alias"; - if (suffix) - oss << suffix; - aliases.prv = aliasWithLabel(ownerId.c_str(),oss.str().c_str()); - aliases.pub = aliasWithLabel(ownerId.c_str(), oss.str().c_str()); +KeyAliasPair getKey(const Algo& algo, KeyIdx idx) +{ + if (algo.type == CKMC_ALGO_RSA_OAEP) + return g_asymKeys[algo.keyLen][idx]; - ckmc_policy_s policy; - policy.extractable = false; - policy.password = passPtr.get(); + KeyAliasPair pair; + pair.prv = g_symKeys[algo.keyLen][idx]; + pair.pub = pair.prv; + return pair; +} - auto mgr = CKM::Manager::create(); - RUNNER_ASSERT_MSG(CKM_API_SUCCESS == mgr->createKeyAES(m_keyLen, Alias(aliases.prv.c_str()), - _toCkmPolicy(policy, g_backend)), - "AES key creation failed"); +class EncGroupFixture: public DPL::Test::TestGroup +{ +public: + void Init() override + { + remove_user_data(UID); + int ret = ckmc_unlock_user_key(UID, "db-pass"); + if (ret != CKMC_ERROR_NONE) + RUNNER_ERROR_MSG("DB unlock failed: " << CKMCErrorToString(ret)); + + // Policy backend to use in subsequent operations (global for each test case) +#ifdef TZ_BACKEND + m_backend = PolicyBackend::FORCE_HARDWARE; +#else + m_backend = PolicyBackend::FORCE_SOFTWARE; +#endif + + // generate keys + m_manager = Manager::create(); + generateSymmetricKeys(128); + generateSymmetricKeys(192); + generateSymmetricKeys(256); + generateRsaKeys(1024); + generateRsaKeys(2048); + generateRsaKeys(4096); + + PLAIN_DATA = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); +#ifdef TZ_BACKEND + BIG_DATA = create_raw_buffer(createRandomBufferCAPI(1000)); +#else + BIG_DATA = create_raw_buffer(createRandomBufferCAPI(5000000)); +#endif + DEFAULT_IV = createRandomBufferCAPI(DEFAULT_IV_LEN); + IV11 = createRandomBufferCAPI(11); + IV12 = createRandomBufferCAPI(12); + IV15 = createRandomBufferCAPI(15); + IV17 = createRandomBufferCAPI(17); + IV128 = createRandomBufferCAPI(128); + AAD32 = createRandomBufferCAPI(32); + AAD64 = createRandomBufferCAPI(64); + } - return aliases; -} + void generateSymmetricKeys(size_t bitLen) + { + for (int i = 0; i < KEY_IDX_MAX; i++) + { + Policy p(Password(), false, m_backend); + if (i == PASSWORD_PROTECTED) + p.password.assign(PASSWORD); + + std::string alias = std::string("skey_") + std::to_string(bitLen) + std::string("_") + std::to_string(i); + int ret = m_manager->createKeyAES(bitLen, alias, p); + if (ret != CKM_API_SUCCESS) + RUNNER_ERROR_MSG("AES key creation failed"); + + g_symKeys[bitLen].push_back(alias); + } + } -struct AlgoRsa : public AlgoBase { - AlgoRsa(ckmc_algo_type_e type, size_t keyLen) : AlgoBase(type, keyLen) {} - KeyAliasPair keyGen(const char* pass = nullptr, const char* suffix = nullptr); -}; + void generateRsaKeys(size_t bitLen) + { + for (int i = 0; i < KEY_IDX_MAX; i++) + { + Policy prvPolicy(Password(), false, m_backend); + Policy pubPolicy(Password(), true, m_backend); + if (i == PASSWORD_PROTECTED) { + prvPolicy.password.assign(PASSWORD); + pubPolicy.password.assign(PASSWORD); + } + + KeyAliasPair alias; + alias.prv = std::string("akey_") + std::to_string(bitLen) + std::string("_") + std::to_string(i); + alias.pub = std::string("pub") + alias.prv; + int ret = m_manager->createKeyPairRSA(bitLen, alias.prv, alias.pub, prvPolicy, pubPolicy); + if (ret != CKM_API_SUCCESS) + RUNNER_ERROR_MSG("RSA key creation failed"); + + g_asymKeys[bitLen].push_back(alias); + } + } -KeyAliasPair AlgoRsa::keyGen(const char* pass, const char* suffix) -{ - std::ostringstream oss_prv, oss_pub; - oss_prv << "rsa_oaep_prv_alias_" << m_keyLen; - oss_pub << "rsa_oaep_pub_alias_" << m_keyLen; - if (suffix) { - oss_prv << suffix; - oss_pub << suffix; + void Finish() override + { + for (const auto &entry : g_asymKeys) { + for (const auto &keyPair : entry.second) { + m_manager->removeAlias(keyPair.prv); + m_manager->removeAlias(keyPair.pub); + } + } + + for (const auto &entry : g_symKeys) { + for (const auto &key : entry.second) { + m_manager->removeAlias(key); + } + } + + BIG_DATA.reset(); + PLAIN_DATA.reset(); + ckmc_buffer_free(AAD64); + ckmc_buffer_free(AAD32); + ckmc_buffer_free(IV128); + ckmc_buffer_free(IV17); + ckmc_buffer_free(IV15); + ckmc_buffer_free(IV12); + ckmc_buffer_free(IV11); + ckmc_buffer_free(DEFAULT_IV); + + int ret = ckmc_lock_user_key(UID); + if (ret != CKMC_ERROR_NONE) + RUNNER_ERROR_MSG("DB lock failed: " << CKMCErrorToString(ret)); + remove_user_data(UID); } - KeyAliasPair aliases = { - aliasWithLabel(getOwnerIdFromSelf().c_str(), oss_prv.str().c_str()), - aliasWithLabel(getOwnerIdFromSelf().c_str(), oss_pub.str().c_str()) - }; - CharPtr passPtr(nullptr, free); - if (pass) - passPtr.reset(strdup(pass)); - - ckmc_policy_s policyPrv; - policyPrv.password = passPtr.get(); - policyPrv.extractable = 0; - - ckmc_policy_s policyPub; - policyPub.password = passPtr.get(); - policyPub.extractable = 0; - - auto mgr = CKM::Manager::create(); - - RUNNER_ASSERT_MSG(CKM_API_SUCCESS == mgr->createKeyPairRSA(static_cast(m_keyLen), - CKM::Alias(aliases.prv.c_str()), - CKM::Alias(aliases.pub.c_str()), - _toCkmPolicy(policyPrv, g_backend), - _toCkmPolicy(policyPub, g_backend)), "RSA key pair generation failed" ); - return aliases; -} - -enum Algorithm { - AES_CBC_128, - AES_CBC_192, - AES_CBC_256, - AES_GCM_128, - AES_GCM_192, - AES_GCM_256, - AES_CTR_128, - AES_CTR_192, - AES_CTR_256, - AES_CFB_128, - AES_CFB_192, - AES_CFB_256, - RSA_OAEP_1024, - RSA_OAEP_2048, - RSA_OAEP_4096, +private: + ManagerShPtr m_manager; + PolicyBackend m_backend; }; -std::map g_algorithms = { - { AES_CBC_128, createAlgo(CKMC_ALGO_AES_CBC, 128) }, - { AES_CBC_192, createAlgo(CKMC_ALGO_AES_CBC, 192) }, - { AES_CBC_256, createAlgo(CKMC_ALGO_AES_CBC, 256) }, - { AES_GCM_128, createAlgo(CKMC_ALGO_AES_GCM, 128) }, - { AES_GCM_192, createAlgo(CKMC_ALGO_AES_GCM, 192) }, - { AES_GCM_256, createAlgo(CKMC_ALGO_AES_GCM, 256) }, - { AES_CTR_128, createAlgo(CKMC_ALGO_AES_CTR, 128) }, - { AES_CTR_192, createAlgo(CKMC_ALGO_AES_CTR, 192) }, - { AES_CTR_256, createAlgo(CKMC_ALGO_AES_CTR, 256) }, - { AES_CFB_128, createAlgo(CKMC_ALGO_AES_CFB, 128) }, - { AES_CFB_192, createAlgo(CKMC_ALGO_AES_CFB, 192) }, - { AES_CFB_256, createAlgo(CKMC_ALGO_AES_CFB, 256) }, - { RSA_OAEP_1024, createAlgo(CKMC_ALGO_RSA_OAEP, 1024) }, - { RSA_OAEP_2048, createAlgo(CKMC_ALGO_RSA_OAEP, 2048) }, - { RSA_OAEP_4096, createAlgo(CKMC_ALGO_RSA_OAEP, 4096) }, -}; void setParam(ParamListPtr& params, ckmc_param_name_e name, ckmc_raw_buffer_s* buffer) { @@ -311,18 +310,18 @@ struct EncryptionResult Alias pubKey; }; -EncryptionResult encrypt(const AlgoBasePtr& algo, +EncryptionResult encrypt(const Algo& algo, const RawBufferPtr& plain, const char* pass = nullptr) { EncryptionResult ret; ckmc_raw_buffer_s* encrypted = nullptr; - KeyAliasPair aliases = algo->keyGen(pass); + KeyAliasPair aliases = getKey(algo, pass == nullptr ? PRIMARY : PASSWORD_PROTECTED); ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ret.params = ParamListPtr(handle, ckmc_param_list_free); - setParam(ret.params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(ret.params, CKMC_PARAM_ED_IV, DEFAULT_IV); assert_crypto_positive(apiEncrypt, ret.params.get(), @@ -338,48 +337,55 @@ EncryptionResult encrypt(const AlgoBasePtr& algo, } void testAllAlgorithms( - const std::function& test) -{ - for(const auto& it : g_algorithms) - test(it.second); -} - -void testNoIvEnc(Algorithm type) + const std::function& test) +{ + test( { CKMC_ALGO_AES_CBC, 128 }); + test( { CKMC_ALGO_AES_CBC, 192 }); + test( { CKMC_ALGO_AES_CBC, 256 }); + test( { CKMC_ALGO_AES_GCM, 128 }); + test( { CKMC_ALGO_AES_GCM, 192 }); + test( { CKMC_ALGO_AES_GCM, 256 }); + test( { CKMC_ALGO_AES_CTR, 128 }); + test( { CKMC_ALGO_AES_CTR, 192 }); + test( { CKMC_ALGO_AES_CTR, 256 }); + test( { CKMC_ALGO_AES_CFB, 128 }); + test( { CKMC_ALGO_AES_CFB, 192 }); + test( { CKMC_ALGO_AES_CFB, 256 }); + test( { CKMC_ALGO_RSA_OAEP, 1024 }); + test( { CKMC_ALGO_RSA_OAEP, 2048 }); + test( { CKMC_ALGO_RSA_OAEP, 4096 }); +} + +void testNoIvEnc(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encrypted = nullptr; // add key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // param list with algo type only ParamListPtr params = createParamListPtr(); - setParam(params, CKMC_PARAM_ALGO_TYPE, algo->m_type); + setParam(params, CKMC_PARAM_ALGO_TYPE, algo.type); assert_crypto_invalid_param(apiEncrypt, params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encrypted); } -void testNoIvDec(Algorithm type) +void testNoIvDec(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt; - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); // param list with algo type only ParamListPtr params = createParamListPtr(); - setParam(params, CKMC_PARAM_ALGO_TYPE, algo->m_type); + setParam(params, CKMC_PARAM_ALGO_TYPE, algo.type); assert_crypto_invalid_param(apiDecrypt, params.get(), ret.prvKey.c_str(), @@ -388,20 +394,17 @@ void testNoIvDec(Algorithm type) &decrypted); } -void testInvalidIvEnc(Algorithm type) +void testInvalidIvEnc(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encryptedTmp = nullptr; // add key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); // invalid encryption @@ -410,28 +413,25 @@ void testInvalidIvEnc(Algorithm type) params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encryptedTmp); ckmc_buffer_free(encryptedTmp); encryptedTmp = nullptr; }; // invalid iv size - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN-1)); + setParam(params, CKMC_PARAM_ED_IV, IV15); test(); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN+1)); + setParam(params, CKMC_PARAM_ED_IV, IV17); test(); }; -void testInvalidIvDec(Algorithm type) +void testInvalidIvDec(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // valid encryption - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); // decryption auto test2 = [&](){ @@ -446,40 +446,37 @@ void testInvalidIvDec(Algorithm type) }; // invalid iv size - setParam(ret.params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN-1)); + setParam(ret.params, CKMC_PARAM_ED_IV, IV15); test2(); - setParam(ret.params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN+1)); + setParam(ret.params, CKMC_PARAM_ED_IV, IV17); test2(); }; -void encryptionWithCustomData(Algorithm type, ckmc_param_name_e name) +void encryptionWithCustomData(const Algo& algo, ckmc_param_name_e name) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encrypted = nullptr; ckmc_raw_buffer_s* decrypted = nullptr; // add key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); // set AAD - setParam(params, name, createRandomBufferCAPI(64)); + setParam(params, name, AAD64); // encrypt assert_crypto_positive(apiEncrypt, params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encrypted); RawBufferPtr tmpEnc = create_raw_buffer(encrypted); @@ -493,12 +490,12 @@ void encryptionWithCustomData(Algorithm type, ckmc_param_name_e name) RawBufferPtr tmpDec = create_raw_buffer(decrypted); // check - assert_buffers_equal(*plain.get(), *tmpDec.get()); + assert_buffers_equal(*PLAIN_DATA.get(), *tmpDec.get()); tmpDec.reset(); decrypted = nullptr; // set wrong AAD - setParam(params, name, createRandomBufferCAPI(32)); + setParam(params, name, AAD32); // decrypt assert_crypto_result(EncryptionError::INVALID_PARAM, @@ -510,12 +507,11 @@ void encryptionWithCustomData(Algorithm type, ckmc_param_name_e name) &decrypted); } -void testGcmIvSize(size_t size, +void testGcmIvSize(ckmc_raw_buffer_s* iv, const KeyAliasPair& aliases, EncryptionError error = EncryptionError::SUCCESS) { // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); RawBufferPtr encrypted; RawBufferPtr decrypted; ckmc_raw_buffer_s* encryptedTmp = nullptr; @@ -525,8 +521,8 @@ void testGcmIvSize(size_t size, ckmc_param_list_h handle = NULL; assert_positive(ckmc_generate_new_params, CKMC_ALGO_AES_GCM, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(size)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); + setParam(params, CKMC_PARAM_ED_IV, iv); // encryption assert_crypto_result(error, @@ -534,7 +530,7 @@ void testGcmIvSize(size_t size, params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encryptedTmp); if(error != EncryptionError::SUCCESS) @@ -550,19 +546,16 @@ void testGcmIvSize(size_t size, &decryptedTmp); decrypted = create_raw_buffer(decryptedTmp); - assert_buffers_equal(*plain.get(), *decrypted.get()); + assert_buffers_equal(*PLAIN_DATA.get(), *decrypted.get()); } -void testIntegrity(Algorithm type) +void testIntegrity(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); // break the encrypted data ret.encrypted->data[BUF_LEN/2]++; @@ -576,25 +569,22 @@ void testIntegrity(Algorithm type) &decrypted); RawBufferPtr tmp = create_raw_buffer(decrypted); - assert_buffers_equal(*plain.get(), *decrypted, false); + assert_buffers_equal(*PLAIN_DATA.get(), *decrypted, false); } -void testCtrEncryptionInvalidLength(Algorithm type) +void testCtrEncryptionInvalidLength(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encryptedTmp = nullptr; // add AES CTR key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); // encryption auto test = [&](){ @@ -602,7 +592,7 @@ void testCtrEncryptionInvalidLength(Algorithm type) params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encryptedTmp); ckmc_buffer_free(encryptedTmp); encryptedTmp = nullptr; @@ -616,22 +606,19 @@ void testCtrEncryptionInvalidLength(Algorithm type) test(); } -void testCtrEncryptionValidLength(Algorithm type) +void testCtrEncryptionValidLength(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encryptedTmp = nullptr; // add AES CTR key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); // encryption auto test = [&](){ @@ -639,7 +626,7 @@ void testCtrEncryptionValidLength(Algorithm type) params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encryptedTmp); ckmc_buffer_free(encryptedTmp); encryptedTmp = nullptr; @@ -655,16 +642,13 @@ void testCtrEncryptionValidLength(Algorithm type) test(); } -void testCtrDecryptionInvalidLength(Algorithm type) +void testCtrDecryptionInvalidLength(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // add AES CTR key & encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); // decryption auto test = [&](){ @@ -686,16 +670,13 @@ void testCtrDecryptionInvalidLength(Algorithm type) test(); } -void testCtrDecryptionValidLength(Algorithm type) +void testCtrDecryptionValidLength(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // add AES CTR key & encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); // decryption auto test = [&](){ @@ -707,7 +688,7 @@ void testCtrDecryptionValidLength(Algorithm type) &decrypted); ckmc_buffer_free(decrypted); RawBufferPtr tmp = create_raw_buffer(decrypted); - assert_buffers_equal(*plain.get(), *decrypted); + assert_buffers_equal(*PLAIN_DATA.get(), *decrypted); }; // invalid counter size setParam(ret.params, CKMC_PARAM_ED_CTR_LEN, 1); @@ -720,22 +701,19 @@ void testCtrDecryptionValidLength(Algorithm type) test(); } -void testGcmEncryptionTagLen(Algorithm type) +void testGcmEncryptionTagLen(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encryptedTmp = nullptr; // add AES GCM key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); std::vector testData = { // illegal tag lengths @@ -749,9 +727,16 @@ void testGcmEncryptionTagLen(Algorithm type) { 116, EncryptionError::INVALID_PARAM }, { 124, EncryptionError::INVALID_PARAM }, { 256, EncryptionError::INVALID_PARAM }, +#ifdef TZ_BACKEND + { 32, EncryptionError::INVALID_PARAM }, + { 64, EncryptionError::INVALID_PARAM }, + // legal tag lengths +#else // legal tag lengths { 32, EncryptionError::SUCCESS }, { 64, EncryptionError::SUCCESS }, +#endif + { 96, EncryptionError::SUCCESS }, { 104, EncryptionError::SUCCESS }, { 112, EncryptionError::SUCCESS }, @@ -768,23 +753,20 @@ void testGcmEncryptionTagLen(Algorithm type) params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encryptedTmp); ckmc_buffer_free(encryptedTmp); encryptedTmp = nullptr; } } -void testGcmDecryptionTagLen(Algorithm type) +void testGcmDecryptionTagLen(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // add AES GCM key & encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); std::vector testData = { // illegal tag lengths @@ -825,16 +807,13 @@ void testGcmDecryptionTagLen(Algorithm type) } } -void testGcmWrongTag(Algorithm type) +void testGcmWrongTag(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt with AES GCM - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); // modify tag (last 16B of encrypted message) ret.encrypted->data[ret.encrypted->size-1]++; @@ -849,29 +828,24 @@ void testGcmWrongTag(Algorithm type) &decrypted); } -void testGcmDifferentIvSizes(Algorithm type) +void testGcmDifferentIvSizes(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // add AES GCM key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); - testGcmIvSize(11, aliases, EncryptionError::SERVER_ERROR); // 12B is the smallest - testGcmIvSize(12, aliases); - testGcmIvSize(17, aliases); - testGcmIvSize(128, aliases); + testGcmIvSize(IV11, aliases, EncryptionError::SERVER_ERROR); // 12B is the smallest + testGcmIvSize(IV12, aliases); + testGcmIvSize(IV17, aliases); + testGcmIvSize(IV128, aliases); } -void testEncryptDecryptBigData(Algorithm type) +void testEncryptDecryptBigData(const Algo& algo) { - const AlgoBasePtr& algo = g_algorithms.at(type); - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(5000000)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, BIG_DATA); assert_positive(apiDecrypt, ret.params.get(), @@ -881,53 +855,44 @@ void testEncryptDecryptBigData(Algorithm type) &decrypted); RawBufferPtr tmp = create_raw_buffer(decrypted); - assert_buffers_equal(*plain.get(), *decrypted); + assert_buffers_equal(*BIG_DATA.get(), *decrypted); } -void testEncryptDecryptDifferentKeys(Algorithm type, bool success) +void testEncryptDecryptDifferentKeys(const Algo& algo, bool success) { - const AlgoBasePtr& algo = g_algorithms.at(type); // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); - // add different key - KeyAliasPair differentKeys = algo->keyGen(nullptr, "_wrong"); + // get different keys + KeyAliasPair differentKeys = getKey(algo, PASSWORD_PROTECTED); if (success) { // some algorithms don't verify key validity assert_crypto_positive(apiDecrypt, ret.params.get(), differentKeys.prv.c_str(), - nullptr, + PASSWORD, *ret.encrypted.get(), &decrypted); RawBufferPtr tmp = create_raw_buffer(decrypted); - assert_buffers_equal(*plain.get(), *decrypted, false); + assert_buffers_equal(*PLAIN_DATA.get(), *decrypted, false); } else { - assert_crypto_result(EncryptionError::INVALID_PARAM, + assert_crypto_result(EncryptionError::INVALID_PARAM, apiDecrypt, ret.params.get(), differentKeys.prv.c_str(), - nullptr, + PASSWORD, *ret.encrypted.get(), &decrypted); - } - - // Cleanup before testing next algorithm. Ignore results because not all keys are present - ckmc_remove_alias(ret.prvKey.c_str()); - ckmc_remove_alias(ret.pubKey.c_str()); - ckmc_remove_alias(differentKeys.prv.c_str()); - ckmc_remove_alias(differentKeys.pub.c_str()); + } } -void testRsaLongestData(Algorithm type, size_t dataSize) +void testRsaLongestData(const Algo& algo, size_t dataSize) { - const AlgoBasePtr& algo = g_algorithms.at(type); // prepare buffers RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(dataSize)); ckmc_raw_buffer_s* decrypted = nullptr; @@ -946,19 +911,18 @@ void testRsaLongestData(Algorithm type, size_t dataSize) assert_buffers_equal(*plain.get(), *decrypted); } -void testRsaDataTooLong(Algorithm type, size_t dataSize) +void testRsaDataTooLong(const Algo& algo, size_t dataSize) { - const AlgoBasePtr& algo = g_algorithms.at(type); // prepare buffers RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(dataSize)); // encrypt EncryptionResult ret; ckmc_raw_buffer_s* encrypted = nullptr; - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ret.params = ParamListPtr(handle, ckmc_param_list_free); assert_crypto_result(EncryptionError::INVALID_PARAM, apiEncrypt, @@ -971,8 +935,7 @@ void testRsaDataTooLong(Algorithm type, size_t dataSize) } // namespace anonymous - -RUNNER_TEST_GROUP_INIT(CKM_ENCRYPTION_DECRYPTION); +RUNNER_TEST_GROUP_INIT_ENV(CKM_ENCRYPTION_DECRYPTION, EncGroupFixture); ///////////////////////////////////////// // Generic encryption decryption tests @@ -980,20 +943,19 @@ RUNNER_TEST_GROUP_INIT(CKM_ENCRYPTION_DECRYPTION); RUNNER_TEST_MULTIPLE(TED_0010_encrypt_invalid_param_list, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encrypted = nullptr; // add key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // null param list assert_crypto_invalid_param(apiEncrypt, nullptr, aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encrypted); // empty param list @@ -1002,49 +964,48 @@ RUNNER_TEST_MULTIPLE(TED_0010_encrypt_invalid_param_list, SyncEnv, AsyncEnv) params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encrypted); }); } RUNNER_TEST_MULTIPLE(TED_0020_encrypt_missing_key, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* encrypted = nullptr; // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); assert_crypto_result(EncryptionError::ALIAS_UNKNOWN, apiEncrypt, params.get(), "non-existing-key-alias", nullptr, - *plain.get(), + *PLAIN_DATA.get(), &encrypted); }); } RUNNER_TEST_MULTIPLE(TED_0030_encrypt_no_plain_text, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers ckmc_raw_buffer_s plain = { nullptr, 0 }; ckmc_raw_buffer_s* encrypted = nullptr; // add key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); assert_crypto_invalid_param(apiEncrypt, params.get(), @@ -1057,38 +1018,36 @@ RUNNER_TEST_MULTIPLE(TED_0030_encrypt_no_plain_text, SyncEnv, AsyncEnv) RUNNER_TEST_MULTIPLE(TED_0040_encrypt_no_output_buffer, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s** encrypted = nullptr; // add key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); assert_crypto_invalid_param(apiEncrypt, params.get(), aliases.pub.c_str(), nullptr, - *plain.get(), + *PLAIN_DATA.get(), encrypted); }); } RUNNER_TEST_MULTIPLE(TED_0110_decrypt_invalid_param_list, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt; - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); // null param list assert_crypto_invalid_param(apiDecrypt, @@ -1111,22 +1070,18 @@ RUNNER_TEST_MULTIPLE(TED_0110_decrypt_invalid_param_list, SyncEnv, AsyncEnv) RUNNER_TEST_MULTIPLE(TED_0120_decrypt_missing_key, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt - auto ret = encrypt(algo, plain); - - // remove key - assert_positive(ckmc_remove_alias, ret.prvKey.c_str()); + auto ret = encrypt(algo, PLAIN_DATA); // try to decrypt assert_crypto_result(EncryptionError::ALIAS_UNKNOWN, apiDecrypt, ret.params.get(), - ret.prvKey.c_str(), + "non-existent-key", nullptr, *ret.encrypted.get(), &decrypted); @@ -1135,19 +1090,19 @@ RUNNER_TEST_MULTIPLE(TED_0120_decrypt_missing_key, SyncEnv, AsyncEnv) RUNNER_TEST_MULTIPLE(TED_0130_decrypt_no_encrypted_text, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers ckmc_raw_buffer_s encrypted = { nullptr, 0 }; ckmc_raw_buffer_s* decrypted = nullptr; // add key - KeyAliasPair aliases = algo->keyGen(); + KeyAliasPair aliases = getKey(algo, PRIMARY); // setup params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); assert_crypto_invalid_param(apiDecrypt, params.get(), @@ -1160,13 +1115,12 @@ RUNNER_TEST_MULTIPLE(TED_0130_decrypt_no_encrypted_text, SyncEnv, AsyncEnv) RUNNER_TEST_MULTIPLE(TED_0140_decrypt_no_output_buffer, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s** decrypted = nullptr; // encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); assert_crypto_invalid_param(apiDecrypt, ret.params.get(), @@ -1179,33 +1133,28 @@ RUNNER_TEST_MULTIPLE(TED_0140_decrypt_no_output_buffer, SyncEnv, AsyncEnv) RUNNER_TEST_MULTIPLE(TED_0200_encrypt_decrypt_different_keys, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptDifferentKeys(AES_CBC_128, false); - testEncryptDecryptDifferentKeys(AES_CBC_192, false); - testEncryptDecryptDifferentKeys(AES_CBC_256, false); - testEncryptDecryptDifferentKeys(AES_GCM_128, false); - testEncryptDecryptDifferentKeys(AES_GCM_192, false); - testEncryptDecryptDifferentKeys(AES_GCM_256, false); - testEncryptDecryptDifferentKeys(AES_CTR_128, true); - testEncryptDecryptDifferentKeys(AES_CTR_192, true); - testEncryptDecryptDifferentKeys(AES_CTR_256, true); - testEncryptDecryptDifferentKeys(AES_CFB_128, true); - testEncryptDecryptDifferentKeys(AES_CFB_192, true); - testEncryptDecryptDifferentKeys(AES_CFB_256, true); - testEncryptDecryptDifferentKeys(RSA_OAEP_1024, false); - testEncryptDecryptDifferentKeys(RSA_OAEP_2048, false); - testEncryptDecryptDifferentKeys(RSA_OAEP_4096, false); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_GCM, 128}, false); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_GCM, 192}, false); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_GCM, 256}, false); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CTR, 128}, true); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CTR, 192}, true); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CTR, 256}, true); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CFB, 128}, true); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CFB, 192}, true); + testEncryptDecryptDifferentKeys({CKMC_ALGO_AES_CFB, 256}, true); + testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 1024}, false); + testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 2048}, false); + testEncryptDecryptDifferentKeys({CKMC_ALGO_RSA_OAEP, 4096}, false); } RUNNER_TEST_MULTIPLE(TED_0300_encrypt_decrypt, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); assert_crypto_positive(apiDecrypt, ret.params.get(), @@ -1215,19 +1164,18 @@ RUNNER_TEST_MULTIPLE(TED_0300_encrypt_decrypt, SyncEnv, AsyncEnv) &decrypted); RawBufferPtr tmp = create_raw_buffer(decrypted); - assert_buffers_equal(*plain.get(), *decrypted); + assert_buffers_equal(*PLAIN_DATA.get(), *decrypted); }); } RUNNER_TEST_MULTIPLE(TED_0310_encrypt_decrypt_password, SyncEnv, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); ckmc_raw_buffer_s* decrypted = nullptr; // encrypt - auto ret = encrypt(algo, plain, PASSWORD); + auto ret = encrypt(algo, PLAIN_DATA, PASSWORD); // wrong password assert_crypto_result(EncryptionError::AUTH_FAILED, @@ -1247,81 +1195,69 @@ RUNNER_TEST_MULTIPLE(TED_0310_encrypt_decrypt_password, SyncEnv, AsyncEnv) &decrypted); RawBufferPtr tmp = create_raw_buffer(decrypted); // guarantees deletion - assert_buffers_equal(*plain.get(), *decrypted); + assert_buffers_equal(*PLAIN_DATA.get(), *decrypted); }); } // long test split into smaller ones -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cbc_128, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_128, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CBC_128); + testEncryptDecryptBigData({CKMC_ALGO_AES_CBC, 128}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cbc_192, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_192, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CBC_192); + testEncryptDecryptBigData({CKMC_ALGO_AES_CBC, 192}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cbc_256, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CBC_256, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CBC_256); + testEncryptDecryptBigData({CKMC_ALGO_AES_CBC, 256}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_gcm_128, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_128, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_GCM_128); + testEncryptDecryptBigData({CKMC_ALGO_AES_GCM, 128}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_gcm_192, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_192, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_GCM_192); + testEncryptDecryptBigData({CKMC_ALGO_AES_GCM, 192}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_gcm_256, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_GCM_256, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_GCM_256); + testEncryptDecryptBigData({CKMC_ALGO_AES_GCM, 256}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_ctr_128, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_128, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CTR_128); + testEncryptDecryptBigData({CKMC_ALGO_AES_CTR, 128}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_ctr_192, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_192, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CTR_192); + testEncryptDecryptBigData({CKMC_ALGO_AES_CTR, 192}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_ctr_256, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CTR_256, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CTR_256); + testEncryptDecryptBigData({CKMC_ALGO_AES_CTR, 256}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cfb_128, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_128, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CFB_128); + testEncryptDecryptBigData({CKMC_ALGO_AES_CFB, 128}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cfb_192, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_192, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CFB_192); + testEncryptDecryptBigData({CKMC_ALGO_AES_CFB, 192}); } -RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cfb_256, SyncEnv, AsyncEnv) +RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_AES_CFB_256, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testEncryptDecryptBigData(AES_CFB_256); + testEncryptDecryptBigData({CKMC_ALGO_AES_CFB, 256}); } ///////////////////////////////////////// @@ -1330,183 +1266,179 @@ RUNNER_TEST_MULTIPLE(TED_0400_encrypt_decrypt_big_data_aes_cfb_256, SyncEnv, Asy RUNNER_TEST_MULTIPLE(TED_1005_no_iv_enc, SyncEnv, AsyncEnv) { - testNoIvEnc(AES_CTR_128); - testNoIvEnc(AES_CTR_192); - testNoIvEnc(AES_CTR_256); - testNoIvEnc(AES_CBC_128); - testNoIvEnc(AES_CBC_192); - testNoIvEnc(AES_CBC_256); - testNoIvEnc(AES_CFB_128); - testNoIvEnc(AES_CFB_192); - testNoIvEnc(AES_CFB_256); - testNoIvEnc(AES_GCM_128); - testNoIvEnc(AES_GCM_192); - testNoIvEnc(AES_GCM_256); + testNoIvEnc({CKMC_ALGO_AES_CTR, 128}); + testNoIvEnc({CKMC_ALGO_AES_CTR, 192}); + testNoIvEnc({CKMC_ALGO_AES_CTR, 256}); + testNoIvEnc({CKMC_ALGO_AES_CBC, 128}); + testNoIvEnc({CKMC_ALGO_AES_CBC, 192}); + testNoIvEnc({CKMC_ALGO_AES_CBC, 256}); + testNoIvEnc({CKMC_ALGO_AES_CFB, 128}); + testNoIvEnc({CKMC_ALGO_AES_CFB, 192}); + testNoIvEnc({CKMC_ALGO_AES_CFB, 256}); + testNoIvEnc({CKMC_ALGO_AES_GCM, 128}); + testNoIvEnc({CKMC_ALGO_AES_GCM, 192}); + testNoIvEnc({CKMC_ALGO_AES_GCM, 256}); } RUNNER_TEST_MULTIPLE(TED_1010_invalid_iv_enc, SyncEnv, AsyncEnv) { - testInvalidIvEnc(AES_CTR_128); - testInvalidIvEnc(AES_CTR_192); - testInvalidIvEnc(AES_CTR_256); - testInvalidIvEnc(AES_CBC_128); - testInvalidIvEnc(AES_CBC_192); - testInvalidIvEnc(AES_CBC_256); - testInvalidIvEnc(AES_CFB_128); - testInvalidIvEnc(AES_CFB_192); - testInvalidIvEnc(AES_CFB_256); + testInvalidIvEnc({CKMC_ALGO_AES_CTR, 128}); + testInvalidIvEnc({CKMC_ALGO_AES_CTR, 192}); + testInvalidIvEnc({CKMC_ALGO_AES_CTR, 256}); + testInvalidIvEnc({CKMC_ALGO_AES_CBC, 128}); + testInvalidIvEnc({CKMC_ALGO_AES_CBC, 192}); + testInvalidIvEnc({CKMC_ALGO_AES_CBC, 256}); + testInvalidIvEnc({CKMC_ALGO_AES_CFB, 128}); + testInvalidIvEnc({CKMC_ALGO_AES_CFB, 192}); + testInvalidIvEnc({CKMC_ALGO_AES_CFB, 256}); } RUNNER_TEST_MULTIPLE(TED_1015_no_iv_dec, SyncEnv, AsyncEnv) { - testNoIvDec(AES_CTR_128); - testNoIvDec(AES_CTR_192); - testNoIvDec(AES_CTR_256); - testNoIvDec(AES_CBC_128); - testNoIvDec(AES_CBC_192); - testNoIvDec(AES_CBC_256); - testNoIvDec(AES_CFB_128); - testNoIvDec(AES_CFB_192); - testNoIvDec(AES_CFB_256); - testNoIvDec(AES_GCM_128); - testNoIvDec(AES_GCM_192); - testNoIvDec(AES_GCM_256); + testNoIvDec({CKMC_ALGO_AES_CTR, 128}); + testNoIvDec({CKMC_ALGO_AES_CTR, 192}); + testNoIvDec({CKMC_ALGO_AES_CTR, 256}); + testNoIvDec({CKMC_ALGO_AES_CBC, 128}); + testNoIvDec({CKMC_ALGO_AES_CBC, 192}); + testNoIvDec({CKMC_ALGO_AES_CBC, 256}); + testNoIvDec({CKMC_ALGO_AES_CFB, 128}); + testNoIvDec({CKMC_ALGO_AES_CFB, 192}); + testNoIvDec({CKMC_ALGO_AES_CFB, 256}); + testNoIvDec({CKMC_ALGO_AES_GCM, 128}); + testNoIvDec({CKMC_ALGO_AES_GCM, 192}); + testNoIvDec({CKMC_ALGO_AES_GCM, 256}); } RUNNER_TEST_MULTIPLE(TED_1020_invalid_iv_dec, SyncEnv, AsyncEnv) { - testInvalidIvDec(AES_CTR_128); - testInvalidIvDec(AES_CTR_192); - testInvalidIvDec(AES_CTR_256); - testInvalidIvDec(AES_CBC_128); - testInvalidIvDec(AES_CBC_192); - testInvalidIvDec(AES_CBC_256); - testInvalidIvDec(AES_CFB_128); - testInvalidIvDec(AES_CFB_192); - testInvalidIvDec(AES_CFB_256); + testInvalidIvDec({CKMC_ALGO_AES_CTR, 128}); + testInvalidIvDec({CKMC_ALGO_AES_CTR, 192}); + testInvalidIvDec({CKMC_ALGO_AES_CTR, 256}); + testInvalidIvDec({CKMC_ALGO_AES_CBC, 128}); + testInvalidIvDec({CKMC_ALGO_AES_CBC, 192}); + testInvalidIvDec({CKMC_ALGO_AES_CBC, 256}); + testInvalidIvDec({CKMC_ALGO_AES_CFB, 128}); + testInvalidIvDec({CKMC_ALGO_AES_CFB, 192}); + testInvalidIvDec({CKMC_ALGO_AES_CFB, 256}); } RUNNER_TEST_MULTIPLE(TED_1050_data_integrity, SyncEnv, AsyncEnv) { - testIntegrity(AES_CTR_128); - testIntegrity(AES_CTR_192); - testIntegrity(AES_CTR_256); - testIntegrity(AES_CBC_128); - testIntegrity(AES_CBC_192); - testIntegrity(AES_CBC_256); - testIntegrity(AES_CFB_128); - testIntegrity(AES_CFB_192); - testIntegrity(AES_CFB_256); + testIntegrity({CKMC_ALGO_AES_CTR, 128}); + testIntegrity({CKMC_ALGO_AES_CTR, 192}); + testIntegrity({CKMC_ALGO_AES_CTR, 256}); + testIntegrity({CKMC_ALGO_AES_CBC, 128}); + testIntegrity({CKMC_ALGO_AES_CBC, 192}); + testIntegrity({CKMC_ALGO_AES_CBC, 256}); + testIntegrity({CKMC_ALGO_AES_CFB, 128}); + testIntegrity({CKMC_ALGO_AES_CFB, 192}); + testIntegrity({CKMC_ALGO_AES_CFB, 256}); } RUNNER_TEST_MULTIPLE(TED_1100_ctr_encryption_invalid_length, SyncEnv, AsyncEnv) { - testCtrEncryptionInvalidLength(AES_CTR_128); - testCtrEncryptionInvalidLength(AES_CTR_192); - testCtrEncryptionInvalidLength(AES_CTR_256); + testCtrEncryptionInvalidLength({CKMC_ALGO_AES_CTR, 128}); + testCtrEncryptionInvalidLength({CKMC_ALGO_AES_CTR, 192}); + testCtrEncryptionInvalidLength({CKMC_ALGO_AES_CTR, 256}); } RUNNER_TEST_MULTIPLE(TED_1105_ctr_encryption_valid_length, SyncEnv, AsyncEnv) { RUNNER_IGNORED_MSG("Openssl supports only 128-bit AES CTR length"); - testCtrEncryptionValidLength(AES_CTR_128); - testCtrEncryptionValidLength(AES_CTR_192); - testCtrEncryptionValidLength(AES_CTR_256); + testCtrEncryptionValidLength({CKMC_ALGO_AES_CTR, 128}); + testCtrEncryptionValidLength({CKMC_ALGO_AES_CTR, 192}); + testCtrEncryptionValidLength({CKMC_ALGO_AES_CTR, 256}); } RUNNER_TEST_MULTIPLE(TED_1110_ctr_decryption_invalid_length, SyncEnv, AsyncEnv) { - testCtrDecryptionInvalidLength(AES_CTR_128); - testCtrDecryptionInvalidLength(AES_CTR_192); - testCtrDecryptionInvalidLength(AES_CTR_256); + testCtrDecryptionInvalidLength({CKMC_ALGO_AES_CTR, 128}); + testCtrDecryptionInvalidLength({CKMC_ALGO_AES_CTR, 192}); + testCtrDecryptionInvalidLength({CKMC_ALGO_AES_CTR, 256}); } RUNNER_TEST_MULTIPLE(TED_1115_ctr_decryption_valid_length, SyncEnv, AsyncEnv) { RUNNER_IGNORED_MSG("Openssl supports only 128-bit AES CTR length"); - testCtrDecryptionValidLength(AES_CTR_128); - testCtrDecryptionValidLength(AES_CTR_192); - testCtrDecryptionValidLength(AES_CTR_256); + testCtrDecryptionValidLength({CKMC_ALGO_AES_CTR, 128}); + testCtrDecryptionValidLength({CKMC_ALGO_AES_CTR, 192}); + testCtrDecryptionValidLength({CKMC_ALGO_AES_CTR, 256}); } RUNNER_TEST_MULTIPLE(TED_1200_gcm_encryption_tag_len, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testGcmEncryptionTagLen(AES_GCM_128); - testGcmEncryptionTagLen(AES_GCM_192); - testGcmEncryptionTagLen(AES_GCM_256); + testGcmEncryptionTagLen({CKMC_ALGO_AES_GCM, 128}); + testGcmEncryptionTagLen({CKMC_ALGO_AES_GCM, 192}); + testGcmEncryptionTagLen({CKMC_ALGO_AES_GCM, 256}); } RUNNER_TEST_MULTIPLE(TED_1210_gcm_decryption_tag_len, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testGcmDecryptionTagLen(AES_GCM_128); - testGcmDecryptionTagLen(AES_GCM_192); - testGcmDecryptionTagLen(AES_GCM_256); + testGcmDecryptionTagLen({CKMC_ALGO_AES_GCM, 128}); + testGcmDecryptionTagLen({CKMC_ALGO_AES_GCM, 192}); + testGcmDecryptionTagLen({CKMC_ALGO_AES_GCM, 256}); } RUNNER_TEST_MULTIPLE(TED_1230_gcm_wrong_tag, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - testGcmWrongTag(AES_GCM_128); - testGcmWrongTag(AES_GCM_192); - testGcmWrongTag(AES_GCM_256); + testGcmWrongTag({CKMC_ALGO_AES_GCM, 128}); + testGcmWrongTag({CKMC_ALGO_AES_GCM, 192}); + testGcmWrongTag({CKMC_ALGO_AES_GCM, 256}); } RUNNER_TEST_MULTIPLE(TED_1240_gcm_different_iv_sizes, SyncEnv, AsyncEnv) { - testGcmDifferentIvSizes(AES_GCM_128); - testGcmDifferentIvSizes(AES_GCM_192); - testGcmDifferentIvSizes(AES_GCM_256); + testGcmDifferentIvSizes({CKMC_ALGO_AES_GCM, 128}); + testGcmDifferentIvSizes({CKMC_ALGO_AES_GCM, 192}); + testGcmDifferentIvSizes({CKMC_ALGO_AES_GCM, 256}); } RUNNER_TEST_MULTIPLE(TED_1250_gcm_aad, SyncEnv, AsyncEnv) { - testBackend b(PolicyBackend::FORCE_SOFTWARE); - encryptionWithCustomData(AES_GCM_128, CKMC_PARAM_ED_AAD); - encryptionWithCustomData(AES_GCM_192, CKMC_PARAM_ED_AAD); - encryptionWithCustomData(AES_GCM_256, CKMC_PARAM_ED_AAD); + encryptionWithCustomData({CKMC_ALGO_AES_GCM, 128}, CKMC_PARAM_ED_AAD); + encryptionWithCustomData({CKMC_ALGO_AES_GCM, 192}, CKMC_PARAM_ED_AAD); + encryptionWithCustomData({CKMC_ALGO_AES_GCM, 256}, CKMC_PARAM_ED_AAD); } RUNNER_TEST_MULTIPLE(TED_1300_rsa_label, SyncEnv, AsyncEnv) { RUNNER_IGNORED_MSG("RSA-OAEP labels are not supported in openssl"); - encryptionWithCustomData(RSA_OAEP_1024, CKMC_PARAM_ED_LABEL); - encryptionWithCustomData(RSA_OAEP_2048, CKMC_PARAM_ED_LABEL); - encryptionWithCustomData(RSA_OAEP_4096, CKMC_PARAM_ED_LABEL); + encryptionWithCustomData({CKMC_ALGO_RSA_OAEP, 1024}, CKMC_PARAM_ED_LABEL); + encryptionWithCustomData({CKMC_ALGO_RSA_OAEP, 2048}, CKMC_PARAM_ED_LABEL); + encryptionWithCustomData({CKMC_ALGO_RSA_OAEP, 4096}, CKMC_PARAM_ED_LABEL); } RUNNER_TEST_MULTIPLE(TED_1330_rsa_longest_data, SyncEnv, AsyncEnv) { - testRsaLongestData(RSA_OAEP_1024, 86); - testRsaLongestData(RSA_OAEP_2048, 214); - testRsaLongestData(RSA_OAEP_4096, 470); + testRsaLongestData({CKMC_ALGO_RSA_OAEP, 1024}, 86); + testRsaLongestData({CKMC_ALGO_RSA_OAEP, 2048}, 214); + testRsaLongestData({CKMC_ALGO_RSA_OAEP, 4096}, 470); } RUNNER_TEST_MULTIPLE(TED_1350_rsa_data_too_long, SyncEnv, AsyncEnv) { - testRsaDataTooLong(RSA_OAEP_1024, 87); - testRsaDataTooLong(RSA_OAEP_2048, 215); - testRsaDataTooLong(RSA_OAEP_4096, 471); + testRsaDataTooLong({CKMC_ALGO_RSA_OAEP, 1024}, 87); + testRsaDataTooLong({CKMC_ALGO_RSA_OAEP, 2048}, 215); + testRsaDataTooLong({CKMC_ALGO_RSA_OAEP, 4096}, 471); } ///////////////////////////////////////// // Asynchronous only tests ///////////////////////////////////////// -RUNNER_TEST(TED_2000_enc_no_observer_async, EncEnv) +RUNNER_TEST(TED_2000_enc_no_observer_async, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ + testAllAlgorithms([](const Algo& algo){ // prepare buffers RawBuffer plain = createRandomBuffer(BUF_LEN); // keys - KeyAliasPair aliases = algo->keyGen(nullptr); + KeyAliasPair aliases = getKey(algo, PRIMARY); // params ckmc_param_list_h handle = NULL; - assert_positive(ckmc_generate_new_params, algo->m_type, &handle); + assert_positive(ckmc_generate_new_params, algo.type, &handle); ParamListPtr params = ParamListPtr(handle, ckmc_param_list_free); - setParam(params, CKMC_PARAM_ED_IV, createRandomBufferCAPI(DEFAULT_IV_LEN)); + setParam(params, CKMC_PARAM_ED_IV, DEFAULT_IV); // encrypt test_no_observer(&ManagerAsync::encrypt, @@ -1519,12 +1451,9 @@ RUNNER_TEST(TED_2000_enc_no_observer_async, EncEnv) RUNNER_TEST(TED_2010_dec_no_observer_async, AsyncEnv) { - testAllAlgorithms([](const AlgoBasePtr& algo){ - // prepare buffers - RawBufferPtr plain = create_raw_buffer(createRandomBufferCAPI(BUF_LEN)); - + testAllAlgorithms([](const Algo& algo){ // encrypt - auto ret = encrypt(algo, plain); + auto ret = encrypt(algo, PLAIN_DATA); RawBuffer encrypted(ret.encrypted->data, ret.encrypted->data + ret.encrypted->size); // decrypt diff --git a/src/ckm/unprivileged/main.cpp b/src/ckm/unprivileged/main.cpp index 6f0966f..f4a2eec 100644 --- a/src/ckm/unprivileged/main.cpp +++ b/src/ckm/unprivileged/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2020 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. @@ -280,6 +280,42 @@ RUNNER_TEST(T1014_save_with_label) "Key value has been changed by service"); } +RUNNER_TEST(T1020_save_big_data) +{ +#ifdef TZ_BACKEND + const size_t BIG_SIZE = 100000; + CKM::PolicyBackend backend = CKM::PolicyBackend::FORCE_HARDWARE; +#else + const size_t BIG_SIZE = 5000000; + CKM::PolicyBackend backend = CKM::PolicyBackend::FORCE_SOFTWARE; +#endif + + int temp; + std::vector big_data(BIG_SIZE); + std::ifstream is("/dev/urandom", std::ifstream::binary); + if(is) + is.read(big_data.data(), BIG_SIZE); + + RUNNER_ASSERT_MSG(is, + "Only " << is.gcount() << "/" << BIG_SIZE << " bytes read from /dev/urandom"); + + CKM::RawBuffer buffer(big_data.begin(), big_data.end()); + CKM::Policy policy(CKM::Password(), true, backend); + CKM::RawBuffer returned; + + auto manager = CKM::Manager::create(); + + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (temp = manager->saveData("big_data", buffer, policy)), + "Error=" << CKM::APICodeToString(temp)); + + RUNNER_ASSERT_MSG( + CKM_API_SUCCESS == (temp = manager->getData("big_data", CKM::Password(), returned)), + "Error=" << CKM::APICodeToString(temp)); + + RUNNER_ASSERT_MSG(buffer == returned, "Returned data doesn't match the original"); +} + RUNNER_TEST(T1015_deinit) { remove_user_data(USER_APP); @@ -1267,7 +1303,7 @@ RUNNER_TEST(T13129_get_chain) auto manager = CKM::Manager::create(); RUNNER_ASSERT_MSG(NULL != cert.get(), "Certificate should not be empty"); - RUNNER_ASSERT_MSG(false != cert1.get(), "Certificate should not be empty"); + RUNNER_ASSERT_MSG(NULL != cert1.get(), "Certificate should not be empty"); tmp = manager->getCertificateChain(cert, EMPTY_CERT_VECTOR, @@ -2290,68 +2326,13 @@ RUNNER_TEST(T14184_ECDSA_create_signatue_nohash) std::string message = "message test"; - CKM::Alias aliasPub = "ecpub_nohash1"; CKM::Alias aliasPrv = "ecprv_nohash1"; CKM::HashAlgorithm hash = CKM::HashAlgorithm::NONE; CKM::RSAPaddingAlgorithm padd = CKM::RSAPaddingAlgorithm::PKCS1; CKM::RawBuffer signature; RUNNER_ASSERT_MSG( - CKM_API_SUCCESS == (temp = manager->createSignature( - aliasPrv, - CKM::Password(), - CKM::RawBuffer(message.begin(), message.end()), - hash, - padd, - signature)), - "Error=" << CKM::APICodeToString(temp)); - - RUNNER_ASSERT_MSG( - CKM_API_SUCCESS == (temp = manager->verifySignature( - aliasPub, - CKM::Password(), - CKM::RawBuffer(message.begin(), message.end()), - signature, - hash, - padd)), - "Error=" << CKM::APICodeToString(temp)); - - RUNNER_ASSERT_MSG(signature.size() > 6, "Signature is too small"); - - memcpy((void*)signature.data(), "BROKEN", 6); - - RUNNER_ASSERT_MSG( - CKM_API_ERROR_VERIFICATION_FAILED == (temp = manager->verifySignature( - aliasPub, - CKM::Password(), - CKM::RawBuffer(message.begin(), message.end()), - signature, - hash, - padd)), - "Error=" << CKM::APICodeToString(temp)); -} - -RUNNER_TEST(T14185_ECDSA_create_signatue_nohash_bigmsg) -{ - int temp; - auto manager = CKM::Manager::create(); - - int msgSize = 1024*1024; - char big_msg[msgSize]; - for(int i =0; icreateSignature( + CKM_API_ERROR_INPUT_PARAM == (temp = manager->createSignature( aliasPrv, CKM::Password(), CKM::RawBuffer(message.begin(), message.end()), @@ -2361,7 +2342,6 @@ RUNNER_TEST(T14185_ECDSA_create_signatue_nohash_bigmsg) "Error=" << CKM::APICodeToString(temp)); } - RUNNER_TEST(T14189_deinit) { remove_user_data(USER_APP); @@ -2634,21 +2614,23 @@ RUNNER_TEST(T1808_create_signature_on_raw_key_and_verify_on_PKCS) int temp; auto manager = CKM::Manager::create(); - std::string prv = "-----BEGIN RSA PRIVATE KEY-----\n" - "MIICXQIBAAKBgQD1W9neUbXL1rnq9SvyzprjhWBKXyYKQirG3V2zyUnUaE24Sq2I\n" - "v7ISrwMN/G6WcjrGmeZDEWwrL4zXh002N8BD1waJPRonxwtVkhFy3emGatSmx7eI\n" - "ely5H+PBNImRvBh2u4GWga6OEXcUNdfaBUcxn+P6548/zpDhyNLzQKk5FwIDAQAB\n" - "AoGAR+4WkBuqTUj1FlGsAbHaLKt0UDlWwJknS0eoacWwFEpDxqx19WolfV67aYVA\n" - "snBolMKXg7/+0yZMhv8Ofr+XaHkPQplVVn9BwT0rmtEovJXwx+poRP9Bm3emglj/\n" - "iYd8EkaXDlIXCtewtQW9JEIctWppntHj3TvA/h7FCXPN6SkCQQD/N7sn5S1gBkVh\n" - "dyXQKoyKsZDb7hMIS1q6cKwYCMf2UrsD1/lnr7xXkvORdL213MfueO8g0WkuKfRY\n" - "bDD6WGX1AkEA9hxiOlsgvermqLJkOlJffbSaM8n/6wtnM0HV+Vd9NfSBOmxFDXPO\n" - "vrvdgiDPENhbqTJSQVDsfzHilTpK7lEvWwJBAJLxHoOg0tg3pBiyxgWtic+M3q+R\n" - "ykl7QViY6KzJ2X98MIrM/Z7yMollZXE4+sVLwZ0O6fdGOr3GkBWc7TImVUUCQQC7\n" - "pf6bQfof9Ce0fnf/I+ldHkPost7nJsWkBlGQkM2OQwP5OK4ZyK/dK76DxmI7FMwm\n" - "oJCo7nuzq6R4ZX7WYJ47AkBavxBDo/e9/0Vk5yrloGKW3f8RQXBJLcCkVUGyyJ3D\n" - "3gu/nafW4hzjSJniTjC1fOj0eb0OSg1JAvqHTYAnUsI7\n" - "-----END RSA PRIVATE KEY-----"; + std::string prv = + "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICWwIBAAKBgQDDgmPurTQa3wbnlM+9nCEQvhDviYRvSC9TL5lAMBCmBSl93v0U\n" + "BXWsqO+fmAINm5QJa89hF5N7Q4xtvfSJUPIeyzowTOEGM4U3FnJtlsNQsoNbFlNy\n" + "QLoZZmmY4ljG6/YqX+JGBgS9/J8uvaDWkvs+ktkORygfNz4Gi5DERT7eeQIDAQAB\n" + "AoGAARIqx/js6yTDnesjxC8hwzy3TQic0Bs+Hx+IoGBjBvXKR2U8T6rD/UEjpuUn\n" + "RbnPcsnDZg3CAg/ZqhQ7TbFC0kPo+S6+wKsZGDWUUvnpMkdcZUqXel8GFhdnmeIh\n" + "22vYthP4TCbolxwXlwvuhu0PLZWhRO/Z+g37T3QENexqGv0CQQDmqJ9PDoUj5eUR\n" + "wWEqEPraoU6ARBUUX5EhmTT9g9/BXnhwumIOksDHcBqNUwNOlKCUlWfBOelO93Ys\n" + "PRW3QyejAkEA2P0tW/8iU4j+0a6DV+TUYFDTjD29y8KPw0Aj59591xD5eIPK3IgU\n" + "91vnmtvU/QR26PnMOx4OAPk9a7BtN62zMwJAIFV0950edtjMUr/cAgydTbadDYf9\n" + "uHxpGN+kOQGahT3b/llyU36o/YwufK8tYH+fPxTulXyrwwEXlL3/ZFBKpwJAeLGS\n" + "Wlp2WGqZ+j2MdwYkDxLGKHprKHwnBN6XWjCKZGbfrGX6H2Jd7xyinaNrO/UQwxO2\n" + "wqc7+NSpkk3G4jJuuwJAODYlk2Q+djE4jkjDc4xiqsQGBQlI2dlgzjRjIF4HWiLx\n" + "bIrI0uCCbGItx++hlvmDx7G8anBmIFfBWIaKdX0aWw==\n" + "-----END RSA PRIVATE KEY-----\n"; + std::string message = "message test"; auto keyPrv = CKM::Key::create(CKM::RawBuffer(prv.begin(), prv.end()), CKM::Password()); @@ -2745,15 +2727,21 @@ RUNNER_TEST(T1810_verify_get_certificate_chain) // this certificate has been signed using PKCS chain std::string im = "-----BEGIN CERTIFICATE-----\n" - "MIIBozCCAQwCAQEwDQYJKoZIhvcNAQEFBQAwHDEaMBgGA1UEAwwRc2VydmVyQHRl\n" - "c3RtZS5jb20wHhcNMTUxMjA5MTA0NjU0WhcNMjUxMjA2MTA0NjU0WjAYMRYwFAYD\n" - "VQQDDA1lZUB0ZXN0bWUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP\n" - "+fNsZB1Vlmhnk0IwYDs7Pw9E38KQfTt/egqqRFN6IvIt0CCDBXqnPTujuvlO2OyL\n" - "XVuALnIBmTDm5Oz+oz+qiY6/XrVS/CoACNZyMo6ihG9OeocvDbU3jXEaPGL6ib/x\n" - "jlms0aA9d5L9TO2lEzEP7bFKgHCB8FWINcxSP5zl1QIDAQABMA0GCSqGSIb3DQEB\n" - "BQUAA4GBAKBpVJMkdK6/qnAz7d7Bul/BhhSLEYbNPdxRiUj3U2dt0GJgswMu2SNT\n" - "/3NXB8V8mnnXR6cWn5bmjyA7ZpQEKAatS/KEQ9wfLXyCgYDRebX71mVKAI3XcyxB\n" - "p2qsOWWaJhuHmC1GVjx3foL+RDrmRo6BiucNHMIuvrd1W36eKdhj\n" + "MIICxDCCAi0CFGHuCEUksqn0Rr3SXdhn+TlnL804MA0GCSqGSIb3DQEBCwUAMGEx\n" + "CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl\n" + "cm5ldCBXaWRnaXRzIFB0eSBMdGQxGjAYBgNVBAMMEXNlcnZlckB0ZXN0bWUuY29t\n" + "MB4XDTE5MDYxMzEyMTkyNloXDTI5MDYxMDEyMTkyNlowXTELMAkGA1UEBhMCQVUx\n" + "EzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg\n" + "UHR5IEx0ZDEWMBQGA1UEAwwNZWVAdGVzdG1lLmNvbTCCASIwDQYJKoZIhvcNAQEB\n" + "BQADggEPADCCAQoCggEBAK3/XvE3uc2EhzwmsAfq6KEw52J8kCAB9Rma/qjkw6ZT\n" + "yUYmSQvmcK8wSDt015Y/ekYLereCeWNLNkFlQeZC7LHT6T1mGnxNIgL3oUS2c+15\n" + "FEYX9QJIN/CoJYQ/tmiQPa1OJz4prUFwqAzM1kRtHGfcAGmQHfgu77P3ljAJzfsW\n" + "2beVHM+MTNSybkGHql28Z93bp382k5FQXegkxbozsKBMk37QjKiqes29J/ET0Huy\n" + "yzOkf+XvbizIPRvMt/2guw9sgRb7YrM2M+igmHIHxfzxuqzpPr+bmcqQdyFdVkAK\n" + "Qcx930HbfjHJ5k5vcovPLQ3LvSnYVCTe7aCAAmMzKXsCAwEAATANBgkqhkiG9w0B\n" + "AQsFAAOBgQBfFMim/9zLd+EeZyeYA0vy3C9YuNJI+KsZlKAfrFDQNeIT/qg/GQM4\n" + "o7I3TIHQ62tdEx6nBJs0DKSAmhRh4yc+P1KHMzIQIgSjftqS3Z+AKbJn6vOpWNTq\n" + "cexnpexaNn69dbqJZsjr0fHsGAkh5n96icAB4VZyFncEknZKbTdd0g==\n" "-----END CERTIFICATE-----\n"; auto cert = CKM::Certificate::create(CKM::RawBuffer(im.begin(), im.end()), CKM::DataFormat::FORM_PEM); diff --git a/src/ckm/unprivileged/sign-verify.cpp b/src/ckm/unprivileged/sign-verify.cpp new file mode 100644 index 0000000..c1a7b44 --- /dev/null +++ b/src/ckm/unprivileged/sign-verify.cpp @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2019 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 sign-verify.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace CKM; + +namespace { + +const char* PASSWORD = "test-password"; +const uid_t UID = 5001; + +struct KeyAliasPair +{ + Alias prv; + Alias pub; +}; + +enum Algo { + RSA, + DSA, + ECDSA +}; + +// algo names +const std::unordered_map ALGO2STR = { + { RSA, "RSA" }, + { DSA, "DSA" }, + { ECDSA, "ECDSA" }, +}; + +// keys +std::unordered_map>> KEYS; + +enum KeyIdx { + PRIMARY = 0, + PASSWORD_PROTECTED = 1, + + KEY_IDX_MAX +}; + +// hash algo names +const std::unordered_map HASH2STR = { +#ifndef TZ_BACKEND + // no hash is not supported in TZ + { CKMC_HASH_NONE, "NONE" }, +#endif + { CKMC_HASH_SHA1, "SHA1" }, + { CKMC_HASH_SHA256, "SHA256" }, + { CKMC_HASH_SHA384, "SHA384" }, + { CKMC_HASH_SHA512, "SHA512" }, +}; + +// padding names +const std::unordered_map PAD2STR = { +#ifndef TZ_BACKEND + // no padding is not supported in TZ + { CKMC_NONE_PADDING, "NONE" }, +#endif + { CKMC_PKCS1_PADDING, "PKCS1" }, +#ifndef TZ_BACKEND + // X9.31 is not supported in TZ + { CKMC_X931_PADDING, "X931" }, +#endif +}; + +const int EC_PRIME192V1 = static_cast(ElipticCurve::prime192v1); +const int EC_PRIME256V1 = static_cast(ElipticCurve::prime256v1); +const int EC_SECP384R1 = static_cast(ElipticCurve::secp384r1); + +// test messages +RawBufferPtr MESSAGE_SHORT; +std::unordered_map MESSAGES; +RawBufferPtr MESSAGE_LONG; + +class SignVerifyGroupFixture: public DPL::Test::TestGroup +{ +public: + void Init() override + { + remove_user_data(UID); + int ret = ckmc_unlock_user_key(UID, "db-pass"); + if (ret != CKMC_ERROR_NONE) + RUNNER_ERROR_MSG("DB unlock failed: " << CKMCErrorToString(ret)); + + // Policy backend to use in subsequent operations (global for each test case) +#ifdef TZ_BACKEND + m_backend = PolicyBackend::FORCE_HARDWARE; +#else + m_backend = PolicyBackend::FORCE_SOFTWARE; +#endif + + // generate keys + m_manager = Manager::create(); + generateKeys(RSA, 1024); + generateKeys(RSA, 2048); + generateKeys(RSA, 4096); + generateKeys(DSA, 1024); +#ifndef TZ_BACKEND + /* + * For DSA with SHA1 only 1024-bit keys are supported and TZ does not currently support + * anything else than SHA1 for DSA. + */ + generateKeys(DSA, 2048); + generateKeys(DSA, 3072); + generateKeys(DSA, 4096); +#endif +#ifndef TZ_BACKEND + // ECDSA is not yet supported on TZ + generateKeys(ECDSA, EC_PRIME192V1); + generateKeys(ECDSA, EC_PRIME256V1); + generateKeys(ECDSA, EC_SECP384R1); +#endif + + MESSAGE_SHORT = create_raw_buffer(createRandomBufferCAPI(512/8)); + + // Set first byte to 0 to avoid "data too large for modulus" error in unpadded RSA + MESSAGES[1024] = create_raw_buffer(createRandomBufferCAPI(1024/8)); + MESSAGES[1024]->data[0] = 0; + MESSAGES[2048] = create_raw_buffer(createRandomBufferCAPI(2048/8)); + MESSAGES[2048]->data[0] = 0; + MESSAGES[3072] = create_raw_buffer(createRandomBufferCAPI(3072/8)); + MESSAGES[3072]->data[0] = 0; + MESSAGES[4096]= create_raw_buffer(createRandomBufferCAPI(4096/8)); + MESSAGES[4096]->data[0] = 0; + + MESSAGE_LONG = create_raw_buffer(createRandomBufferCAPI(1000)); + } + + void generateKeys(Algo type, size_t bitLen) + { + for (int i = 0; i < KEY_IDX_MAX; i++) + { + Policy prvPolicy(Password(), false, m_backend); + Policy pubPolicy(Password(), true, m_backend); + if (i == PASSWORD_PROTECTED) { + prvPolicy.password.assign(PASSWORD); + pubPolicy.password.assign(PASSWORD); + } + + KeyAliasPair alias; + alias.prv = ALGO2STR.at(type) + std::string("_") + std::to_string(bitLen) + + std::string("_") + std::to_string(i); + alias.pub = std::string("pub") + alias.prv; + int ret; + switch (type) + { + case RSA: + ret = m_manager->createKeyPairRSA(bitLen, + alias.prv, alias.pub, + prvPolicy, pubPolicy); + break; + case DSA: + ret = m_manager->createKeyPairDSA(bitLen, + alias.prv, alias.pub, + prvPolicy, pubPolicy); + break; + case ECDSA: + ret = m_manager->createKeyPairECDSA(static_cast(bitLen), + alias.prv, alias.pub, + prvPolicy, pubPolicy); + break; + default: + ret = CKM_API_ERROR_UNKNOWN; + } + if (ret != CKM_API_SUCCESS) + RUNNER_ERROR_MSG("key creation failed. Type: " << ALGO2STR.at(type) << + " bits: " << bitLen << " error: " << APICodeToString(ret)); + + KEYS[type][bitLen].push_back(alias); + } + } + + void Finish() override + { + for (const auto &type : KEYS) { + for (const auto &entry : type.second) { + for (const auto &keyPair : entry.second) { + m_manager->removeAlias(keyPair.prv); + m_manager->removeAlias(keyPair.pub); + } + } + } + + MESSAGE_SHORT.reset(); + + int ret = ckmc_lock_user_key(UID); + if (ret != CKMC_ERROR_NONE) + RUNNER_ERROR_MSG("DB lock failed: " << CKMCErrorToString(ret)); + remove_user_data(UID); + } +private: + ManagerShPtr m_manager; + PolicyBackend m_backend; +}; + +std::string params2str(const Alias& alias, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding, + const RawBufferPtr& message) +{ + std::stringstream ss; + ss << " Alias: " << alias << ", hash algo: " << HASH2STR.at(hash) << + ", padding: " << PAD2STR.at(padding) << ", message len: " << message->size << "B."; + return ss.str(); +} + +void signExpect(int expected, + const Alias& alias, + const char* pw, + const RawBufferPtr& message, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding, + RawBufferPtr& signature) +{ + ckmc_raw_buffer_s* cSignature = nullptr; + + int ret = ckmc_create_signature(alias.c_str(), pw, *message, hash, padding, &cSignature); + RUNNER_ASSERT_MSG(ret == expected, "Unexpected result during signature creation." << + params2str(alias, hash, padding, message) << + " Expected: " << CKMCErrorToString(expected) << + " got: " << CKMCErrorToString(ret)); + if (ret == CKMC_ERROR_NONE) { + RUNNER_ASSERT_MSG(cSignature != nullptr && cSignature->size > 0, + "Empty signature returned." << + params2str(alias, hash, padding, message)); + signature = create_raw_buffer(cSignature); + } else { + RUNNER_ASSERT_MSG(cSignature == nullptr, + "Non-empty signature returned." << + params2str(alias, hash, padding, message)); + } +} + +void signInvalid(const Alias& alias, + const char* pw, + const RawBufferPtr& message, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding) +{ + RawBufferPtr signature; + signExpect(CKMC_ERROR_INVALID_PARAMETER, alias, pw, message, hash, padding, signature); +} + +void verifyExpect(int expected, + const Alias& alias, + const char* pw, + const RawBufferPtr& message, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding, + const RawBufferPtr& signature) +{ + int ret = ckmc_verify_signature(alias.c_str(), pw, *message, *signature, hash, padding); + RUNNER_ASSERT_MSG(ret == expected, "Unexpected result during signature verification." << + params2str(alias, hash, padding, message) << + " Expected: " << CKMCErrorToString(expected) << + " got: " << CKMCErrorToString(ret)); +} + +void signVerify(const KeyAliasPair& aliasPair, + const char* pw, + const RawBufferPtr& message, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding) +{ + RawBufferPtr signature; + signExpect(CKMC_ERROR_NONE, aliasPair.prv, pw, message, hash, padding, signature); + + RUNNER_ASSERT_MSG(signature->size > 0, "Empty signature returned"); + + verifyExpect(CKMC_ERROR_NONE, aliasPair.pub, pw, message, hash, padding, signature); + + // modify 1 bit of the signature + signature->data[0] ^= 0x01; + + // expect verification failure + verifyExpect(CKMC_ERROR_VERIFICATION_FAILED, + aliasPair.pub, + pw, + message, + hash, + padding, + signature); +} +// test given key pair against all hash and padding algos +void testSignVerify(Algo algo, size_t keyBits, int idx) +{ +#ifdef TZ_BACKEND + if (algo == DSA && keyBits > 1024) + RUNNER_IGNORED_MSG("For DSA with SHA1 only 1024-bit keys are supported and TZ does not"\ + " currently support anything else than SHA1 for DSA."); + if (algo == ECDSA) + RUNNER_IGNORED_MSG("ECDSA is not yet supported in TZ"); +#endif + + std::string pw; + if (idx == PASSWORD_PROTECTED) + pw = PASSWORD; + + const KeyAliasPair& keys = KEYS[algo][keyBits][idx]; + + // iterate over hash algorithms + for (const auto& hash : HASH2STR) { +#ifdef TZ_BACKEND + // in case of DSA only SHA1 is supported on TZ + if (algo == DSA && hash.first != CKMC_HASH_SHA1) + continue; +#endif + + // iterate over padding algorithms + for (const auto& pad : PAD2STR) { + auto expectSuccess = [&](const RawBufferPtr& msg) { + signVerify(keys, pw.c_str(), msg, hash.first, pad.first); + }; + auto expectInvalid = [&](const RawBufferPtr& msg) { + signInvalid(keys.prv, pw.c_str(), msg, hash.first, pad.first); + }; + + // padding is for RSA only, other algos should ignore it + if (algo == RSA && pad.first == CKMC_NONE_PADDING) { + if (hash.first == CKMC_HASH_NONE) { + // no hash + no padding + key matching message + expectSuccess(MESSAGES.at(keyBits)); + } + // no padding + short message + expectInvalid(MESSAGE_SHORT); + + // no padding + long message + expectInvalid(MESSAGE_LONG); + + } else { + if (hash.first == CKMC_HASH_NONE) { + // no hash + padding + long message + expectInvalid(MESSAGE_LONG); + + // no hash + padding + short message + if (algo == RSA) + expectSuccess(MESSAGE_SHORT); + else + expectInvalid(MESSAGE_SHORT); // no support for CKMC_HASH_NONE + } else { + // hash + padding + short message + expectSuccess(MESSAGE_SHORT); + + // hash + padding + long message + expectSuccess(MESSAGE_LONG); + } + } + } + } +} + +} // namespace anonymous + +RUNNER_TEST_GROUP_INIT_ENV(CKM_SIGN_VERIFY, SignVerifyGroupFixture); + + +// RSA +RUNNER_TEST(TSV_0110_sign_verify_rsa_1024) +{ + testSignVerify(RSA, 1024, PRIMARY); +} + +RUNNER_TEST(TSV_0120_sign_verify_rsa_1024_pw) +{ + testSignVerify(RSA, 1024, PASSWORD_PROTECTED); +} + +RUNNER_TEST(TSV_0130_sign_verify_rsa_2048) +{ + testSignVerify(RSA, 2048, PRIMARY); +} + +RUNNER_TEST(TSV_0140_sign_verify_rsa_2048_pw) +{ + testSignVerify(RSA, 2048, PASSWORD_PROTECTED); +} + +RUNNER_TEST(TSV_0150_sign_verify_rsa_4096) +{ + testSignVerify(RSA, 4096, PRIMARY); +} + +RUNNER_TEST(TSV_0160_sign_verify_rsa_4096_pw) +{ + testSignVerify(RSA, 4096, PASSWORD_PROTECTED); +} + + +// DSA +RUNNER_TEST(TSV_0210_sign_verify_dsa_1024) +{ + testSignVerify(DSA, 1024, PRIMARY); +} + +RUNNER_TEST(TSV_0220_sign_verify_dsa_1024_pw) +{ + testSignVerify(DSA, 1024, PASSWORD_PROTECTED); +} + +RUNNER_TEST(TSV_0230_sign_verify_dsa_2048) +{ + testSignVerify(DSA, 2048, PRIMARY); +} + +RUNNER_TEST(TSV_0240_sign_verify_dsa_2048_pw) +{ + testSignVerify(DSA, 2048, PASSWORD_PROTECTED); +} + +RUNNER_TEST(TSV_0250_sign_verify_dsa_3072) +{ + testSignVerify(DSA, 3072, PRIMARY); +} + +RUNNER_TEST(TSV_0260_sign_verify_dsa_3072_pw) +{ + testSignVerify(DSA, 3072, PASSWORD_PROTECTED); +} + +RUNNER_TEST(TSV_0270_sign_verify_dsa_4096) +{ + testSignVerify(DSA, 4096, PRIMARY); +} + +RUNNER_TEST(TSV_0280_sign_verify_dsa_4096_pw) +{ + testSignVerify(DSA, 4096, PASSWORD_PROTECTED); +} + + +// ECDSA +RUNNER_TEST(TSV_0310_sign_verify_ecdsa_PRIME192V1) +{ + testSignVerify(ECDSA, EC_PRIME192V1, PRIMARY); +} + +RUNNER_TEST(TSV_0320_sign_verify_ecdsa_PRIME192V1_pw) +{ + testSignVerify(ECDSA, EC_PRIME192V1, PASSWORD_PROTECTED); +} + +RUNNER_TEST(TSV_0330_sign_verify_ecdsa_PRIME256V1) +{ + testSignVerify(ECDSA, EC_PRIME256V1, PRIMARY); +} + +RUNNER_TEST(TSV_0340_sign_verify_ecdsa_PRIME256V1_pw) +{ + testSignVerify(ECDSA, EC_PRIME256V1, PASSWORD_PROTECTED); +} + +RUNNER_TEST(TSV_0350_sign_verify_ecdsa_SECP384R1) +{ + testSignVerify(ECDSA, EC_SECP384R1, PRIMARY); +} + +RUNNER_TEST(TSV_0360_sign_verify_ecdsa_SECP384R1_pw) +{ + testSignVerify(ECDSA, EC_SECP384R1, PASSWORD_PROTECTED); +} + +// TODO: border cases for padding +// TODO: invalid arguments +// TODO: Big data diff --git a/src/common/app_install_helper.cpp b/src/common/app_install_helper.cpp index 093da6b..1f6e0e8 100644 --- a/src/common/app_install_helper.cpp +++ b/src/common/app_install_helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2019 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. @@ -34,6 +34,9 @@ #include "app_install_helper.h" namespace { + +const gid_t FILE_GROUP = 100; + std::string genSkelPath() { static std::string skelPkgDir; if (!skelPkgDir.empty()) @@ -94,6 +97,18 @@ void AppInstallHelper::setInstallPath(RootType type) const { case RootType::SKEL: info.path = genSkelPath() + "/" + getPkgId(); break; + case RootType::SHARED: + if (m_isLocal) + info.path = TzPlatformConfig::appDirPath(getUID()) + ".shared/" + getPkgId(); + else + info.path = TzPlatformConfig::globalAppDir() + "/.shared/" + getPkgId(); + break; + case RootType::SHARED_TMP: + if (m_isLocal) + info.path = TzPlatformConfig::appDirPath(getUID()) + ".shared_tmp/" + getPkgId(); + else + info.path = TzPlatformConfig::globalAppDir() + "/.shared_tmp/" + getPkgId(); + break; } } @@ -110,7 +125,7 @@ std::string AppInstallHelper::getPath(app_install_path_type smType, PathType pTy break; case PathType::FILE: // put files in the directory of the same type - path = getInstallDir(rType) + "/" + typeToPath.at(smType) + "_dir0/" + typeToPath.at(smType) + std::to_string(i); + path = getPath(smType, PathType::DIR, 0, rType) + "/" + typeToPath.at(smType) + std::to_string(i); break; } return path; @@ -137,7 +152,11 @@ std::string AppInstallHelper::getPrivatePath(int i, RootType type) const { } std::string AppInstallHelper::getSharedRODir(int i, RootType type) const { - return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type); +return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type); +} + +std::string AppInstallHelper::getSharedROPath(int i, RootType type) const { + return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::FILE, i, type); } std::string AppInstallHelper::getAppId() const { @@ -167,8 +186,8 @@ int AppInstallHelper::getGID() const { bool AppInstallHelper::createFile(app_install_path_type smType, const std::string &path) { if (creat(path.c_str(), 0751) == 0) { // Local paths need user change - m_fileTypeMap[smType].push_back(std::move(path)); - if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0) + m_fileTypeMap[smType].push_back(path); + if (!m_isLocal || chown(path.c_str(), m_uidGid, FILE_GROUP) == 0) return true; } return false; @@ -178,8 +197,8 @@ bool AppInstallHelper::createDir(app_install_path_type smType, const std::string mktreeSafe(path, 0777); // Dont pass base pkg dirs to SM, because transmute will be forced on RO subdirs if (!isBasePath) - m_dirTypeMap[smType].push_back(std::move(path)); - if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0) + m_dirTypeMap[smType].push_back(path); + if (!m_isLocal || chown(path.c_str(), m_uidGid, FILE_GROUP) == 0) return true; return false; @@ -202,12 +221,25 @@ void AppInstallHelper::createPath(app_install_path_type smType, PathType pType, createDir(smType, path); break; case PathType::FILE: - createPath(smType, PathType::DIR, i, rType); + createPath(smType, PathType::DIR, 0, rType); createFile(smType, path); break; } } +void AppInstallHelper::createDirLink(app_install_path_type smType, const std::string &dest, int i, + RootType rType) +{ + createInstallDir(rType); + std::string linkPath = getPath(smType, PathType::DIR, i, rType); + if (symlink(dest.c_str(), linkPath.c_str()) == 0) { + m_fileTypeMap[smType].push_back(linkPath); + if (m_isLocal) { + chown(linkPath.c_str(), m_uidGid, FILE_GROUP); + } + } +} + void AppInstallHelper::createTrustedDir(int i, RootType type) { createPath(SECURITY_MANAGER_PATH_TRUSTED_RW, PathType::DIR, i, type); } @@ -225,7 +257,14 @@ void AppInstallHelper::createPrivateFile(int i, RootType type) { } void AppInstallHelper::createSharedRODir(int i, RootType type) { - createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type); + createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, RootType::SHARED); + createInstallDir(RootType::SHARED_TMP); + auto linkPath = getSharedRODir(i, RootType::SHARED); + createDirLink(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, linkPath, i, type); +} + +void AppInstallHelper::createSharedROFile(int i, RootType type) { + createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::FILE, i, type); } void AppInstallHelper::createPrivateRODir(int i, RootType type) { diff --git a/src/common/app_install_helper.h b/src/common/app_install_helper.h index e238261..cefeb71 100644 --- a/src/common/app_install_helper.h +++ b/src/common/app_install_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2019 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. @@ -90,7 +90,9 @@ struct AppInstallHelper { enum RootType { BASE, SKEL, - EXTENDED + EXTENDED, + SHARED, + SHARED_TMP }; enum PathType { @@ -107,6 +109,7 @@ struct AppInstallHelper { void createPublicDir(RootType type = RootType::BASE); void createPrivateFile(int i = 0, RootType type = RootType::BASE); void createSharedRODir(int i = 0, RootType type = RootType::BASE); + void createSharedROFile(int i = 0, RootType type = RootType::BASE); void createPrivateRODir(int i = 0, RootType type = RootType::BASE); void removePaths(); @@ -121,6 +124,7 @@ struct AppInstallHelper { std::string getPublicDir(RootType type = RootType::BASE) const; std::string getPrivatePath(int i = 0, RootType type = RootType::BASE) const; std::string getSharedRODir(int i = 0, RootType type = RootType::BASE) const; + std::string getSharedROPath(int i = 0, RootType type = RootType::BASE) const; const TypePathsMap& getDirsMap() const; const TypePathsMap& getFilesMap() const; @@ -155,6 +159,8 @@ protected: bool createFile(app_install_path_type smType, const std::string &path); bool createDir(app_install_path_type smType, const std::string &path, bool isBasePath = false); + void createDirLink(app_install_path_type smType, const std::string &dest, int i = 0, + RootType rType = RootType::BASE); void createInstallDir(RootType type); std::string m_appName; diff --git a/src/common/label_generator.cpp b/src/common/label_generator.cpp index 6fc5140..dbd00b5 100644 --- a/src/common/label_generator.cpp +++ b/src/common/label_generator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2017-2019 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. @@ -36,11 +36,6 @@ std::string generatePathROLabel(const std::string &pkgId) return generatePathRWLabel(pkgId) + "::RO"; } -std::string generatePathSharedROLabel(const std::string &pkgId) -{ - return generatePathRWLabel(pkgId) + "::SharedRO"; -} - std::string generatePathTrustedLabel(int64_t authorId) { return "User::Author::" + std::to_string(authorId); @@ -50,3 +45,8 @@ std::string getPublicPathLabel() { return "User::Home"; } + +std::string getSharedROPathLabel() +{ + return "User::App::Shared"; +} diff --git a/src/common/label_generator.h b/src/common/label_generator.h index 8c99ed4..b4af291 100644 --- a/src/common/label_generator.h +++ b/src/common/label_generator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2017-2019 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. @@ -20,6 +20,6 @@ std::string generateProcessLabel(const std::string &appId, const std::string &pkgId, bool isHybrid = false); std::string generatePathRWLabel(const std::string &pkgId); std::string generatePathROLabel(const std::string &pkgId); -std::string generatePathSharedROLabel(const std::string &pkgId); std::string generatePathTrustedLabel(int64_t authorId); std::string getPublicPathLabel(); +std::string getSharedROPathLabel(); diff --git a/src/common/scoped_installer.h b/src/common/scoped_installer.h index 4a0ff06..82175ce 100644 --- a/src/common/scoped_installer.h +++ b/src/common/scoped_installer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2019 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. @@ -36,7 +36,7 @@ class ScopedInstaller { public: ScopedInstaller(const AppInstallHelper &app, bool requestUid = true) - : m_appId(app.getAppId()), + : m_appIds({app.getAppId()}), m_uid(app.getUID()), m_installType(app.getInstallType()), m_shouldUninstall(true), @@ -70,9 +70,30 @@ public: SecurityManagerTest::Api::install(instReq); } + ScopedInstaller(const std::vector &appIds, const std::string &pkgId) + : m_appIds(appIds), + m_uid(0), + m_installType(SM_APP_INSTALL_NONE), + m_shouldUninstall(true), + m_requestUid(false), + m_creatorPid(getpid()) + { + SecurityManagerTest::InstallRequest instReq; + + instReq.setPkgId(pkgId); + for (unsigned int i = 0; i < appIds.size(); i++) { + if (i > 0) + instReq.nextApp(); + + instReq.setAppId(appIds[i]); + } + + SecurityManagerTest::Api::install(instReq); + } + ScopedInstaller(const ScopedInstaller &) = delete; ScopedInstaller(ScopedInstaller &&other) - : m_appId(std::move(other.m_appId)), + : m_appIds(std::move(other.m_appIds)), m_uid(other.m_uid), m_installType(other.m_installType), m_shouldUninstall(other.m_shouldUninstall), @@ -97,7 +118,12 @@ public: if (!m_shouldUninstall) return; SecurityManagerTest::InstallRequest uninstReq; - uninstReq.setAppId(m_appId); + for (unsigned int i = 0; i < m_appIds.size(); i++) { + if (i > 0) + uninstReq.nextApp(); + + uninstReq.setAppId(m_appIds[i]); + } if (m_requestUid) uninstReq.setUid(m_uid); if (m_installType != SM_APP_INSTALL_NONE) @@ -107,7 +133,7 @@ public: } protected: - std::string m_appId; + std::vector m_appIds; uid_t m_uid; app_install_type m_installType; bool m_shouldUninstall; diff --git a/src/common/scoped_process_label.cpp b/src/common/scoped_process_label.cpp index 47872bc..aa642fe 100644 --- a/src/common/scoped_process_label.cpp +++ b/src/common/scoped_process_label.cpp @@ -68,7 +68,10 @@ OnlycapSet smackGetOnlycap() break; last = onlycap.find_first_of(SEPARATORS, first + 1); - onlycapSet.insert(onlycap.substr(first, last - first)); + if (last == std::string::npos) + onlycapSet.insert(onlycap.substr(first)); + else + onlycapSet.insert(onlycap.substr(first, last - first)); } return onlycapSet; } @@ -122,7 +125,6 @@ ScopedProcessLabel::ScopedProcessLabel(std::string label, bool restore) : newOnlycap.insert(m_label); smackSetOnlycap(newOnlycap); } else { - m_originalLabel.clear(); m_originalOnlycap.clear(); } } @@ -135,7 +137,8 @@ ScopedProcessLabel::~ScopedProcessLabel() if (!m_originalLabel.empty()) { try { smackSetLabelForSelf(m_originalLabel); - smackSetOnlycap(m_originalOnlycap); + if (!m_originalOnlycap.empty()) + smackSetOnlycap(m_originalOnlycap); } catch (const DPL::Test::TestException& e) { RUNNER_ERROR_MSG("Test exception occurred: " << e.GetMessage()); } catch (const std::exception& e) { diff --git a/src/common/service_manager.cpp b/src/common/service_manager.cpp index c571d5f..4441ace 100644 --- a/src/common/service_manager.cpp +++ b/src/common/service_manager.cpp @@ -283,10 +283,10 @@ void ServiceManager::executeMethod(const std::string &method, const std::string void ServiceManager::startService(bool withSockets) { - executeMethod("StartUnit", m_serviceName); if (withSockets) for (const auto &socket : m_socketsNames) executeMethod("StartUnit", socket); + executeMethod("StartUnit", m_serviceName); } void ServiceManager::stopService(bool withSockets) diff --git a/src/common/sm_api.cpp b/src/common/sm_api.cpp index e8c5bba..4516755 100644 --- a/src/common/sm_api.cpp +++ b/src/common/sm_api.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2019 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. @@ -123,6 +123,15 @@ void dropProcessPrivileges(lib_retcode expectedResult) << " Expected result: " << expectedResult); } +void prepareAppCandidate(lib_retcode expectedResult) +{ + int result = security_manager_prepare_app_candidate(); + RUNNER_ASSERT_MSG((lib_retcode) result == expectedResult, + "preparing app candidate process returned wrong value." + << " Result: " << result << ";" + << " Expected result: " << expectedResult); +} + void prepareApp(const std::string &appId, lib_retcode expectedResult) { int result = security_manager_prepare_app(appId.c_str()); diff --git a/src/common/sm_api.h b/src/common/sm_api.h index 1b4d2e1..a623ab8 100644 --- a/src/common/sm_api.h +++ b/src/common/sm_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2019 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. @@ -37,6 +37,7 @@ void setProcessLabel(const std::string &appId, lib_retcode expectedResult = SECU void setProcessGroups(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void dropProcessPrivileges(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void prepareApp(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); +void prepareAppCandidate(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void cleanupApp(const std::string &appId, uid_t uid, pid_t pid, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void addUser(const UserRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void deleteUser(const UserRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); diff --git a/src/common/sm_request.cpp b/src/common/sm_request.cpp index 6e06150..b6fa1a1 100644 --- a/src/common/sm_request.cpp +++ b/src/common/sm_request.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2019 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. @@ -70,7 +70,6 @@ void InstallRequest::setAppId(std::string appId, lib_retcode expectedResult) << " App id: " << appId << ";" << " Result: " << result << ";" << " Expected result: " << expectedResult); - m_appId = std::move(appId); } void InstallRequest::setPkgId(std::string pkgId, lib_retcode expectedResult) @@ -167,10 +166,17 @@ void InstallRequest::setHybrid(lib_retcode expectedResult) << " Expected result: " << expectedResult); } +void InstallRequest::nextApp(lib_retcode expectedResult) +{ + int result = security_manager_app_inst_req_next(m_req); + RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult, + "security_manager_app_inst_req_next() returned wrong value." + << " Result: " << result << ";" + << " Expected result: " << expectedResult); +} + std::ostream& operator<<(std::ostream &os, const InstallRequest &request) { - if (!request.m_appId.empty()) - os << "app id: " << request.m_appId << "; "; if (!request.m_pkgId.empty()) os << "pkg id: " << request.m_pkgId << "; "; if (!request.m_privileges.empty()) { diff --git a/src/common/sm_request.h b/src/common/sm_request.h index 4efb5c9..d58d43e 100644 --- a/src/common/sm_request.h +++ b/src/common/sm_request.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2019 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. @@ -42,7 +42,6 @@ public: InstallRequest& operator=(const InstallRequest&) = delete; InstallRequest(InstallRequest &&other) : m_req(std::move(other.m_req)), - m_appId(std::move(other.m_appId)), m_pkgId(std::move(other.m_pkgId)), m_authorId(std::move(other.m_authorId)), m_privileges(std::move(other.m_privileges)), @@ -67,6 +66,7 @@ public: void setAuthorId(std::string authorId, lib_retcode expectedResult= SECURITY_MANAGER_SUCCESS); void setInstallType(const enum app_install_type &type, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void setHybrid(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); + void nextApp(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); std::string getPkgId() const { return m_pkgId; } std::string getAppTizenVersion() const { return m_tizenVer; } app_inst_req *get() { return m_req; } @@ -77,7 +77,6 @@ private: app_inst_req *m_req; std::string m_tizenVer; - std::string m_appId; std::string m_pkgId; std::string m_authorId; PrivilegeVector m_privileges; diff --git a/src/common/synchronization_pipe.cpp b/src/common/synchronization_pipe.cpp index dcf9d30..8336767 100644 --- a/src/common/synchronization_pipe.cpp +++ b/src/common/synchronization_pipe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2020 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. @@ -20,6 +20,7 @@ * @brief A crippled abstraction of widely praised, but often misused communication mechanism */ +#include #include #include @@ -76,15 +77,33 @@ void SynchronizationPipe::claimChildEp() { } void SynchronizationPipe::post() { - RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed"); - auto ret = TEMP_FAILURE_RETRY(write(m_writeEp, "#", 1)); - RUNNER_ASSERT_ERRNO_MSG(ret > 0, "Write failed ret = " << ret); + post("#", 1); } void SynchronizationPipe::wait() { + char dummy; + wait(&dummy, 1); +} + +void SynchronizationPipe::pollForWait() { + RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed"); + + pollfd fds[1]; + fds->fd = m_readEp; + fds->events = POLLIN; + auto ret = TEMP_FAILURE_RETRY(poll(fds, 1, -1)); + RUNNER_ASSERT_ERRNO(ret > 0); +} + +void SynchronizationPipe::post(const void *data, size_t size) { + RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed"); + auto ret = TEMP_FAILURE_RETRY(write(m_writeEp, data, size)); + RUNNER_ASSERT_ERRNO_MSG(ret > 0 && size_t(ret) == size, "Write failed size = " << size << " ret = " << ret); +} + +void SynchronizationPipe::wait(void *data, size_t size) { RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed"); - char buf; - auto ret = TEMP_FAILURE_RETRY(read(m_readEp, &buf, 1)); - RUNNER_ASSERT_ERRNO_MSG(ret > 0, "Read failed ret = " << ret); + auto ret = TEMP_FAILURE_RETRY(read(m_readEp, data, size)); + RUNNER_ASSERT_ERRNO_MSG(ret > 0 && size_t(ret) == size, "Read failed size = " << size << " ret = " << ret); } diff --git a/src/common/synchronization_pipe.h b/src/common/synchronization_pipe.h index e072ca2..099323d 100644 --- a/src/common/synchronization_pipe.h +++ b/src/common/synchronization_pipe.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2020 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. @@ -33,6 +33,10 @@ public: void post(); void wait(); + void pollForWait(); + + void post(const void *data, size_t size); + void wait(void *data, size_t size); private: int m_pipeCP[2]; // Child -> Parent diff --git a/src/common/tests_common.h b/src/common/tests_common.h index 2eb4a00..bfb46d9 100644 --- a/src/common/tests_common.h +++ b/src/common/tests_common.h @@ -38,7 +38,7 @@ #include const uid_t APP_UID = 5001; -const gid_t APP_GID = 5001; +const gid_t APP_GID = 100; const uid_t APP_UID_2 = 5200; const gid_t APP_GID_2 = 5200; const uid_t DB_ALARM_UID = 6001; diff --git a/src/cynara-tests/common/cynara_test_client_async_client.cpp b/src/cynara-tests/common/cynara_test_client_async_client.cpp index 57fc289..885b3e1 100644 --- a/src/cynara-tests/common/cynara_test_client_async_client.cpp +++ b/src/cynara-tests/common/cynara_test_client_async_client.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2020 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. @@ -21,6 +21,7 @@ #include #include +#include #include namespace CynaraTestClientAsync { @@ -129,31 +130,22 @@ void Client::process(int expectedResult, if (m_statusMonitor.getStatus() == DISCONNECTED) return; - int fd = m_statusMonitor.getFd(); - fd_set fds; - timeval tv; - FD_ZERO(&fds); - FD_SET(fd, &fds); - tv.tv_sec = timeoutSeconds; - tv.tv_usec = 0; - - int ret; - if (m_statusMonitor.getStatus() == READ) - ret = TEMP_FAILURE_RETRY(select(fd + 1, &fds, NULL, NULL, &tv)); - else - ret = TEMP_FAILURE_RETRY(select(fd + 1, &fds, &fds, NULL, &tv)); + pollfd fds[1]; + fds->fd = m_statusMonitor.getFd(); + fds->events = POLLIN | (m_statusMonitor.getStatus() == READ ? 0 : POLLOUT); + int ret = TEMP_FAILURE_RETRY(poll(fds, 1, timeoutSeconds * 1000)); if (ret == 0) { RUNNER_ASSERT_MSG(timeoutExpectation != EXPECT_NO_TIMEOUT, - "Unexpected select timeout." + "Unexpected poll timeout." << " ret = " << ret); return; } RUNNER_ASSERT_ERRNO_MSG(ret > 0, - "Select returned error:" + "Poll returned error:" << " ret = " << ret); RUNNER_ASSERT_MSG(timeoutExpectation != EXPECT_TIMEOUT, - "Select returned positive value, when timeout was expected." + "Poll returned positive value, when timeout was expected." << " ret = " << ret); RUNNER_DEFER_SCOPE(ret = cynara_async_process(m_cynara);); diff --git a/src/framework/src/assert.cpp b/src/framework/src/assert.cpp index 636a7cf..6adc2ef 100644 --- a/src/framework/src/assert.cpp +++ b/src/framework/src/assert.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2011-2020 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. @@ -58,7 +58,7 @@ void AssertProc(const char *condition, INTERNAL_LOG("### Function: " << function); INTERNAL_LOG( "################################################################################"); - } catch (Exception) { + } catch (Exception&) { // Just ignore possible double errors } diff --git a/src/framework/src/test_runner.cpp b/src/framework/src/test_runner.cpp index 8c91236..26a11d2 100644 --- a/src/framework/src/test_runner.cpp +++ b/src/framework/src/test_runner.cpp @@ -274,6 +274,7 @@ void TestRunner::RunTestCase(TestCasePtr testCase) if (!testReason.empty()) testReason += "\n"; testReason += finishReason; + break; case TestResult::FailStatus::NONE: if (!cleanupReason.empty()) { if (!testReason.empty()) diff --git a/src/nether-tests/CMakeLists.txt b/src/nether-tests/CMakeLists.txt new file mode 100644 index 0000000..5cf7915 --- /dev/null +++ b/src/nether-tests/CMakeLists.txt @@ -0,0 +1,79 @@ +# Copyright (c) 2017 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 CMakeLists.txt +# @author Piotr Sawicki (p.sawicki2@partner.samsung.com) +# @brief CMake configuration file +# + +INCLUDE(FindPkgConfig) + +SET(TARGET_NETHER_TESTS "nether-tests") + +SET(NETHER_TESTS_SOURCES + ${PROJECT_SOURCE_DIR}/src/nether-tests/nether_tests.cpp + ${PROJECT_SOURCE_DIR}/src/common/tests_common.cpp + ${PROJECT_SOURCE_DIR}/src/common/tzplatform.cpp + ${PROJECT_SOURCE_DIR}/src/common/sm_api.cpp + ${PROJECT_SOURCE_DIR}/src/common/sm_request.cpp + ${PROJECT_SOURCE_DIR}/src/common/sm_user_request.cpp + ${PROJECT_SOURCE_DIR}/src/common/sm_policy_request.cpp + ${PROJECT_SOURCE_DIR}/src/common/app_install_helper.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/policy_configuration.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/template_parser.cpp + ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp + ) + +INCLUDE_DIRECTORIES(SYSTEM + ${SEC_MGR_TESTS_DEP_INCLUDE_DIRS} + ) + +INCLUDE_DIRECTORIES(SYSTEM + ${CYNARA_TARGET_DEP_INCLUDE_DIRS} + ) + +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR}/src/common/ + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/ + ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/ + ) + +FIND_PACKAGE(Threads) + +ADD_EXECUTABLE(${TARGET_NETHER_TESTS} ${NETHER_TESTS_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_NETHER_TESTS} + ${SEC_MGR_TESTS_DEP_LIBRARIES} + dpl-test-framework + tests-common + ${CMAKE_THREAD_LIBS_INIT} + ) + +INSTALL(TARGETS ${TARGET_NETHER_TESTS} DESTINATION /usr/bin) + +INSTALL(FILES + ${PROJECT_SOURCE_DIR}/src/nether-tests/setup-nether-tests-nns.sh + ${PROJECT_SOURCE_DIR}/src/nether-tests/teardown-nether-tests-nns.sh + ${PROJECT_SOURCE_DIR}/src/nether-tests/setup-nether-tests-dns.sh + ${PROJECT_SOURCE_DIR}/src/nether-tests/teardown-nether-tests-dns.sh + DESTINATION bin + PERMISSIONS OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE + ) diff --git a/src/nether-tests/nether_tests.cpp b/src/nether-tests/nether_tests.cpp new file mode 100644 index 0000000..69bf807 --- /dev/null +++ b/src/nether-tests/nether_tests.cpp @@ -0,0 +1,1441 @@ +/* + * Copyright (c) 2017 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 nether_tests.cpp + * @author Piotr Sawicki (p.sawicki2@partner.samsung.com) + * @version 1.0 + * @brief Tests for Nether service + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +using namespace SecurityManagerTest; +using namespace DPL::Test; + +const std::string INTERNET_ACCESS_PRIVILEGE = "http://tizen.org/privilege/internet"; +const std::string NETHER_NETNS_NAME_NONE = ""; +const std::string NETHER_NETNS_NAME_TEST = "nether_test_network_ns"; +const std::string NETNS_RUN_DIR = "/var/run/netns"; // taken from iproute2 +const std::string NETHER_NETNS_SETUP_COMMAND = "/usr/bin/setup-nether-tests-nns.sh " + NETHER_NETNS_NAME_TEST; +const std::string NETHER_NETNS_TEARDOWN_COMMAND = "/usr/bin/teardown-nether-tests-nns.sh " + NETHER_NETNS_NAME_TEST; +const std::string NETHER_DNS_SETUP_COMMAND = "/usr/bin/setup-nether-tests-dns.sh"; +const std::string NETHER_DNS_TEARDOWN_COMMAND = "/usr/bin/teardown-nether-tests-dns.sh"; + + +const ssize_t NET_BUFFER_SIZE = 2048; +const int UDP_MESSAGES_COUNT = 20000; +const int TCP_MESSAGES_COUNT = 20000; + +const uint16_t UDP_TEST_PORT = 12000; +const uint16_t TCP_TEST_PORT = 12000; + +const std::string REMOTE_INTERFACE_ADDRESS = "10.1.0.2"; +const std::string REMOTE_INTERFACE_NAME = "veth1"; +const std::string LOCAL_HOST_TEST_SERVER_ADDRESS = "127.0.0.1"; +const std::string LOCAL_TEST_MCAST_GROUP = "225.0.0.250"; +const std::string DNS_TEST_ADDRESS = "www.samsung.com"; +const std::string ANY_INTERFACE = ""; + +const char TTL_MCAST_RESTRIC_SUBNET = 1; + +const int MONITOR_TIMEOUT = 1000; // ms + +enum class NetherInternetAccess { + ACCESS_GRANTED, + ACCESS_DENIED +}; + + +void runShellScriptInChildAndWait(const std::string &command) +{ + RUNNER_ASSERT_MSG(system(command.c_str()) != -1, "Couldn't run command: " << command); +} + + +class ScopedShellScriptRunner final { +public: + ScopedShellScriptRunner(const std::string &setupCmd, const std::string &teardownCmd) + : m_teardownCmd(teardownCmd) + { + runShellScriptInChildAndWait(setupCmd); + } + + ~ScopedShellScriptRunner() + { + SafeCleanup::run([this]() { + runShellScriptInChildAndWait(m_teardownCmd); + }); + } + + ScopedShellScriptRunner(const ScopedShellScriptRunner &) = delete; + ScopedShellScriptRunner &operator=(const ScopedShellScriptRunner &) = delete; + +private: + std::string m_teardownCmd; +}; + + +void createChildProcess(const std::function &procedure, pid_t &childPid, int &childPipeFd) +{ + int pipeFd[2]; + RUNNER_ASSERT_ERRNO_MSG(pipe2(pipeFd, O_DIRECT) == 0, "pipe() failed"); + + pid_t pid = fork(); + RUNNER_ASSERT_ERRNO_MSG(pid != -1, "fork() failed"); + + if (pid != 0) { + // parent code + TEMP_FAILURE_RETRY(close(pipeFd[1])); + + childPipeFd = pipeFd[0]; + childPid = pid; + } else { + // child code + TestRunnerSingleton::Instance().Terminate(); + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + close(pipeFd[0]); + + int retStatus = EXIT_FAILURE; + + int devNullFd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY)); + if (devNullFd == -1) { + goto end; + } + + if (TEMP_FAILURE_RETRY(dup2(devNullFd, STDIN_FILENO)) == -1) { + goto end; + } + + if (TEMP_FAILURE_RETRY(dup2(devNullFd, STDOUT_FILENO)) == -1) { + goto end; + } + + if (TEMP_FAILURE_RETRY(dup2(devNullFd, STDERR_FILENO)) == -1) { + goto end; + } + + retStatus = procedure(pipeFd[1]); +end: + exit(retStatus); + } +} + + +int switchToNetworkNamespace(const std::string &netnsName) +{ + if (netnsName == NETHER_NETNS_NAME_NONE) { + return 0; + } + + const std::string netnsPath { NETNS_RUN_DIR + "/" + netnsName }; + if (netnsPath.length() >= PATH_MAX) { + return -1; + } + + int netNsFd = open(netnsPath.c_str(), O_RDONLY); + if (netNsFd == -1) { + return -1; + } + + // uses an existing network name-space (previously created by "ip netns" command) + if (setns(netNsFd, CLONE_NEWNET) == -1) { + close(netNsFd); + return -1; + } + + return 0; +} + + +class TemporaryNormalTestUser +{ +public: + TemporaryNormalTestUser(const std::string &userName) + : m_user(userName, GUM_USERTYPE_NORMAL, false) + { + m_user.create(); + } + + uid_t getUid() const + { + return m_user.getUid(); + } + +private: + TemporaryTestUser m_user; +}; + + +class InternetLocalAppInstallHelper : public AppInstallHelper +{ +public: + InternetLocalAppInstallHelper(const std::string &namePrefix, uid_t uid, NetherInternetAccess access) + : AppInstallHelper(namePrefix, uid) + { + setInstallType(app_install_type::SM_APP_INSTALL_LOCAL); + if (access == NetherInternetAccess::ACCESS_GRANTED) { + addPrivilege(INTERNET_ACCESS_PRIVILEGE); + } + } +}; + + +class AppContext +{ +public: + AppContext() + : m_appId{} + , m_appUID(-1) + , m_appGID(-1) + { + } + + AppContext(const std::string &appId, uid_t appUID, gid_t appGID) + : m_appId(appId) + , m_appUID(appUID) + , m_appGID(appGID) + { + } + + const std::string &appId() const + { + return m_appId; + } + + void setAppId(const std::string &appId) + { + m_appId = appId; + } + + uid_t getUID() const + { + return m_appUID; + } + + void setUID(uid_t appUID) + { + m_appUID = appUID; + } + + gid_t getGID() const + { + return m_appGID; + } + + void setGID(gid_t appGID) + { + m_appGID = appGID; + } + +private: + std::string m_appId; + uid_t m_appUID; + gid_t m_appGID; +}; + + +class ScopedAppContext : public AppContext +{ +public: + ScopedAppContext(const std::string &appPrefix, NetherInternetAccess access) + : m_user(appPrefix + "_user") + , m_installHelper(appPrefix + "_app_normal", m_user.getUid(), access) + , m_scopedInstaller(m_installHelper) + { + setAppId(m_installHelper.getAppId()); + setUID(m_installHelper.getUID()); + setGID(m_installHelper.getGID()); + } + +private: + TemporaryNormalTestUser m_user; + InternetLocalAppInstallHelper m_installHelper; + ScopedInstaller m_scopedInstaller; +}; + + +void runProcedureInNetAppContext( + const std::string &appPrefix, + const std::function &procedure, + const NetherInternetAccess access = NetherInternetAccess::ACCESS_DENIED) +{ + ScopedAppContext scopedAppContext(appPrefix, access); + + auto smackLabel = scopedAppContext.appId(); + auto appUID = scopedAppContext.getUID(); + auto appGID = scopedAppContext.getGID(); + + // run client procedure in app context + runInChildParentWait([=]() { + Api::setProcessLabel(smackLabel); + RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(appUID, appGID) == 0, + "drop_root_privileges() failed"); + procedure(); + }); +} + + +class NetServer +{ +public: + NetServer() + : m_monitorIsRunning(false) + , m_receivedBytes(0ull) + , m_serverPid(-1) + , m_serverPipeFd(-1) + {} + + NetServer(const NetServer &) = delete; + NetServer &operator=(const NetServer &) = delete; + + virtual ~NetServer() + { + SafeCleanup::run([this]() { + stop(); + }); + } + + void start(const std::string &netnsName = NETHER_NETNS_NAME_NONE) + { + std::unique_lock lock(m_monitorMutex); + + RUNNER_ASSERT_MSG(!m_monitorIsRunning, "Monitor thread is already running"); + + createChildProcess([=] (int pipeFd) -> int { + if (netnsName != NETHER_NETNS_NAME_NONE) { + if (switchToNetworkNamespace(netnsName) == -1) { + exit(EXIT_FAILURE); + } + } + return serverProcedure(pipeFd); + }, m_serverPid, m_serverPipeFd); + + waitForServer(); + + m_monitorThread = std::move(std::thread(&NetServer::monitorThreadProc, this)); + + m_monitorSyncPoint.wait(lock, [this]() { + return m_monitorIsRunning; + }); + } + + void stop() + { + stopMonitor(); + closeServerPipe(); + stopServerProcess(); + } + + uint64_t getReceivedBytes() const + { + RUNNER_ASSERT_MSG(!isAlive(), "Cannot read statistics. Server is still running: " << (*this)); + return m_receivedBytes; + } + + bool isAlive() const + { + int status; + return waitpid(m_serverPid, &status, WNOHANG) == 0; + } + + virtual int serverProcedure(int) = 0; + + virtual std::string getDescription() const = 0; + +protected: + void notifyManager(int pipeFd) + { + char c = 'X'; + ssize_t ret = TEMP_FAILURE_RETRY(write(pipeFd, &c, sizeof(c))); + if (ret == -1) { + exit(EXIT_FAILURE); + } + } + +private: + void waitForServer() const + { + pollfd pfd { m_serverPipeFd, POLLIN, 0 }; + + int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, MONITOR_TIMEOUT)); + RUNNER_ASSERT_ERRNO_MSG(ret >= 0, "poll() failed"); + + if (pfd.revents & POLLIN) { + char c; + ssize_t len = TEMP_FAILURE_RETRY(read(m_serverPipeFd, &c, sizeof(c))); + RUNNER_ASSERT_ERRNO_MSG(len >= 0, "Read pipe failed"); + } + } + + ssize_t collectStatistics() + { + char buffer[NET_BUFFER_SIZE]; + + ssize_t ret = TEMP_FAILURE_RETRY(read(m_serverPipeFd, buffer, sizeof(buffer))); + if (ret > 0) { + m_receivedBytes += static_cast(ret); + } + + return ret; + } + + void closeServerPipe() + { + if (m_serverPipeFd == -1) { + return; + } + + close(m_serverPipeFd); + m_serverPipeFd = -1; + } + + void stopServerProcess() + { + if (m_serverPid == -1) { + return; + } + + if (!isAlive()) { + m_serverPid = -1; + return; + } + + RUNNER_ASSERT_ERRNO_MSG(kill(m_serverPid, SIGTERM) == 0, "kill() failed"); + + int status; + do { + pid_t ret = TEMP_FAILURE_RETRY(waitpid(m_serverPid, &status, WUNTRACED | WCONTINUED)); + RUNNER_ASSERT_ERRNO_MSG(ret != -1, "waitpid() failed"); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + + m_serverPid = -1; + } + + void stopMonitor() + { + { + std::lock_guard lock(m_monitorMutex); + m_monitorIsRunning = false; + } + + if (m_monitorThread.joinable()) { + m_monitorThread.join(); + } + } + + void monitorThreadProc() + { + std::unique_lock lock(m_monitorMutex); + m_monitorIsRunning = true; + lock.unlock(); + + m_monitorSyncPoint.notify_one(); + + lock.lock(); + + pollfd pollFd{ m_serverPipeFd, POLLIN, 0 }; + + while (m_monitorIsRunning) { + + lock.unlock(); + + int ret = TEMP_FAILURE_RETRY(poll(&pollFd, 1, MONITOR_TIMEOUT)); + if (ret == -1) { + lock.lock(); + break; + } + + if (ret > 0 && (pollFd.revents & POLLIN)) { + if (collectStatistics() == -1) { + lock.lock(); + break; + } + } + + lock.lock(); + } + + m_monitorIsRunning = false; + lock.unlock(); + } + + // monitor variables + std::thread m_monitorThread; + bool m_monitorIsRunning; + std::mutex m_monitorMutex; + std::condition_variable m_monitorSyncPoint; + + // server variables + uint64_t m_receivedBytes; + pid_t m_serverPid; + int m_serverPipeFd; + + friend std::ostream &operator<<(std::ostream &os, const NetServer &); +}; + + +std::ostream &operator<<(std::ostream &os, const NetServer &server) +{ + os << server.getDescription(); + return os; +} + + +class UDPServer : public NetServer +{ +public: + UDPServer(uint16_t port, int protocol = IPPROTO_UDP) + : NetServer{} + , m_port(port) + , m_protocol(protocol) + {} + + virtual ~UDPServer() {} + + virtual std::string getDescription() const override + { + return "UDPServer port: " + std::to_string(m_port); + } + + virtual bool applyExtraSocketOptions(int) + { + return true; + } + + virtual int serverProcedure(int pipeFd) override + { + FdUniquePtr pipePtr(&pipeFd); + + int sockFd = socket(AF_INET, SOCK_DGRAM, m_protocol); + if (sockFd == -1) { + exit(EXIT_FAILURE); + } + + SockUniquePtr sockPtr(&sockFd); + + int optionValue = 1; + if (setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, static_cast(&optionValue) , sizeof(int)) == -1) { + exit(EXIT_FAILURE); + } + + struct sockaddr_in serverAddress; + memset(&serverAddress, 0, sizeof(serverAddress)); + serverAddress.sin_family = AF_INET; + serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); + serverAddress.sin_port = htons(m_port); + + if (bind(sockFd, reinterpret_cast(&serverAddress), sizeof(serverAddress)) == -1) { + exit(EXIT_FAILURE); + } + + if (!applyExtraSocketOptions(sockFd)) { + exit(EXIT_FAILURE); + } + + struct sockaddr_in clntAddress; + socklen_t clntAddressLength = static_cast(sizeof(clntAddress)); + char receiveBuffer[NET_BUFFER_SIZE]; + + notifyManager(pipeFd); + + while (true) { + ssize_t len = TEMP_FAILURE_RETRY(recvfrom(sockFd, receiveBuffer, sizeof(receiveBuffer), 0, + reinterpret_cast(&clntAddress), &clntAddressLength)); + + if (len == -1) { + exit(EXIT_FAILURE); + } + + if (len == 0) { + continue; + } + + do { + ssize_t pos = 0; + ssize_t ret = TEMP_FAILURE_RETRY(write(pipeFd, &receiveBuffer[pos], len)); + if (ret == -1) { + exit(EXIT_FAILURE); + } + + len -= ret; + pos += ret; + } while (len != 0); + } + + return EXIT_SUCCESS; + } + +private: + uint16_t m_port; + int m_protocol; +}; + + +class UDPServerApp : public UDPServer +{ +public: + UDPServerApp(uint16_t port, int protocol, const AppContext &appContext) + : UDPServer(port, protocol) + , m_appContext(appContext) + { + } + + virtual int serverProcedure(int pipeFd) override + { + Api::setProcessLabel(m_appContext.appId()); + RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(m_appContext.getUID(), m_appContext.getGID()) == 0, + "drop_root_privileges() failed"); + + return UDPServer::serverProcedure(pipeFd); + } + +private: + AppContext m_appContext; +}; + +class UDPMulticastServer : public UDPServer +{ +public: + UDPMulticastServer(uint16_t port, int protocol, + const std::string &mcastGroup, const std::string &networkInterface) + : UDPServer(port, protocol) + , m_mcastGroup(mcastGroup) + , m_networkInterface(networkInterface) + { + } + + bool applyExtraSocketOptions(int sockFd) override + { + struct ip_mreq multicastRequest; + memset(&multicastRequest, 0, sizeof(multicastRequest)); + + in_addr_t mcastGroupAddr = inet_addr(m_mcastGroup.c_str()); + if (!IN_MULTICAST(ntohl(mcastGroupAddr))) { + return false; + } + + multicastRequest.imr_multiaddr.s_addr = mcastGroupAddr; + + if (m_networkInterface == ANY_INTERFACE) { + multicastRequest.imr_interface.s_addr = INADDR_ANY; + } else { + struct ifreq interfaceRequest; + memset(&interfaceRequest, 0, sizeof(interfaceRequest)); + + interfaceRequest.ifr_addr.sa_family = AF_INET; + strncpy(interfaceRequest.ifr_name, m_networkInterface.c_str(), IFNAMSIZ); + interfaceRequest.ifr_name[IFNAMSIZ - 1] = '\0'; + + if (ioctl(sockFd, SIOCGIFADDR, &interfaceRequest) == -1) { + return false; + } + + struct sockaddr_in *addr = reinterpret_cast(&interfaceRequest.ifr_addr); + multicastRequest.imr_interface.s_addr = addr->sin_addr.s_addr; + } + + return setsockopt(sockFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + static_cast(&multicastRequest), sizeof(multicastRequest)) == 0; + } + +private: + std::string m_mcastGroup; + std::string m_networkInterface; +}; + + +class UDPMulticastServerApp : public UDPMulticastServer +{ +public: + UDPMulticastServerApp(uint16_t port, int protocol, const std::string &mcastGroup, const std::string &networkInterface, + const AppContext &appContext) + : UDPMulticastServer(port, protocol, mcastGroup, networkInterface) + , m_appContext(appContext) + { + } + + virtual int serverProcedure(int pipeFd) override + { + Api::setProcessLabel(m_appContext.appId()); + RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(m_appContext.getUID(), m_appContext.getGID()) == 0, + "drop_root_privileges() failed"); + + return UDPServer::serverProcedure(pipeFd); + } + +private: + AppContext m_appContext; +}; + + +class TCPServer : public NetServer +{ +public: + explicit TCPServer(uint16_t port) + : NetServer{} + , m_port(port) + {} + + virtual ~TCPServer() {} + + virtual std::string getDescription() const override + { + return "TCPServer port: " + std::to_string(m_port); + } + + virtual int serverProcedure(int pipeFd) override + { + FdUniquePtr pipePtr(&pipeFd); + + int sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sockFd == -1) { + exit(EXIT_FAILURE); + } + + SockUniquePtr sockPtr(&sockFd); + + int optionValue = 1; + if (setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, static_cast(&optionValue) , sizeof(int)) == -1) { + exit(EXIT_FAILURE); + } + + struct sockaddr_in serverAddress; + memset(&serverAddress, 0, sizeof(serverAddress)); + serverAddress.sin_family = AF_INET; + serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); + serverAddress.sin_port = htons(m_port); + + if (bind(sockFd, reinterpret_cast(&serverAddress), sizeof(serverAddress)) == -1) { + exit(EXIT_FAILURE); + } + + if (listen(sockFd, 1) == -1) { + exit(EXIT_FAILURE); + } + + struct sockaddr_in clntAddress; + socklen_t clntAddressLength = static_cast(sizeof(clntAddress)); + char receiveBuffer[NET_BUFFER_SIZE]; + + notifyManager(pipeFd); + + while (true) { + int acceptedSocketFd = TEMP_FAILURE_RETRY(accept(sockFd, reinterpret_cast(&clntAddress), + &clntAddressLength)); + if (acceptedSocketFd == -1) { + exit(EXIT_FAILURE); + } + + SockUniquePtr acceptSockPtr(&acceptedSocketFd); + + while (true) { + ssize_t len = TEMP_FAILURE_RETRY(recv(acceptedSocketFd, receiveBuffer, sizeof(receiveBuffer), 0)); + if (len == -1) { + exit(EXIT_FAILURE); + } + + if (len == 0) { + break; + } + + do { + ssize_t pos = 0; + ssize_t ret = TEMP_FAILURE_RETRY(write(pipeFd, &receiveBuffer[pos], len)); + if (ret == -1) { + exit(EXIT_FAILURE); + } + + len -= ret; + pos += ret; + } while (len != 0); + } + } + + return EXIT_SUCCESS; + } + +private: + uint16_t m_port; +}; + + +class TCPServerApp : public TCPServer +{ +public: + TCPServerApp(int port, const AppContext &appContext) + : TCPServer(port) + , m_appContext(appContext) + { + } + + virtual int serverProcedure(int pipeFd) override + { + Api::setProcessLabel(m_appContext.appId()); + RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(m_appContext.getUID(), m_appContext.getGID()) == 0, + "drop_root_privileges() failed"); + + return TCPServer::serverProcedure(pipeFd); + } + +private: + AppContext m_appContext; +}; + + +class NetClient +{ +public: + NetClient(const std::string &appPrefix, NetherInternetAccess access, int msgCount) + : m_appPrefix(appPrefix) + , m_access(access) + , m_msgCount(msgCount) + { + } + + NetClient(const NetClient &) = delete; + NetClient &operator=(const NetClient &) = delete; + + void start() + { + runProcedureInNetAppContext(m_appPrefix, [this]() { clientProcedure(); } , m_access); + } + + virtual void clientProcedure() = 0; + +protected: + std::string m_appPrefix; + NetherInternetAccess m_access; + int m_msgCount; +}; + +class UDPClientApp : public NetClient +{ +public: + UDPClientApp(const std::string &appPrefix, NetherInternetAccess access, int msgCount, + int protocol, const std::string &hostName, uint16_t port) + : NetClient(appPrefix, access, msgCount) + , m_protocol(protocol) + , m_hostName(hostName) + , m_port(port) + { + } + + virtual bool applyExtraSocketOptions(int) + { + return true; + } + +private: + virtual void clientProcedure() override + { + int sockFd = socket(AF_INET, SOCK_DGRAM, m_protocol); + RUNNER_ASSERT_ERRNO_MSG(sockFd >= 0, "socket() failed"); + SockUniquePtr sockPtr(&sockFd); + + struct hostent *server = gethostbyname(m_hostName.c_str()); + RUNNER_ASSERT_MSG(server != nullptr, "Couldn't find host " << m_hostName + << " h_errno = " << hstrerror(h_errno)); + + RUNNER_ASSERT_MSG (applyExtraSocketOptions(sockFd), "Couldn't prepare socket"); + + struct sockaddr_in serverAddress; + memset(&serverAddress, 0, sizeof(serverAddress)); + serverAddress.sin_family = AF_INET; + memcpy(&serverAddress.sin_addr.s_addr, server->h_addr, server->h_length); + serverAddress.sin_port = htons(m_port); + + char sendBuffer[NET_BUFFER_SIZE]; + + memset(sendBuffer, 'X', sizeof(sendBuffer)); + size_t serverAddressLength = sizeof(serverAddress); + + int msgCount = m_msgCount; + while (msgCount-- > 0) { + ssize_t len = sizeof(sendBuffer); + ssize_t pos = 0; + do { + ssize_t ret = TEMP_FAILURE_RETRY(sendto(sockFd, &sendBuffer[pos], len, 0, + reinterpret_cast(&serverAddress), serverAddressLength)); + RUNNER_ASSERT_ERRNO_MSG(ret >= 0, "sendto() failed"); + len -= ret; + pos += ret; + } while (len != 0); + } + } + + int m_protocol; + std::string m_hostName; + uint16_t m_port; +}; + +class UDPMulticastClientApp : public UDPClientApp +{ +public: + UDPMulticastClientApp(const std::string &appPrefix, NetherInternetAccess access, int msgCount, + int protocol, const std::string &hostName, uint16_t port, char ttl, bool enableLoop) + : UDPClientApp(appPrefix, access, msgCount, protocol, hostName, port) + , m_ttl(ttl) + , m_enableLoop(enableLoop) + { + } + + virtual bool applyExtraSocketOptions(int sockFd) override + { + if (setsockopt(sockFd, IPPROTO_IP, IP_MULTICAST_TTL, static_cast(&m_ttl), sizeof(m_ttl)) == -1) { + return false; + } + + char multicastEnableLoop = m_enableLoop ? 1 : 0; + return setsockopt(sockFd, IPPROTO_IP, IP_MULTICAST_LOOP, static_cast(&multicastEnableLoop), + sizeof(multicastEnableLoop)) == 0; + } + +private: + char m_ttl; + bool m_enableLoop; +}; + +class TCPClientApp : public NetClient +{ +public: + TCPClientApp(const std::string &appPrefix, NetherInternetAccess access, int msgCount, + const std::string &hostName, int port, bool expectConnectionError) + : NetClient(appPrefix, access, msgCount) + , m_hostName(hostName) + , m_port(port) + , m_expectConnectionError(expectConnectionError) + { + } + +private: + virtual void clientProcedure() override + { + int sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + RUNNER_ASSERT_ERRNO_MSG(sockFd >= 0, "socket() failed"); + SockUniquePtr sockPtr(&sockFd); + + struct hostent *server = gethostbyname(m_hostName.c_str()); + RUNNER_ASSERT_MSG(server != nullptr, "Couldn't find host " << m_hostName + << " h_errno = " << hstrerror(h_errno)); + + struct sockaddr_in serverAddress; + memset(&serverAddress, 0, sizeof(serverAddress)); + serverAddress.sin_family = AF_INET; + memcpy(&serverAddress.sin_addr.s_addr, server->h_addr, server->h_length); + serverAddress.sin_port = htons(m_port); + size_t serverAddressLength = sizeof(serverAddress); + + int ret = TEMP_FAILURE_RETRY(connect(sockFd, + reinterpret_cast(&serverAddress),serverAddressLength)); + if (ret == -1 && m_expectConnectionError) { + return; + } + + RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Couldn't connect to " << m_hostName); + + char sendBuffer[NET_BUFFER_SIZE]; + memset(sendBuffer, 'X', sizeof(sendBuffer)); + + int msgCount = m_msgCount; + while (msgCount-- > 0) { + ssize_t len = sizeof(sendBuffer); + ssize_t pos = 0; + do { + ssize_t ret = TEMP_FAILURE_RETRY(send(sockFd, &sendBuffer[pos], len, 0)); + RUNNER_ASSERT_ERRNO_MSG(ret >= 0, "send() failed"); + len -= ret; + pos += ret; + } while (len != 0); + } + } + + std::string m_hostName; + uint16_t m_port; + bool m_expectConnectionError; +}; + + +RUNNER_TEST_GROUP_INIT(NETHER_REMOTE_CONNECTION) + + +RUNNER_CHILD_TEST(nether_check_udp_connection_internet_access_granted) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + UDPServer udpServer(UDP_TEST_PORT); + udpServer.start(NETHER_NETNS_NAME_TEST); + + UDPClientApp udpClientApp("nether_test_uciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT, + IPPROTO_UDP, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpServer.isAlive(), "UDP server was not running"); + udpServer.stop(); + RUNNER_ASSERT_MSG(udpServer.getReceivedBytes() > 0, "UDP server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_connection_internet_access_denied) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + UDPServer udpServer(UDP_TEST_PORT); + udpServer.start(NETHER_NETNS_NAME_TEST); + + UDPClientApp udpClientApp("nether_test_uciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT, + IPPROTO_UDP, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpServer.isAlive(), "UDP server was not running"); + udpServer.stop(); + RUNNER_ASSERT_MSG(udpServer.getReceivedBytes() == 0, "UDP server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_lite_connection_internet_access_granted) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE); + udpLiteServer.start(NETHER_NETNS_NAME_TEST); + + UDPClientApp udpClientApp("nether_test_ulciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT, + IPPROTO_UDPLITE, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDPLite server was not running"); + udpLiteServer.stop(); + RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDPLite server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_lite_connection_internet_access_denied) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE); + udpLiteServer.start(NETHER_NETNS_NAME_TEST); + + UDPClientApp udpClientApp("nether_test_ulciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT, + IPPROTO_UDPLITE, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running"); + udpLiteServer.stop(); + RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() == 0, "UDP server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_tcp_connection_internet_access_granted) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + TCPServer tcpServer(TCP_TEST_PORT); + tcpServer.start(NETHER_NETNS_NAME_TEST); + + TCPClientApp tcpClientApp("nether_test_tciag", NetherInternetAccess::ACCESS_GRANTED, TCP_MESSAGES_COUNT, + REMOTE_INTERFACE_ADDRESS, TCP_TEST_PORT, false); + tcpClientApp.start(); + + RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running"); + tcpServer.stop(); + RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() > 0, "TCP server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_tcp_connection_internet_access_denied) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + TCPServer tcpServer(TCP_TEST_PORT); + tcpServer.start(NETHER_NETNS_NAME_TEST); + + TCPClientApp tcpClientApp("nether_test_tciad", NetherInternetAccess::ACCESS_DENIED, TCP_MESSAGES_COUNT, + REMOTE_INTERFACE_ADDRESS, TCP_TEST_PORT, true); + tcpClientApp.start(); + + RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running"); + tcpServer.stop(); + RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() == 0, "TCP server received some data"); +} + +// Communication between application and local service +RUNNER_TEST_GROUP_INIT(NETHER_LOCAL_SERVICE_CONNECTION) + + +RUNNER_CHILD_TEST(nether_check_udp_local_connection_internet_access_granted) +{ + UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDP); + udpLiteServer.start(); + + UDPClientApp udpClientApp("nether_test_ulciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT, + IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running"); + udpLiteServer.stop(); + RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_local_connection_internet_access_denied) +{ + UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDP); + udpLiteServer.start(); + + UDPClientApp udpClientApp("nether_test_ulciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT, + IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running"); + udpLiteServer.stop(); + RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_lite_local_connection_internet_access_granted) +{ + UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE); + udpLiteServer.start(); + + UDPClientApp udpClientApp("nether_test_ullciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT, + IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running"); + udpLiteServer.stop(); + RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_lite_local_connection_internet_access_denied) +{ + UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE); + udpLiteServer.start(); + + UDPClientApp udpClientApp("nether_test_ullciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT, + IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running"); + udpLiteServer.stop(); + RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_tcp_local_connection_internet_access_granted) +{ + TCPServer tcpServer(TCP_TEST_PORT); + tcpServer.start(); + + TCPClientApp tcpClientApp("nether_test_tlciad", NetherInternetAccess::ACCESS_GRANTED, TCP_MESSAGES_COUNT, + LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, false); + tcpClientApp.start(); + + RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running"); + tcpServer.stop(); + RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() > 0, "TCP server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_tcp_local_connection_internet_access_denied) +{ + TCPServer tcpServer(TCP_TEST_PORT); + tcpServer.start(); + + TCPClientApp tcpClientApp("nether_test_tlciad", NetherInternetAccess::ACCESS_DENIED, TCP_MESSAGES_COUNT, + LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, false); + tcpClientApp.start(); + + RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running"); + tcpServer.stop(); + RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() > 0, "TCP server didn't receive any data"); +} + + +// Applications mustn't communicate with each other even if access to the Internet is granted. +RUNNER_TEST_GROUP_INIT(NETHER_LOCAL_INTER_APP_CONNECTION) + + +RUNNER_CHILD_TEST(nether_check_udp_local_inter_app_connection_internet_access_granted) +{ + ScopedAppContext appContext("nether_test_uliaciag_a", NetherInternetAccess::ACCESS_GRANTED); + UDPServerApp udpServerApp(UDP_TEST_PORT, IPPROTO_UDP, appContext); + udpServerApp.start(); + + UDPClientApp udpClientApp("nether_test_uliaciag_b", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT, + IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpServerApp.isAlive(), "UDP server was not running"); + udpServerApp.stop(); + RUNNER_ASSERT_MSG(udpServerApp.getReceivedBytes() == 0, "UDP server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_local_inter_app_connection_internet_access_denied) +{ + ScopedAppContext appContext("nether_test_uliaciad_a", NetherInternetAccess::ACCESS_DENIED); + UDPServerApp udpServerApp(UDP_TEST_PORT, IPPROTO_UDP, appContext); + udpServerApp.start(); + + UDPClientApp udpClientApp("nether_test_uliaciad_b", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT, + IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpServerApp.isAlive(), "UDP server was not running"); + udpServerApp.stop(); + RUNNER_ASSERT_MSG(udpServerApp.getReceivedBytes() == 0, "UDP server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_lite_local_inter_app_connection_internet_access_granted) +{ + ScopedAppContext appContext("nether_test_ulliaciag_a", NetherInternetAccess::ACCESS_GRANTED); + UDPServerApp udpLiteServerApp(UDP_TEST_PORT, IPPROTO_UDPLITE, appContext); + udpLiteServerApp.start(); + + UDPClientApp udpClientApp("nether_ulliaciag_b", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT, + IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServerApp.isAlive(), "UDP server was not running"); + udpLiteServerApp.stop(); + RUNNER_ASSERT_MSG(udpLiteServerApp.getReceivedBytes() == 0, "UDP server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_udp_lite_local_inter_app_connection_internet_access_denied) +{ + ScopedAppContext appContext("nether_test_ulliaciad_a", NetherInternetAccess::ACCESS_DENIED); + UDPServerApp udpLiteServerApp(UDP_TEST_PORT, IPPROTO_UDPLITE, appContext); + udpLiteServerApp.start(); + + UDPClientApp udpClientApp("nether_ulliaciad_b", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT, + IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT); + udpClientApp.start(); + + RUNNER_ASSERT_MSG(udpLiteServerApp.isAlive(), "UDP server was not running"); + udpLiteServerApp.stop(); + RUNNER_ASSERT_MSG(udpLiteServerApp.getReceivedBytes() == 0, "UDP server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_tcp_local_inter_app_connection_internet_access_granted) +{ + ScopedAppContext appContext("nether_test_tliaciag_a", NetherInternetAccess::ACCESS_GRANTED); + TCPServerApp tcpServerApp(TCP_TEST_PORT, appContext); + tcpServerApp.start(); + + TCPClientApp tcpClientApp("nether_test_tliaciag_b", NetherInternetAccess::ACCESS_GRANTED, TCP_MESSAGES_COUNT, + LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, true); + tcpClientApp.start(); + + RUNNER_ASSERT_MSG(tcpServerApp.isAlive(), "TCP server was not running"); + tcpServerApp.stop(); + RUNNER_ASSERT_MSG(tcpServerApp.getReceivedBytes() == 0, "TCP server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_tcp_local_inter_app_connection_internet_access_denied) +{ + ScopedAppContext appContext("nether_test_tliaciad_a", NetherInternetAccess::ACCESS_DENIED); + TCPServerApp tcpServerApp(TCP_TEST_PORT, appContext); + tcpServerApp.start(); + + TCPClientApp tcpClientApp("nether_test_tliaciad_b", NetherInternetAccess::ACCESS_DENIED, TCP_MESSAGES_COUNT, + LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, true); + tcpClientApp.start(); + + RUNNER_ASSERT_MSG(tcpServerApp.isAlive(), "TCP server was not running"); + tcpServerApp.stop(); + RUNNER_ASSERT_MSG(tcpServerApp.getReceivedBytes() == 0, "TCP server received some data"); +} + + +RUNNER_TEST_GROUP_INIT(NETHER_MULTICAST) + + +RUNNER_CHILD_TEST(nether_check_multicast_inter_app_connection_access_granted) +{ + // one app acts as a server (receiver), the second as a sender + ScopedAppContext appContext("nether_test_miacag_a", NetherInternetAccess::ACCESS_GRANTED); + UDPMulticastServerApp udpMulticastServerApp(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, + ANY_INTERFACE, appContext); + udpMulticastServerApp.start(); + + UDPMulticastClientApp udpMulticastClientApp("nether_test_miacag_b", NetherInternetAccess::ACCESS_GRANTED, + UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, true); + udpMulticastClientApp.start(); + + RUNNER_ASSERT_MSG(udpMulticastServerApp.isAlive(), "UDP multicast server was not running"); + udpMulticastServerApp.stop(); + RUNNER_ASSERT_MSG(udpMulticastServerApp.getReceivedBytes() > 0, "UDP multicast server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_multicast_inter_app_connection_access_denied) +{ + ScopedAppContext appContext("nether_test_miacad_a", NetherInternetAccess::ACCESS_DENIED); + UDPMulticastServerApp udpMulticastServerApp(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, + ANY_INTERFACE, appContext); + udpMulticastServerApp.start(); + + UDPMulticastClientApp udpMulticastClientApp("nether_test_miacad_b", NetherInternetAccess::ACCESS_DENIED, + UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, true); + udpMulticastClientApp.start(); + + RUNNER_ASSERT_MSG(udpMulticastServerApp.isAlive(), "UDP multicast server was not running"); + udpMulticastServerApp.stop(); + RUNNER_ASSERT_MSG(udpMulticastServerApp.getReceivedBytes() == 0, "UDP multicast server received some data"); +} + + +RUNNER_CHILD_TEST(nether_check_multicast_remote_connection_app_sender_access_granted) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + UDPMulticastServer udpMulticastServer(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, REMOTE_INTERFACE_NAME); + udpMulticastServer.start(NETHER_NETNS_NAME_TEST); + + UDPMulticastClientApp udpMulticastClientApp("nether_test_mrcasag", NetherInternetAccess::ACCESS_GRANTED, + UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, false); + udpMulticastClientApp.start(); + + RUNNER_ASSERT_MSG(udpMulticastServer.isAlive(), "UDP multicast server was not running"); + udpMulticastServer.stop(); + RUNNER_ASSERT_MSG(udpMulticastServer.getReceivedBytes() > 0, "UDP multicast server didn't receive any data"); +} + + +RUNNER_CHILD_TEST(nether_check_multicast_remote_connection_app_sender_access_denied) +{ + ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND, + NETHER_NETNS_TEARDOWN_COMMAND); + + UDPMulticastServer udpMulticastServer(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, REMOTE_INTERFACE_NAME); + udpMulticastServer.start(NETHER_NETNS_NAME_TEST); + + UDPMulticastClientApp udpMulticastClientApp("nether_test_mrcasad", NetherInternetAccess::ACCESS_DENIED, + UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, false); + udpMulticastClientApp.start(); + + RUNNER_ASSERT_MSG(udpMulticastServer.isAlive(), "UDP multicast server was not running"); + udpMulticastServer.stop(); + RUNNER_ASSERT_MSG(udpMulticastServer.getReceivedBytes() == 0, "UDP multicast server received some data"); +} + + +RUNNER_TEST_GROUP_INIT(NETHER_LOCAL_DNS_CONNECTION) + + +RUNNER_CHILD_TEST(nether_check_gethostbyname_internet_access_granted) +{ + ScopedShellScriptRunner networkDNSRunner(NETHER_DNS_SETUP_COMMAND, + NETHER_DNS_TEARDOWN_COMMAND); + + const auto getHostAddress = [](void) { + struct hostent *server = gethostbyname(DNS_TEST_ADDRESS.c_str()); + RUNNER_ASSERT_MSG(server != nullptr, "Couldn't find host " + << DNS_TEST_ADDRESS << " h_errno = " << h_errno); + }; + runProcedureInNetAppContext("nether_test_giag", getHostAddress, NetherInternetAccess::ACCESS_GRANTED); +} + + +RUNNER_CHILD_TEST(nether_check_gethostbyname_internet_access_denied) +{ + ScopedShellScriptRunner networkDNSRunner(NETHER_DNS_SETUP_COMMAND, + NETHER_DNS_TEARDOWN_COMMAND); + + const auto getHostAddress = [](void) { + struct hostent *server = gethostbyname(DNS_TEST_ADDRESS.c_str()); + RUNNER_ASSERT_MSG(server == nullptr, "Host was found " << DNS_TEST_ADDRESS); + }; + + runProcedureInNetAppContext("nether_test_giad", getHostAddress, NetherInternetAccess::ACCESS_DENIED); +} + + +void checkRawSocket(void) +{ + const std::vector protocols { + IPPROTO_ICMP, + IPPROTO_IGMP + }; + + for (const auto protocol : protocols) { + int sockFd = socket(AF_INET, SOCK_RAW, protocol); + RUNNER_ASSERT_ERRNO_MSG(sockFd == -1, "RAW socket was successfully created for protocol " << protocol); + } +}; + + +RUNNER_TEST_GROUP_INIT(NETHER_RAW_SOCKET) + + +RUNNER_CHILD_TEST(nether_check_raw_socket_access_granted) +{ + runProcedureInNetAppContext("nether_test_rsag", checkRawSocket, NetherInternetAccess::ACCESS_GRANTED); +} + + +RUNNER_CHILD_TEST(nether_check_raw_socket_access_denied) +{ + runProcedureInNetAppContext("nether_test_rsad", checkRawSocket, NetherInternetAccess::ACCESS_DENIED); +} + + +int main(int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); +} diff --git a/src/nether-tests/setup-nether-tests-dns.sh b/src/nether-tests/setup-nether-tests-dns.sh new file mode 100644 index 0000000..c3e1fea --- /dev/null +++ b/src/nether-tests/setup-nether-tests-dns.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +##################################################################### +# Copyright (c) 2017 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. +##################################################################### + +# make sure the filesystem is mounted in RW mode +rw + +# backup old resolv.conf +cp /etc/resolv.conf /etc/resolv.conf.back + +# configure Connman as a local DNS server +echo "nameserver 127.0.0.1" > /etc/resolv.conf diff --git a/src/nether-tests/setup-nether-tests-nns.sh b/src/nether-tests/setup-nether-tests-nns.sh new file mode 100644 index 0000000..6ddf174 --- /dev/null +++ b/src/nether-tests/setup-nether-tests-nns.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +##################################################################### +# Copyright (c) 2017 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. +##################################################################### + +if [[ $# -eq 0 ]] ; then + scrname=`basename "$0"` + echo "Usage: $scrname " + exit 0 +fi + +ip netns add $1 +ip link add veth0 type veth peer name veth1 +ip link set veth1 netns $1 +ip netns exec $1 ifconfig lo 127.0.0.1 +ip netns exec $1 ifconfig veth1 10.1.0.2 netmask 255.255.255.252 +ip netns exec $1 route add -net 224.0.0.0 netmask 224.0.0.0 veth1 + +# force mtu size (we want to test that Nether's rules can deal with fragmentation) +ifconfig veth0 mtu 1500 +ifconfig veth0 10.1.0.1 netmask 255.255.255.252 +route add -net 224.0.0.0 netmask 240.0.0.0 veth0 + +# force ARP response +ping -c 1 10.1.0.2 > /dev/null diff --git a/src/nether-tests/teardown-nether-tests-dns.sh b/src/nether-tests/teardown-nether-tests-dns.sh new file mode 100644 index 0000000..0d240f6 --- /dev/null +++ b/src/nether-tests/teardown-nether-tests-dns.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +##################################################################### +# Copyright (c) 2017 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. +##################################################################### + +# restore old resolv.conf +mv /etc/resolv.conf.back /etc/resolv.conf + + diff --git a/src/nether-tests/teardown-nether-tests-nns.sh b/src/nether-tests/teardown-nether-tests-nns.sh new file mode 100644 index 0000000..455db1a --- /dev/null +++ b/src/nether-tests/teardown-nether-tests-nns.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +##################################################################### +# Copyright (c) 2017 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. +##################################################################### + +if [[ $# -eq 0 ]] ; then + scrname=`basename "$0"` + echo "Usage: $scrname " + exit 0 +fi + +ifconfig veth0 down +ip netns exec $1 ifconfig veth1 down +ip netns exec $1 ifconfig lo down + +ip link delete veth0 +ip netns delete $1 diff --git a/src/ode/CMakeLists.txt b/src/ode/CMakeLists.txt new file mode 100644 index 0000000..f7fd464 --- /dev/null +++ b/src/ode/CMakeLists.txt @@ -0,0 +1,55 @@ +# +# Copyright (c) 2017-2018 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 CMakeLists.txt +# @author Pawel Kowalski (p.kowalski2@partner.samsung.com) +# + +MESSAGE(STATUS "") +MESSAGE(STATUS "Generating makefile for the ODE tests...") + +FILE(GLOB ode_tests_SRCS *.cpp) + +OPTION("EMULATOR" ON) +IF(EMULATOR) + ADD_DEFINITIONS("-DEMULATOR") +ENDIF(EMULATOR) + +## Setup target ################################################################ +SET(ODE_TESTS "ode-tests") +ADD_EXECUTABLE(${ODE_TESTS} ${ode_tests_SRCS}) + +## Link libraries ############################################################## +PKG_CHECK_MODULES(ODE_TESTS_DEPS REQUIRED + ode + security-manager + dbus-1 + libgum +) + +INCLUDE_DIRECTORIES(SYSTEM + ${ODE_TESTS_DEPS_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/src/common/ +) + +TARGET_LINK_LIBRARIES( + ${ODE_TESTS} + ${ODE_TESTS_DEPS_LIBRARIES} + dpl-test-framework + tests-common +) + +## Install ##################################################################### +INSTALL(TARGETS ${ODE_TESTS} DESTINATION bin) diff --git a/src/ode/ode-tests-common.cpp b/src/ode/ode-tests-common.cpp new file mode 100644 index 0000000..fd82703 --- /dev/null +++ b/src/ode/ode-tests-common.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2018 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 ode-tests-common.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include "ode-tests-common.h" + +#define ERRORDESCRIBE(name) case name: return #name + +const char* ODEErrorToString(int error) { + switch(error) { + ERRORDESCRIBE(ODE_ERROR_NONE); + ERRORDESCRIBE(ODE_ERROR_INVALID_PARAMETER); + ERRORDESCRIBE(ODE_ERROR_CONNECTION_REFUSED); + ERRORDESCRIBE(ODE_ERROR_PERMISSION_DENIED); + ERRORDESCRIBE(ODE_ERROR_NO_SUCH_FILE); + ERRORDESCRIBE(ODE_ERROR_NO_SUCH_DEVICE); + ERRORDESCRIBE(ODE_ERROR_KEY_REJECTED); + ERRORDESCRIBE(ODE_ERROR_NO_DATA); + ERRORDESCRIBE(ODE_ERROR_RESOURCE_BUSY); + ERRORDESCRIBE(ODE_ERROR_UNKNOWN); + default: return "Error not defined"; + } +} + +#undef ERRORDESCRIBE + +// helper classes + +HelperKeys::HelperKeys(const char* device, const char* password, bool initialize) { + dev = device; + pass = password; + + if (initialize) { + bool result; + assert_positive(ode_key_is_initialized, dev, &result); + + if (!result) { + assert_positive(ode_key_init, dev, pass, ODE_KEY_DEFAULT_256BIT); + } + } +} + +HelperKeys::~HelperKeys() { + ode_key_remove_master_key(dev); + ode_key_remove(dev, pass); +} + +HelperInternalEncryption::HelperInternalEncryption(const char* password) { + pass = password; + + bool result; + assert_positive(ode_internal_encryption_is_password_initialized, &result); + + if (!result) { + assert_positive(ode_internal_encryption_init_password, pass); + } +} + +HelperInternalEncryption::~HelperInternalEncryption() { + ode_internal_encryption_umount(); + ode_internal_encryption_clean_password(pass); +} + +std::unique_ptr> createScopedOdeStopper() { + auto sm_start = [](ServiceManager* sm) { + try { + sm->startService(true); + delete sm; + sleep(1); + //TODO: startService should wait until the sm is really started but it does not + // because of that the sleep is needed + } catch (...) { + RUNNER_ERROR_MSG("Unexpected exception during service startup"); + } + }; + std::unique_ptr sm_stop( + new ServiceManager("ode.service", { "ode.socket" }), + std::move(sm_start)); + + sm_stop->stopService(true); + + return sm_stop; +} diff --git a/src/ode/ode-tests-common.h b/src/ode/ode-tests-common.h new file mode 100644 index 0000000..0151b9c --- /dev/null +++ b/src/ode/ode-tests-common.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2018 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 ode-tests-common.h + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#pragma once + +#include +#include +#include + +#include + +#include + +#define RUNNER_TEST_DUMMY(Proc, ...) \ + void Proc(std::tuple<__VA_ARGS__> &optionalArgsTuple DPL_UNUSED) + +#ifndef EMULATOR +#define RUNNER_TEST_DEVICE(...) RUNNER_TEST(__VA_ARGS__) +#else +#define RUNNER_TEST_DEVICE(...) RUNNER_TEST_DUMMY(__VA_ARGS__) +#endif + +#include + +const char* ODEErrorToString(int error); + +// RUNNER_ASSERT wrappers + +template +void assert_result(int expected, F&& func, Args... args) +{ + int ret = func(args...); + RUNNER_ASSERT_MSG(ret == expected, + "Expected: " << ODEErrorToString(expected) << "(" << expected << ")" + " got: " << ODEErrorToString(ret) << "(" << ret << ")"); +} + +template +void assert_positive(F&& func, Args... args) +{ + assert_result(ODE_ERROR_NONE, std::move(func), args...); +} + +template +void assert_invalid_parameter(F&& func, Args... args) +{ + assert_result(ODE_ERROR_INVALID_PARAMETER, std::move(func), args...); +} + +template +void assert_connection_refused(F&& func, Args... args) +{ + assert_result(ODE_ERROR_CONNECTION_REFUSED, std::move(func), args...); +} + +template +void assert_permission_denied(F&& func, Args... args) +{ + assert_result(ODE_ERROR_PERMISSION_DENIED, std::move(func), args...); +} + +template +void assert_no_such_file(F&& func, Args... args) +{ + assert_result(ODE_ERROR_NO_SUCH_FILE, std::move(func), args...); +} + +template +void assert_no_such_device(F&& func, Args... args) +{ + assert_result(ODE_ERROR_NO_SUCH_DEVICE, std::move(func), args...); +} + +template +void assert_key_rejected(F&& func, Args... args) +{ + assert_result(ODE_ERROR_KEY_REJECTED, std::move(func), args...); +} + +template +void assert_no_data(F&& func, Args... args) +{ + assert_result(ODE_ERROR_NO_DATA, std::move(func), args...); +} + +template +void assert_resource_busy(F&& func, Args... args) +{ + assert_result(ODE_ERROR_RESOURCE_BUSY, std::move(func), args...); +} + +// helper classes + +class HelperKeys { + const char* dev; + const char* pass; + +public: + HelperKeys(const char* device, const char* password, bool initialize = true); + ~HelperKeys(); +}; + +class HelperInternalEncryption { + const char* pass; + +public: + HelperInternalEncryption(const char* password); + ~HelperInternalEncryption(); +}; + +std::unique_ptr> createScopedOdeStopper(); diff --git a/src/ode/ode-tests-external-encryption.cpp b/src/ode/ode-tests-external-encryption.cpp new file mode 100644 index 0000000..1e5d55a --- /dev/null +++ b/src/ode/ode-tests-external-encryption.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017-2018 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 ode-tests-external-encryption.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#include "dpl/test/test_runner.h" + +RUNNER_TEST_GROUP_INIT(T0000_ODE_API_EXTERNAL_ENCRYPTION); \ No newline at end of file diff --git a/src/ode/ode-tests-internal-encryption.cpp b/src/ode/ode-tests-internal-encryption.cpp new file mode 100644 index 0000000..881ecaa --- /dev/null +++ b/src/ode/ode-tests-internal-encryption.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2017-2018 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 ode-tests-internal-encryption.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "ode-tests-common.h" + +namespace OdeTestsInternalEncryption { + +const char * password = "abc123"; +const char * password_new = "def456"; + +RUNNER_TEST_GROUP_INIT(T1000_ODE_API_INTERNAL_ENCRYPTION); + +RUNNER_TEST_DEVICE(T1001_internal_encryption_set_mount_password_1_invalid_parameter) +{ + HelperInternalEncryption helper(password); + + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_set_mount_password, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_set_mount_password, nullptr); +} + +RUNNER_TEST_DEVICE(T1002_internal_encryption_set_mount_password_2_key_rejected) +{ + HelperInternalEncryption helper(password); + + // try to set the mount password different than the init password + assert_key_rejected(ode_internal_encryption_set_mount_password, password_new); +} + +RUNNER_TEST_DEVICE(T1003_internal_encryption_mount_1_no_such_device) +{ + HelperInternalEncryption helper(password); + + // set mount password + assert_positive(ode_internal_encryption_set_mount_password, password); + + assert_no_such_device(ode_internal_encryption_mount); +} + +RUNNER_TEST(T1004_internal_encryption_mount_2_no_data) +{ + assert_no_data(ode_internal_encryption_mount); +} + +RUNNER_TEST_DEVICE(T1005_internal_encryption_umount_1_no_such_device) +{ + HelperInternalEncryption helper(password); + + // set mount password + assert_positive(ode_internal_encryption_set_mount_password, password); + + assert_no_such_device(ode_internal_encryption_umount); +} + +RUNNER_TEST_DEVICE(T1006_internal_encryption_encrypt_1_invalid_parameter) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NONE is returned " + "instead of the ODE_ERROR_INVALID_PARAMETER in case " + "when options are set to NULL. Because no error is " + "returned, the device is encrypted. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_encrypt, "", 0); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_encrypt, nullptr, 0); + + // options set to NULL + assert_invalid_parameter(ode_internal_encryption_encrypt, password, NULL); + /* + * TODO: + * Maybe also value of the options (even if it is uint) should be checked + * and only 0 or 1 should be available. Alternatively options should be bool + * or if more options may be available in the future - enum. Currently, if + * options is set to any value different than 0, fast encryption is enabled. + * Otherwise it is disabled. Needs improvement in ode. + */ +} + +RUNNER_TEST_DEVICE(T1007_internal_encryption_encrypt_2_key_rejected) +{ + HelperInternalEncryption helper(password); + + // try to encrypt using the password different than the init password + assert_key_rejected(ode_internal_encryption_encrypt, password_new, 0); +} + +RUNNER_TEST(T1008_internal_encryption_encrypt_3_no_such_device) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NO_SUCH_FILE is returned " + "instead of the ODE_ERROR_NO_SUCH_DEVICE. " + "Needs improvement in ode module."); + + assert_no_such_device(ode_internal_encryption_encrypt, password, 0); +} + +RUNNER_TEST_DEVICE(T1009_internal_encryption_decrypt_1_invalid_parameter) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NO_SUCH_DEVICE is returned " + "instead of the ODE_ERROR_INVALID_PARAMETER. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_decrypt, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_decrypt, nullptr); +} + +RUNNER_TEST_DEVICE(T1010_internal_encryption_decrypt_2_key_rejected) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_NO_SUCH_DEVICE is returned " + "instead of the ODE_ERROR_KEY_REJECTED. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + // try to decrypt using the password different than the init password + assert_key_rejected(ode_internal_encryption_decrypt, password_new); +} + +RUNNER_TEST_DEVICE(T1011_internal_encryption_decrypt_3_no_such_device) +{ + HelperInternalEncryption helper(password); + + assert_no_such_device(ode_internal_encryption_decrypt, password); +} + +RUNNER_TEST_DEVICE(T1012_internal_encryption_recovery_1_no_such_device) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_UNKNOWN is returned " + "instead of the ODE_ERROR_NO_SUCH_DEVICE. " + "Needs improvement in ode module."); + + HelperInternalEncryption helper(password); + + assert_no_such_device(ode_internal_encryption_recovery); +} + +RUNNER_TEST(T1013_internal_encryption_is_password_initialized_1_invalid_parameter) +{ + // result set to NULL + assert_invalid_parameter(ode_internal_encryption_is_password_initialized, nullptr); +} + +RUNNER_TEST(T1014_internal_encryption_init_password_1_invalid_parameter) +{ + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_init_password, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_init_password, nullptr); +} + +RUNNER_TEST(T1015_internal_encryption_clean_password_1_invalid_parameter) +{ + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_clean_password, ""); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_clean_password, nullptr); +} + +RUNNER_TEST_DEVICE(T1016_internal_encryption_change_password_1_invalid_parameter) +{ + HelperInternalEncryption helper(password); + + // old password set to empty string + assert_invalid_parameter(ode_internal_encryption_change_password, "", password_new); + // old password set to NULL + assert_invalid_parameter(ode_internal_encryption_change_password, nullptr, password_new); + + // new password set to empty string + assert_invalid_parameter(ode_internal_encryption_change_password, password_new, ""); + // new password set to NULL + assert_invalid_parameter(ode_internal_encryption_change_password, password_new, nullptr); +} + +RUNNER_TEST_DEVICE(T1017_internal_encryption_change_password_2_key_rejected) +{ + HelperInternalEncryption helper(password); + + assert_key_rejected(ode_internal_encryption_change_password, password_new, password); +} + +RUNNER_TEST(T1018_internal_encryption_verify_password_1_invalid_parameter) +{ + bool result; + // password set to empty string + assert_invalid_parameter(ode_internal_encryption_verify_password, "", &result); + // password set to NULL + assert_invalid_parameter(ode_internal_encryption_verify_password, nullptr, &result); + + // result set to NULL + assert_invalid_parameter(ode_internal_encryption_verify_password, password, nullptr); + assert_invalid_parameter(ode_internal_encryption_verify_password, password_new, nullptr); +} + +RUNNER_TEST(T1019_internal_encryption_get_state_1_invalid_parameter) +{ + // state set to NULL + assert_invalid_parameter(ode_internal_encryption_get_state, nullptr); +} + +RUNNER_TEST(T1020_internal_encryption_connection_refused) +{ + auto sm_stop = createScopedOdeStopper(); + + unsigned int options = 0; + bool result; + int state; + + assert_connection_refused(ode_internal_encryption_set_mount_password, password); + assert_connection_refused(ode_internal_encryption_mount); + assert_connection_refused(ode_internal_encryption_umount); + assert_connection_refused(ode_internal_encryption_encrypt, password, options); + assert_connection_refused(ode_internal_encryption_decrypt, password); + assert_connection_refused(ode_internal_encryption_recovery); + assert_connection_refused(ode_internal_encryption_is_password_initialized, &result); + assert_connection_refused(ode_internal_encryption_init_password, password); + assert_connection_refused(ode_internal_encryption_clean_password, password); + assert_connection_refused(ode_internal_encryption_change_password, password, password_new); + assert_connection_refused(ode_internal_encryption_verify_password, password, &result); + assert_connection_refused(ode_internal_encryption_get_state, &state); +} + +RUNNER_CHILD_TEST(T1021_internal_encryption_permission_denied) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_UNKNOWN is returned " + "instead of the ODE_ERROR_PERMISSION_DENIED. " + "Needs improvement in ode module."); + + TemporaryTestUser adminUserToSwitch("ode_test_T1021_user", GUM_USERTYPE_ADMIN); + adminUserToSwitch.create(); + + AppInstallHelper appInstallHelper("ode_test_T1021_app_install_helper", + adminUserToSwitch.getUid()); + + ScopedInstaller scopedInstaller(appInstallHelper); + + pid_t pid = fork(); + if (pid != 0) { + waitPid(pid); + } else { //child process + SecurityManagerTest::Api::setProcessLabel(appInstallHelper.getAppId()); + RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUserToSwitch.getUid(), + adminUserToSwitch.getGid()) == 0, + "drop_root_privileges failed"); + + unsigned int options = 0; + bool result; + int state; + + // check if there is access to unprotected function + assert_positive(ode_internal_encryption_is_password_initialized, &result); + assert_positive(ode_internal_encryption_get_state, &state); + + // check if there is no access to protected function + assert_permission_denied(ode_internal_encryption_set_mount_password, password); + assert_permission_denied(ode_internal_encryption_mount); + assert_permission_denied(ode_internal_encryption_umount); + assert_permission_denied(ode_internal_encryption_encrypt, password, options); + assert_permission_denied(ode_internal_encryption_decrypt, password); + assert_permission_denied(ode_internal_encryption_recovery); + assert_permission_denied(ode_internal_encryption_init_password, password); + assert_permission_denied(ode_internal_encryption_clean_password, password); + assert_permission_denied(ode_internal_encryption_change_password, password, password_new); + assert_permission_denied(ode_internal_encryption_verify_password, password, &result); + } +} + +} // namespace OdeTestsInternalEncryption diff --git a/src/ode/ode-tests-keys.cpp b/src/ode/ode-tests-keys.cpp new file mode 100644 index 0000000..3596a29 --- /dev/null +++ b/src/ode/ode-tests-keys.cpp @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2017-2018 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 ode-tests-keys.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "ode-tests-common.h" + +namespace OdeTestsKeys { + +const std::string PRIVILEGE_INTERNAL_USERMANAGEMENT = + "http://tizen.org/privilege/internal/usermanagement"; +const std::string PRIVILEGE_INTERNAL_DEFAULT_PLATFORM = + "http://tizen.org/privilege/internal/default/platform"; + +const char* device1 = "/dev/vda1"; +const char* device2 = "/dev/vda2"; + +const char* password = "abc123"; +const char* password_new = "def456"; + +// TODO: obtain existing block devices from /proc/mounts + +RUNNER_TEST_GROUP_INIT(T2000_ODE_API_KEYS); + +/* + * If at least one of the parameters in invalid, then the INVALID_PARAM error + * is returned. + */ +RUNNER_TEST(T2001_ode_key_is_initialized_1_invalid_parameter) +{ + bool result; + + // device set to empty string + assert_invalid_parameter(ode_key_is_initialized, "", &result); + // device set to NULL + assert_invalid_parameter(ode_key_is_initialized, nullptr, &result); + + // result set to NULL + assert_invalid_parameter(ode_key_is_initialized, device1, nullptr); +} + +/* + * The third argument of the ode_key_init function is the type of key + * initialization method used. It may be ODE_KEY_DEFAULT_256BIT (1) or + * ODE_KEY_DEFAULT_512BIT (2). So if value different than 1 or 2 is passed, + * invalid parameter error is returned by the function. + * Invalid parameter error is returned also if empty strings or null pointers + * are passed as the arguments of the function. + */ +RUNNER_TEST(T2002_ode_key_init_1_invalid_parameter) +{ + // device set to empty string + assert_invalid_parameter(ode_key_init, "", password, ODE_KEY_DEFAULT_256BIT); + // device set to NULL + assert_invalid_parameter(ode_key_init, nullptr, password, ODE_KEY_DEFAULT_256BIT); + + // password set to empty string + assert_invalid_parameter(ode_key_init, device1, "", ODE_KEY_DEFAULT_256BIT); + // password set to NULL + assert_invalid_parameter(ode_key_init, device1, nullptr, ODE_KEY_DEFAULT_256BIT); + + // if the key will be initialized, the helper will remove it after the test execution + HelperKeys helper(device1, password, false); + // invalid type of key + assert_invalid_parameter(ode_key_init, device1, password, static_cast(0)); + assert_invalid_parameter(ode_key_init, device1, password, static_cast(3)); +} + +/* + * TODO: ode_key_init should return invalid param in case of double init + * + * Calling ode_key_init() second time for given device should fail (now it just + * overwrites the existing key). + */ +RUNNER_TEST(T2003_ode_key_init_2_invalid_parameter_double_init) +{ + RUNNER_IGNORED_MSG("Test ignored because no error is returned in case of " + "the double init, while the ODE_ERROR_INVALID_PARAMETER " + "should be returned."); + + HelperKeys helper(device1, password); + + assert_invalid_parameter(ode_key_init, device1, password, ODE_KEY_DEFAULT_256BIT); +} + +/* + * Invalid parameter error is returned if empty strings or null pointers + * are passed as the arguments of the function. + */ +RUNNER_TEST(T2004_ode_key_remove_1_invalid_parameter) +{ + HelperKeys helper(device1, password); + + // device set to empty string + assert_invalid_parameter(ode_key_remove, "", password); + // device set to NULL + assert_invalid_parameter(ode_key_remove, nullptr, password); + + // password set to empty string + assert_invalid_parameter(ode_key_remove, device1, ""); + // password set to NULL + assert_invalid_parameter(ode_key_remove, device1, nullptr); +} + +/* + * If the password is wrong, then the key cannot be removed and the error + * should be returned by the ode_key_remove function. + */ +RUNNER_TEST(T2005_ode_key_remove_2_rejected) +{ + const char* password_wrong = "abc321"; + + HelperKeys helper(device1, password); + + assert_key_rejected(ode_key_remove, device1, password_wrong); +} + +/* + * If no key exists for the given device, then the error should be returned by + * the ode_key_remove function. + */ +RUNNER_TEST(T2006_ode_key_remove_3_no_such_file) +{ + assert_no_such_file(ode_key_remove, device1, password); + assert_no_such_file(ode_key_remove, device2, password); +} + +/* + * Invalid parameter error is returned if empty strings or null pointers + * are passed as the arguments of the function. + */ +RUNNER_TEST(T2007_ode_key_change_password_1_invalid_parameter) +{ + HelperKeys helper(device1, password); + + // device set to empty string + assert_invalid_parameter(ode_key_change_password, "", password, password_new); + // device set to NULL + assert_invalid_parameter(ode_key_change_password, nullptr, password, password_new); + + // old password set to empty string + assert_invalid_parameter(ode_key_change_password, device1, "", password_new); + // old password set to NULL + assert_invalid_parameter(ode_key_change_password, device1, nullptr, password_new); + + // new password set to empty string + assert_invalid_parameter(ode_key_change_password, device1, password, ""); + // new password set to NULL + assert_invalid_parameter(ode_key_change_password, device1, password, nullptr); +} + +/* + * If the current password is wrong (for example the developer mistook the + * string with the current password with the new one), then the password cannot + * be changed and the error is returned by the ode_key_change_password + * function. + */ +RUNNER_TEST(T2008_ode_key_change_password_2_key_rejected) +{ + HelperKeys helper(device1, password); + + assert_key_rejected(ode_key_change_password, device1, password_new, password); +} + +/* + * If no key exists for the given device, then the password cannot be changed + * and the error is returned by the ode_key_change_password function. + */ +RUNNER_TEST(T2009_ode_key_change_password_3_no_such_file) +{ + assert_no_such_file(ode_key_change_password, device1, password, password_new); + assert_no_such_file(ode_key_change_password, device2, password, password_new); +} + +/* + * Invalid parameter error is returned if empty strings or null pointers + * are passed as the arguments of the function. + */ +RUNNER_TEST(T2010_ode_key_verify_password_1_invalid_parameter) +{ + HelperKeys helper(device1, password); + + bool result; + + // device set to empty string + assert_invalid_parameter(ode_key_verify_password, "", password, &result); + // device set to NULL + assert_invalid_parameter(ode_key_verify_password, nullptr, password, &result); + + // password set to empty string + assert_invalid_parameter(ode_key_verify_password, device1, "", &result); + // password set to NULL + assert_invalid_parameter(ode_key_verify_password, device1, nullptr, &result); + + // result set to NULL + assert_invalid_parameter(ode_key_verify_password, device1, password, nullptr); +} + +RUNNER_TEST(T2011_ode_key_verify_password_2_no_such_file) +{ + bool result; + + assert_no_such_file(ode_key_verify_password, device1, password, &result); + assert_no_such_file(ode_key_verify_password, device2, password, &result); +} + +/* + * Invalid parameter error is returned if empty strings or null pointers + * are passed as the arguments of the function. + */ +RUNNER_TEST(T2012_ode_key_store_master_key_1_invalid_parameter) +{ + HelperKeys helper(device1, password); + + // device set to empty string + assert_invalid_parameter(ode_key_store_master_key, "", password); + // device set to NULL + assert_invalid_parameter(ode_key_store_master_key, nullptr, password); + + // password set to empty string + assert_invalid_parameter(ode_key_store_master_key, device1, ""); + // password set to NULL + assert_invalid_parameter(ode_key_store_master_key, device1, nullptr); +} + +/* + * If the password passed into the ode_key_store_master_key function is wrong, + * then the key cannot be stored and ODE_ERROR_KEY_REJECTED should be returned + * by the storing function. + */ +RUNNER_TEST(T2013_ode_key_store_master_key_2_key_rejected) +{ + HelperKeys helper(device1, password); + + assert_key_rejected(ode_key_store_master_key, device1, password_new); +} + +RUNNER_TEST(T2014_ode_key_store_master_key_3_no_such_file) +{ + assert_no_such_file(ode_key_store_master_key, device1, password); + assert_no_such_file(ode_key_store_master_key, device2, password); +} + +/* + * Invalid parameter error is returned if empty strings or null pointers + * are passed as the arguments of the function. + */ +RUNNER_TEST(T2015_ode_key_remove_master_key_1_invalid_parameter) +{ + HelperKeys helper(device1, password); + + assert_positive(ode_key_store_master_key, device1, password); + + // device set to empty string + assert_invalid_parameter(ode_key_remove_master_key, ""); + // device set to NULL + assert_invalid_parameter(ode_key_remove_master_key, nullptr); +} + +/* + * If the ode service is not active during the try of using the API functions, + * then the connection should be refused and the error should be returned by + * the API function. + */ +RUNNER_TEST(T2016_ode_keys_connection_refused) +{ + HelperKeys helper(device1, password); + + auto sm_stop = createScopedOdeStopper(); + + bool result; + + assert_connection_refused(ode_key_is_initialized, device1, &result); + assert_connection_refused(ode_key_init, device1, password, ODE_KEY_DEFAULT_256BIT); + assert_connection_refused(ode_key_remove, device1, password); + assert_connection_refused(ode_key_change_password, device1, password, password_new); + assert_connection_refused(ode_key_verify_password, device1, password, &result); + assert_connection_refused(ode_key_store_master_key, device1, password); + assert_connection_refused(ode_key_remove_master_key, device1); +} + +/* + * When the unprivileged process (without the privilege internal/default/platform) + * tries to use protected API functions, then the PERMISSION_DENIED error is + * returned. + * + * TODO: permission denied should be returned instead of unknown error + */ +RUNNER_CHILD_TEST(T2017_ode_keys_permission_denied) +{ + RUNNER_IGNORED_MSG("Test ignored because the ODE_ERROR_UNKNOWN is returned " + "instead of the ODE_ERROR_PERMISSION_DENIED."); + + TemporaryTestUser adminUserToSwitch("ode_test_T2016_user", GUM_USERTYPE_ADMIN); + adminUserToSwitch.create(); + + AppInstallHelper appInstallHelper("ode_test_T2016_app_install_helper", + adminUserToSwitch.getUid()); + + ScopedInstaller scopedInstaller(appInstallHelper); + + pid_t pid = fork(); + if (pid != 0) { + waitPid(pid); + } else { //child process + SecurityManagerTest::Api::setProcessLabel(appInstallHelper.getAppId()); + RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(adminUserToSwitch.getUid(), + adminUserToSwitch.getGid()) == 0, + "drop_root_privileges failed"); + + bool result; + + // check if there is access to unprotected function + assert_positive(ode_key_is_initialized, device1, &result); + + // check if there is no access to protected function + assert_permission_denied(ode_key_init, device1, password, ODE_KEY_DEFAULT_256BIT); + assert_permission_denied(ode_key_remove, device1, password); + assert_permission_denied(ode_key_change_password, device1, password, password_new); + assert_permission_denied(ode_key_verify_password, device1, password, &result); + assert_permission_denied(ode_key_store_master_key, device1, password); + assert_permission_denied(ode_key_remove_master_key, device1); + } +} + +} // namespace OdeTestsKeys diff --git a/src/ode/ode-tests-luks.cpp b/src/ode/ode-tests-luks.cpp new file mode 100644 index 0000000..6e79858 --- /dev/null +++ b/src/ode/ode-tests-luks.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017-2018 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 ode-tests-luks.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#include "dpl/test/test_runner.h" + +RUNNER_TEST_GROUP_INIT(T3000_ODE_API_LUKS); \ No newline at end of file diff --git a/src/ode/ode-tests-secure-erase.cpp b/src/ode/ode-tests-secure-erase.cpp new file mode 100644 index 0000000..19b62ec --- /dev/null +++ b/src/ode/ode-tests-secure-erase.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017-2018 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 ode-tests-secure-erase.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#include "dpl/test/test_runner.h" + +RUNNER_TEST_GROUP_INIT(T4000_ODE_API_SECURE_ERASE); \ No newline at end of file diff --git a/src/ode/ode-tests.cpp b/src/ode/ode-tests.cpp new file mode 100644 index 0000000..040d7a9 --- /dev/null +++ b/src/ode/ode-tests.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017-2018 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 ode-test.cpp + * @author Pawel Kowalski (p.kowalski2@partner.samsung.com) + * @brief Tests for the ODE API + */ + +#include +#include + +int main (int argc, char *argv[]) +{ + DPL::Log::LogSystemSingleton::Instance().SetTag("SECURITY_TESTS_ODE"); + int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); + return status; +} diff --git a/src/security-manager-tests/CMakeLists.txt b/src/security-manager-tests/CMakeLists.txt index 46e51d8..cf08aa4 100644 --- a/src/security-manager-tests/CMakeLists.txt +++ b/src/security-manager-tests/CMakeLists.txt @@ -57,6 +57,7 @@ SET(SEC_MGR_SOURCES ${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/policy_configuration.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/template_parser.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_admin.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/plugins/plugins.cpp diff --git a/src/security-manager-tests/common/sm_commons.cpp b/src/security-manager-tests/common/sm_commons.cpp index b8b389b..16db76c 100644 --- a/src/security-manager-tests/common/sm_commons.cpp +++ b/src/security-manager-tests/common/sm_commons.cpp @@ -21,13 +21,16 @@ #include #include #include +#include #include #include #include #include #include +#include #include +#include #include #include @@ -47,9 +50,17 @@ #include #include "tzplatform.h" #include +#include +#include using namespace SecurityManagerTest; +#define CONF_DIR "/usr/share/security-manager/policy/" +#define SMACK_RULES_PATH "/sys/fs/smackfs/load2" + +#define ALLOW 0 +#define DENY -1 + // Common DB/nftw checks // nftw doesn't allow passing user data to functions. Work around by using global variable @@ -181,7 +192,75 @@ void sm_app_has_privileges(const AppInstallHelper &app, } } -static void check_app(const std::string &appId, const std::string &pkgId, bool shouldBeInstalled) +static void check_app_smack_accesses(const std::string &appId, const std::string &pkgId, + bool isHybrid = false) +{ + static const std::vector rules[] = + {parseSmackRulesFile(CONF_DIR "pkg-rules-template.smack"), + parseSmackRulesFile(CONF_DIR "app-rules-template.smack")}; + + const std::pair switchAliases[] = + {std::make_pair("~PATH_RW~", generatePathRWLabel(pkgId)), + std::make_pair("~PATH_RO~", generatePathROLabel(pkgId)), + std::make_pair("~PATH_SHARED_RO~", getSharedROPathLabel()), + std::make_pair("~PROCESS~", generateProcessLabel(appId, pkgId, isHybrid))}; + + for (auto rule : rules[isHybrid]) { + if (rule.object == "~PATH_TRUSTED~") { + continue; + } + + for (const auto &alias : switchAliases) { + if (rule.subject == alias.first) { + rule.subject = alias.second; + } + if (rule.object == alias.first) { + rule.object = alias.second; + } + } + + if (rule.object == "_") { + rule.access = "rx" + rule.access; + } + + check_exact_smack_accesses(rule.subject, rule.object, rule.access); + } +} + +static void assert_no_label_in_rule(const AccessRequest &rule, const std::string &label) +{ + RUNNER_ASSERT_MSG(rule.object != label && rule.subject != label, + "Smack rule left after uninstallation process." << + " Subject: " << rule.subject << + " object: " << rule.object << + " access: " << rule.access); +} + +static void check_pkg_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId) +{ + const std::vector rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH))); + const std::string labels[] = {generatePathRWLabel(pkgId), + generatePathROLabel(pkgId), + generateProcessLabel(appId, pkgId, true), + generateProcessLabel(appId, pkgId)}; + for (const auto &rule : rules) { + for (const auto &label : labels) { + assert_no_label_in_rule(rule, label); + } + } +} + +static void check_hybrid_app_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId) +{ + const std::vector rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH))); + const std::string appLabel = generateProcessLabel(appId, pkgId, true); + for (const auto &rule : rules) { + assert_no_label_in_rule(rule, appLabel); + } +} + +static void check_app(const std::string &appId, const std::string &pkgId, + bool shouldBeInstalled, bool isHybrid, bool removePkg) { char *retPkgId; int ret = security_manager_get_app_pkgid(&retPkgId, appId.c_str()); @@ -194,14 +273,21 @@ static void check_app(const std::string &appId, const std::string &pkgId, bool s RUNNER_ASSERT_MSG(strcmp(pkgId.c_str(), retPkgId) == 0, "The given appId does not belong to the given pkgId."); } + check_app_smack_accesses(appId, pkgId, isHybrid); } else { RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "The given appId is installed."); + + if (removePkg) { + check_pkg_smack_rules_after_uninstall(appId, pkgId); + } else if (isHybrid) { + check_hybrid_app_smack_rules_after_uninstall(appId, pkgId); + } } } -void check_app_after_install(const std::string &app_id, const std::string &pkg_id) +void check_app_after_install(const std::string &app_id, const std::string &pkg_id, bool isHybrid) { - check_app(app_id, pkg_id, true); + check_app(app_id, pkg_id, true, isHybrid, false); } static void check_app_gids(const std::string &app_id, const std::vector &allowed_gids) @@ -239,8 +325,7 @@ void check_app_after_install(const std::string &app_id, const std::string &pkg_i const privileges_t &denied_privs, bool isHybrid) { - check_app(app_id, pkg_id, true); - + check_app(app_id, pkg_id, true, isHybrid, false); /* Privileges should be granted to all users if root installs app */ check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs, isHybrid); @@ -270,15 +355,17 @@ void check_path(const std::string &path, const std::string &label, bool transmut RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path); } -void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id) +void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id, + bool isHybrid, bool removePkg) { - check_app(app_id, pkg_id, false); + check_app(app_id, pkg_id, false, isHybrid, removePkg); } void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id, - const privileges_t &privileges, bool isHybrid) + const privileges_t &privileges, bool isHybrid, + bool removePkg) { - check_app(app_id, pkg_id, false); + check_app(app_id, pkg_id, false, isHybrid, removePkg); /* Privileges should not be granted anymore to any user */ check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, {}, privileges, isHybrid); @@ -355,22 +442,30 @@ void accessCheck(const std::string &id, const std::string &path, int accessType, << " (" << accessTypeToString.at(accessType) << ")"); } +void accessTest(const std::string &id, const std::string &testPath, int accessType) { + int oppositeAccessType = getOppositeAccessType(accessType); + + if (accessType != 0) { + accessCheck(id, testPath, accessType, ALLOW); + } + if (oppositeAccessType != 0) { + static const std::vector singleAccessTypes = {R_OK, W_OK, X_OK}; + for (auto singleAccessType : singleAccessTypes) { + if (oppositeAccessType & singleAccessType) { + accessCheck(id, testPath, singleAccessType, DENY); + } + } + } +} + void runAccessTest(const std::string &label, uid_t uid, gid_t gid, const std::string &testPath, int accessType) { auto fun = [&](){ - int oppositeAccessType = getOppositeAccessType(accessType); ScopedProcessLabel spl(label, false); RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(uid, gid), "drop_root_privileges failed."); - if (accessType != 0) - accessCheck(label, testPath, accessType, 0); - if (oppositeAccessType != 0) { - std::vector singleAccessTypes = {R_OK, W_OK, X_OK}; - for (auto singleAccessType : singleAccessTypes) - if (oppositeAccessType & singleAccessType) - accessCheck(label, testPath, singleAccessType, -1); - } + accessTest(label, testPath, accessType); }; runInChildParentWait(fun); @@ -378,18 +473,10 @@ void runAccessTest(const std::string &label, uid_t uid, gid_t gid, void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType) { auto fun = [&](){ - int oppositeAccessType = getOppositeAccessType(accessType); Api::setProcessLabel(app.getAppId()); RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(app.getUID(), app.getGID()), "drop_root_privileges failed."); - if (accessType != 0) - accessCheck(app.getAppId(), testPath, accessType, 0); - if (oppositeAccessType != 0) { - std::vector singleAccessTypes = {R_OK, W_OK, X_OK}; - for (auto singleAccessType : singleAccessTypes) - if (oppositeAccessType & singleAccessType) - accessCheck(app.getAppId(), testPath, singleAccessType, -1); - } + accessTest(app.getAppId(), testPath, accessType); }; runInChildParentWait(fun); @@ -429,3 +516,29 @@ int countPrivacyPrivileges(const std::vector &privs) { return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy); } +int setLauncherSecurityAttributes(uid_t uid, gid_t gid) +{ + // Add launcher capabilities (cap_dac_override, cap_setgid, cap_sys_admin, cap_mac_admin), + // launcher is user process, we must drop root privileges (cap_setgid, cap_setuid are needed). + // By default, the permitted capability set is cleared when credentials change is made + // (if a process drops a capability from its permitted set, it can never reacquire that capability), + // setting the "keep capabilities" flag prevents it from being cleared. + // Effective capability set is always cleared when credential change is made, we need to add them again. + + setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep cap_setuid+ep"); + int ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0); + if (ret != 0) + return ret; + + ret = drop_root_privileges(uid, gid); + if (ret != 0) + return ret; + + setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep"); + return ret; +} +int setLauncherSecurityAttributes(TemporaryTestUser &user) +{ + return setLauncherSecurityAttributes(user.getUid(), user.getGid()); +} + diff --git a/src/security-manager-tests/common/sm_commons.h b/src/security-manager-tests/common/sm_commons.h index 902d70c..6840281 100644 --- a/src/security-manager-tests/common/sm_commons.h +++ b/src/security-manager-tests/common/sm_commons.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2019 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,17 +45,19 @@ void check_app_permissions(const std::string &app_id, const std::string &pkg_id, void sm_app_has_privileges(const AppInstallHelper &app, const std::vector &privileges, int result); -void check_app_after_install(const std::string &app_id, const std::string &pkg_id); +void check_app_after_install(const std::string &app_id, const std::string &pkg_id, + bool isHybrid = false); void check_app_after_install(const std::string &app_id, const std::string &pkg_id, const privileges_t &allowed_privs, const privileges_t &denied_privs, bool isHybrid = false); void check_path(const std::string &path, const std::string &label, bool transmute = true, bool execute = false); -void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id); void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id, - const privileges_t &privileges, bool isHybrid = false); - + bool isHybrid = false, bool removePkg = false); +void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id, + const privileges_t &privileges, bool isHybrid = false, + bool removePkg = false); std::string access_opposite(std::string &access); void check_exact_smack_accesses(const std::string &subject, const std::string &object, @@ -63,6 +65,7 @@ void check_exact_smack_accesses(const std::string &subject, CapsSetsUniquePtr setCaps(const char *cap_string); +void accessTest(const std::string &id, const std::string &testPath, int accessType); void runAccessTest(const std::string &label, uid_t uid, gid_t gid, const std::string &testPath, int accessType); void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType); @@ -72,3 +75,6 @@ bool isAskuserDisabled(); bool isPrivilegePrivacy(const std::string &priv); int countPrivacyPrivileges(const PrivilegeVector &privs); int countPrivacyPrivileges(const std::vector &privs); + +int setLauncherSecurityAttributes(uid_t uid, gid_t gid); +int setLauncherSecurityAttributes(TemporaryTestUser &user); diff --git a/src/security-manager-tests/common/template_parser.cpp b/src/security-manager-tests/common/template_parser.cpp new file mode 100644 index 0000000..83c5b46 --- /dev/null +++ b/src/security-manager-tests/common/template_parser.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019 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 template_parser.cpp + * @author Alicja Kluczek + * @brief Parsing function for smack rules templates + */ +#include "template_parser.h" +#include + +std::vector parseSmackRulesFile(const std::string &path) +{ + std::vector rules; + std::ifstream rulesFile(path); + std::string object, subject, access; + while (rulesFile >> subject >> object >> access) { + rules.emplace_back(std::move(subject), std::move(object), std::move(access)); + } + return rules; +} + diff --git a/src/security-manager-tests/common/template_parser.h b/src/security-manager-tests/common/template_parser.h new file mode 100644 index 0000000..81a3674 --- /dev/null +++ b/src/security-manager-tests/common/template_parser.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 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 template_parser.h + * @author Alicja Kluczek + * @brief Parsing function for smack rules templates + */ +#include +#include + +struct AccessRequest { + AccessRequest(std::string sub, std::string obj, std::string acc) + : subject(std::move(sub)), + object(std::move(obj)), + access(std::move(acc)) + {} + std::string subject; + std::string object; + std::string access; +}; + +std::vector parseSmackRulesFile(const std::string &path); + diff --git a/src/security-manager-tests/test_cases.cpp b/src/security-manager-tests/test_cases.cpp index 5bde91d..8b7a7fc 100644 --- a/src/security-manager-tests/test_cases.cpp +++ b/src/security-manager-tests/test_cases.cpp @@ -139,7 +139,7 @@ RUNNER_TEST(security_manager_01d_app_install_complicated_dir_tree) check_path(privateDir, generatePathRWLabel(pkgId)); check_path(privateRODir, generatePathROLabel(pkgId), false); check_path(publicRODir, getPublicPathLabel()); - check_path(sharedRODir, generatePathSharedROLabel(pkgId)); + check_path(sharedRODir, getSharedROPathLabel()); } RUNNER_TEST(security_manager_02_app_install_uninstall_full) @@ -176,7 +176,7 @@ RUNNER_TEST(security_manager_02_app_install_uninstall_full) check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId())); check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false); check_path(app.getPublicDir(), getPublicPathLabel()); - check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId())); + check_path(app.getSharedRODir(), getSharedROPathLabel()); } check_app_after_uninstall(app.getAppId(), app.getPkgId(), app.getPrivilegesNames()); @@ -508,6 +508,98 @@ RUNNER_TEST(security_manager_09_app_install_constraint_check) install(users[0], pkgId[0], appId[0], version[0], author[1], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM); } +RUNNER_TEST(security_manager_09a_install_many_apps_in_single_request) +{ + const std::string pkgId = "sm_test_09a_pkg_id_0"; + const std::vector appIds = {"sm_test_09a_app_id_0", "sm_test_09a_app_id_1", "sm_test_09a_app_id_2"}; + + { + ScopedInstaller appsInstall(appIds, pkgId); + // Installing many applications in single request + for (const auto &appId : appIds) { + check_app_after_install(appId, pkgId); + } + } + + for (const auto &appId : appIds) { + check_app_after_uninstall(appId, pkgId); + } +} + +RUNNER_TEST(security_manager_09b_install_many_apps_in_single_request_duplicated_ids) +{ + const std::string pkgId = "sm_test_09b_pkg_id_0"; + const std::string appId = "sm_test_09b_app_id_0"; + + { + ScopedInstaller appsInstall({appId, appId}, pkgId); + check_app_after_install(appId, pkgId); + } + + check_app_after_uninstall(appId, pkgId); +} + +RUNNER_TEST(security_manager_09c_update_many_apps_in_single_request_hybrid_package) +{ + const std::vector appIds = {"sm_test_09c_app_id_0", "sm_test_09c_app_id_1", "sm_test_09c_app_id_2"}; + const std::string pkgId = "sm_test_09c_pkg_id_0"; + + { + ScopedInstaller appsInstall(appIds, pkgId); + // Package is not hybrid, every app has same policy. + for (const auto &appId : appIds) { + check_app_after_install(appId, pkgId); + } + + // Updating package -- changing set of apps in package and setting hybrid mode + InstallRequest updateRequest; + updateRequest.setPkgId(pkgId); + updateRequest.setAppId(appIds[0]); + updateRequest.nextApp(); + updateRequest.setAppId(appIds[1]); + updateRequest.setHybrid(); + + Api::update(updateRequest); + // Package became hybrid, so every app has its own Smack label + check_app_after_install(appIds[0], pkgId, true); + check_app_after_install(appIds[1], pkgId, true); + // Package became hybrid properly, + // so app not included in updated version of package was uninstalled. + check_app_after_uninstall(appIds[2], pkgId); + } + + for (const auto &appId : appIds) { + check_app_after_uninstall(appId, pkgId, true, true); + } +} + +RUNNER_TEST(security_manager_09d_uninstall_app_from_hybrid_package) +{ + const std::vector appIds = {"sm_test_09d_app_id_0", "sm_test_09d_app_id_1", "sm_test_09d_app_id_2"}; + const std::string pkgId = "sm_test_09d_pkg_id_0"; + { + ScopedInstaller appsInstall(appIds, pkgId); + + InstallRequest updateRequest; + updateRequest.setPkgId(pkgId); + for (unsigned int i = 0; i < appIds.size(); i++) { + if (i > 0) { + updateRequest.nextApp(); + } + updateRequest.setAppId(appIds[i]); + } + updateRequest.setHybrid(); + Api::update(updateRequest); + + InstallRequest uninstRequest; + uninstRequest.setPkgId(pkgId); + uninstRequest.setAppId(appIds[0]); + Api::uninstall(uninstRequest); + + check_app_after_uninstall(appIds[0], pkgId, true); + } +} + RUNNER_CHILD_TEST(security_manager_10_app_has_privilege) { const std::vector allowedPrivs = { diff --git a/src/security-manager-tests/test_cases_prepare_app.cpp b/src/security-manager-tests/test_cases_prepare_app.cpp index 79f75ad..9ff9179 100644 --- a/src/security-manager-tests/test_cases_prepare_app.cpp +++ b/src/security-manager-tests/test_cases_prepare_app.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2020 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. @@ -14,10 +14,13 @@ * limitations under the License. */ +#include #include #include #include +#include +#include #include #include #include @@ -118,28 +121,6 @@ struct ThreadWrapper std::thread thread; }; -int setLauncherSecurityAttributes(TemporaryTestUser &user) -{ - // Add launcher capabilities (cap_dac_override, cap_setgid, cap_sys_admin, cap_mac_admin), - // launcher is user process, we must drop root privileges (cap_setgid, cap_setuid are needed). - // By default, the permitted capability set is cleared when credentials change is made - // (if a process drops a capability from its permitted set, it can never reacquire that capability), - // setting the "keep capabilities" flag prevents it from being cleared. - // Effective capability set is always cleared when credential change is made, we need to add them again. - - setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep cap_setuid+ep"); - int ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0); - if (ret != 0) - return ret; - - ret = drop_root_privileges(user.getUid(), user.getGid()); - if (ret != 0) - return ret; - - setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep"); - return ret; -} - ino_t getFileInode(const std::string &path) { struct stat st; @@ -186,7 +167,7 @@ RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_test) if (pid == 0) { { RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed"); - + Api::prepareAppCandidate(); ThreadWrapper threads[THREADS]; for (size_t i = 0; i < THREADS; i++) @@ -202,6 +183,34 @@ RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_test) } } +RUNNER_CHILD_TEST(security_manager_101_create_namespace_test_n) +{ + TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false); + tmpUser.create(); + + AppInstallHelper app("app100_n", tmpUser.getUid()); + ScopedInstaller appInstall(app); + const std::string expectedLabel = app.generateAppLabel(); + + pid_t pid = fork(); + RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed"); + if (pid == 0) { + { + RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed"); + ThreadWrapper threads[THREADS]; + + for (size_t i = 0; i < THREADS; i++) + threads[i].run(i, expectedLabel); + + Api::prepareAppCandidate(SECURITY_MANAGER_ERROR_INPUT_PARAM); + } + RUNNER_ASSERT_MSG(!thread_errors.empty(), std::endl << thread_errors); + exit(0); + } else { + waitPid(pid); + } +} + RUNNER_CHILD_TEST(security_manager_101_create_namespace_test) { TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false); @@ -216,7 +225,7 @@ RUNNER_CHILD_TEST(security_manager_101_create_namespace_test) if (pid == 0) { synchPipe.claimParentEp(); RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed"); - + Api::prepareAppCandidate(); Api::prepareApp(app.getAppId().c_str()); synchPipe.post(); synchPipe.wait(); @@ -262,7 +271,7 @@ RUNNER_CHILD_TEST(security_manager_102_check_propagation_test) if (pid == 0) { synchPipe.claimParentEp(); RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed"); - + Api::prepareAppCandidate(); Api::prepareApp(app.getAppId().c_str()); synchPipe.post(); synchPipe.wait(); @@ -308,7 +317,7 @@ RUNNER_CHILD_TEST(security_manager_103_policy_change_test) if (pid == 0) { synchPipe.claimParentEp(); RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed"); - + Api::prepareAppCandidate(); Api::prepareApp(app.getAppId().c_str()); synchPipe.post(); synchPipe.wait(); @@ -363,3 +372,194 @@ RUNNER_CHILD_TEST(security_manager_103_policy_change_test) Api::cleanupApp(app.getAppId().c_str(), tmpUser.getUid(), pid); } } + +namespace { +class Timestamp { + uint64_t _; + explicit Timestamp(uint64_t ts) : _(ts) {} +public: + Timestamp operator-(const Timestamp &other) const { + RUNNER_ASSERT(_ > other._); + return Timestamp(_ - other._); + } + Timestamp operator+(const Timestamp &other) const { + return Timestamp(_ + other._); + } + bool operator<(const Timestamp &other) const { + return _ < other._; + } + Timestamp() = default; + static Timestamp future(uint64_t ns) { + timespec ts; + const auto res = clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + RUNNER_ASSERT_ERRNO(!res); + return Timestamp(ts.tv_sec * 1000000000ULL + ts.tv_nsec + ns); + } + static Timestamp now() { + return future(0); + } + template + static void report(Timestamp *ts, size_t n) { + std::sort(ts, ts+n); + uint64_t sum = 0, mn = -1, mx = 0; + long double qsum = 0; + for (size_t i = 0; i < n; i++) { + const auto t = ts[i]._; + sum += t; + qsum += decltype(qsum)(t) * t; + mn = std::min(mn, t); + mx = std::max(mx, t); + } + uint64_t avg = sum / n; + auto qstddev = qsum/n - decltype(qsum)(avg)*avg; + const auto out = [](const char *desc, uint64_t t) { + char raw[20]; + char s[20 + 20/3 + 1]; + size_t j = 0, i = 0; + do + raw[j++] = '0' + t % 10ULL; + while (t /= 10ULL); + for (;;) { + s[i++] = raw[--j]; + if (j <= nLowDigitsToSkip) + break; + if (!(j % 3)) + s[i++] = ' '; + } + s[i] = '\0'; + std::cerr << desc << s; + }; + out("min ", mn); + out(" max ", mx); + out(" avg ", avg); + out(" median ", ts[n/2]._); + out(" stddev ", std::floor(std::sqrt(qstddev))); + std::cerr << '\n'; + } +}; + +template +constexpr size_t arraySize(T (&)[N]) { return N; } +} // namespace + +RUNNER_TEST(security_manager_200_prepare_app_perf) +{ + constexpr int8_t nThreads = 32; + constexpr int8_t nConcurrentAppsSamples[] = { 0 /* 1 app w/ nThreads */, 1, 2, 4, 8, 16, 32 }; + constexpr uint64_t minTotalBenchTime = 60 * 1000ULL*1000*1000; // 60s + + TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false); + tmpUser.create(); + + struct App { + AppInstallHelper hlp; + pid_t pid; + }; + + std::vector candidate, prepare, everything; + + std::vector apps; + std::vector appInstalls; + + constexpr auto nAppsMax = nConcurrentAppsSamples[arraySize(nConcurrentAppsSamples) - 1] ?: 1; + apps.reserve(nAppsMax); + appInstalls.reserve(nAppsMax); + + const auto uid = tmpUser.getUid(); + for (int i = 0; i < nAppsMax; i++) { + apps.emplace_back(App{AppInstallHelper("app200_" + std::to_string(i), uid), 0}); + auto &hlp = apps.back().hlp; + for (const auto &p : { EXTERNAL_STORAGE_PRIVILEGE, MEDIA_STORAGE_PRIVILEGE, + std::string("http://tizen.org/privilege/camera"), + std::string("http://tizen.org/privilege/internet") }) + hlp.addPrivilege(p); + hlp.createSharedRODir(); + appInstalls.emplace_back(ScopedInstaller(hlp)); + } + + for (const auto nConcurrentAppsDesc : nConcurrentAppsSamples) { + const auto nConcurrentApps = nConcurrentAppsDesc ?: 1; + const auto timeout = Timestamp::future(minTotalBenchTime / arraySize(nConcurrentAppsSamples)); + do { + SynchronizationPipe synchPipe; + auto exitEvFd = eventfd(0, 0); + RUNNER_ASSERT(exitEvFd >= 0); + + for (int i = 0; i < nConcurrentApps; i++) { + auto &app = apps[i]; + const auto pid = fork(); + RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed"); + if (pid) + app.pid = pid; + else { + synchPipe.claimChildEp(); + RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed"); + + const auto appId = app.hlp.getAppId(); + + synchPipe.post(); // declare readiness to start measuring + synchPipe.pollForWait(); // wait for parent to signal all kids simultaneously + + const auto candBeg = Timestamp::now(); + Api::prepareAppCandidate(); + const auto candEnd = Timestamp::now(); + + if (!nConcurrentAppsDesc) { + for (int i = 0; i < nThreads; i++) + std::thread([]{ for (;;) usleep(1000); }).detach(); + } + + const auto prepBeg = Timestamp::now(); + Api::prepareApp(appId); + const auto prepEnd = Timestamp::now(); + + const Timestamp ts[2] = { candEnd-candBeg, prepEnd-prepBeg }; + synchPipe.post(ts, sizeof ts); // post measurement payload + + // stay idle until all kids are done to simulate idle apps and reduce benchmark noise + pollfd fds[1]; + fds->fd = exitEvFd; + fds->events = POLLIN; + auto ret = TEMP_FAILURE_RETRY(poll(fds, 1, -1)); + RUNNER_ASSERT_ERRNO(ret > 0); + + exit(0); + } + } + synchPipe.claimParentEp(); + + for (int i = 0; i < nConcurrentApps; i++) // wait for all kids to be ready to start measurement + synchPipe.wait(); + synchPipe.post(); // signal all kids to start measuring + + for (int i = 0; i < nConcurrentApps; i++) { + Timestamp ts[2]; + synchPipe.wait(ts, sizeof ts); + candidate.emplace_back(ts[0]); + prepare.emplace_back(ts[1]); + everything.emplace_back(ts[0] + ts[1]); + } + + RUNNER_ASSERT(!eventfd_write(exitEvFd, 1)); // signal all kids to exit now + + for (int i = 0; i < nConcurrentApps; i++) { + const auto &app = apps[i]; + waitPid(app.pid); + Api::cleanupApp(app.hlp.getAppId(), uid, app.pid); + } + } while (Timestamp::now() < timeout); + + if (!nConcurrentAppsDesc) + std::cerr << "additionalThreads " << int(nThreads) << ' '; + std::cerr << "nConcurrentApps " << int(nConcurrentApps) << " samples " << candidate.size() << '\n'; + std::cerr << " prepareAppCandidate [us]: "; + Timestamp::report(candidate.data(), candidate.size()); + std::cerr << " prepareApp [us]: "; + Timestamp::report(prepare.data(), prepare.size()); + std::cerr << " prepareAppCandidate + prepareApp [us]: "; + Timestamp::report(everything.data(), everything.size()); + candidate.clear(); + prepare.clear(); + everything.clear(); + } +} diff --git a/src/security-manager-tests/test_cases_public_sharing.cpp b/src/security-manager-tests/test_cases_public_sharing.cpp index d882c0f..b71ad04 100644 --- a/src/security-manager-tests/test_cases_public_sharing.cpp +++ b/src/security-manager-tests/test_cases_public_sharing.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2019 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. @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ using namespace SecurityManagerTest; namespace { const uid_t OWNER_UID = 5001; +const uid_t OWNER_GID = 100; const std::vector versions = { "2.4", @@ -54,6 +56,25 @@ const VersionCombinations versionCombinations = makeVersionCombinations(versions RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_SHARED_RO) +static void runAccessTest(uid_t uid, gid_t gid, const std::string &appId, + std::function f) +{ + pid_t pid = fork(); + + RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed"); + if (pid == 0) { + setLauncherSecurityAttributes(uid, gid); + Api::prepareAppCandidate(); + Api::prepareApp(appId.c_str()); + f(); + exit(0); + } else { + + waitPid(pid); + Api::cleanupApp(appId.c_str(), uid, pid); + } +} + /** * Check whether owner app have access to own sharedRO dir */ @@ -64,10 +85,29 @@ RUNNER_CHILD_TEST(security_manager_76_owner_access) app.createSharedRODir(); ScopedInstaller sharedROPkgApp(app); - runAccessTest(app, app.getSharedRODir(), R_OK|W_OK|X_OK); + runAccessTest(OWNER_UID, OWNER_GID, app.getAppId(), [&]() { + accessTest(app.getAppId(), app.getSharedRODir(), R_OK|W_OK|X_OK); + }); } } +RUNNER_CHILD_TEST(security_manager_7x_test) +{ + AppInstallHelper ownerApp("owner_7x", OWNER_UID); + ownerApp.createSharedRODir(); + ScopedInstaller ownerAppInstall(ownerApp); + + AppInstallHelper otherApp("other_7x", OWNER_UID); + otherApp.createSharedRODir(); + ScopedInstaller otherAppInstall(otherApp); + + runAccessTest(OWNER_UID, OWNER_GID, ownerApp.getAppId(), [&]() { + accessTest(ownerApp.getAppId(), ownerApp.getSharedRODir(), R_OK | W_OK | X_OK); + accessTest(ownerApp.getAppId(), otherApp.getSharedRODir(), R_OK | X_OK); + exit(0); + }); +} + /** * Check whether app without shared RO path has access to shared RO dir and * no access to private directories of application from different package between @@ -84,9 +124,14 @@ RUNNER_CHILD_TEST(security_manager_77_owner_other_access_version_combinations) AppInstallHelper nonSharedApp("sm_test_77_nonshared", OWNER_UID, version.second); ScopedInstaller nonSharedAppInstall(nonSharedApp); - runAccessTest(sharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK); - runAccessTest(nonSharedApp, sharedApp.getPrivateDir(), 0); - runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|X_OK); + runAccessTest(OWNER_UID, OWNER_GID, sharedApp.getAppId(), [&]() { + accessTest(sharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|W_OK|X_OK); + }); + + runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() { + accessTest(nonSharedApp.getAppId(), sharedApp.getPrivateDir(), 0); + accessTest(nonSharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|X_OK); + }); } } @@ -108,12 +153,17 @@ RUNNER_CHILD_TEST(security_manager_78_another_pkg_shared_ro_have_ro_access_to_sh sharedApp2.createPrivateDir(); ScopedInstaller sharedApp2Install(sharedApp2); - runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), R_OK|X_OK); - runAccessTest(sharedApp1, sharedApp2.getSharedRODir(), R_OK|X_OK); - runAccessTest(sharedApp1, sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK); - runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); - runAccessTest(sharedApp2, sharedApp1.getPrivateDir(), 0); - runAccessTest(sharedApp1, sharedApp2.getPrivateDir(), 0); + runAccessTest(OWNER_UID, OWNER_GID, sharedApp1.getAppId(), [&]() { + accessTest(sharedApp1.getAppId(), sharedApp2.getSharedRODir(), R_OK|X_OK); + accessTest(sharedApp1.getAppId(), sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK); + accessTest(sharedApp1.getAppId(), sharedApp2.getPrivateDir(), 0); + }); + + runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() { + accessTest(sharedApp2.getAppId(), sharedApp1.getSharedRODir(), R_OK|X_OK); + accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); + accessTest(sharedApp2.getAppId(), sharedApp1.getPrivateDir(), 0); + }); } } @@ -134,9 +184,13 @@ RUNNER_CHILD_TEST(security_manager_79a_same_pkg_shared_ro_have_ro_access_to_shar sharedApp2.createSharedRODir(); ScopedInstaller sharedAppInstall2(sharedApp2); - runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK); - runAccessTest(sharedApp1, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); - }; + runAccessTest(OWNER_UID, OWNER_GID, sharedApp1.getAppId(), [&]() { + accessTest(sharedApp1.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); + }); + runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() { + accessTest(sharedApp2.getAppId(), sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK); + }); + } } /** @@ -155,7 +209,9 @@ RUNNER_CHILD_TEST(security_manager_79b_same_pkg_shared_ro_have_ro_access_to_shar AppInstallHelper nonSharedApp("sm_test_79b_shared2", sharedPkgName, OWNER_UID, version); ScopedInstaller nonSharedAppInstall(nonSharedApp); - runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK); + runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() { + accessTest(nonSharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|W_OK|X_OK); + }); }; } @@ -181,14 +237,23 @@ RUNNER_CHILD_TEST(security_manager_80_same_pkg_shared_ro_have_no_access_to_share AppInstallHelper nonSharedApp("sm_test_80_nonshared", sharedPkgName, OWNER_UID, version); ScopedInstaller nonSharedAppInstall(nonSharedApp); - runAccessTest(sharedApp2, sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK); - runAccessTest(sharedApp1, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK); - runAccessTest(nonSharedApp, sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK); - runAccessTest(nonSharedApp, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK); + runAccessTest(OWNER_UID, OWNER_GID, sharedApp1.getAppId(), [&]() { + accessTest(sharedApp1.getAppId(), sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK); + }); + runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() { + accessTest(sharedApp2.getAppId(), sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK); + }); + + runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() { + accessTest(nonSharedApp.getAppId(), sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK); + accessTest(nonSharedApp.getAppId(), sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK); + }); sharedAppInstall1.uninstallApp(); - runAccessTest(nonSharedApp, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK); + runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() { + accessTest(nonSharedApp.getAppId(), sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK); + }); } } @@ -218,16 +283,22 @@ RUNNER_CHILD_TEST(security_manager_81_add_path_to_app_and_check_all) sharedRORequest.setUid(sharedApp2.getUID()); Api::registerPaths(sharedRORequest); - runAccessTest(sharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK); - runAccessTest(sharedApp, sharedApp.getPrivateDir(), R_OK|W_OK|X_OK); - - runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); - runAccessTest(sharedApp2, sharedApp.getSharedRODir(), R_OK|X_OK); - runAccessTest(sharedApp2, sharedApp.getPrivateDir(), 0); - - runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|X_OK); - runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(), R_OK|X_OK); - runAccessTest(nonSharedApp, sharedApp.getPrivateDir(), 0); + runAccessTest(OWNER_UID, OWNER_GID, sharedApp.getAppId(), [&]() { + accessTest(sharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|W_OK|X_OK); + accessTest(sharedApp.getAppId(), sharedApp.getPrivateDir(), R_OK|W_OK|X_OK); + }); + + runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() { + accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); + accessTest(sharedApp2.getAppId(), sharedApp.getSharedRODir(), R_OK|X_OK); + accessTest(sharedApp2.getAppId(), sharedApp.getPrivateDir(), 0); + }); + + runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() { + accessTest(nonSharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|X_OK); + accessTest(nonSharedApp.getAppId(), sharedApp2.getSharedRODir(), R_OK|X_OK); + accessTest(nonSharedApp.getAppId(), sharedApp.getPrivateDir(), 0); + }); } } @@ -270,12 +341,17 @@ RUNNER_CHILD_TEST(security_manager_83_install_uninstall_shared_ro_app_and_check_ ScopedInstaller nonSharedAppInstall(nonSharedApp); sharedAppInstall1.uninstallApp(); + sharedApp1.removePaths(); - runAccessTest(nonSharedApp, sharedApp1.getSharedRODir(), 0); - runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), 0); + runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() { + accessTest(nonSharedApp.getAppId(), sharedApp1.getSharedRODir(), 0); + accessTest(nonSharedApp.getAppId(), sharedApp2.getSharedRODir(), R_OK|X_OK); + }); - runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(), R_OK|X_OK); - runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); + runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() { + accessTest(sharedApp2.getAppId(), sharedApp1.getSharedRODir(), 0); + accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK); + }); } } @@ -302,7 +378,12 @@ RUNNER_CHILD_TEST(security_manager_84_install_uninstall_shared_ro_two_apps_in_on sharedAppInstall1.uninstallApp(); - runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(2), R_OK|X_OK); - runAccessTest(sharedApp2, sharedApp2.getSharedRODir(2), R_OK|W_OK|X_OK); + runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() { + accessTest(nonSharedApp.getAppId(), sharedApp2.getSharedRODir(2), R_OK|X_OK); + }); + + runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() { + accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(2), R_OK|W_OK|X_OK); + }); } } diff --git a/src/security-manager-tests/test_cases_register_paths.cpp b/src/security-manager-tests/test_cases_register_paths.cpp index ba37c8b..26970c0 100644 --- a/src/security-manager-tests/test_cases_register_paths.cpp +++ b/src/security-manager-tests/test_cases_register_paths.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2019 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. @@ -347,7 +347,7 @@ RUNNER_TEST(security_manager_66_path_req_check_labels) check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId())); check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false); check_path(app.getPublicDir(), getPublicPathLabel()); - check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId())); + check_path(app.getSharedRODir(), getSharedROPathLabel()); } RUNNER_TEST(security_manager_67_path_req_shared_ro_3_0) @@ -367,7 +367,7 @@ RUNNER_TEST(security_manager_67_path_req_shared_ro_3_0) preq.addPath(app.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO); Api::registerPaths(preq); - check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId())); + check_path(app.getSharedRODir(), getSharedROPathLabel()); } RUNNER_TEST(security_manager_68_path_req_shared_ro_2_X) @@ -387,7 +387,7 @@ RUNNER_TEST(security_manager_68_path_req_shared_ro_2_X) preq.addPath(app.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO); Api::registerPaths(preq); - check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId())); + check_path(app.getSharedRODir(), getSharedROPathLabel()); } RUNNER_TEST(security_manager_69_path_req_trusted_rw_no_author) diff --git a/src/security-tests-all.sh b/src/security-tests-all.sh index 12c5f87..3584e95 100644 --- a/src/security-tests-all.sh +++ b/src/security-tests-all.sh @@ -57,6 +57,7 @@ runTest security-manager runTest cynara runTest ckm runTest yaca +runTest nether printSummary diff --git a/src/security-tests.sh b/src/security-tests.sh index 45dd3b5..1cf60b6 100644 --- a/src/security-tests.sh +++ b/src/security-tests.sh @@ -56,11 +56,17 @@ case $1 in echo yaca-test "${@:2}" ;; +"nether") + echo "=========================================================================" + echo "NETHER TESTS" + echo + nether-tests "${@:2}" + ;; *) echo "Correct using:" echo " security_test.sh " echo - echo "modules: smack, security-manager, cynara, ckm, yaca" + echo "modules: smack, security-manager, cynara, ckm, yaca, nether" ;; esac