Security.kt (1693B)
1 package org.gnu.gnunet.ipc 2 3 import android.content.Context 4 import android.content.pm.PackageManager 5 import android.os.Binder 6 import android.util.Base64 7 import java.security.MessageDigest 8 import java.security.cert.CertificateFactory 9 import java.security.cert.X509Certificate 10 11 private val allowedPackages = setOf("org.gnunet.gnunetmessenger") 12 13 // SHA-256 der Signing-Zertifikate erlaubter Clients (Base64 der DER-Bytes) 14 private val ALLOWED_CERT_SHA256: Set<String> = setOf( 15 // TODO: hier echten Fingerprint der Client-App(s) eintragen 16 ) 17 18 private fun X509Certificate.sha256Base64(): String { 19 val md = MessageDigest.getInstance("SHA-256") 20 return Base64.encodeToString(md.digest(encoded), Base64.NO_WRAP) 21 } 22 23 private fun Context.packageCertsBase64(pkg: String): List<String> { 24 val info = packageManager.getPackageInfo(pkg, PackageManager.GET_SIGNING_CERTIFICATES) 25 val cf = CertificateFactory.getInstance("X.509") 26 return info.signingInfo.apkContentsSigners.map { sig -> 27 val cert = cf.generateCertificate(sig.toByteArray().inputStream()) as X509Certificate 28 cert.sha256Base64() 29 } 30 } 31 32 fun Context.enforceAllowedCaller() { 33 val uid = Binder.getCallingUid() 34 val pkgs = packageManager.getPackagesForUid(uid)?.toList().orEmpty() 35 if (pkgs.isEmpty()) throw SecurityException("No package for uid=$uid") 36 else if ((pkgs intersect allowedPackages).isEmpty()) { 37 throw SecurityException("Caller not allowed. uid=$uid pkgs=$pkgs") 38 } 39 /*val ok = pkgs.any { pkg -> runCatching { packageCertsBase64(pkg) }.getOrNull()?.any { it in ALLOWED_CERT_SHA256 } == true } 40 if (!ok) throw SecurityException("Caller not allowed. uid=$uid pkgs=$pkgs")*/ 41 }