Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/signjars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Sign jars and internal native libraries

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
runs-on: macos-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'

- name: Codesign JARs and Internal Native Libraries
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
run: |
# Step 1: Decode and import the certificate into a keychain
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
/usr/bin/security create-keychain -p espressif build.keychain
/usr/bin/security default-keychain -s build.keychain
/usr/bin/security unlock-keychain -p espressif build.keychain
/usr/bin/security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
/usr/bin/security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k espressif build.keychain

# Step 2: Define the directory containing the JARs and native libraries and the temp directory for signed JARs
LIB_DIR="${PWD}/BUNDLES/com.espressif.idf.serial.monitor/lib"
SIGNED_JARS_DIR="${RUNNER_TEMP}/signed-jars" # Use GitHub's RUNNER_TEMP for storing signed JARs
mkdir -p "$SIGNED_JARS_DIR"

# Step 3: Extract, sign native libraries, repackage, and sign the JARs with Apple codesign
for jar in "${LIB_DIR}"/*.jar; do
echo "Processing JAR file: ${jar}"

# Check if the JAR exists
if [ -f "$jar" ]; then
echo "JAR file found: ${jar}"
else
echo "JAR file not found: ${jar}"
continue
fi

# Create a temporary directory to extract the JAR contents
TEMP_DIR=$(mktemp -d)
unzip -q "$jar" -d "$TEMP_DIR"

# Find and sign all .jnilib and .dylib files in the extracted JAR directory
find "$TEMP_DIR" -name "*.jnilib" -o -name "*.dylib" | while read lib; do
echo "Signing native library: ${lib}"
/usr/bin/codesign -vvvv --entitlements $PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" --timestamp --deep "$lib"
done

# Repackage the signed JAR
pushd "$TEMP_DIR"
zip -r "${SIGNED_JARS_DIR}/$(basename "$jar")" * # Save signed JAR to the temporary signed directory
popd

# Sign the entire JAR with Apple codesign, using the same entitlements
echo "Signing repackaged JAR: ${SIGNED_JARS_DIR}/$(basename "$jar")"
/usr/bin/codesign -vvvv --entitlements $PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement --force --deep --options runtime --timestamp -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" "${SIGNED_JARS_DIR}/$(basename "$jar")"

# Verify the signed JAR
echo "Verifying signed JAR: ${SIGNED_JARS_DIR}/$(basename "$jar")"
/usr/bin/codesign -dvv "${SIGNED_JARS_DIR}/$(basename "$jar")"

# Clean up extracted directory (but leave the signed JAR in SIGNED_JARS_DIR)
rm -rf "$TEMP_DIR"
done
Comment on lines +36 to +78
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize JAR processing and signing

Consider the following improvements to enhance performance, reliability, and security:

  1. Use parallel processing for signing multiple JARs.
  2. Add error checking and logging for each step.
  3. Use read -r to prevent backslash mangling in filenames.
  4. Quote variables to prevent word splitting and globbing.

Here's an optimized version:

export -f codesign_and_verify
find "$LIB_DIR" -name "*.jar" -print0 | parallel -0 process_jar {}

process_jar() {
  local jar_file="$1"
  echo "Processing JAR file: $jar_file"
  local temp_dir
  temp_dir=$(mktemp -d) || { echo "Failed to create temp directory"; return 1; }
  
  if ! unzip -q "$jar_file" -d "$temp_dir"; then
    echo "Error extracting $jar_file"
    rm -rf "$temp_dir"
    return 1
  fi

  find "$temp_dir" \( -name "*.jnilib" -o -name "*.dylib" \) -print0 | 
    xargs -0 -I {} bash -c 'codesign_and_verify "$@"' _ {} "$PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement"

  if ! (cd "$temp_dir" && zip -qr "$jar_file" .); then
    echo "Error repackaging $jar_file"
    rm -rf "$temp_dir"
    return 1
  fi

  if ! codesign_and_verify "$jar_file" "$PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement"; then
    echo "Error signing JAR $jar_file"
    rm -rf "$temp_dir"
    return 1
  fi

  rm -rf "$temp_dir"
  echo "Successfully processed $jar_file"
}

codesign_and_verify() {
  local file="$1"
  local entitlements="$2"
  echo "Signing file: $file"
  if ! /usr/bin/codesign --entitlements "$entitlements" --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" --timestamp --deep "$file"; then
    echo "Error signing $file"
    return 1
  fi
  if ! /usr/bin/codesign --verify --deep --strict --verbose=2 "$file"; then
    echo "Verification failed for $file"
    return 1
  fi
  echo "Successfully signed and verified $file"
}

This version uses GNU Parallel for concurrent processing, adds error checking, uses read -r, and quotes variables for improved security and reliability.

Comment on lines +42 to +78
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve bash script for better error handling and security.

Consider the following improvements to the JAR signing process:

  1. Use set -euo pipefail at the beginning of the script for better error handling.
  2. Use read -r to prevent backslash interpretation in filenames.
  3. Quote variables to prevent word splitting and globbing.
  4. Use find with -print0 and xargs -0 for better handling of filenames with spaces.

Here's an example of how to improve the script:

set -euo pipefail

for jar in "${LIB_DIR}"/*.jar; do
  if [ ! -f "$jar" ]; then
    echo "JAR file not found: ${jar}"
    continue
  fi

  TEMP_DIR=$(mktemp -d)
  trap 'rm -rf "$TEMP_DIR"' EXIT

  unzip -q "$jar" -d "$TEMP_DIR"

  find "$TEMP_DIR" \( -name "*.jnilib" -o -name "*.dylib" \) -print0 | 
    xargs -0 -I {} /usr/bin/codesign -vvvv --entitlements "$PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement" --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" --timestamp --deep "{}"

  (
    cd "$TEMP_DIR" && 
    zip -r "${SIGNED_JARS_DIR}/$(basename "$jar")" .
  )

  /usr/bin/codesign -vvvv --entitlements "$PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement" --force --deep --options runtime --timestamp -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" "${SIGNED_JARS_DIR}/$(basename "$jar")"

  /usr/bin/codesign -dvv "${SIGNED_JARS_DIR}/$(basename "$jar")"
done

These changes will make the script more robust and secure.

🧰 Tools
🪛 yamllint

[error] 75-75: trailing spaces

(trailing-spaces)

Comment on lines +36 to +78
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize JAR processing and signing.

The current implementation works, but it can be improved for better performance, reliability, and security:

  1. Use parallel processing for signing multiple JARs.
  2. Add error checking and logging for each step.
  3. Use read -r to prevent backslash mangling in filenames.
  4. Quote variables to prevent word splitting and globbing.

Here's an optimized version of the JAR processing logic:

export -f codesign_and_verify
find "$LIB_DIR" -name "*.jar" -print0 | parallel -0 process_jar {}

process_jar() {
  local jar_file="$1"
  echo "Processing JAR file: $jar_file"
  local temp_dir
  temp_dir=$(mktemp -d) || { echo "Failed to create temp directory"; return 1; }
  
  if ! unzip -q "$jar_file" -d "$temp_dir"; then
    echo "Error extracting $jar_file"
    rm -rf "$temp_dir"
    return 1
  fi

  find "$temp_dir" \( -name "*.jnilib" -o -name "*.dylib" \) -print0 | 
    xargs -0 -I {} bash -c 'codesign_and_verify "$@"' _ {} "$PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement"

  if ! (cd "$temp_dir" && zip -qr "$jar_file" .); then
    echo "Error repackaging $jar_file"
    rm -rf "$temp_dir"
    return 1
  fi

  if ! codesign_and_verify "$jar_file" "$PWD/releng/com.espressif.idf.product/entitlements/espressif-ide.entitlement"; then
    echo "Error signing JAR $jar_file"
    rm -rf "$temp_dir"
    return 1
  fi

  rm -rf "$temp_dir"
  echo "Successfully processed $jar_file"
}

codesign_and_verify() {
  local file="$1"
  local entitlements="$2"
  echo "Signing file: $file"
  if ! /usr/bin/codesign --entitlements "$entitlements" --options runtime --force -s "ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. (QWXF6GB4AV)" --timestamp --deep "$file"; then
    echo "Error signing $file"
    return 1
  fi
  if ! /usr/bin/codesign --verify --deep --strict --verbose=2 "$file"; then
    echo "Verification failed for $file"
    return 1
  fi
  echo "Successfully signed and verified $file"
}

This version uses GNU Parallel for concurrent processing, adds error checking, uses read -r, and quotes variables for improved security and reliability.


- name: Check if signed JAR files exist
run: |
echo "Checking signed JAR files in ${SIGNED_JARS_DIR}:"
ls -al ${SIGNED_JARS_DIR}

- name: Upload Signed JAR Files
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: signed-jar-files
path: ${{ runner.temp }}/signed-jars/*