From 23799f1a6fa8e17bd353278c28e974a033cf89d8 Mon Sep 17 00:00:00 2001 From: FriendlyNeighborhoodShane Date: Wed, 27 May 2020 12:47:30 +0530 Subject: [PATCH] Add cert verification function --- README.md | 2 ++ conf/resdl-download.txt | 57 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/README.md b/README.md index ceac9da..f8af16c 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,8 @@ That's it! If it tells you that some dependency is missing, install it. You can pass update.sh several perl-style regexes as arguments to only download specific files. You can pass build.sh a specific pack's conf name instead of all to build only the specific pack. +If you have the Java SDK and openssl tool installed, the update script will dump the signing certificates of all downloaded APKs and repo jars to resdl/util/certs. It will compare all future downloads with those certs, and in case of any signature errors or mismatches, will warn you. + To build your own custom pack, refer to custom-pack.md in the conf directory. ### Credits diff --git a/conf/resdl-download.txt b/conf/resdl-download.txt index 3a68416..0d895b4 100644 --- a/conf/resdl-download.txt +++ b/conf/resdl-download.txt @@ -70,6 +70,7 @@ post_update_actions() { unzipmaps; getzipsigner; updatedelta; + verifycerts; return 0; } @@ -135,3 +136,59 @@ updatedelta() { done; } + +verifycerts() { + + [ "$(which jarsigner)" ] && [ "$(which openssl)" ] || { + echo " "; + echo " !! Not checking certificates (missing jarsigner or openssl)"; + return 0; + } + + certdir="$resdldir/util/certs"; + + echo " "; + echo " - Checking certs for repos..."; + + for repo in $(echo "$stuff_repo" | select_word 1); do + certobject="repo/$repo.cer"; + jarsigner verify "$tmpdir/repos/$repo.jar" > /dev/null || { + echo " !! Verification failed for repo ($repo)" >&2; + continue; + } + [ -f "$certdir/$certobject" ] || { + echo " -- Adding cert for new repo ($repo)"; + mkdir -p "$certdir/$(dirname "$certobject")"; + unzip -p "$tmpdir/repos/$repo.jar" "META-INF/*.RSA" | openssl pkcs7 -inform der -print_certs > "$certdir/$certobject"; + continue; + } + unzip -p "$tmpdir/repos/$repo.jar" "META-INF/*.RSA" | openssl pkcs7 -inform der -print_certs > "$tmpdir/tmp.cer"; + [ "$(diff -w "$tmpdir/tmp.cer" "$certdir/$certobject")" ] && { + echo " !! Cert mismatch for repo ($repo)" >&2; + cp -f "$tmpdir/tmp.cer" "$certdir/$certobject.new"; + } + done; + + echo " "; + echo " - Checking certs for APKs..."; + + for object in $(echo "$stuff_download" | grep -P "^[ \t]*[^ \t]+.apk[ \t]+" | select_word 1); do + certobject="$(dirname "$object")/$(basename "$object" .apk).cer"; + jarsigner verify "$resdldir/$object" > /dev/null || { + echo " !! Verification failed for APK ($object)" >&2; + continue; + } + [ -f "$certdir/$certobject" ] || { + echo " -- Adding cert for new APK ($object)"; + mkdir -p "$certdir/$(dirname "$certobject")"; + unzip -p "$resdldir/$object" "META-INF/*.RSA" | openssl pkcs7 -inform der -print_certs > "$certdir/$certobject"; + continue; + } + unzip -p "$resdldir/$object" "META-INF/*.RSA" | openssl pkcs7 -inform der -print_certs > "$tmpdir/tmp.cer"; + [ "$(diff -w "$tmpdir/tmp.cer" "$certdir/$certobject")" ] && { + echo " !! Cert mismatch for APK ($object)" >&2; + cp -f "$tmpdir/tmp.cer" "$certdir/$certobject.new"; + } + done; + +}