build ttyd with client cert patch
client cert doesn't work as intented, so added patch for that, and then
made it build during build
in addition, fixed the bug in reading client cert logic as well(actually
alias isn't set in p12, so need to enumerate and get the first one),
BTW, this logic will be removed very soon with the logic which generates
key on the fly
Bug: 363235314
Test: run ttyd and check if client cert works well
Change-Id: I5d08f3d11cf4846677f19137e860236c42b9c9d8
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
index e278165..0b130f5 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
@@ -72,6 +72,7 @@
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
+import java.util.Enumeration;
public class MainActivity extends BaseActivity
implements VmLauncherServices.VmLauncherServiceCallback,
@@ -116,8 +117,8 @@
mAccessibilityManager = getSystemService(AccessibilityManager.class);
mAccessibilityManager.addTouchExplorationStateChangeListener(this);
- connectToTerminalService();
readClientCertificate();
+ connectToTerminalService();
manageExternalStorageActivityResultLauncher =
registerForActivityResult(
@@ -184,15 +185,19 @@
getClass().getResourceAsStream("/assets/client.p12")) {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
String password = "1234";
- String alias = "1";
keyStore.load(keystoreFileStream, password != null ? password.toCharArray() : null);
- Key key = keyStore.getKey(alias, password.toCharArray());
- if (key instanceof PrivateKey) {
- mPrivateKey = (PrivateKey) key;
- Certificate cert = keyStore.getCertificate(alias);
- mCertificates = new X509Certificate[1];
- mCertificates[0] = (X509Certificate) cert;
+ Enumeration<String> enumeration = keyStore.aliases();
+ while (enumeration.hasMoreElements()) {
+ String alias = enumeration.nextElement();
+ Key key = keyStore.getKey(alias, password.toCharArray());
+ if (key instanceof PrivateKey) {
+ mPrivateKey = (PrivateKey) key;
+ Certificate cert = keyStore.getCertificate(alias);
+ mCertificates = new X509Certificate[1];
+ mCertificates[0] = (X509Certificate) cert;
+ return;
+ }
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
diff --git a/build/debian/build.sh b/build/debian/build.sh
index b4e8b2f..5829ecc 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -50,15 +50,21 @@
install_prerequisites() {
apt update
packages=(
+ automake
binfmt-support
build-essential
ca-certificates
+ cmake
curl
debsums
dosfstools
fai-server
fai-setup-storage
fdisk
+ git
+ libjson-c-dev
+ libtool
+ libwebsockets-dev
make
protobuf-compiler
python3
@@ -121,6 +127,23 @@
popd > /dev/null
}
+build_ttyd() {
+ local ttyd_version=1.7.7
+ local url="https://github.com/tsl0922/ttyd/archive/refs/tags/${ttyd_version}.tar.gz"
+ cp -r $(dirname $0)/ttyd ${workdir}/ttyd
+
+ pushd "${workdir}" > /dev/null
+ wget "${url}" -O - | tar xz
+ cp ttyd/* ttyd-${ttyd_version}/scripts
+ pushd "$workdir/ttyd-${ttyd_version}" > /dev/null
+ bash -c "env BUILD_TARGET=${arch} ./scripts/cross-build.sh"
+ mkdir -p "${dst}/files/usr/local/bin/ttyd"
+ cp /tmp/stage/${arch}-linux-musl/bin/ttyd "${dst}/files/usr/local/bin/ttyd/AVF"
+ chmod 777 "${dst}/files/usr/local/bin/ttyd/AVF"
+ popd > /dev/null
+ popd > /dev/null
+}
+
copy_android_config() {
local src="$(dirname "$0")/fai_config"
local dst="${config_space}"
@@ -128,12 +151,7 @@
cp -R "${src}"/* "${dst}"
cp "$(dirname "$0")/image.yaml" "${resources_dir}"
- local ttyd_version=1.7.7
- local url="https://github.com/tsl0922/ttyd/releases/download/${ttyd_version}/ttyd.${arch}"
- mkdir -p "${dst}/files/usr/local/bin/ttyd"
- wget "${url}" -O "${dst}/files/usr/local/bin/ttyd/AVF"
- chmod 777 "${dst}/files/usr/local/bin/ttyd/AVF"
-
+ build_ttyd
build_rust_binary_and_copy forwarder_guest
build_rust_binary_and_copy forwarder_guest_launcher
build_rust_binary_and_copy ip_addr_reporter
diff --git a/build/debian/ttyd/client_cert.patch b/build/debian/ttyd/client_cert.patch
new file mode 100644
index 0000000..93b8aed
--- /dev/null
+++ b/build/debian/ttyd/client_cert.patch
@@ -0,0 +1,41 @@
+diff --git a/lib/tls/mbedtls/mbedtls-server.c b/lib/tls/mbedtls/mbedtls-server.c
+index efd7fc8b..ca5ebc15 100644
+--- a/lib/tls/mbedtls/mbedtls-server.c
++++ b/lib/tls/mbedtls/mbedtls-server.c
+@@ -39,7 +39,7 @@ lws_tls_server_client_cert_verify_config(struct lws_vhost *vh)
+ }
+
+ if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
+- verify_options = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
++ verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+
+ lwsl_notice("%s: vh %s requires client cert %d\n", __func__, vh->name,
+ verify_options);
+diff --git a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c
+index 3879e977..e47d4c13 100755
+--- a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c
++++ b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c
+@@ -255,9 +255,9 @@ static int ssl_pm_reload_crt(SSL *ssl)
+ struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm;
+ struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm;
+
+- if (ssl->verify_mode == SSL_VERIFY_PEER)
++ if ((ssl->verify_mode & SSL_VERIFY_PEER) > 0)
+ mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+- else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
++ else if ((ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) > 0)
+ mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
+ else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE)
+ mode = MBEDTLS_SSL_VERIFY_UNSET;
+@@ -980,9 +980,9 @@ void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
+
+ #if defined(LWS_HAVE_mbedtls_ssl_set_hs_authmode)
+
+- if (ctx->verify_mode == SSL_VERIFY_PEER)
++ if ((ctx->verify_mode & SSL_VERIFY_PEER) > 0)
+ mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+- else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
++ else if ((ctx->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) > 0)
+ mode = MBEDTLS_SSL_VERIFY_REQUIRED;
+ else if (ctx->verify_mode == SSL_VERIFY_CLIENT_ONCE)
+ mode = MBEDTLS_SSL_VERIFY_UNSET;
diff --git a/build/debian/ttyd/cross-build.sh b/build/debian/ttyd/cross-build.sh
new file mode 100755
index 0000000..dda8f78
--- /dev/null
+++ b/build/debian/ttyd/cross-build.sh
@@ -0,0 +1,193 @@
+#!/bin/bash
+#
+# Example:
+# env BUILD_TARGET=mips ./scripts/cross-build.sh
+#
+set -eo pipefail
+
+CROSS_ROOT="${CROSS_ROOT:-/tmp/cross}"
+STAGE_ROOT="${STAGE_ROOT:-/tmp/stage}"
+BUILD_ROOT="${BUILD_ROOT:-/tmp/build}"
+BUILD_TARGET="${BUILD_TARGET:-x86_64}"
+
+ZLIB_VERSION="${ZLIB_VERSION:-1.3.1}"
+JSON_C_VERSION="${JSON_C_VERSION:-0.17}"
+MBEDTLS_VERSION="${MBEDTLS_VERSION:-2.28.5}"
+LIBUV_VERSION="${LIBUV_VERSION:-1.44.2}"
+LIBWEBSOCKETS_VERSION="${LIBWEBSOCKETS_VERSION:-4.3.3}"
+
+build_zlib() {
+ echo "=== Building zlib-${ZLIB_VERSION} (${TARGET})..."
+ curl -fSsLo- "https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+ pushd "${BUILD_DIR}"/zlib-"${ZLIB_VERSION}"
+ env CHOST="${TARGET}" ./configure --static --archs="-fPIC" --prefix="${STAGE_DIR}"
+ make -j"$(nproc)" install
+ popd
+}
+
+build_json-c() {
+ echo "=== Building json-c-${JSON_C_VERSION} (${TARGET})..."
+ curl -fSsLo- "https://s3.amazonaws.com/json-c_releases/releases/json-c-${JSON_C_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+ pushd "${BUILD_DIR}/json-c-${JSON_C_VERSION}"
+ rm -rf build && mkdir -p build && cd build
+ cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+ -DCMAKE_BUILD_TYPE=RELEASE \
+ -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DBUILD_TESTING=OFF \
+ -DDISABLE_THREAD_LOCAL_STORAGE=ON \
+ ..
+ make -j"$(nproc)" install
+ popd
+}
+
+build_mbedtls() {
+ echo "=== Building mbedtls-${MBEDTLS_VERSION} (${TARGET})..."
+ curl -fSsLo- "https://github.com/ARMmbed/mbedtls/archive/v${MBEDTLS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+ pushd "${BUILD_DIR}/mbedtls-${MBEDTLS_VERSION}"
+ rm -rf build && mkdir -p build && cd build
+ cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+ -DCMAKE_BUILD_TYPE=RELEASE \
+ -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+ -DENABLE_TESTING=OFF \
+ ..
+ make -j"$(nproc)" install
+ popd
+}
+
+build_libuv() {
+ echo "=== Building libuv-${LIBUV_VERSION} (${TARGET})..."
+ curl -fSsLo- "https://dist.libuv.org/dist/v${LIBUV_VERSION}/libuv-v${LIBUV_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+ pushd "${BUILD_DIR}/libuv-v${LIBUV_VERSION}"
+ ./autogen.sh
+ env CFLAGS=-fPIC ./configure --disable-shared --enable-static --prefix="${STAGE_DIR}" --host="${TARGET}"
+ make -j"$(nproc)" install
+ popd
+}
+
+install_cmake_cross_file() {
+ cat << EOF > "${BUILD_DIR}/cross-${TARGET}.cmake"
+SET(CMAKE_SYSTEM_NAME $1)
+
+set(CMAKE_C_COMPILER "${TARGET}-gcc")
+set(CMAKE_CXX_COMPILER "${TARGET}-g++")
+
+set(CMAKE_FIND_ROOT_PATH "${STAGE_DIR}")
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(OPENSSL_USE_STATIC_LIBS TRUE)
+EOF
+}
+
+build_libwebsockets() {
+ echo "=== Building libwebsockets-${LIBWEBSOCKETS_VERSION} (${TARGET})..."
+ curl -fSsLo- "https://github.com/warmcat/libwebsockets/archive/v${LIBWEBSOCKETS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}"
+ cp "$(dirname $0)/client_cert.patch" ${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION}
+ pushd "${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION}"
+ patch -p1 < client_cert.patch
+ sed -i 's/ websockets_shared//g' cmake/libwebsockets-config.cmake.in
+ sed -i 's/ OR PC_OPENSSL_FOUND//g' lib/tls/CMakeLists.txt
+ sed -i '/PC_OPENSSL/d' lib/tls/CMakeLists.txt
+ rm -rf build && mkdir -p build && cd build
+ cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+ -DCMAKE_BUILD_TYPE=RELEASE \
+ -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+ -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \
+ -DCMAKE_EXE_LINKER_FLAGS="-static" \
+ -DLWS_WITHOUT_TESTAPPS=ON \
+ -DLWS_WITH_MBEDTLS=ON \
+ -DLWS_WITH_LIBUV=ON \
+ -DLWS_STATIC_PIC=ON \
+ -DLWS_WITH_SHARED=OFF \
+ -DLWS_UNIX_SOCK=ON \
+ -DLWS_IPV6=ON \
+ -DLWS_ROLE_RAW_FILE=OFF \
+ -DLWS_WITH_HTTP2=ON \
+ -DLWS_WITH_HTTP_BASIC_AUTH=OFF \
+ -DLWS_WITH_UDP=OFF \
+ -DLWS_WITHOUT_CLIENT=ON \
+ -DLWS_WITHOUT_EXTENSIONS=OFF \
+ -DLWS_WITH_LEJP=OFF \
+ -DLWS_WITH_LEJP_CONF=OFF \
+ -DLWS_WITH_LWSAC=OFF \
+ -DLWS_WITH_SEQUENCER=OFF \
+ ..
+ make -j"$(nproc)" install
+ popd
+}
+
+build_ttyd() {
+ echo "=== Building ttyd (${TARGET})..."
+ rm -rf build && mkdir -p build && cd build
+ cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \
+ -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \
+ -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \
+ -DCMAKE_C_FLAGS="-Os -ffunction-sections -fdata-sections -fno-unwind-tables -fno-asynchronous-unwind-tables -flto" \
+ -DCMAKE_EXE_LINKER_FLAGS="-static -no-pie -Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections" \
+ -DCMAKE_BUILD_TYPE=RELEASE \
+ ..
+ make install
+}
+
+build() {
+ TARGET="$1"
+ ALIAS="$2"
+ STAGE_DIR="${STAGE_ROOT}/${TARGET}"
+ BUILD_DIR="${BUILD_ROOT}/${TARGET}"
+ MUSL_CC_URL="https://github.com/tsl0922/musl-toolchains/releases/download/2021-11-23"
+ COMPONENTS="1"
+ SYSTEM="Linux"
+
+ if [ "$ALIAS" = "win32" ]; then
+ COMPONENTS=2
+ SYSTEM="Windows"
+ fi
+
+ echo "=== Installing toolchain ${ALIAS} (${TARGET})..."
+
+ mkdir -p "${CROSS_ROOT}" && export PATH="${PATH}:${CROSS_ROOT}/bin"
+ curl -fSsLo- "${MUSL_CC_URL}/${TARGET}-cross.tgz" | tar xz -C "${CROSS_ROOT}" --strip-components=${COMPONENTS}
+
+ echo "=== Building target ${ALIAS} (${TARGET})..."
+
+ rm -rf "${STAGE_DIR}" "${BUILD_DIR}"
+ mkdir -p "${STAGE_DIR}" "${BUILD_DIR}"
+ export PKG_CONFIG_PATH="${STAGE_DIR}/lib/pkgconfig"
+
+ install_cmake_cross_file ${SYSTEM}
+
+ build_zlib
+ build_json-c
+ build_libuv
+ build_mbedtls
+ build_libwebsockets
+ build_ttyd
+}
+
+case ${BUILD_TARGET} in
+ amd64) BUILD_TARGET="x86_64" ;;
+ arm64) BUILD_TARGET="aarch64" ;;
+ armv7) BUILD_TARGET="armv7l" ;;
+esac
+
+case ${BUILD_TARGET} in
+ i686|x86_64|aarch64|mips|mipsel|mips64|mips64el|s390x)
+ build "${BUILD_TARGET}-linux-musl" "${BUILD_TARGET}"
+ ;;
+ arm)
+ build "${BUILD_TARGET}-linux-musleabi" "${BUILD_TARGET}"
+ ;;
+ armhf)
+ build arm-linux-musleabihf "${BUILD_TARGET}"
+ ;;
+ armv7l)
+ build armv7l-linux-musleabihf "${BUILD_TARGET}"
+ ;;
+ win32)
+ build x86_64-w64-mingw32 "${BUILD_TARGET}"
+ ;;
+ *)
+ echo "unknown cross target: ${BUILD_TARGET}" && exit 1
+esac