add corrupted jar and start working on jar signing parsing
continuous-integration/drone/push Build is failing Details

master
eater 4 years ago
parent 2b9ff0d04c
commit b3180f70e0
Signed by: eater
GPG Key ID: AD2560A0F84F0759

@ -1,18 +0,0 @@
<?php
namespace CubiStore\Web\Utils;
class APKSignatureInfo
{
/**
* Which version of signature is used 1, 2, and 3 exist
* 1. uses JAR Signing
* 2. uses APK Signature Scheme
* 3. extended APK Signature Scheme
* @var int
*/
public $version;
public $signer;
public $signature;
}

@ -10,15 +10,21 @@ class ApkSignUtils
const ZIP_END_OF_CENTRAL_DIRECTORY_RECORD = "PK\x05\x06";
const ZIP_CENTRAL_DIRECTORY_RECORD = "PK\x01\x02";
const ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LOCATOR = "PK\x07\x06";
const ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LOCATOR = "PK\x06\x07";
const ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD = "PK\x06\x06";
public static function findSignature($file)
public static function findSignature($file): ?ApkSignatureInfo
{
self::tryAPKSignatureV2($file);
$signature = self::tryAPKSignatureV2($file);
if ($signature !== null) {
return $signature;
}
return self::tryJARSignature($file);
}
public static function tryAPKSignatureV2($file)
public static function tryAPKSignatureV2($file): ?ApkSignatureInfo
{
// APK Signature Block is located -before- the Central Directory Record
// Try finding offset of that
@ -42,11 +48,13 @@ class ApkSignUtils
if (substr($data, 8) === "APK Sig Block 42") {
$blockSize = Bytes::readUint8LE($data);
static::readAPKSignatureInfo($fh, $offset - $blockSize, $blockSize);
return static::readAPKSignatureInfo($fh, $offset - $blockSize, $blockSize);
}
} finally {
fclose($fh);
}
return null;
}
public static function findStartOfCentralDirectoryRecord($file): int
@ -197,7 +205,7 @@ class ApkSignUtils
$zip64Offset = Bytes::readUint8LE($zip64EOCD, 48);
if ($legacyOffset !== 2 * 32 && $legacyOffset != $zip64Offset) {
if ($legacyOffset !== 2 ** 32 && $legacyOffset !== $zip64Offset) {
throw new RuntimeException("Corrupted ZIP, ZIP64 offset and normal offset don't match up.");
}
@ -206,7 +214,50 @@ class ApkSignUtils
return true;
}
private static function readAPKSignatureInfo($fh, int $offset, int $size)
private static function readAPKSignatureInfo($fh, int $offset, int $size): ?ApkSignatureInfo
{
return null;
}
private static function tryJARSignature($file)
{
$zip = new \ZipArchive();
if ($zip->open($file) !== true) {
throw new RuntimeException("Failed to open APK");
}
$manifest = $zip->getFromName("META-INF/MANIFEST.MF");
if ($manifest === false) {
return null;
}
$found = false;
$entryName = "";
for ($i = 0; $i < $zip->numFiles; $i++) {
$entryStat = $zip->statIndex($i);
if ($entryStat === false || !isset($entryStat['name'])) {
continue;
}
$entryName = $entryStat['name'];
if (!preg_match("~^META-INF/[^\/]+\.SF$~", $entryName)) {
continue;
}
$found = true;
}
if (!$found) {
return null;
}
$signManifest = $zip->getFromName($entryName);
if ($signManifest === false) {
return false;
}
}
}

@ -0,0 +1,34 @@
<?php
namespace CubiStore\Web\Utils;
class ApkSignatureInfo
{
/**
* Which version of signature is used 1, 2, and 3 exist
* 1. uses JAR Signing
* 2. uses APK Signature Scheme
* 3. extended APK Signature Scheme
* @var int
*/
public $version;
public $signer;
/**
* As taken from the fdroidserver code:
*
* This uses a strange algorithm that was devised at the very
* beginning of F-Droid. Since it is only used for checking
* signature compatibility, it does not matter much that it uses MD5.
*
* To get the same MD5 has that fdroidclient gets, we encode the .RSA
* certificate in a specific format and pass it hex-encoded to the
* md5 digest algorithm. This is not the same as the standard X.509
* certificate fingerprint.
*
* @link https://gitlab.com/fdroid/fdroidserver/blob/master/fdroidserver/update.py#L418
* @var string
*/
public $fdroidSignerSignature;
}

@ -9,9 +9,17 @@ use PHPUnit\Framework\TestCase;
class ApkSignUtilsTest extends TestCase
{
function testCorruptedZip64() {
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage("Corrupted ZIP, ZIP64 offset and normal offset don't match up.");
$utils = new ApkSignUtils();
$utils->findSignature(__DIR__ . '/../../var/testdata/signedapks/zip64corrupted.jar');
}
function testSha1Signature()
{
$utils = new ApkSignUtils();
$utils->findSignature(__DIR__ . '/../../var/testdata/signedapks/apksignv2.apk');
$apkSignature = $utils->findSignature(__DIR__ . '/../../var/testdata/signedapks/sha1.apk');
$this->assertNotNull($apkSignature, "Couldn't find APK signature");
}
}

Binary file not shown.
Loading…
Cancel
Save