Skip to content

Commit

Permalink
For example apps create Tizen security profile on the fly
Browse files Browse the repository at this point in the history
  • Loading branch information
arkq committed Jul 14, 2022
1 parent 41ef15e commit 554f2e3
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 9 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/examples-tizen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,12 @@ jobs:
run: scripts/checkout_submodules.py --shallow --platform tizen
- name: Build Tizen examples
run: scripts/run_in_build_env.sh "./scripts/build/build_examples.py --target-glob 'tizen-*' build"
- name: Package Tizen lighting-app
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
--enable-flashbundle \
--target tizen-arm-light \
build \
--copy-artifacts-to out/artifacts \
"
5 changes: 4 additions & 1 deletion examples/all-clusters-app/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ executable("chip-all-clusters-app") {
}

tizen_sdk_package("chip-all-clusters-app:tpk") {
deps = [ ":chip-all-clusters-app" ]
deps = [
":chip-all-clusters-app",
"${chip_root}/examples/platform/tizen:author-certificate-CHIP",
]
manifest = rebase_path("tizen-manifest.xml")
sign_security_profile = "CHIP"
}
Expand Down
5 changes: 4 additions & 1 deletion examples/all-clusters-minimal-app/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ executable("chip-all-clusters-minimal-app") {
}

tizen_sdk_package("chip-all-clusters-minimal-app:tpk") {
deps = [ ":chip-all-clusters-minimal-app" ]
deps = [
":chip-all-clusters-minimal-app",
"${chip_root}/examples/platform/tizen:author-certificate-CHIP",
]
manifest = rebase_path("tizen-manifest.xml")
sign_security_profile = "CHIP"
}
Expand Down
5 changes: 4 additions & 1 deletion examples/lighting-app/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ executable("chip-lighting-app") {
}

tizen_sdk_package("chip-lighting-app:tpk") {
deps = [ ":chip-lighting-app" ]
deps = [
":chip-lighting-app",
"${chip_root}/examples/platform/tizen:author-certificate-CHIP",
]
manifest = rebase_path("tizen-manifest.xml")
sign_security_profile = "CHIP"
}
Expand Down
11 changes: 11 additions & 0 deletions examples/platform/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@

import("//build_overrides/build.gni")
import("//build_overrides/chip.gni")
import("//build_overrides/tizen.gni")

import("${chip_root}/src/app/common_flags.gni")
import("${chip_root}/src/lib/core/core.gni")
import("${chip_root}/src/lib/lib.gni")

import("${build_root}/config/linux/pkg_config.gni")
import("${tizen_sdk_build_root}/tizen_sdk.gni")

