Files

113 lines
3.1 KiB
Python
Raw Permalink Normal View History

2025-12-25 11:16:59 +08:00
import hashlib
import os
from zipfile import ZipFile
from cryptography import x509
from cryptography.hazmat.primitives import serialization
from mitmproxy import certs
from mitmproxy import ctx
from mitmproxy.options import CONF_BASENAME
# The following 3 variables are for including in the magisk module as text file
MODULE_PROP_TEXT = """id=mitmproxycert
name=MITMProxy cert
version=v1
versionCode=1
author=mitmproxy
description=Adds the mitmproxy certificate to the system store
template=3"""
CONFIG_SH_TEXT = """
MODID=mitmproxycert
AUTOMOUNT=true
PROPFILE=false
POSTFSDATA=false
LATESTARTSERVICE=false
print_modname() {
ui_print "*******************************"
ui_print " MITMProxy cert installer "
ui_print "*******************************"
}
REPLACE="
"
set_permissions() {
set_perm_recursive $MODPATH 0 0 0755 0644
}
"""
UPDATE_BINARY_TEXT = """
#!/sbin/sh
#################
# Initialization
#################
umask 022
# echo before loading util_functions
ui_print() { echo "$1"; }
require_new_magisk() {
ui_print "*******************************"
ui_print " Please install Magisk v20.4+! "
ui_print "*******************************"
exit 1
}
OUTFD=$2
ZIPFILE=$3
mount /data 2>/dev/null
[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
. /data/adb/magisk/util_functions.sh
[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
install_module
exit 0
"""
def get_ca_from_files() -> x509.Certificate:
# Borrowed from tlsconfig
certstore_path = os.path.expanduser(ctx.options.confdir)
certstore = certs.CertStore.from_store(
path=certstore_path,
basename=CONF_BASENAME,
key_size=ctx.options.key_size,
passphrase=ctx.options.cert_passphrase.encode("utf8")
if ctx.options.cert_passphrase
else None,
)
return certstore.default_ca._cert
def subject_hash_old(ca: x509.Certificate) -> str:
# Mimics the -subject_hash_old option of openssl used for android certificate names
full_hash = hashlib.md5(ca.subject.public_bytes()).digest()
sho = full_hash[0] | (full_hash[1] << 8) | (full_hash[2] << 16) | full_hash[3] << 24
return hex(sho)[2:]
def write_magisk_module(path: str):
# Makes a zip file that can be loaded by Magisk
# Android certs are stored as DER files
ca = get_ca_from_files()
der_cert = ca.public_bytes(serialization.Encoding.DER)
with ZipFile(path, "w") as zipp:
# Main cert file, name is always the old subject hash with a '.0' added
zipp.writestr(f"system/etc/security/cacerts/{subject_hash_old(ca)}.0", der_cert)
zipp.writestr("module.prop", MODULE_PROP_TEXT)
zipp.writestr("config.sh", CONFIG_SH_TEXT)
zipp.writestr("META-INF/com/google/android/updater-script", "#MAGISK")
zipp.writestr("META-INF/com/google/android/update-binary", UPDATE_BINARY_TEXT)
zipp.writestr(
"common/file_contexts_image", "/magisk(/.*)? u:object_r:system_file:s0"
)
zipp.writestr("common/post-fs-data.sh", "MODDIR=${0%/*}")
zipp.writestr("common/service.sh", "MODDIR=${0%/*}")
zipp.writestr("common/system.prop", "")