config("config") {
include_dirs = [ "." ]
Expand All @@ -28,6 +31,14 @@ pkg_config("capi-appfw-service-application") {
packages = [ "capi-appfw-service-application" ]
}

tizen_sdk_certificate("author-certificate-CHIP") {
# Data for dummy author certificate.
author_certificate_name = "Matter Example"
author_certificate_email = "[email protected]"
author_certificate_password = "0123456789"
sign_security_profile = "CHIP"
}

source_set("app-main") {
sources = [
"OptionsProxy.cpp",
Expand Down
141 changes: 141 additions & 0 deletions third_party/tizen/tizen_dev_certificate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#!/usr/bin/env python

# Copyright (c) 2022 Project CHIP Authors
#
# 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.

import argparse
import logging
import os
import subprocess
import sys

# Absolute path to Tizen Studio CLI tool.
tizen_sdk_root = os.environ["TIZEN_SDK_ROOT"]
tizen_cli = os.path.join(tizen_sdk_root, "tools", "ide", "bin", "tizen")

# Setup basic logging capabilities.
logging.basicConfig(level=logging.DEBUG)


def create_author_certificate(alias: str, password: str,
name: str = "", email: str = ""):
cmd = [tizen_cli, "certificate", "--alias", alias, "--password", password]
if name:
cmd.extend(["--name", name])
if email:
cmd.extend(["--email", email])
logging.debug("Execute: %s", " ".join(cmd))
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as proc:
for line in proc.stdout.readlines():
line = line.decode().rstrip()
if line.startswith("Working path:"):
wd = line[len("Working path:"):].strip()
print(line)
return os.path.join(wd, "author.p12")


def check_security_profile(profile):

# XXX: If Tizen Studio SDK data directory was removed but the config file
# was not, Tizen Studio CLI does not create profiles XML file. This
# is a workaround to create a dummy XML profiles file so later Tizen
# will regenerate it with the correct content.

tizen_sdk_data_dir = None
with open(os.environ["TIZEN_SDK_ROOT"] + "/sdk.info") as f:
for line in f.readlines():
if line.startswith("TIZEN_SDK_DATA_PATH"):
tizen_sdk_data_dir = line.split("=")[1].strip()
break
if not tizen_sdk_data_dir:
logging.error("Cannot find Tizen SDK data directory")
return False

profiles_xml = os.path.join(tizen_sdk_data_dir, "profile", "profiles.xml")
os.makedirs(os.path.dirname(profiles_xml), exist_ok=True)
if not os.path.exists(profiles_xml):
with open(profiles_xml, "w") as f:
f.write('<profiles/>')

cmd = [tizen_cli, "security-profiles", "list", "--name", profile]
logging.debug("Execute: %s", " ".join(cmd))
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as proc:
for line in proc.stdout.readlines():
line = line.decode().rstrip()
print(line)
return proc.wait() == 0


def add_security_profile(profile: str, certificate: str, password: str):
cmd = [tizen_cli, "security-profiles", "add", "--active",
"--name", profile, "--author", certificate, "--password", password]
logging.debug("Execute: %s", " ".join(cmd))
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as proc:
for line in proc.stdout.readlines():
line = line.decode().rstrip()
print(line)
return proc.wait() == 0


def update_stamp_file(path: str, message: str):
if path:
with open(path, "w") as f:
f.write(message + "\n")


parser = argparse.ArgumentParser(
description="Setup Tizen Studio development security profile.")
parser.add_argument(
'--author-certificate-name', metavar='NAME',
help="Set author certificate 'name' field.")
parser.add_argument(
'--author-certificate-email', metavar='EMAIL',
help="Set author certificate 'email' field.")
parser.add_argument(
'--author-certificate-password', metavar='PASSWORD', required=True,
help="Password for author certificate.")
parser.add_argument(
'--sign-security-profile', metavar='NAME', required=True,
help="Name of the security profile to add.")
parser.add_argument(
'--stamp-file', metavar='FILE',
help="Update the stamp file upon success.")

args = parser.parse_args()

rv = check_security_profile(args.sign_security_profile)
if rv:
update_stamp_file(args.stamp_file, "Using existing security profile.")
logging.info("Security profile already exists")
sys.exit()

# Create author certificate if it does not exist. If the certificate already
# exists, it will be used. However, if the password is different, it will not
# be possible to use the certificate when updating the security profile.
cert = create_author_certificate("CHIP",
args.author_certificate_password,
args.author_certificate_name,
args.author_certificate_email)
if not cert:
logging.error("Failed to create author certificate")
sys.exit(1)

rv = add_security_profile(args.sign_security_profile, cert,
args.author_certificate_password)
if not rv:
logging.error("Failed to add security profile")
sys.exit(1)

update_stamp_file(args.stamp_file, "New security profile created.")
sys.exit()
55 changes: 49 additions & 6 deletions third_party/tizen/tizen_sdk.gni
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,17 @@ import("//build_overrides/tizen.gni")

import("${build_root}/config/tizen/config.gni")

tizen_dev_certificate = rebase_path("tizen_dev_certificate.py")
tizen_manifest_parser = rebase_path("tizen_manifest_parser.py")

# Run Tizen Studio CLI as a project builder.
#
# Parameters:
# project_build_dir: Directory to build the project in.
# project_app_name: Name of the application within the project.
# args: List of arguments to pass to the CLI.
# outputs: List of created output files.
# deps: List of dependencies.
template("tizen_sdk") {
forward_variables_from(invoker,
[
Expand Down Expand Up @@ -59,20 +68,54 @@ template("tizen_sdk") {
}
}

# Generate author certificate and security profile.
#
# Parameters:
# author_certificate_name: Author certificate name field.
# author_certificate_email: Author certificate email field.
# author_certificate_password: Password for the author certificate.
# sign_security_profile: Name of the security profile to add.
template("tizen_sdk_certificate") {
assert(defined(invoker.author_certificate_password),
"It is required to specify `author_certificate_password`.")
assert(defined(invoker.sign_security_profile),
"It is required to specify a `sign_security_profile` which " +
"should be added to Tizen security profiles.")
stamp_file = "${root_build_dir}/.tizen_sdk_dev_certificate_stamp"
action(target_name) {
forward_variables_from(invoker, [ "deps" ])
script = tizen_dev_certificate
args = [
"--author-certificate-name=" + invoker.author_certificate_name,
"--author-certificate-email=" + invoker.author_certificate_email,
"--author-certificate-password=" + invoker.author_certificate_password,
"--sign-security-profile=" + invoker.sign_security_profile,
"--stamp-file=" + stamp_file,
]
outputs = [ stamp_file ]
}
}

# Package Tizen application as a TPK bundle.
#
# Parameters:
# manifest: The path to Tizen XML manifest file to use.
# sign_security_profile: Name of the security profile to use for signing.
# deps: List of dependencies.
template("tizen_sdk_package") {
assert(defined(invoker.manifest),
"It is required to specify Tizen `manifest` XML file.")
assert(defined(invoker.sign_security_profile),
"It is required to specify a `sign_security_profile` which " +
"should be used for signing TPK package.")

# Output directory where packaging will occur. We need a separate directory
# for this, because Tizen Studio CLI scans "res" (resources), "shared" and
# "lib" directories for items to pack. In our case it could include in the
# TPK package libraries available in ${root_out_dir}/lib directory.
tizen_package_dir = "${root_build_dir}/package"
tizen_package_out_dir = "${tizen_package_dir}/out"

assert(defined(invoker.manifest),
"It is required to specify Tizen `manifest` XML file.")
assert(defined(invoker.sign_security_profile),
"It is required to specify a `sign_security_profile` which " +
"should be used for signing TPK package.")

# Extract data from Tizen XML manifest.
manifest = exec_script(tizen_manifest_parser, [ invoker.manifest ], "json")
manifest_package = manifest["package"]
Expand Down

0 comments on commit 554f2e3

Please sign in to comment.