From 93f361c6237cefec637a4e558e4d70c7cacfa577 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 29 Apr 2024 12:31:06 +0200 Subject: [PATCH 1/9] replace decade old pyasn1 crypto impl with working asn1crypto For some APKs, get_certificate() was returning a different result than apksigner and keytool. So I just took the algorithm from androguard, which uses asn1crypto instead of pyasn1. So that removes a dependency as well. asn1crypto is already required by androguard. The original get_certificate() came from 6e2d0a9e1 --- fdroidserver/common.py | 19 +++---------------- setup.py | 3 +-- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index b1a1827b..5205dc7f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -54,16 +54,13 @@ from pathlib import Path import defusedxml.ElementTree as XMLElementTree +from asn1crypto import cms from base64 import urlsafe_b64encode from binascii import hexlify from datetime import datetime, timedelta, timezone from queue import Queue from zipfile import ZipFile -from pyasn1.codec.der import decoder, encoder -from pyasn1_modules import rfc2315 -from pyasn1.error import PyAsn1Error - import fdroidserver.metadata import fdroidserver.lint from fdroidserver import _ @@ -3908,18 +3905,8 @@ def get_certificate(signature_block_file): or None in case of error """ - content = decoder.decode(signature_block_file, asn1Spec=rfc2315.ContentInfo())[0] - if content.getComponentByName('contentType') != rfc2315.signedData: - return None - content = decoder.decode(content.getComponentByName('content'), - asn1Spec=rfc2315.SignedData())[0] - try: - certificates = content.getComponentByName('certificates') - cert = certificates[0].getComponentByName('certificate') - except PyAsn1Error: - logging.error("Certificates not found.") - return None - return encoder.encode(cert) + pkcs7obj = cms.ContentInfo.load(signature_block_file) + return pkcs7obj['content']['certificates'][0].chosen.dump() def load_stats_fdroid_signing_key_fingerprints(): diff --git a/setup.py b/setup.py index 8e4e2452..7e8d1912 100755 --- a/setup.py +++ b/setup.py @@ -93,14 +93,13 @@ setup( install_requires=[ 'appdirs', 'androguard >= 3.3.5', + 'asn1crypto', 'clint', 'defusedxml', 'GitPython', 'paramiko', 'Pillow', 'apache-libcloud >= 0.14.1', - 'pyasn1 >=0.4.1', - 'pyasn1-modules >= 0.2.1', 'python-vagrant', 'PyYAML', 'qrcode', From 2fea71a6c7eb43d5c64ab1cf7a4f31015ac07a53 Mon Sep 17 00:00:00 2001 From: linsui Date: Mon, 8 Apr 2024 14:57:28 +0800 Subject: [PATCH 2/9] get_first_signer_certificate: check all v1 v2 and v3 certs --- fdroidserver/common.py | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 5205dc7f..7fb0ab8d 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3179,31 +3179,39 @@ def signer_fingerprint(cert_encoded): def get_first_signer_certificate(apkpath): """Get the first signing certificate from the APK, DER-encoded.""" - certs = None - cert_encoded = None + cert_encoded_v1 = None + cert_encoded_v2 = None + cert_encoded_v3 = None with zipfile.ZipFile(apkpath, 'r') as apk: - cert_files = [n for n in apk.namelist() if SIGNATURE_BLOCK_FILE_REGEX.match(n)] - if len(cert_files) > 1: + certs_v1 = [n for n in apk.namelist() if SIGNATURE_BLOCK_FILE_REGEX.match(n)] + if len(certs_v1) > 1: logging.error(_("Found multiple JAR Signature Block Files in {path}").format(path=apkpath)) return None - elif len(cert_files) == 1: - cert_encoded = get_certificate(apk.read(cert_files[0])) + elif len(certs_v1) == 1: + cert_encoded_v1 = get_certificate(apk.read(certs_v1[0])) - if not cert_encoded: + if True apkobject = get_androguard_APK(apkpath) - certs = apkobject.get_certificates_der_v2() - if len(certs) > 0: + certs_v2 = apkobject.get_certificates_der_v2() + if len(certs_v2) > 0: logging.debug(_('Using APK Signature v2')) - cert_encoded = certs[0] - if not cert_encoded: - certs = apkobject.get_certificates_der_v3() - if len(certs) > 0: - logging.debug(_('Using APK Signature v3')) - cert_encoded = certs[0] + cert_encoded_v2 = certs_v2[0] + certs_v3 = apkobject.get_certificates_der_v3() + if len(certs_v3) > 0: + logging.debug(_('Using APK Signature v3')) + cert_encoded_v3 = certs_v3[0] + + cert_encoded = cert_encoded_v3 or cert_encoded_v2 or cert_encoded_v1 if not cert_encoded: logging.error(_("No signing certificates found in {path}").format(path=apkpath)) return None + if ( + (cert_encoded_v2 and cert_encoded_v2 != cert_encoded) + or (cert_encoded_v1 and cert_encoded_v1 != cert_encoded) + ): + logging.error(_("Different certificates found in {path}").format(path=apkpath)) + return None return cert_encoded From 312f822764f1fb603f86a50cfcb9003fbe4037ad Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 29 Apr 2024 12:58:50 +0200 Subject: [PATCH 3/9] androguard is required, stop using use_androguard() --- fdroidserver/common.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 7fb0ab8d..d6b85843 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3190,17 +3190,16 @@ def get_first_signer_certificate(apkpath): elif len(certs_v1) == 1: cert_encoded_v1 = get_certificate(apk.read(certs_v1[0])) - if True - apkobject = get_androguard_APK(apkpath) - certs_v2 = apkobject.get_certificates_der_v2() - if len(certs_v2) > 0: - logging.debug(_('Using APK Signature v2')) - cert_encoded_v2 = certs_v2[0] + apkobject = get_androguard_APK(apkpath) + certs_v2 = apkobject.get_certificates_der_v2() + if len(certs_v2) > 0: + logging.debug(_('Using APK Signature v2')) + cert_encoded_v2 = certs_v2[0] - certs_v3 = apkobject.get_certificates_der_v3() - if len(certs_v3) > 0: - logging.debug(_('Using APK Signature v3')) - cert_encoded_v3 = certs_v3[0] + certs_v3 = apkobject.get_certificates_der_v3() + if len(certs_v3) > 0: + logging.debug(_('Using APK Signature v3')) + cert_encoded_v3 = certs_v3[0] cert_encoded = cert_encoded_v3 or cert_encoded_v2 or cert_encoded_v1 if not cert_encoded: From 6f5fd2b132f73995740c0255602ba3dab5791039 Mon Sep 17 00:00:00 2001 From: "FC (Fay) Stegerman" Date: Tue, 9 Apr 2024 11:19:21 +0200 Subject: [PATCH 4/9] PoC + writeup + patch https://github.com/obfusk/fdroid-fakesigner-poc/blob/6c6dc25112a8b28a3802b6cba2921d7b91dac59e/fdroidserver.patch#L28 https://github.com/androguard/androguard/issues/1030 refs #1128 (this is an excerpt of the original patch) --- fdroidserver/common.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index d6b85843..e9c7ad92 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3179,6 +3179,12 @@ def signer_fingerprint(cert_encoded): def get_first_signer_certificate(apkpath): """Get the first signing certificate from the APK, DER-encoded.""" + + class NoOverwriteDict(dict): + def __setitem__(self, k, v): + if k not in self: + super().__setitem__(k, v) + cert_encoded_v1 = None cert_encoded_v2 = None cert_encoded_v3 = None @@ -3191,6 +3197,7 @@ def get_first_signer_certificate(apkpath): cert_encoded_v1 = get_certificate(apk.read(certs_v1[0])) apkobject = get_androguard_APK(apkpath) + apkobject._v2_blocks = NoOverwriteDict() certs_v2 = apkobject.get_certificates_der_v2() if len(certs_v2) > 0: logging.debug(_('Using APK Signature v2')) From a8fd360a8866bbebc10a8564e3420e587e655d9b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 19 Apr 2024 23:16:59 +0200 Subject: [PATCH 5/9] skip AndroidManifest.xml and resources when fetching v2+ certs --- fdroidserver/common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index e9c7ad92..792100b1 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2661,7 +2661,7 @@ def _androguard_logging_level(level=logging.ERROR): pass -def get_androguard_APK(apkfile): +def get_androguard_APK(apkfile, skip_analysis=False): try: # these were moved in androguard 4.0 from androguard.core.apk import APK @@ -2669,7 +2669,7 @@ def get_androguard_APK(apkfile): from androguard.core.bytecodes.apk import APK _androguard_logging_level() - return APK(apkfile) + return APK(apkfile, skip_analysis=skip_analysis) def ensure_final_value(packageName, arsc, value): From 9a327b5097b2dd221a1e8462c51ac6fe0b616d07 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 25 Apr 2024 18:45:00 +0200 Subject: [PATCH 6/9] reliable implementation of get_first_signer_certificate() This keeps key pieces of @linsui's algorithm, specifically the check that all certificates are the same. apksigner also does this check. closes #1128 --- fdroidserver/common.py | 285 +++++++++++++++++++++++++++++++++-------- setup.py | 1 + tests/common.TestCase | 234 +++++++++++++++++++++++++++++++++ tests/index.TestCase | 12 ++ 4 files changed, 482 insertions(+), 50 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 792100b1..b3e41c81 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -3161,10 +3161,7 @@ def signer_fingerprint_short(cert_encoded): def signer_fingerprint(cert_encoded): - """Obtain sha256 signing-key fingerprint for pkcs7 DER certificate. - - Extracts hexadecimal sha256 signing-key fingerprint string - for a given pkcs7 signature. + """Return SHA-256 signer fingerprint for PKCS#7 DER-encoded signature. Parameters ---------- @@ -3172,60 +3169,113 @@ def signer_fingerprint(cert_encoded): Returns ------- - shortened signature fingerprint. + Standard SHA-256 signer fingerprint. + """ return hashlib.sha256(cert_encoded).hexdigest() def get_first_signer_certificate(apkpath): - """Get the first signing certificate from the APK, DER-encoded.""" + """Get the first signing certificate from the APK, DER-encoded. + + JAR and APK Signatures allow for multiple signers, though it is + rarely used, and this is poorly documented. So this method only + fetches the first certificate, and errors out if there are more. + + Starting with targetSdkVersion 30, APK v2 Signatures are required. + https://developer.android.com/about/versions/11/behavior-changes-11#minimum-signature-scheme + + When a APK v2+ signature is present, the JAR signature is not + verified. The verifier parses the signers from the v2+ signature + and does not seem to look at the JAR signature. + https://source.android.com/docs/security/features/apksigning/v2#apk-signature-scheme-v2-block + https://android.googlesource.com/platform/tools/apksig/+/refs/tags/android-13.0.0_r3/src/main/java/com/android/apksig/ApkVerifier.java#270 + + apksigner checks that the signers from all the APK signatures match: + https://android.googlesource.com/platform/tools/apksig/+/refs/tags/android-13.0.0_r3/src/main/java/com/android/apksig/ApkVerifier.java#383 + + apksigner verifies each signer's signature block file + .(RSA|DSA|EC) against the corresponding signature file .SF + https://android.googlesource.com/platform/tools/apksig/+/refs/tags/android-13.0.0_r3/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java#280 + + NoOverwriteDict is a workaround for: + https://github.com/androguard/androguard/issues/1030 + + Lots more discusion here: + https://gitlab.com/fdroid/fdroidserver/-/issues/1128 + + """ class NoOverwriteDict(dict): def __setitem__(self, k, v): if k not in self: super().__setitem__(k, v) - cert_encoded_v1 = None - cert_encoded_v2 = None - cert_encoded_v3 = None - with zipfile.ZipFile(apkpath, 'r') as apk: - certs_v1 = [n for n in apk.namelist() if SIGNATURE_BLOCK_FILE_REGEX.match(n)] - if len(certs_v1) > 1: - logging.error(_("Found multiple JAR Signature Block Files in {path}").format(path=apkpath)) - return None - elif len(certs_v1) == 1: - cert_encoded_v1 = get_certificate(apk.read(certs_v1[0])) - + cert_encoded = None + found_certs = [] apkobject = get_androguard_APK(apkpath) apkobject._v2_blocks = NoOverwriteDict() - certs_v2 = apkobject.get_certificates_der_v2() - if len(certs_v2) > 0: - logging.debug(_('Using APK Signature v2')) - cert_encoded_v2 = certs_v2[0] - certs_v3 = apkobject.get_certificates_der_v3() - if len(certs_v3) > 0: - logging.debug(_('Using APK Signature v3')) - cert_encoded_v3 = certs_v3[0] + if certs_v3: + cert_v3 = certs_v3[0] + found_certs.append(cert_v3) + if not cert_encoded: + logging.debug(_('Using APK Signature v3')) + cert_encoded = cert_v3 + + certs_v2 = apkobject.get_certificates_der_v2() + if certs_v2: + cert_v2 = certs_v2[0] + found_certs.append(cert_v2) + if not cert_encoded: + logging.debug(_('Using APK Signature v2')) + cert_encoded = cert_v2 + + if get_min_sdk_version(apkobject) < 24 or ( + not (certs_v3 or certs_v2) and get_effective_target_sdk_version(apkobject) < 30 + ): + with zipfile.ZipFile(apkpath, 'r') as apk: + cert_files = [ + n for n in apk.namelist() if SIGNATURE_BLOCK_FILE_REGEX.match(n) + ] + if len(cert_files) > 1: + logging.error( + _("Found multiple JAR Signature Block Files in {path}").format( + path=apkpath + ) + ) + return + elif len(cert_files) == 1: + signature_block_file = cert_files[0] + signature_file = ( + cert_files[0][: signature_block_file.rindex('.')] + '.SF' + ) + cert_v1 = get_certificate( + apk.read(signature_block_file), + apk.read(signature_file), + ) + found_certs.append(cert_v1) + if not cert_encoded: + logging.debug(_('Using JAR Signature')) + cert_encoded = cert_v1 - cert_encoded = cert_encoded_v3 or cert_encoded_v2 or cert_encoded_v1 if not cert_encoded: logging.error(_("No signing certificates found in {path}").format(path=apkpath)) - return None - if ( - (cert_encoded_v2 and cert_encoded_v2 != cert_encoded) - or (cert_encoded_v1 and cert_encoded_v1 != cert_encoded) - ): - logging.error(_("Different certificates found in {path}").format(path=apkpath)) - return None + return + + if not all(cert == found_certs[0] for cert in found_certs): + logging.error( + _("APK signatures have different certificates in {path}:").format( + path=apkpath + ) + ) + return + return cert_encoded def apk_signer_fingerprint(apk_path): - """Obtain sha256 signing-key fingerprint for APK. - - Extracts hexadecimal sha256 signing-key fingerprint string - for a given APK. + """Get SHA-256 fingerprint string for the first signer from given APK. Parameters ---------- @@ -3234,7 +3284,8 @@ def apk_signer_fingerprint(apk_path): Returns ------- - signature fingerprint + Standard SHA-256 signer fingerprint + """ cert_encoded = get_first_signer_certificate(apk_path) if not cert_encoded: @@ -3243,10 +3294,7 @@ def apk_signer_fingerprint(apk_path): def apk_signer_fingerprint_short(apk_path): - """Obtain shortened sha256 signing-key fingerprint for APK. - - Extracts the first 7 hexadecimal digits of sha256 signing-key fingerprint - for a given pkcs7 APK. + """Get 7 hex digit SHA-256 fingerprint string for the first signer from given APK. Parameters ---------- @@ -3255,7 +3303,8 @@ def apk_signer_fingerprint_short(apk_path): Returns ------- - shortened signing-key fingerprint + first 7 chars of the standard SHA-256 signer fingerprint + """ return apk_signer_fingerprint(apk_path)[:7] @@ -3474,7 +3523,7 @@ def apk_extract_signatures(apkpath, outdir): def get_min_sdk_version(apk): - """Wrap the androguard function to always return and int. + """Wrap the androguard function to always return an integer. Fall back to 1 if we can't get a valid minsdk version. @@ -3485,7 +3534,7 @@ def get_min_sdk_version(apk): Returns ------- - minsdk: int + minSdkVersion: int """ try: return int(apk.get_min_sdk_version()) @@ -3493,6 +3542,24 @@ def get_min_sdk_version(apk): return 1 +def get_effective_target_sdk_version(apk): + """Wrap the androguard function to always return an integer. + + Parameters + ---------- + apk + androguard APK object + + Returns + ------- + targetSdkVersion: int + """ + try: + return int(apk.get_effective_target_sdk_version()) + except TypeError: + return get_min_sdk_version(apk) + + def get_apksigner_smartcardoptions(smartcardoptions): if '-providerName' in smartcardoptions.copy(): pos = smartcardoptions.index('-providerName') @@ -3904,14 +3971,33 @@ def get_cert_fingerprint(pubkey): return " ".join(ret) -def get_certificate(signature_block_file): - """Extract a DER certificate from JAR Signature's "Signature Block File". +def get_certificate(signature_block_file, signature_file=None): + """Extract a single DER certificate from JAR Signature's "Signature Block File". + + If there is more than one signer certificate, this exits with an + error, unless the signature_file is provided. If that is set, it + will return the certificate that matches the Signature File, for + example, if there is a certificate chain, like TLS does. In the + fdroidserver use cases, there should always be a single signer. + But rarely, some APKs include certificate chains. + + This could be replaced by androguard's APK.get_certificate_der() + provided the cert chain fix was merged there. Maybe in 4.1.2? + https://github.com/androguard/androguard/pull/1038 + + https://docs.oracle.com/en/java/javase/21/docs/specs/man/jarsigner.html#the-signed-jar-file Parameters ---------- signature_block_file - file bytes (as string) representing the - certificate, as read directly out of the APK/ZIP + Bytes representing the PKCS#7 signer certificate and + signature, as read directly out of the JAR/APK, e.g. CERT.RSA. + + signature_file + Bytes representing the manifest signed by the Signature Block + File, e.g. CERT.SF. If this is not given, the assumption is + there will be only a single certificate in + signature_block_file, otherwise it is an error. Returns ------- @@ -3920,7 +4006,106 @@ def get_certificate(signature_block_file): """ pkcs7obj = cms.ContentInfo.load(signature_block_file) - return pkcs7obj['content']['certificates'][0].chosen.dump() + certificates = pkcs7obj['content']['certificates'] + if len(certificates) == 1: + return certificates[0].chosen.dump() + elif not signature_file: + logging.error(_('Found multiple Signer Certificates!')) + return + certificate = get_jar_signer_certificate(pkcs7obj, signature_file) + if certificate: + return certificate.chosen.dump() + + +def _find_matching_certificate(signer_info, certificate): + """Find the certificates that matches signer_info using issuer and serial number. + + https://android.googlesource.com/platform/tools/apksig/+/refs/tags/android-13.0.0_r3/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java#590 + https://android.googlesource.com/platform/tools/apksig/+/refs/tags/android-13.0.0_r3/src/main/java/com/android/apksig/internal/x509/Certificate.java#55 + + """ + certificate_serial = certificate.chosen['tbs_certificate']['serial_number'] + expected_issuer_serial = signer_info['sid'].chosen + return ( + expected_issuer_serial['issuer'] == certificate.chosen.issuer + and expected_issuer_serial['serial_number'] == certificate_serial + ) + + +def get_jar_signer_certificate(pkcs7obj: cms.ContentInfo, signature_file: bytes): + """Return the one certificate in a chain that actually signed the manifest. + + PKCS#7-signed data can include certificate chains for use cases + where an Certificate Authority (CA) is used. Android does not + validate the certificate chain on APK signatures, so neither does + this. + https://android.googlesource.com/platform/tools/apksig/+/refs/tags/android-13.0.0_r3/src/main/java/com/android/apksig/internal/apk/v1/V1SchemeVerifier.java#512 + + Some useful fodder for understanding all this: + https://docs.oracle.com/javase/tutorial/deployment/jar/intro.html + https://technotes.shemyak.com/posts/jar-signature-block-file-format/ + https://docs.oracle.com/en/java/javase/21/docs/specs/man/jarsigner.html#the-signed-jar-file + https://qistoph.blogspot.com/2012/01/manual-verify-pkcs7-signed-data-with.html + + """ + import oscrypto.asymmetric + import oscrypto.errors + + # Android attempts to verify all SignerInfos and then picks the first verified SignerInfo. + first_verified_signer_info = None + first_verified_signer_info_signing_certificate = None + for signer_info in pkcs7obj['content']['signer_infos']: + signature = signer_info['signature'].contents + digest_algorithm = signer_info["digest_algorithm"]["algorithm"].native + public_key = None + for certificate in pkcs7obj['content']['certificates']: + if _find_matching_certificate(signer_info, certificate): + public_key = oscrypto.asymmetric.load_public_key(certificate.chosen.public_key) + break + if public_key is None: + logging.info('No certificate found that matches signer info!') + continue + + signature_algo = signer_info['signature_algorithm'].signature_algo + if signature_algo == 'rsassa_pkcs1v15': + # ASN.1 - 1.2.840.113549.1.1.1 + verify_func = oscrypto.asymmetric.rsa_pkcs1v15_verify + elif signature_algo == 'rsassa_pss': + # ASN.1 - 1.2.840.113549.1.1.10 + verify_func = oscrypto.asymmetric.rsa_pss_verify + elif signature_algo == 'dsa': + # ASN.1 - 1.2.840.10040.4.1 + verify_func = oscrypto.asymmetric.dsa_verify + elif signature_algo == 'ecdsa': + # ASN.1 - 1.2.840.10045.4 + verify_func = oscrypto.asymmetric.ecdsa_verify + else: + logging.error( + 'Unknown signature algorithm %s:\n %s\n %s' + % ( + signature_algo, + hexlify(certificate.chosen.sha256).decode(), + certificate.chosen.subject.human_friendly, + ), + ) + return + + try: + verify_func(public_key, signature, signature_file, digest_algorithm) + if not first_verified_signer_info: + first_verified_signer_info = signer_info + first_verified_signer_info_signing_certificate = certificate + + except oscrypto.errors.SignatureError as e: + logging.error( + '"%s", skipping:\n %s\n %s' % ( + e, + hexlify(certificate.chosen.sha256).decode(), + certificate.chosen.subject.human_friendly), + ) + + if first_verified_signer_info_signing_certificate: + return first_verified_signer_info_signing_certificate def load_stats_fdroid_signing_key_fingerprints(): diff --git a/setup.py b/setup.py index 7e8d1912..0b437735 100755 --- a/setup.py +++ b/setup.py @@ -97,6 +97,7 @@ setup( 'clint', 'defusedxml', 'GitPython', + 'oscrypto', 'paramiko', 'Pillow', 'apache-libcloud >= 0.14.1', diff --git a/tests/common.TestCase b/tests/common.TestCase index 925d61e0..52522b14 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -2915,6 +2915,240 @@ class CommonTest(unittest.TestCase): ) +APKS_WITH_JAR_SIGNATURES = ( + ( + 'SpeedoMeterApp.main_1.apk', + '2e6b3126fb7e0db6a9d4c2a06df690620655454d6e152cf244cc9efe9787a77d', + ), + ( + 'apk.embedded_1.apk', + '764f0eaac0cdcde35023658eea865c4383ab580f9827c62fdd3daf9e654199ee', + ), + ( + 'bad-unicode-πÇÇ现代通用字-български-عربي1.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'janus.apk', + 'ebb0fedf1942a099b287c3db00ff732162152481abb2b6c7cbcdb2ba5894a768', + ), + ( + 'org.bitbucket.tickytacky.mirrormirror_1.apk', + 'feaa63df35b4635cf091513dfcd6d11209632555efdfc47e33b70d4e4eb5ba28', + ), + ( + 'org.bitbucket.tickytacky.mirrormirror_2.apk', + 'feaa63df35b4635cf091513dfcd6d11209632555efdfc47e33b70d4e4eb5ba28', + ), + ( + 'org.bitbucket.tickytacky.mirrormirror_3.apk', + 'feaa63df35b4635cf091513dfcd6d11209632555efdfc47e33b70d4e4eb5ba28', + ), + ( + 'org.bitbucket.tickytacky.mirrormirror_4.apk', + 'feaa63df35b4635cf091513dfcd6d11209632555efdfc47e33b70d4e4eb5ba28', + ), + ( + 'org.dyndns.fules.ck_20.apk', + '9326a2cc1a2f148202bc7837a0af3b81200bd37fd359c9e13a2296a71d342056', + ), + ( + 'org.sajeg.fallingblocks_3.apk', + '033389681f4288fdb3e72a28058c8506233ca50de75452ab6c9c76ea1ca2d70f', + ), + ( + 'repo/com.example.test.helloworld_1.apk', + 'c3a5ca5465a7585a1bda30218ae4017083605e3576867aa897d724208d99696c', + ), + ( + 'repo/com.politedroid_3.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/com.politedroid_4.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/com.politedroid_5.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/com.politedroid_6.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/duplicate.permisssions_9999999.apk', + '659e1fd284549f70d13fb02c620100e27eeea3420558cce62b0f5d4cf2b77d84', + ), + ( + 'repo/info.zwanenburg.caffeinetile_4.apk', + '51cfa5c8a743833ad89acf81cb755936876a5c8b8eca54d1ffdcec0cdca25d0e', + ), + ( + 'repo/no.min.target.sdk_987.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/obb.main.oldversion_1444412523.apk', + '818e469465f96b704e27be2fee4c63ab9f83ddf30e7a34c7371a4728d83b0bc1', + ), + ( + 'repo/obb.main.twoversions_1101613.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/obb.main.twoversions_1101615.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/obb.main.twoversions_1101617.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/obb.mainpatch.current_1619.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/obb.mainpatch.current_1619_another-release-key.apk', + 'ce9e200667f02d96d49891a2e08a3c178870e91853d61bdd33ef5f0b54701aa5', + ), + ( + 'repo/souch.smsbypass_9.apk', + 'd3aec784b1fd71549fc22c999789122e3639895db6bd585da5835fbe3db6985c', + ), + ( + 'repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'repo/v1.v2.sig_1020.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'urzip-release.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), + ( + 'urzip.apk', + '7eabd8c15de883d1e82b5df2fd4f7f769e498078e9ad6dc901f0e96db77ceac3', + ), +) + + +class SignerExtractionTest(unittest.TestCase): + """Test extraction of the signer certificate from JARs and APKs + + These fingerprints can be confirmed with: + apksigner verify --print-certs foo.apk | grep SHA-256 + keytool -printcert -file ____.RSA + """ + + def setUp(self): + os.chdir(os.path.join(localmodule, 'tests')) + self._td = mkdtemp() + self.testdir = self._td.name + + self.apksigner = shutil.which('apksigner') + self.keytool = shutil.which('keytool') + + def tearDown(self): + self._td.cleanup() + + def test_get_first_signer_certificate_with_jars(self): + for jar in ( + 'signindex/guardianproject-v1.jar', + 'signindex/guardianproject.jar', + 'signindex/testy.jar', + ): + outdir = os.path.join(self.testdir, jar[:-4].replace('/', '_')) + os.mkdir(outdir) + fdroidserver.common.apk_extract_signatures(jar, outdir) + certs = glob.glob(os.path.join(outdir, '*.RSA')) + with open(certs[0], 'rb') as fp: + self.assertEqual( + fdroidserver.common.get_certificate(fp.read()), + fdroidserver.common.get_first_signer_certificate(jar), + ) + + @unittest.skip("slow and only needed when adding to APKS_WITH_JAR_SIGNATURES") + def test_vs_keytool(self): + unittest.skipUnless(self.keytool, 'requires keytool to run') + pat = re.compile(r'[0-9A-F:]{95}') + cmd = [self.keytool, '-printcert', '-jarfile'] + for apk, fingerprint in APKS_WITH_JAR_SIGNATURES: + o = subprocess.check_output(cmd + [apk], text=True) + try: + self.assertEqual( + fingerprint, + pat.search(o).group().replace(':', '').lower(), + ) + except AttributeError as e: + print(e, o) + + @unittest.skip("slow and only needed when adding to APKS_WITH_JAR_SIGNATURES") + def test_vs_apksigner(self): + unittest.skipUnless(self.apksigner, 'requires apksigner to run') + pat = re.compile(r'\s[0-9a-f]{64}\s') + cmd = [self.apksigner, 'verify', '--print-certs'] + for apk, fingerprint in APKS_WITH_JAR_SIGNATURES: + output = subprocess.check_output(cmd + [apk], text=True) + self.assertEqual( + fingerprint, + pat.search(output).group().strip(), + apk + " should have matching signer fingerprints", + ) + + def test_apk_signer_fingerprint_with_v1_apks(self): + for apk, fingerprint in APKS_WITH_JAR_SIGNATURES: + self.assertEqual( + fingerprint, + fdroidserver.common.apk_signer_fingerprint(apk), + f'apk_signer_fingerprint should match stored fingerprint for {apk}', + ) + + def test_get_first_signer_certificate_with_unsigned_jar(self): + self.assertIsNone( + fdroidserver.common.get_first_signer_certificate('signindex/unsigned.jar') + ) + + def test_apk_extract_fingerprint(self): + """Test extraction of JAR signatures (does not cover APK v2+ extraction).""" + for apk, fingerprint in APKS_WITH_JAR_SIGNATURES: + outdir = os.path.join(self.testdir, apk[:-4].replace('/', '_')) + os.mkdir(outdir) + try: + fdroidserver.common.apk_extract_signatures(apk, outdir) + except fdroidserver.apksigcopier.APKSigCopierError: + # nothing to test here when this error is thrown + continue + v1_certs = [str(cert) for cert in Path(outdir).glob('*.[DR]SA')] + cert = fdroidserver.common.get_certificate( + signature_block_file=Path(v1_certs[0]).read_bytes(), + signature_file=Path(v1_certs[0][:-4] + '.SF').read_bytes(), + ) + self.assertEqual( + fingerprint, + fdroidserver.common.signer_fingerprint(cert), + ) + apkobject = fdroidserver.common.get_androguard_APK(apk, skip_analysis=True) + v2_certs = apkobject.get_certificates_der_v2() + if v2_certs: + if v1_certs: + self.assertEqual(len(v1_certs), len(v2_certs)) + self.assertEqual( + fingerprint, + fdroidserver.common.signer_fingerprint(v2_certs[0]), + ) + v3_certs = apkobject.get_certificates_der_v3() + if v3_certs: + if v2_certs: + self.assertEqual(len(v2_certs), len(v3_certs)) + self.assertEqual( + fingerprint, + fdroidserver.common.signer_fingerprint(v3_certs[0]), + ) + + if __name__ == "__main__": os.chdir(os.path.dirname(__file__)) diff --git a/tests/index.TestCase b/tests/index.TestCase index 633c0e5f..3fb4a034 100755 --- a/tests/index.TestCase +++ b/tests/index.TestCase @@ -2,6 +2,7 @@ import copy import datetime +import glob import inspect import logging import optparse @@ -418,6 +419,17 @@ class IndexTest(unittest.TestCase): self.maxDiff = None self.assertEqual(json.dumps(i, indent=2), json.dumps(o, indent=2)) + # and test it still works with get_first_signer_certificate + outdir = os.path.join(self.testdir, 'publishsigkeys') + os.mkdir(outdir) + common.apk_extract_signatures(jarfile, outdir) + certs = glob.glob(os.path.join(outdir, '*.RSA')) + with open(certs[0], 'rb') as fp: + self.assertEqual( + common.get_certificate(fp.read()), + common.get_first_signer_certificate(jarfile), + ) + def test_make_v0_repo_only(self): os.chdir(self.testdir) os.mkdir('repo') From accdd65f91e2850cc071b45258ddbed483618e09 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 19 Apr 2024 23:22:51 +0200 Subject: [PATCH 7/9] also handle APKs entirely without JAR/v1 signatures future-proofing! --- MANIFEST.in | 1 + tests/common.TestCase | 23 ++++++++++++++++++++++- tests/issue-1128-min-sdk-30-poc.apk | Bin 0 -> 10728 bytes 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/issue-1128-min-sdk-30-poc.apk diff --git a/MANIFEST.in b/MANIFEST.in index 05a022b2..ee15b587 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -591,6 +591,7 @@ include tests/index.TestCase include tests/init.TestCase include tests/install.TestCase include tests/IsMD5Disabled.java +include tests/issue-1128-min-sdk-30-poc.apk include tests/janus.apk include tests/keystore.jks include tests/key-tricks.py diff --git a/tests/common.TestCase b/tests/common.TestCase index 52522b14..4739ddab 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1039,6 +1039,7 @@ class CommonTest(unittest.TestCase): ('org.bitbucket.tickytacky.mirrormirror_3.apk', 'org.bitbucket.tickytacky.mirrormirror', 3, '1.0.2'), ('org.bitbucket.tickytacky.mirrormirror_4.apk', 'org.bitbucket.tickytacky.mirrormirror', 4, '1.0.3'), ('org.dyndns.fules.ck_20.apk', 'org.dyndns.fules.ck', 20, 'v1.6pre2'), + ('issue-1128-min-sdk-30-poc.apk', 'org.fdroid.ci', 1, '1.0'), ('urzip.apk', 'info.guardianproject.urzip', 100, '0.1'), ('urzip-badcert.apk', 'info.guardianproject.urzip', 100, '0.1'), ('urzip-badsig.apk', 'info.guardianproject.urzip', 100, '0.1'), @@ -1154,6 +1155,7 @@ class CommonTest(unittest.TestCase): return apk.get_effective_target_sdk_version() self.assertEqual(4, get_minSdkVersion('bad-unicode-πÇÇ现代通用字-български-عربي1.apk')) + self.assertEqual(30, get_minSdkVersion('issue-1128-min-sdk-30-poc.apk')) self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_1.apk')) self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_2.apk')) self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_3.apk')) @@ -1164,6 +1166,7 @@ class CommonTest(unittest.TestCase): self.assertEqual(4, get_minSdkVersion('urzip-badsig.apk')) self.assertEqual(4, get_minSdkVersion('urzip-release.apk')) self.assertEqual(4, get_minSdkVersion('urzip-release-unsigned.apk')) + self.assertEqual(27, get_minSdkVersion('v2.only.sig_2.apk')) self.assertEqual(3, get_minSdkVersion('repo/com.politedroid_3.apk')) self.assertEqual(3, get_minSdkVersion('repo/com.politedroid_4.apk')) self.assertEqual(3, get_minSdkVersion('repo/com.politedroid_5.apk')) @@ -3033,6 +3036,16 @@ APKS_WITH_JAR_SIGNATURES = ( '7eabd8c15de883d1e82b5df2fd4f7f769e498078e9ad6dc901f0e96db77ceac3', ), ) +APKS_WITHOUT_JAR_SIGNATURES = ( + ( + 'issue-1128-min-sdk-30-poc.apk', # APK v3 Signature only + '09350d5f3460a8a0ea5cf6b68ccd296a58754f7e683ba6aa08c19be8353504f3', + ), + ( + 'v2.only.sig_2.apk', + '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', + ), +) class SignerExtractionTest(unittest.TestCase): @@ -3090,7 +3103,7 @@ class SignerExtractionTest(unittest.TestCase): unittest.skipUnless(self.apksigner, 'requires apksigner to run') pat = re.compile(r'\s[0-9a-f]{64}\s') cmd = [self.apksigner, 'verify', '--print-certs'] - for apk, fingerprint in APKS_WITH_JAR_SIGNATURES: + for apk, fingerprint in APKS_WITH_JAR_SIGNATURES + APKS_WITHOUT_JAR_SIGNATURES: output = subprocess.check_output(cmd + [apk], text=True) self.assertEqual( fingerprint, @@ -3106,6 +3119,14 @@ class SignerExtractionTest(unittest.TestCase): f'apk_signer_fingerprint should match stored fingerprint for {apk}', ) + def test_apk_signer_fingerprint_without_v1_apks(self): + for apk, fingerprint in APKS_WITHOUT_JAR_SIGNATURES: + self.assertEqual( + fingerprint, + fdroidserver.common.apk_signer_fingerprint(apk), + f'apk_signer_fingerprint should match stored fingerprint for {apk}', + ) + def test_get_first_signer_certificate_with_unsigned_jar(self): self.assertIsNone( fdroidserver.common.get_first_signer_certificate('signindex/unsigned.jar') diff --git a/tests/issue-1128-min-sdk-30-poc.apk b/tests/issue-1128-min-sdk-30-poc.apk new file mode 100644 index 0000000000000000000000000000000000000000..bef0297f49ef90014471bb39874b2de93af98884 GIT binary patch literal 10728 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 literal 0 HcmV?d00001 From fc4a9c96a5b347843eb01074b38f6394bd657b2a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Fri, 19 Apr 2024 12:49:02 +0200 Subject: [PATCH 8/9] test APK signatures with a cert chain are parsed like apksigner Microsoft and SanDisk sign APKs with a X.509 certificate chain of trust, so there are actually three certificates included. apksigner only cares about one certificate and ignores the other certificates in the chain. The correct values come from: apksigner verify --print-certs 883cbdae7aeb2e4b122e8ee8d89966c7062d0d49107a130235fa220a5b994a79.apk X.509 certificates are machine generated and just data, so are not copyrightable. So I included SANAPPSI.* directly. --- MANIFEST.in | 2 + tests/SANAPPSI.RSA | Bin 0 -> 4060 bytes tests/SANAPPSI.SF | 2044 +++++++++++++++++++++++++++++++++++++++++ tests/common.TestCase | 21 + 4 files changed, 2067 insertions(+) create mode 100644 tests/SANAPPSI.RSA create mode 100644 tests/SANAPPSI.SF diff --git a/MANIFEST.in b/MANIFEST.in index ee15b587..1d7bd768 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -724,6 +724,8 @@ include tests/repo/urzip-*.apk include tests/repo/v1.v2.sig_1020.apk include tests/rewritemeta.TestCase include tests/run-tests +include tests/SANAPPSI.RSA +include tests/SANAPPSI.SF include tests/scanner.TestCase include tests/signatures.TestCase include tests/signindex.TestCase diff --git a/tests/SANAPPSI.RSA b/tests/SANAPPSI.RSA new file mode 100644 index 0000000000000000000000000000000000000000..f727aa8bbfd457009064955c9d6aa017d7bc8672 GIT binary patch literal 4060 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 literal 0 HcmV?d00001 diff --git a/tests/SANAPPSI.SF b/tests/SANAPPSI.SF new file mode 100644 index 00000000..6b32aa9f --- /dev/null +++ b/tests/SANAPPSI.SF @@ -0,0 +1,2044 @@ +Signature-Version: 1.0 +SHA1-Digest-Manifest-Main-Attributes: j30fXwMuyUNMD8CkhJNLiV/4i5U= +Created-By: 1.6.0_26 (Sun Microsystems Inc.) +SHA1-Digest-Manifest: Xrxc4Hzyp+Hy2ZoUSqnJMMLl5rw= + +Name: res/drawable/listselector_black_other.xml +SHA1-Digest: MWLw2UtkVO3XvB4pHy6n040Gf34= + +Name: res/drawable-xhdpi/abs__spinner_ab_pressed_holo_light.9.png +SHA1-Digest: FzjmKCcidOTQaeqKDaRoIPDLRFs= + +Name: res/drawable-ldpi/plus.png +SHA1-Digest: r3DiYpO4vOYO47rZrShRO0BFZhQ= + +Name: res/drawable-mdpi/abs__spinner_48_inner_holo.png +SHA1-Digest: 2lkUs3xv5PleZLwoEPtjpQImnpc= + +Name: res/drawable-xhdpi/network_wifi4_s.png +SHA1-Digest: c2Hm5mmx/ro6D0bz9joCoeKIY+U= + +Name: res/drawable-hdpi/abs__spinner_48_inner_holo.png +SHA1-Digest: CJL2ghapGa7P/c4HGmlTyHSDmUc= + +Name: res/drawable/a02.png +SHA1-Digest: dU9vOCVfKmxTs0qMgCGwiEr5VfQ= + +Name: assets/it/03started_IT.png +SHA1-Digest: mEvR38lU22QT9wFqTmNXGf/nAbc= + +Name: res/drawable/listselector_other.xml +SHA1-Digest: FBWpUfganAevEl3BAaG2T2jd5OI= + +Name: res/layout-v14/sherlock_spinner_item.xml +SHA1-Digest: ql55eok+PCzt8roriI/o6DIfF9s= + +Name: res/drawable-mdpi/settings_dark.png +SHA1-Digest: PlVxcR6DvmNgPigkGtKccKW7hoM= + +Name: res/drawable-xhdpi/abs__ab_bottom_solid_dark_holo.9.png +SHA1-Digest: eFqrKbPnt4coIZuXeRDmTQ2udcQ= + +Name: res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_light.9.png +SHA1-Digest: JpDU0Y1y6F6Ao4HGBg4ANZRivB0= + +Name: assets/es/03started_SP.png +SHA1-Digest: mK6LEVFjuqE64ggWQDhm5GVWLqc= + +Name: res/layout/file_grid_adapter_content.xml +SHA1-Digest: JZ/eJGUIMqzhHUrOderuOCeg2Ro= + +Name: res/drawable-xhdpi/download_dark_green.png +SHA1-Digest: 3tcdWbWCqGwItudsipwUQYQQKXE= + +Name: res/drawable-hdpi/abs__progress_secondary_holo_light.9.png +SHA1-Digest: NclG74rMN1B0DgLYETLDBkWMcNc= + +Name: res/drawable/abs__textfield_searchview_right_holo_light.xml +SHA1-Digest: DKiINexDf/h7yiK0i8DZ++4MCCc= + +Name: res/drawable-mdpi/abs__ic_go.png +SHA1-Digest: gCn3z+l3jF6XzbJ1zu/I/cfOhic= + +Name: res/drawable-xhdpi/abs__cab_background_top_holo_dark.9.png +SHA1-Digest: 0ea3duNXY0J43pi4kHjogRXDHVY= + +Name: res/drawable-hdpi/pause_notify.png +SHA1-Digest: Qhmqe239fUV8+Q2i6vx/0MwbNw8= + +Name: res/drawable/abs__btn_cab_done_holo_dark.xml +SHA1-Digest: LsfiS6IfaXG1BgUZ+g5yuauD4cA= + +Name: res/drawable-hdpi/abs__ab_stacked_transparent_light_holo.9.png +SHA1-Digest: GAKCrxmGsKhItkNy1MAIS2q9vRA= + +Name: res/drawable-mdpi/abs__spinner_ab_default_holo_dark.9.png +SHA1-Digest: LYrwN+jVXg8t1E/QWje1z3utYhE= + +Name: res/drawable-ldpi/download_dark_green.png +SHA1-Digest: 2JmQLIwmNDTuthzVm8qusj0QAzQ= + +Name: res/drawable-mdpi/abs__dialog_full_holo_dark.9.png +SHA1-Digest: 5kMok0yjau7mHw4vozq79vClj1g= + +Name: res/drawable-xhdpi/abs__spinner_ab_pressed_holo_dark.9.png +SHA1-Digest: jZXAbmZiHofjvOsnjGZzKEalq7w= + +Name: res/drawable-xhdpi/abs__ab_stacked_transparent_dark_holo.9.png +SHA1-Digest: Kpd0zjAsuYHF93rPn7rxNL79DQw= + +Name: res/drawable-xhdpi/abs__list_activated_holo.9.png +SHA1-Digest: IfHC/OnL+3bB/ZxOyFCoy5EeBi8= + +Name: res/drawable-xhdpi/settings_downloads.png +SHA1-Digest: SyHeNwSG7iddevDcS21xJZyhEqE= + +Name: assets/fr/03started_FR.png +SHA1-Digest: 7QWErJW9xFOqIlNeRQdur7clgvs= + +Name: res/drawable-xhdpi/abs__ic_search_api_holo_light.png +SHA1-Digest: zzViuA42kPy4ztuyd5jmb69h3UE= + +Name: res/drawable-mdpi/abs__cab_background_top_holo_dark.9.png +SHA1-Digest: AD+zezNsMMkAj2PtUAJjMMu5iDY= + +Name: assets/de/05content_GR.png +SHA1-Digest: 3RuvSnNJFASIQHTF9TYFtdsFCjQ= + +Name: res/drawable-hdpi/abs__list_focused_holo.9.png +SHA1-Digest: cmzK05siG5gg/JMEX6gwLI8okTo= + +Name: res/drawable-mdpi/create_folder_dark.png +SHA1-Digest: yKOjRyT+4K/ay5Zw/gHFGoi+K4o= + +Name: res/drawable-mdpi/abs__list_divider_holo_light.9.png +SHA1-Digest: LYwCyBqiEztiFAeA4HH7i29QWHs= + +Name: assets/ru/04wifi_RUS.png +SHA1-Digest: JPR+kz0ylNKA/oy4LgWuwP5ufxc= + +Name: res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_light.pn + g +SHA1-Digest: tsTtsbOvqALy3nQvq2fpTwpbKF4= + +Name: res/drawable-mdpi/upload2.png +SHA1-Digest: Pb2KTktgUwbKIMnmJ8LFChJdQQc= + +Name: assets/ru/03started_RUS.png +SHA1-Digest: sQ460pKsDXWNKbpYEPYuT7p93cc= + +Name: res/drawable-mdpi/delete_dark.png +SHA1-Digest: lef06JOChh6NdiaUG66+16QSCbs= + +Name: res/drawable/dotted_line.png +SHA1-Digest: 7tyBAkuG9ktS8DcJYsmC+/ADSf8= + +Name: res/drawable-xhdpi/wifi0_s.png +SHA1-Digest: UTmCAMH3PBQG+QiuJPyMcK1tYD4= + +Name: res/drawable-hdpi/abs__list_selector_disabled_holo_dark.9.png +SHA1-Digest: PSYxMX7M0Pyv7qDHlCHIX8N0vBM= + +Name: res/drawable-xhdpi/abs__dialog_full_holo_light.9.png +SHA1-Digest: 9j/eomOMGL6s6MALfx6BoUqHpTE= + +Name: res/drawable-large-mdpi/icon.png +SHA1-Digest: YujYD3yhWG67AgXqFkEaEcVKc60= + +Name: res/drawable-xhdpi/abs__ic_menu_share_holo_light.png +SHA1-Digest: PkuNwXm1UGjUrzPA6Gd3SDdpl0M= + +Name: assets/zh_CN/04wifi_CHS.png +SHA1-Digest: 31sTREsQW3QhXWsbeUXs+mDu4vc= + +Name: res/layout/file_picker_row.xml +SHA1-Digest: 54eaz24HfzWyNXQ93Z45UaxSCh0= + +Name: res/drawable/abs__spinner_ab_holo_light.xml +SHA1-Digest: fKUkdnpNhn2zLqG/TQcyrcRiBz0= + +Name: res/drawable-mdpi/abs__spinner_ab_pressed_holo_light.9.png +SHA1-Digest: MXzCST6BJQJccxQfpI1YKs9soMA= + +Name: res/drawable-mdpi/abs__ab_solid_shadow_holo.9.png +SHA1-Digest: hGrkC3VbA03lIpo5eAWAIKxUACA= + +Name: assets/it/02qsg_IT.png +SHA1-Digest: nw6+ZqnhIDwdaMxlcQiUvYtMWbU= + +Name: res/drawable-ldpi/upload2_dark.png +SHA1-Digest: O6MiwNx0hNWwhmLzI31w2i1pnbA= + +Name: res/drawable-xhdpi/abs__spinner_ab_default_holo_light.9.png +SHA1-Digest: rN3ozv1THFWfASSLprLsIUefo8A= + +Name: assets/es/05content_SP.png +SHA1-Digest: rCIAUYe9WpDtWEq+UVmOxd4Ty2w= + +Name: assets/ja/02qsg_JAP.png +SHA1-Digest: lIymJ/HfciDGnsSJKzmBjko2YFU= + +Name: res/drawable-mdpi/list.png +SHA1-Digest: xTtboHSYByS0OdKOg4C8LDx+xfE= + +Name: res/drawable-xhdpi/abs__textfield_search_default_holo_light.9.pn + g +SHA1-Digest: WtQajziBu+760kiReahU5rVLMqc= + +Name: res/drawable-ldpi/notify_a02.png +SHA1-Digest: oRz9qSdhdyjiJD97U1n80cA6T+Y= + +Name: res/drawable/prompter_later_icon.png +SHA1-Digest: xKAMzyWVvSUonv9TVwtit0FWBaI= + +Name: res/drawable-hdpi/abs__list_pressed_holo_dark.9.png +SHA1-Digest: tyQ5tBsIsMFbB2+EYlw1QOfshGo= + +Name: res/drawable/abs__search_dropdown_light.xml +SHA1-Digest: R3EDawEdTrc8ZZYB1Zq4EjdM+c4= + +Name: res/drawable-mdpi/abs__list_selector_disabled_holo_light.9.png +SHA1-Digest: lUZ07f/+UGDoTLjAZkTwyDWPzS8= + +Name: res/drawable-hdpi/abs__dialog_full_holo_dark.9.png +SHA1-Digest: NZL7OMl0qyFZYaVxYtgttwuB4EM= + +Name: res/drawable-xhdpi/abs__progress_primary_holo_light.9.png +SHA1-Digest: gbM/209feahCWBSz/iSqM+5CQEs= + +Name: res/drawable-xhdpi/abs__ab_solid_light_holo.9.png +SHA1-Digest: oEjEqrCMWcAZlrRm5r9CGgkfbhQ= + +Name: assets/it/04wifi_IT.png +SHA1-Digest: 5jbrfUmBX17mcLNliKGbdePTuuM= + +Name: res/drawable/abs__activated_background_holo_dark.xml +SHA1-Digest: zn1e13WcJRCRd6uIui2lRD/14ps= + +Name: res/drawable/a02_grey.png +SHA1-Digest: aiVy0aSwrCmfwZTzviJwIi0joyc= + +Name: res/drawable/abs__list_selector_background_transition_holo_dark. + xml +SHA1-Digest: nkzZ+Yg/x4857LCaM82WB/8Bv5c= + +Name: res/drawable-hdpi/abs__ab_stacked_solid_light_holo.9.png +SHA1-Digest: VYF3ilhVt0j4XUKE7/i+chELTwU= + +Name: res/layout/abs__action_bar_tab.xml +SHA1-Digest: nGCpM62b21vr2fx48qzseI0Kh2I= + +Name: res/xml/settings_network.xml +SHA1-Digest: Hm4f9jRc32zWhWt7e9ETUSndfqE= + +Name: res/drawable-hdpi/abs__cab_background_bottom_holo_dark.9.png +SHA1-Digest: aXnONgY9LnlqGryUeUqgo7LOSQk= + +Name: res/xml/settings_preferred_networks.xml +SHA1-Digest: aEPm2opo6kZzLtz/SJNIl/ArB7Y= + +Name: res/drawable-ldpi/upload_green_dark.png +SHA1-Digest: qLBaMbh29jvLm4ew5T00JYe86nQ= + +Name: res/drawable-mdpi/abs__tab_selected_holo.9.png +SHA1-Digest: L5T/evq3/QxvwsaGEbem7TflNV4= + +Name: assets/fr/02qsg_FR.png +SHA1-Digest: Q+MQoQYdSNYOvrK67srWZxwyU0E= + +Name: res/drawable-xhdpi/device_grey.png +SHA1-Digest: gJas9+8qpam8yBn92fLMZBfYV8U= + +Name: assets/de/02qsg_GR.png +SHA1-Digest: I+lxqFyScw80Z4jZC3XllZI9tAA= + +Name: res/drawable-xhdpi/sidelink_s.png +SHA1-Digest: YSdNBBj3Twhfakw5mUeob6xmqc8= + +Name: res/drawable-hdpi/abs__ic_ab_back_holo_light.png +SHA1-Digest: CixL+v/te56l/tUQbDjX61YPV00= + +Name: res/drawable/abs__search_dropdown_dark.xml +SHA1-Digest: NXhpyrdvsxnjMhZNexYVfesmAB8= + +Name: res/drawable-xhdpi/abs__spinner_ab_disabled_holo_light.9.png +SHA1-Digest: pdDmHBXa98nEr/3He9uEXSLFC1o= + +Name: res/drawable/android_device.png +SHA1-Digest: W27uCkolI+M1GLnyktdkl8krYXI= + +Name: res/drawable-hdpi/abs__textfield_search_selected_holo_dark.9.png +SHA1-Digest: WBB4+CBudWVmh0lMMVXiNP0JDrU= + +Name: res/drawable-hdpi/create_folder_dark.png +SHA1-Digest: xfti53azeNFBEjWPm6XrcR9T0F0= + +Name: res/drawable-hdpi/notify_a02s.png +SHA1-Digest: oDMYbBNRJAL+bOpfej8MmSlfZHo= + +Name: res/drawable-xhdpi/network_wifi1_s.png +SHA1-Digest: FG1rrohcnefatqyEAdRju68isFw= + +Name: res/layout/prompter.xml +SHA1-Digest: Rd2/j3GAhWBT+9Oyfz+kFG9KZhE= + +Name: res/drawable-mdpi/notify_a02s.png +SHA1-Digest: PYKLvezZQEZhduKHT29nBU36EJg= + +Name: res/drawable/action_bar_background.png +SHA1-Digest: 2kRUSGiW40hppQWVem7dxmBZT9Q= + +Name: res/drawable-hdpi/list_dark.png +SHA1-Digest: 0P1SngBpjnVfhE5k77fqPx+X4lQ= + +Name: res/drawable-hdpi/abs__btn_cab_done_pressed_holo_light.9.png +SHA1-Digest: v8ypJ5NNRgssVGwciTAxLfTJimk= + +Name: res/drawable-mdpi/abs__textfield_search_selected_holo_dark.9.png +SHA1-Digest: HCwKLtZvThjkFwM4ec23apOHRKY= + +Name: res/drawable/listselector_black.xml +SHA1-Digest: Lu3YXjbTs+qeozbdQ6UFpHDFId4= + +Name: res/drawable-hdpi/abs__textfield_search_right_default_holo_dark. + 9.png +SHA1-Digest: 7QBkvHTf6LXBGN5pEiHf8O/eals= + +Name: res/layout/abs__activity_chooser_view_list_item.xml +SHA1-Digest: 8DrPL6nrJch1r5jnnAUGfjufqPI= + +Name: res/drawable-hdpi/abs__ab_bottom_transparent_dark_holo.9.png +SHA1-Digest: u1TLIRZlHuDUKJg9Zfw4ABuD/9E= + +Name: res/drawable-xhdpi/abs__ic_voice_search.png +SHA1-Digest: +GD8FPK5NCAls40MvKX9/6/LJfQ= + +Name: res/drawable-hdpi/abs__textfield_search_right_selected_holo_dark + .9.png +SHA1-Digest: 2IeB+m0vaMbHMFjnOJGzaqY/h2w= + +Name: res/drawable-mdpi/settings.png +SHA1-Digest: YqFHEtD+aqGYihfsfTGKo4Gg4s0= + +Name: res/drawable-xhdpi/abs__ab_transparent_dark_holo.9.png +SHA1-Digest: vSauuGeIKSecU5a1hWJ2RNsNJzQ= + +Name: res/drawable-mdpi/notify_a01.png +SHA1-Digest: qa8aM+G/X1hYqkwGexHSTACFGHc= + +Name: res/drawable-mdpi/abs__ic_search.png +SHA1-Digest: BI0nScADeYpWWpMjIMAT2QY2Umw= + +Name: res/drawable-mdpi/abs__ic_clear_search_api_disabled_holo_light.p + ng +SHA1-Digest: NMg/ydr6pzg1YALEzBCxmkb7kxk= + +Name: res/drawable-xhdpi/wifi1_s.png +SHA1-Digest: +PLjVt6M4emDQvfdVVLjRJeRjvQ= + +Name: res/drawable/file_xls.png +SHA1-Digest: Pf4ayhW4F6PoGLfDrD0bylDULkI= + +Name: res/drawable/folder.png +SHA1-Digest: azkcOt4V16v3sXfFKe0edzAI++o= + +Name: res/drawable-mdpi/download_dark.png +SHA1-Digest: aWHXoyGEKbpj1DTEpRBkpMH6PmI= + +Name: res/drawable-mdpi/abs__ic_menu_share_holo_light.png +SHA1-Digest: magQUaooCQ+JXt60vJsEvewVzkw= + +Name: res/drawable-hdpi/abs__list_divider_holo_light.9.png +SHA1-Digest: dLGGprCGkct4687KEh113PTpG9c= + +Name: res/drawable/checked.png +SHA1-Digest: YGmEtu098UIXrwUi+qILHOocWWk= + +Name: res/drawable-xhdpi/notify_a01.png +SHA1-Digest: fZMn3IkFBOLUwLPbjCQAUj6fSv0= + +Name: assets/es/qsg.html +SHA1-Digest: bZsWIJ91bpeFJSQ93S7g9re+sGU= + +Name: res/drawable/popup_shape.xml +SHA1-Digest: i8MySzOa2xukP/5Wgjw1+BK5qi0= + +Name: res/drawable-hdpi/abs__btn_cab_done_focused_holo_light.9.png +SHA1-Digest: IAoWDEN7FVuyVXzrbwlUiMvTm4A= + +Name: res/drawable/abs__item_background_holo_dark.xml +SHA1-Digest: kvabXA9nk27AJ7fo9ZiEKSYhJUE= + +Name: res/layout/aircruzer_picker.xml +SHA1-Digest: mUa4WrIKIRyAgLqYJ8iAu4NmHK8= + +Name: res/drawable-hdpi/abs__spinner_48_outer_holo.png +SHA1-Digest: UkxSolG4Lj/7rurZhEafioc4GO0= + +Name: res/layout-large/music_land.xml +SHA1-Digest: KlS9PoIMpn+lJLrPIhM73628RfU= + +Name: res/drawable-hdpi/abs__spinner_ab_default_holo_light.9.png +SHA1-Digest: xkdHqtecCptSNAenCziCM6Dx9ug= + +Name: res/layout/gallery_picker.xml +SHA1-Digest: 2iJUVwcyAZVxznNSVnTfV1LlsVc= + +Name: res/drawable-mdpi/abs__menu_dropdown_panel_holo_dark.9.png +SHA1-Digest: xJpDBeVVHEAseQkRi1XAIGMriyA= + +Name: res/drawable-xhdpi/abs__spinner_ab_focused_holo_dark.9.png +SHA1-Digest: 7mQl9j8Z+4d8toEFSV4DWOebffU= + +Name: res/drawable-xhdpi/abs__btn_cab_done_focused_holo_dark.9.png +SHA1-Digest: fxJ1IQV5ASthEhtf9SO0AEDjv24= + +Name: res/layout/file_picker.xml +SHA1-Digest: 7kw3j8NCvK5W62giTMuOIvC8T2E= + +Name: res/drawable-mdpi/abs__ic_ab_back_holo_dark.png +SHA1-Digest: oLfC1AXlyDlkSM5ygmQMDvnKn+k= + +Name: res/drawable-ldpi/upload_green.png +SHA1-Digest: PwNRr2W1ld44CJo390pLw13p4YI= + +Name: assets/fr/04wifi_FR.png +SHA1-Digest: v3KvaQFnOnqzTYAXzp8amgwgRnQ= + +Name: res/drawable-xhdpi/abs__spinner_ab_disabled_holo_dark.9.png +SHA1-Digest: wK6pwNPNoO+a3FlkoF9etbrUgak= + +Name: res/drawable-ldpi/download.png +SHA1-Digest: 1f8VPGCHjHmxVYpgEn2PLCWoHBA= + +Name: res/layout/sherlock_spinner_dropdown_item.xml +SHA1-Digest: 1cUUR7HCn106iA3nxGAf4gLC+Zs= + +Name: res/drawable/prompter_now_icon.png +SHA1-Digest: Xl6Skkfd/1hmJ9pWgKx6fcJ5wV0= + +Name: res/drawable-xhdpi/abs__list_divider_holo_dark.9.png +SHA1-Digest: 7MWXoXdFBtj0xevridg2MwrPea8= + +Name: res/drawable/sandisk_logo.png +SHA1-Digest: qGLW0i4OsY8+etWOKh6/GSu/sbg= + +Name: res/drawable-mdpi/abs__ic_menu_share_holo_dark.png +SHA1-Digest: KUK59sOtpbaNtfvXHu/d4jfjiLc= + +Name: res/drawable-xhdpi/abs__list_longpressed_holo.9.png +SHA1-Digest: +gyZSFuut8L02SGSZyG5FJp9E+Q= + +Name: res/drawable-mdpi/refresh.png +SHA1-Digest: CSig0drvev6druFbHw26duEWnFo= + +Name: res/drawable-v11/abs__progress_medium_holo.xml +SHA1-Digest: LurSPK+0Yc5jfqHJsXs8SvPKWOM= + +Name: res/drawable/a02c_grey.png +SHA1-Digest: 8n2IpMfIu7vjfIyAZTVWll9g8W8= + +Name: res/drawable-mdpi/notify_a02c.png +SHA1-Digest: TBUp+3CWqRFDqdyemYTZvGngOEE= + +Name: assets/es/04wifi_SP.png +SHA1-Digest: xt39BDWJq+w7ApRN9ETYkhDbWqE= + +Name: res/layout/abs__screen_action_bar.xml +SHA1-Digest: UbWFvLTcPmF0fX/XOJ8qhqFOeuE= + +Name: res/drawable-mdpi/abs__dialog_full_holo_light.9.png +SHA1-Digest: 30Fq6J0OLML2NvEWQAhQxTVZd5Y= + +Name: res/drawable-xhdpi/abs__btn_cab_done_pressed_holo_dark.9.png +SHA1-Digest: xAFz3vWGpge38sxmXPLI27vEPuo= + +Name: res/drawable-hdpi/abs__ic_search.png +SHA1-Digest: mmxhF1hpNdi0wm72NijW0w20Wxc= + +Name: res/layout/wep_password_alert.xml +SHA1-Digest: Kaiw5ruYgDSd0vym8pT0gbSW2Ps= + +Name: res/drawable/abs__list_selector_holo_dark.xml +SHA1-Digest: g79M/u/cZDt/7dZ55Jt1qvM6Suc= + +Name: res/drawable/listselector_focused.xml +SHA1-Digest: h8p7/nYjxNaiu6hlXih1FQAk/0c= + +Name: res/layout-v14/sherlock_spinner_dropdown_item.xml +SHA1-Digest: j2ApyFQZMBt+76GszojrnEGCZN8= + +Name: res/drawable/next_enabled.png +SHA1-Digest: 9ICEJCjzSjugC9UrHVT9QZt9jWE= + +Name: res/drawable-xhdpi/network_wifi2.png +SHA1-Digest: tTt97KZdQ1B3XABarNLU6AyigkQ= + +Name: res/drawable-hdpi/abs__textfield_search_selected_holo_light.9.pn + g +SHA1-Digest: LLpilWiHrYuALiQ/5iUQR5OPXf0= + +Name: res/layout/wifi_settings_warning.xml +SHA1-Digest: kvnbz3CLSaBQAordW6dqNayZQM8= + +Name: assets/zh_CN/05content_CHS.png +SHA1-Digest: Dlw67oaNJg6zEs7ffBGDMhHSfaE= + +Name: res/drawable-mdpi/abs__progress_secondary_holo_dark.9.png +SHA1-Digest: /SAgp/k2IQYLgj++eNO4dKNGq5s= + +Name: res/drawable-mdpi/plus.png +SHA1-Digest: lTvzNUMQaZsgu0mE9JTY2Qfx9Tg= + +Name: res/drawable-mdpi/abs__progress_secondary_holo_light.9.png +SHA1-Digest: jFGNeShp/bv741EZVHK7OcedTqc= + +Name: res/drawable-hdpi/abs__menu_dropdown_panel_holo_dark.9.png +SHA1-Digest: zrm68udX1iJ5dagtmsfWz7HTFXo= + +Name: res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_dark.pn + g +SHA1-Digest: 1sb6CD9Si8eb/l514oNT+ScOJrQ= + +Name: res/drawable-hdpi/abs__ab_bottom_solid_dark_holo.9.png +SHA1-Digest: UNxoaN6XzupxEBNdFCWbravjlHI= + +Name: res/drawable-hdpi/abs__ic_clear_normal.png +SHA1-Digest: +TgrkKGRoFESWLJbCtYv3ujChX0= + +Name: assets/de/qsg.html +SHA1-Digest: nHFEaNWoeHgEplG52NGG7RSRf4U= + +Name: assets/fr/qsg.html +SHA1-Digest: CirZ/0A1w1cIHY5asuFquvSVut0= + +Name: res/drawable-xhdpi/abs__list_selector_disabled_holo_dark.9.png +SHA1-Digest: /DYDUk9WKWg/XaPZlHYTRwCZQ78= + +Name: assets/ru/05content_RUS.png +SHA1-Digest: s4Us4TagsG8KKT+RPj8WuF4r6So= + +Name: res/layout/aircruzer_adapter_content_favourite.xml +SHA1-Digest: CWF6fC18Cnm53EfApkidk//Rel8= + +Name: res/drawable-mdpi/abs__list_pressed_holo_dark.9.png +SHA1-Digest: MVZcqs4uf/1z86YrgdchuFApXFM= + +Name: res/drawable/high_white.png +SHA1-Digest: T6mvyxxAO5uOQq8ea7Pc+L7Wvw4= + +Name: res/drawable-hdpi/icon.png +SHA1-Digest: Xsnl13yqIhN0Yhcvt6sFGxiirOo= + +Name: res/drawable-hdpi/grid.png +SHA1-Digest: mngmQBkqDkTgX8qlKQVqmMUeKDE= + +Name: res/drawable-mdpi/abs__ab_stacked_solid_light_holo.9.png +SHA1-Digest: 0JeD4BWiJde5QSs8vsJGbSSRo9w= + +Name: res/drawable-ldpi/refresh.png +SHA1-Digest: /tKyif+HMcLguuOSmjrHG/epHwM= + +Name: res/drawable-hdpi/select.png +SHA1-Digest: VO6hSFGY0YHXhiTM6M/A3PGGpP8= + +Name: assets/it/01logo.png +SHA1-Digest: RNSf8yo0o5QQ3BW+JNLGjlmkYXM= + +Name: res/drawable-hdpi/abs__cab_background_top_holo_dark.9.png +SHA1-Digest: rf/kCJZARmuzLhNTzuiyPaOEskQ= + +Name: assets/en/05content.png +SHA1-Digest: Li5BBPpeE7/LCDZt8u5kNtqYOwg= + +Name: res/drawable-hdpi/notify_a02c.png +SHA1-Digest: Dh52ybGFrkCfij/0fI7PjnvaOc4= + +Name: res/drawable-xhdpi/abs__list_divider_holo_light.9.png +SHA1-Digest: x9+PP/XbxupQBFw9ABGcxRaJgk8= + +Name: res/drawable-mdpi/abs__ab_stacked_solid_dark_holo.9.png +SHA1-Digest: lI9GC0V2P8dv41uhoIPkw4Y6mZo= + +Name: res/drawable-mdpi/abs__ab_stacked_transparent_dark_holo.9.png +SHA1-Digest: Kc817gaU1Y6yov4eCjYPnOidbls= + +Name: res/drawable-mdpi/abs__ic_voice_search_api_holo_light.png +SHA1-Digest: 49Mq99v4olptPThmPP6j0nawT5w= + +Name: assets/en/01logo.png +SHA1-Digest: P2VlOLMuEir8Gdy0m4iyp5dmmhg= + +Name: res/drawable-xhdpi/abs__dialog_full_holo_dark.9.png +SHA1-Digest: 4nyi+mJAOsENtuCTXd465Y7Uq34= + +Name: assets/it/05content_IT.png +SHA1-Digest: VScV9vj7O+YBpuD/KLtHeaDYgM8= + +Name: res/drawable-hdpi/abs__progress_primary_holo_dark.9.png +SHA1-Digest: xXc1hIjT3vO67xsQT889wFhGrKs= + +Name: res/drawable-xhdpi/abs__ic_cab_done_holo_dark.png +SHA1-Digest: 9ghTrZlcnowNCN7lR28T+hDGtx8= + +Name: res/drawable-hdpi/abs__ic_go.png +SHA1-Digest: CWye9x3DUeO8YvBEl1yhf4hqaCE= + +Name: res/drawable-xhdpi/abs__ic_ab_back_holo_light.png +SHA1-Digest: z0ke+ia8F5RJjuMHQV9UdRAL3P4= + +Name: res/drawable-xhdpi/abs__textfield_search_right_selected_holo_lig + ht.9.png +SHA1-Digest: tSHxYUUEcy8RD4s5TEbOlAEJfh0= + +Name: res/drawable/file_doc.png +SHA1-Digest: 3hfZjdvB8ZWf5avOTl+z8c/Vkgc= + +Name: assets/ja/01logo.png +SHA1-Digest: /kWuYVhfsI65oSZy3VdTB6LrflA= + +Name: res/drawable-mdpi/upload_green_dark.png +SHA1-Digest: V1zUuj6ac7912Xmlzxeia6XbmJM= + +Name: assets/fr/01logo.png +SHA1-Digest: tmDNQx2XK65qimY3EhcVQfGlMFQ= + +Name: assets/zh_TW/04wifi_CHT.png +SHA1-Digest: L9fvKVAB54jMZtIe6oRsZGZRVxc= + +Name: res/drawable-xhdpi/abs__cab_background_bottom_holo_dark.9.png +SHA1-Digest: AJF3Ifc4kOwddl5NuxnGmPnK7OU= + +Name: res/drawable-mdpi/abs__ab_transparent_light_holo.9.png +SHA1-Digest: +sJdheZQoN+Dh1tRbjQLO8UssyE= + +Name: res/drawable-xhdpi/abs__btn_cab_done_focused_holo_light.9.png +SHA1-Digest: j2PXHb9r4hT0LWIRTKUHxChl30c= + +Name: res/drawable-xhdpi/upload_green_dark.png +SHA1-Digest: IbTADVnQwWLiu1l43ExAngRW8Dc= + +Name: res/drawable/movie_overlay.png +SHA1-Digest: z2TC/ukywxRi53YxsD0tgyoK4us= + +Name: res/drawable-xhdpi/network_wifi1.png +SHA1-Digest: 7PAxMoYaxPIPNGuREZCEEnRjRYc= + +Name: res/drawable-hdpi/abs__ab_solid_light_holo.9.png +SHA1-Digest: 7J9Q5byq8vS6biNpHOPV7jomAk8= + +Name: assets/ru/02qsg_RUS.png +SHA1-Digest: Kl1hRbcezp9vKUlIqxtzio5Ft58= + +Name: res/drawable-xhdpi/plus.png +SHA1-Digest: rxqIzUjL1DFneMGTIZ0fuqCUUN4= + +Name: res/drawable-xhdpi/network_wifi2_s.png +SHA1-Digest: J3h3K/KDENlGE3agp94SGGgVnWM= + +Name: res/drawable-hdpi/abs__spinner_ab_focused_holo_light.9.png +SHA1-Digest: AQXKZr6CJIMys4qb8nRR6AwGmeI= + +Name: res/drawable-xhdpi/abs__progress_bg_holo_dark.9.png +SHA1-Digest: mkjM/2bQaaMvKLY2Mu+dvCM66IQ= + +Name: res/drawable-xhdpi/list.png +SHA1-Digest: zfCy6xQnp3SG6VbxFb07FLfVbcM= + +Name: res/drawable/a02s.png +SHA1-Digest: GSeeNT/Is+ISxESrkcR/BkEIIhg= + +Name: res/drawable/a01_grey.png +SHA1-Digest: o4x4egouND9Eg5F/V7gYepH8BN8= + +Name: res/layout/wifi_enable_alert.xml +SHA1-Digest: FgLGchDLnLd7+qzxlJ2+7keKbRY= + +Name: res/drawable-hdpi/upload_green.png +SHA1-Digest: XP257A4Y2Y6FUjE62C860jDOLY4= + +Name: res/drawable-xhdpi/abs__list_selector_disabled_holo_light.9.png +SHA1-Digest: sJGoCoseoFVk5x28K8JfgpfauJU= + +Name: res/raw/wfd1080.df2 +SHA1-Digest: Ze7bkm1Xf+wAM3smectt968klJU= + +Name: res/layout/abs__search_dropdown_item_icons_2line.xml +SHA1-Digest: 4yM8M6LQlEPx2E+FHxwod7YcekM= + +Name: res/layout/aircruzer_adapter_content.xml +SHA1-Digest: 3qvJQmem0vvS/7ZR6cmu41EFTiY= + +Name: res/drawable/file_transfer_progress.xml +SHA1-Digest: zB1xmdjVW6s5lICKEF8R1CvjR5U= + +Name: res/drawable-xhdpi/abs__tab_unselected_pressed_holo.9.png +SHA1-Digest: 93qSifuDk+T5snBLIpvN4wO1K7U= + +Name: res/drawable-mdpi/abs__ab_bottom_transparent_light_holo.9.png +SHA1-Digest: vubKHcANJCKtDTtxkgYFicJ4SNY= + +Name: res/drawable-mdpi/abs__ab_bottom_solid_inverse_holo.9.png +SHA1-Digest: lkth7LAKOZYfoGCArce+VxCnMkE= + +Name: AndroidManifest.xml +SHA1-Digest: 1Q6sDBqzh5rE3qugFvZGPvLd1XU= + +Name: res/drawable/listselector.xml +SHA1-Digest: 3hAl/K8dWhvmmpXiOVOgNsm+r3c= + +Name: res/drawable-xhdpi/grid.png +SHA1-Digest: v+u9B3UCpBYlFWM8jLqBkH+bYBc= + +Name: res/drawable-xhdpi/wifi3_s.png +SHA1-Digest: RxU+HxB9gVfKWrvwmqxWnxyw2x8= + +Name: assets/ko/04wifi_KOR.png +SHA1-Digest: GdSrIVVUgjwMHjdlzuj4wo6+I7I= + +Name: res/layout/network_adapter_content.xml +SHA1-Digest: kZG1xqaJa5j9h4oUCh2HivuxkD4= + +Name: res/drawable-mdpi/grid_dark.png +SHA1-Digest: H0+9LNUPoy819qukjO/zCq812yI= + +Name: res/drawable/close.png +SHA1-Digest: CyX8gjcx2fMTrzKkUSeloiLvntA= + +Name: res/drawable-hdpi/abs__ab_transparent_light_holo.9.png +SHA1-Digest: 4kTcWnz88o9/SYFJwj/yXDU8yEE= + +Name: res/layout/abs__list_menu_item_radio.xml +SHA1-Digest: w+7s4YfCDkdrD+3Kd2/8Upoj5IA= + +Name: res/drawable-mdpi/abs__progress_bg_holo_light.9.png +SHA1-Digest: xVHcWEktmp97Mv3RfXsYYUYbTZE= + +Name: classes.dex +SHA1-Digest: 3km0wVfqQhtB471ajuKsk/KN6ik= + +Name: res/drawable/file_generic.png +SHA1-Digest: g2sd8B1VVAF2jZIDPuREiP1OrfM= + +Name: res/drawable-hdpi/abs__ab_stacked_solid_dark_holo.9.png +SHA1-Digest: UN6hqgMRSJHlLtONWT/5Dj1jldI= + +Name: res/drawable-xhdpi/pause_notify +SHA1-Digest: QqGYzYpLgbJ/DYEo97b5qkriSss= + +Name: res/drawable-xhdpi/abs__ab_solid_dark_holo.9.png +SHA1-Digest: jFrVTtT+2Gung7B7LdaO7zrVRCs= + +Name: res/drawable-xhdpi/settings_about.png +SHA1-Digest: 1FNVYaUf6Q/xrQoIeUD72aYQOuE= + +Name: res/drawable-hdpi/settings.png +SHA1-Digest: 6GK/sbX5QyQgjDZZ4r1w6UzrybU= + +Name: res/drawable-hdpi/abs__list_activated_holo.9.png +SHA1-Digest: I5QuxwxZ7oH/jjm7tnyYPs5kGh4= + +Name: assets/zh_TW/qsg.html +SHA1-Digest: pg0DYaTbVF+LvhneZsCK/Ucz0pY= + +Name: res/drawable-hdpi/abs__list_selector_disabled_holo_light.9.png +SHA1-Digest: aHGtLDCWy+vhaDj0NTpqi86fqY8= + +Name: res/drawable-hdpi/upload2_dark.png +SHA1-Digest: X9LMedqsA/ZvVUdh3Qu7hvBYGE0= + +Name: res/drawable-mdpi/abs__ab_solid_dark_holo.9.png +SHA1-Digest: JA/enCGf3vLcIhBUD+ZyXReZbdA= + +Name: res/drawable/file_txt.png +SHA1-Digest: 4emL5HYvYse7i3yqh7ckcaKlDJQ= + +Name: assets/ko/01logo.png +SHA1-Digest: KITx/kNaTnhYUbCm08v6jANm6b4= + +Name: res/layout/abs__list_menu_item_icon.xml +SHA1-Digest: A7MIR0vPrtL5J9AnNtIEnrB2h58= + +Name: res/color/abs__primary_text_disable_only_holo_dark.xml +SHA1-Digest: N3cOSy8QRTwjEm+T8Vyr7f7m5vM= + +Name: res/drawable-xhdpi/abs__btn_cab_done_default_holo_dark.9.png +SHA1-Digest: kSrvB3EWls1z+/3U+R3NgEiJtIQ= + +Name: res/drawable/phone_memory.png +SHA1-Digest: Lzo4e5YM8LSI0J6AD9/Wm3flT3c= + +Name: res/drawable-ldpi/movie.png +SHA1-Digest: 9QUv1g/c1L/X+774grvlhsRYFyw= + +Name: assets/it/qsg.html +SHA1-Digest: M/tpiMIqBAHpWB6Xs+fYzvCPv24= + +Name: assets/ko/03started_KOR.png +SHA1-Digest: /7pcS0DbudzUokivNnHhQpyn9vo= + +Name: res/drawable-hdpi/abs__cab_background_top_holo_light.9.png +SHA1-Digest: xTKcdW1X3evtBeWUTRtQHGUmvPg= + +Name: res/drawable-ldpi/upload2.png +SHA1-Digest: DMzgDh+wLox+OTp+CIL+ft2RONY= + +Name: res/drawable-mdpi/abs__ic_cab_done_holo_light.png +SHA1-Digest: gEkAYxPguS0vwjdi5GNBkBtKy/c= + +Name: res/drawable-mdpi/abs__progress_primary_holo_light.9.png +SHA1-Digest: dnKu/UA+XXZ6wxpF4RwPVuFfv1o= + +Name: res/drawable-mdpi/download_green.png +SHA1-Digest: 7anCwJPhKan3u7r2hUfxECEa8Bg= + +Name: res/drawable-mdpi/abs__progress_primary_holo_dark.9.png +SHA1-Digest: kzQLW28P8eWguDdlc8z7TZJH1NI= + +Name: res/drawable-ldpi/icon.png +SHA1-Digest: Y2eY1QCqoql+tnKq3j92CqrYq+I= + +Name: res/drawable-xhdpi/abs__spinner_48_outer_holo.png +SHA1-Digest: z8eDjuVkpuobA0RIVrS16o9J5Bk= + +Name: assets/ko/02qsg_KOR.png +SHA1-Digest: KBeJT96DDIcncWn+3jlNnpTVhnQ= + +Name: assets/zh_TW/05content_CHT.png +SHA1-Digest: d79KVFIyEH6iyDUsTSkxmXIi4FM= + +Name: res/drawable-xhdpi/sidelink.png +SHA1-Digest: QpuIs015XEkg+CQyNlzlYVjwfJA= + +Name: res/drawable/charging_2.png +SHA1-Digest: tRCy1BdHmg1HW46UxkPAHTywUFw= + +Name: res/drawable-xhdpi/abs__textfield_search_right_default_holo_ligh + t.9.png +SHA1-Digest: ZlENnTiHiVJnaXNDZziSFqGsy04= + +Name: res/drawable-mdpi/abs__progress_bg_holo_dark.9.png +SHA1-Digest: sa9YmWZKkkpUQ2bim/IvHhRtTVc= + +Name: res/drawable-mdpi/abs__ab_bottom_transparent_dark_holo.9.png +SHA1-Digest: TkJkUaylN89agUsoukHpqVXP8DQ= + +Name: res/drawable-xhdpi/abs__menu_dropdown_panel_holo_dark.9.png +SHA1-Digest: ts+1yVv8L3pBUMna7Ynj/ql914g= + +Name: res/drawable-hdpi/abs__tab_selected_holo.9.png +SHA1-Digest: kEcZGvbxtC+bZbKatmju03RhNRY= + +Name: res/layout-large/abs__action_mode_close_item.xml +SHA1-Digest: Fpvreh8RqsZaupAX541M3lS2nJc= + +Name: res/drawable-mdpi/abs__spinner_ab_disabled_holo_light.9.png +SHA1-Digest: B33L83GqHqw+54XJNHCEERj1J+4= + +Name: res/drawable-hdpi/abs__spinner_ab_pressed_holo_dark.9.png +SHA1-Digest: GRtPmHKBT0GPZ09Wsdm3QBp8sf8= + +Name: res/drawable-hdpi/notify_a02.png +SHA1-Digest: ZMmQ+l3zl+VAlPgNT6VPZpQyP2k= + +Name: res/layout/abs__dialog_title_holo.xml +SHA1-Digest: fvAYG2/jNVDTJyw0zh2uuqEirgI= + +Name: res/drawable/abs__list_selector_background_transition_holo_light + .xml +SHA1-Digest: 5RlvHkuer3Si6PKrDVOiblzLKBg= + +Name: res/drawable/unchecked.png +SHA1-Digest: 6kie/fO5imSzHMh8BvJHhzM6Mgo= + +Name: res/layout/settings_quick_start.xml +SHA1-Digest: jcU39268CLX4fsu1zy9cE/Hjb5s= + +Name: res/drawable-mdpi/abs__ic_clear_normal.png +SHA1-Digest: RYYQ9ky5+LbX58GkSGnq9am+1YQ= + +Name: res/xml/settings.xml +SHA1-Digest: 5OP8tootKpWlqnA7SikzWuyknno= + +Name: res/drawable-hdpi/abs__ab_solid_dark_holo.9.png +SHA1-Digest: LQeQB4SfeOCgaQHq+K6yaooPJA4= + +Name: res/drawable-xhdpi/abs__textfield_search_right_default_holo_dark + .9.png +SHA1-Digest: CUR20AnfKGpE6ZXBnCAmkld8mdU= + +Name: res/drawable-hdpi/abs__textfield_search_default_holo_light.9.png +SHA1-Digest: 2e1Mor2JS0wSl3OmphZG535kkvE= + +Name: res/drawable-xhdpi/abs__ab_stacked_solid_dark_holo.9.png +SHA1-Digest: T7wOXmWiHfzmkjzz0TfzB4wPVl8= + +Name: res/drawable-xhdpi/abs__ic_clear_search_api_holo_light.png +SHA1-Digest: ALPTzi3RYWU+XkKuUFTrF2Yu+Qo= + +Name: res/drawable-mdpi/notify_a02.png +SHA1-Digest: ch0TDRJtGTuqhLuIgoSPc/ogzQg= + +Name: res/drawable-xhdpi/settings_add_sidelink.png +SHA1-Digest: rlkNafw0Cdbd9oevb3szbVs7xfU= + +Name: res/drawable-ldpi/delete.png +SHA1-Digest: NT/6wAnfi2V3ythODSAy+EXKRwM= + +Name: res/drawable-xhdpi/refresh.png +SHA1-Digest: bJzPCd5afynpWcACYMWvWPBEISE= + +Name: res/drawable-mdpi/download.png +SHA1-Digest: ovU6EIzUCsuQKCYtcHOHLgY1NOc= + +Name: res/drawable-ldpi/settings_dark.png +SHA1-Digest: dIU0DmABk6uuWPzLbIjUMemi1jg= + +Name: res/drawable-hdpi/abs__progress_primary_holo_light.9.png +SHA1-Digest: gGaVM0Vmse4mOSdADodc6mtJFZg= + +Name: res/drawable/file_image.png +SHA1-Digest: Ory2TMW7mANQ+kQBpXEkEmiATWs= + +Name: res/drawable-hdpi/abs__list_pressed_holo_light.9.png +SHA1-Digest: lrdJqITpjN42AK/wk4XF5TW2F3o= + +Name: res/drawable/prev_disabled.png +SHA1-Digest: RQdm581WhsrZBwC8HdzGWQQm1G4= + +Name: res/drawable/plus.png +SHA1-Digest: pMpXmy+CndNOxwrr+B5J4w4iphw= + +Name: assets/zh_CN/qsg.html +SHA1-Digest: oEkFXywdARdww0f2EOlovUG7jwg= + +Name: res/drawable-xhdpi/upload_green.png +SHA1-Digest: krb7Ir2CQGe8ULAckNfpm6ViHeE= + +Name: res/layout/dont_show_again_alert.xml +SHA1-Digest: 33C+BkPykj1hw1CHXjqpWdNCeTM= + +Name: res/drawable-hdpi/abs__ic_voice_search.png +SHA1-Digest: xJSe4BJ4nYKbd+WcV1T2xS5C7Ow= + +Name: res/drawable-mdpi/upload_green.png +SHA1-Digest: 0wmicv11B9J7nFOyGqz9buxoXHU= + +Name: assets/zh_TW/03started_CHT.png +SHA1-Digest: 4thCG4SOiqQ/c7hXIFhi8lzR4ec= + +Name: res/drawable/abs__ic_clear.xml +SHA1-Digest: AnjKtWthsqQULZk99/sIGJSnzAg= + +Name: res/drawable-xhdpi/done.png +SHA1-Digest: qNLm+BKA2mTo5sucg1P47+sJCtY= + +Name: res/drawable-mdpi/abs__cab_background_top_holo_light.9.png +SHA1-Digest: vpL96k3QycLONseeKSz3oaWx9eY= + +Name: res/drawable-hdpi/abs__ab_solid_shadow_holo.9.png +SHA1-Digest: 6OZJVooibrgAG4so7MyBqyoZ1Rw= + +Name: res/layout/network_picker.xml +SHA1-Digest: 8ucReCx0LTuK9A7tz2U98tkNo+k= + +Name: res/drawable-mdpi/abs__tab_selected_focused_holo.9.png +SHA1-Digest: RjbehNC+s+86XH6BAkRT8tX87/s= + +Name: res/drawable-hdpi/grid_dark.png +SHA1-Digest: bv/l0oNM/6xojmTDPG7Gsh7AwCE= + +Name: res/drawable-mdpi/abs__btn_cab_done_default_holo_dark.9.png +SHA1-Digest: Ozw4TlLeSWs8hngXydrlW9kpIRg= + +Name: res/drawable-ldpi/list_dark.png +SHA1-Digest: p8KD1grmc28ukpM5sEz6caaq5LA= + +Name: res/drawable-xhdpi/icon.png +SHA1-Digest: aTowbLou/uvqaOWA3OeF8IkoVlA= + +Name: res/drawable-mdpi/abs__menu_dropdown_panel_holo_light.9.png +SHA1-Digest: T50IgNiJErJZ5L3zMlptrDfcYkA= + +Name: res/drawable-mdpi/abs__btn_cab_done_default_holo_light.9.png +SHA1-Digest: evd0EU/YZFFZwbRyq7iIZV65NZE= + +Name: res/drawable/abs__activated_background_holo_light.xml +SHA1-Digest: FBWGpnGlMqY8RPrk+hRcFMf8KbI= + +Name: res/layout/file_adapter_content.xml +SHA1-Digest: Gt3T5t94Q+r2QSrMG8iKqW0lLdo= + +Name: res/drawable-mdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png +SHA1-Digest: 0Aj78jP3sBP8PkkWsGNC1z2lOQE= + +Name: res/drawable-hdpi/refresh.png +SHA1-Digest: S55rUzlaDEVRMYYFSX8zSshqW0A= + +Name: res/drawable-xhdpi/abs__btn_cab_done_default_holo_light.9.png +SHA1-Digest: UrSk0ksmUU7GG5QwHZgVRtcqKN8= + +Name: res/drawable-xhdpi/download_dark.png +SHA1-Digest: eETLMRWn4DkJ//FSRV0ex4z/7jY= + +Name: res/drawable-xhdpi/movie.png +SHA1-Digest: UotaDgVtsouiUozS8pUwU5ljj/o= + +Name: res/drawable-xhdpi/network_wifi0.png +SHA1-Digest: dHYVoH/BCSO1q3vLBeYsrdGMZiY= + +Name: res/drawable-xhdpi/abs__textfield_search_right_selected_holo_dar + k.9.png +SHA1-Digest: UZN37FsBXN6zAqAGuA/27ev7Abw= + +Name: res/drawable-xhdpi/music.png +SHA1-Digest: AAXWmTvJGXynO8WP1WkGXZ/x4ko= + +Name: res/drawable-xhdpi/delete.png +SHA1-Digest: Vl6ScT2fsW+vHHjFv3PVJQzQCDk= + +Name: res/drawable-hdpi/abs__ab_transparent_dark_holo.9.png +SHA1-Digest: m5QFx1gdJhv0MAkVCkXC3cRnNfo= + +Name: res/drawable-hdpi/abs__cab_background_bottom_holo_light.9.png +SHA1-Digest: fTxB+O/i4iEBg9WIU38rF2dXunA= + +Name: res/drawable-hdpi/abs__spinner_ab_default_holo_dark.9.png +SHA1-Digest: 2rYQimeQPm5hvMbPTxBaNcQkQA8= + +Name: res/drawable-hdpi/abs__tab_selected_focused_holo.9.png +SHA1-Digest: dSOC1a8cXwFnX0u71qyzWpi2+Zw= + +Name: res/drawable-xhdpi/list_dark.png +SHA1-Digest: R/4Aglc02iaYKOMACASzxYmNSlY= + +Name: res/drawable-mdpi/abs__ic_clear_disabled.png +SHA1-Digest: Ki2UTczwfwNOkUEnyx/NMm7GyGA= + +Name: res/layout/abs__action_mode_bar.xml +SHA1-Digest: tlL9SCmRn+5lq0o5Z0a0+DhwpkU= + +Name: res/drawable-xhdpi/abs__list_pressed_holo_dark.9.png +SHA1-Digest: U1NKbASgVgLDtGy9HhgJxUn2c4w= + +Name: res/drawable-xhdpi/abs__ic_go_search_api_holo_light.png +SHA1-Digest: wzA+8Ljcy2akPbprGw4w32gdrOw= + +Name: res/drawable-xhdpi/abs__ic_menu_moreoverflow_normal_holo_light.p + ng +SHA1-Digest: H/D//hjVU/DU3NJd13C1gaei/M8= + +Name: res/layout/analytics.xml +SHA1-Digest: dEyAiP1QhfHgDSpsT+hQgQSuOP4= + +Name: res/drawable-ldpi/notify_a02s.png +SHA1-Digest: niCCuVt1iLzN0EJHqdNI8IIXig8= + +Name: res/drawable-hdpi/abs__ic_menu_share_holo_light.png +SHA1-Digest: qvb0r6mGk80Hbb6FtXQyv/Sv5Uk= + +Name: res/layout/download_picker.xml +SHA1-Digest: j8uGKAJBmGRmHupZJKakBCRzHoA= + +Name: res/layout/abs__activity_chooser_view.xml +SHA1-Digest: b5/Pamx650HKd5U3sy4iCzf13dc= + +Name: res/drawable-ldpi/notify_a01.png +SHA1-Digest: 0Jp6QN+2+5FQeG+U4PPtCZcfYpM= + +Name: res/drawable-xhdpi/abs__ic_voice_search_api_holo_light.png +SHA1-Digest: YCTrsgeKIr16tx32cC2YhAOND+o= + +Name: res/drawable-xhdpi/abs__ab_share_pack_holo_dark.9.png +SHA1-Digest: LWefLX40khiUm1NZGd3ArFBTvMw= + +Name: res/drawable-hdpi/abs__ic_clear_search_api_disabled_holo_light.p + ng +SHA1-Digest: EAwIyhomIP1ZkBoIYaX+LHCgXhI= + +Name: assets/ja/qsg.html +SHA1-Digest: j2EJucBH5tk0BCbo75FTA1ePfFg= + +Name: assets/ko/05content_KOR.png +SHA1-Digest: lhhRj1QrQodjajI3J2tMG8CKLxY= + +Name: assets/en/qsg.html +SHA1-Digest: L4WyriSUCsuotT5sy/joXliau0s= + +Name: com/localytics/android/android_2.16.0.version +SHA1-Digest: 8vmXA1CdlgR4L6RtCP55DSyi/6o= + +Name: res/drawable-mdpi/abs__list_activated_holo.9.png +SHA1-Digest: k0KH726CtUSh87GvbE2iA7vlVBY= + +Name: res/layout/settings_about_eula.xml +SHA1-Digest: alefGbVB6CyA22WkTaLFwNP72hk= + +Name: res/drawable-ldpi/grid_dark.png +SHA1-Digest: XefQGtsfgQzsYdUwcCa4sCySJxQ= + +Name: res/drawable-mdpi/done.png +SHA1-Digest: dRrB78Y6EuXJ33qlfvc8O3T58t8= + +Name: assets/ru/01logo.png +SHA1-Digest: 9LYc9U94Zhdq0aSTWpN/gzvkJOE= + +Name: res/drawable-hdpi/abs__ic_clear_search_api_holo_light.png +SHA1-Digest: vTnHJ3zZ/fr/BUGO7lumSG7aPN4= + +Name: assets/de/03started_GR.png +SHA1-Digest: LoAnMO/v3ThsKZ35mOfAbgdwwvE= + +Name: res/layout/start.xml +SHA1-Digest: 4Z6i8+u5RqhPBKgF7vLB9EHSG5A= + +Name: res/drawable-hdpi/abs__ic_clear_disabled.png +SHA1-Digest: mCEgFmgmOmgpYrPjaKjE6mco9vA= + +Name: res/drawable/local_folder.png +SHA1-Digest: 87+WOFlWO6AAwFEyFazCXftx/sU= + +Name: res/layout/settings_sidelink_help.xml +SHA1-Digest: U6PICtVEJVadftRGi/mMeHvItKU= + +Name: assets/en/04wifi.png +SHA1-Digest: i2oWpZvGaoh8D6oJOMSdY7XQm54= + +Name: assets/ja/05content_JAP.png +SHA1-Digest: XhL+hEKCNQkd+aCd+kh+kyCQato= + +Name: res/drawable/abs__textfield_searchview_holo_dark.xml +SHA1-Digest: lZ9XgP4ybfr9V8R6nQAyLqYJTSk= + +Name: res/drawable-hdpi/abs__spinner_ab_disabled_holo_dark.9.png +SHA1-Digest: 291iL0AV8tlaZg9RNR0sVcA0Xz4= + +Name: assets/ja/03started_JAP.png +SHA1-Digest: Iw2lUovNgd7BGpxpjXRMShkEqa4= + +Name: res/drawable-hdpi/download.png +SHA1-Digest: 0tynPz2gqW7l1z6GZs+ZAsiZXQw= + +Name: res/drawable-mdpi/abs__cab_background_bottom_holo_dark.9.png +SHA1-Digest: n3dtdQ9T0vK71LFyTnyarQ7fxZE= + +Name: res/layout/abs__popup_menu_item_layout.xml +SHA1-Digest: v3o5lftz9eb9C7gT6rsrrJh9PWg= + +Name: res/layout/aircruzer_picker_help_dialog.xml +SHA1-Digest: bQMriOAAryoYSY4CYQdJy7QTSR4= + +Name: res/drawable-ldpi/device_grey.png +SHA1-Digest: EVLUj1xJ5UA9InvK9CjaCfXoWmQ= + +Name: res/drawable-hdpi/plus.png +SHA1-Digest: kgWTdfQphEdmYLgU0sWg3SkQ1oA= + +Name: res/drawable/arrow.png +SHA1-Digest: js2zkZOr1jN1onpDnHIRaCtRsas= + +Name: assets/de/01logo.png +SHA1-Digest: qW7tfDCGqc4stdVQY6xKLJf+pHA= + +Name: res/drawable-xhdpi/wifi4_s.png +SHA1-Digest: BMEFX0MtE3HXC/GuoyUbI2y9fAE= + +Name: res/drawable-hdpi/abs__progress_secondary_holo_dark.9.png +SHA1-Digest: AMuJ/WfMGopnmJb+32Vz3m5Am1g= + +Name: res/drawable/no_internet.png +SHA1-Digest: 6kFc/LiVNvdTd378J+EAjW73uas= + +Name: res/drawable-mdpi/abs__cab_background_bottom_holo_light.9.png +SHA1-Digest: YAD+7uhwn3C0CEVGoxT7j8bucVQ= + +Name: res/drawable-hdpi/abs__ab_share_pack_holo_dark.9.png +SHA1-Digest: buvtfh9lLA0kHo+UdZy9EgSy8oI= + +Name: res/drawable-xhdpi/abs__ic_search.png +SHA1-Digest: kpW6HlG/LB21Na4Li7xUvCDGZgw= + +Name: res/drawable/listselector_selected.xml +SHA1-Digest: HGReVF2qF/QDPhO7G7tzo21C+Dg= + +Name: res/layout/gallery_grid_adapter_content.xml +SHA1-Digest: 5PeytUOBjqp3OmJp421OWJLTv/Q= + +Name: res/drawable-hdpi/list.png +SHA1-Digest: TU1siR5UoHv45/k1KjVXqB+Cizo= + +Name: res/drawable-xhdpi/select.png +SHA1-Digest: kWgP2Ind7BdBPAO4JA9P1i0IAqY= + +Name: res/drawable/charging_0.png +SHA1-Digest: MdboS4toC08CAxgPCPbrln3YfhI= + +Name: res/drawable-xhdpi/upload2.png +SHA1-Digest: AcbXC1MP2a2Zxgu+ykFuhML0Zrc= + +Name: res/drawable-xhdpi/abs__ab_bottom_solid_inverse_holo.9.png +SHA1-Digest: 24/SkEr0uzW3efbr12bid3TOmc4= + +Name: res/drawable-hdpi/download_dark.png +SHA1-Digest: qH6C5nIuc60QOU2tU6v4CZUtO/o= + +Name: res/layout-xlarge/abs__screen_action_bar.xml +SHA1-Digest: tInI78ruYKzZFPwxS79mfk9uyfg= + +Name: res/drawable-xhdpi/abs__progress_bg_holo_light.9.png +SHA1-Digest: 9YJMbOWf99gghxun1lt4eR+M5/0= + +Name: res/layout/aircruzer_adapter_content_section.xml +SHA1-Digest: vOFOzGyr6DS5ZyG/4q9ZvwA2/CQ= + +Name: res/drawable/black.png +SHA1-Digest: YnQOafsw9lxQswFN9ROfmopfVHI= + +Name: res/drawable-mdpi/abs__textfield_search_right_selected_holo_dark + .9.png +SHA1-Digest: z30TT9I43uVknBQFcYGozxadtKg= + +Name: res/drawable-hdpi/delete_dark.png +SHA1-Digest: 5KT758/nYY+QwfbaHRwLsgb6RiM= + +Name: res/drawable-mdpi/abs__textfield_search_right_selected_holo_ligh + t.9.png +SHA1-Digest: 6SqUSlc7AzrADiM8+4UhC0SoNoI= + +Name: res/drawable-hdpi/abs__list_divider_holo_dark.9.png +SHA1-Digest: YCNfTwWWU/kOX50OLTka+djt2a0= + +Name: res/drawable-xhdpi/upload2_dark.png +SHA1-Digest: my824UVeH87Ig9Mjb22p+LmusVI= + +Name: res/layout/abs__action_bar_tab_bar_view.xml +SHA1-Digest: qIFOunmTDNPoxbaXf5Ke+e1Z7/A= + +Name: res/drawable-xhdpi/abs__spinner_ab_focused_holo_light.9.png +SHA1-Digest: EElqPd2sfc94OIfGfM2c6PFhdG0= + +Name: res/drawable/low_white.png +SHA1-Digest: 1K7p7Su15oKaGUrSTjRCMjhkYhU= + +Name: res/layout/direct_connect_warning.xml +SHA1-Digest: fA+3RHqNB1pnJ8jzWxre5c5Mkls= + +Name: res/layout/abs__screen_action_bar_overlay.xml +SHA1-Digest: 3+QVbD58gDSSTchlepS0gA2xUIo= + +Name: res/drawable/play.png +SHA1-Digest: rqy/bcqzDfq8czyEAPHFcrlQthA= + +Name: res/drawable-mdpi/abs__spinner_ab_focused_holo_light.9.png +SHA1-Digest: RlKXmBRG932A/8TUkCqDEp/Oec8= + +Name: res/drawable/grey.png +SHA1-Digest: IaZHlnMauSqa/dH4jDo4FCrK/LA= + +Name: res/drawable-mdpi/abs__ab_share_pack_holo_light.9.png +SHA1-Digest: 5hykmbRZCNgaYVriQNRE6mXKEVw= + +Name: res/drawable-xhdpi/settings_dark.png +SHA1-Digest: WDtudlc+u2w59KmlX6Xx4rGBli4= + +Name: res/drawable-mdpi/movie.png +SHA1-Digest: OparaqzckIJwKZoZbSbh9m6azho= + +Name: res/drawable-xhdpi/abs__spinner_48_inner_holo.png +SHA1-Digest: aZIHa9Czmu4cWLFew7pcXD4rkGc= + +Name: res/drawable/folder_up.png +SHA1-Digest: zGiS10bWvYuuZkpL9DTRTlHDLvA= + +Name: res/drawable/pause.png +SHA1-Digest: p/LZKuBdGLW7xRqzKTYjhcAaQx0= + +Name: res/drawable/a02c.png +SHA1-Digest: txEZZCyYUl2zG05dSRtMgxehdYs= + +Name: res/drawable-ldpi/settings.png +SHA1-Digest: 2u2hCuuJwOjloaeoY/GWcArWkEQ= + +Name: res/drawable-mdpi/abs__textfield_search_right_default_holo_light + .9.png +SHA1-Digest: SJw/VaVPuHa0U3ypOixHPXRhT6s= + +Name: res/drawable-xhdpi/settings_sidelink_grey.png +SHA1-Digest: bvszkCqcT6b08gl54gBxZe9s9Xc= + +Name: res/drawable-xhdpi/settings_timer_grey.png +SHA1-Digest: 8GV4CJNEGoP0aBcnmrB/GiMGSMw= + +Name: res/drawable-xhdpi/wifi1.png +SHA1-Digest: V0mwPuqE+FwkmKAtWqI+COlgnOY= + +Name: res/drawable-mdpi/abs__btn_cab_done_pressed_holo_light.9.png +SHA1-Digest: vLrFK/b+U1ubMj5LsccQrZPqhPI= + +Name: res/drawable-mdpi/upload2_dark.png +SHA1-Digest: hO6TyHKEn/0pJY/QeUxOb3uHtFs= + +Name: res/drawable-mdpi/abs__ab_transparent_dark_holo.9.png +SHA1-Digest: fFPUiwdMkRL8REn+TBfT9FX9St4= + +Name: res/drawable-hdpi/abs__spinner_ab_pressed_holo_light.9.png +SHA1-Digest: GIl5naK+PDdSFWeTucie7Fi+y4g= + +Name: res/drawable/abs__textfield_searchview_holo_light.xml +SHA1-Digest: VD8f3CF3zy2PqjZIXCkVHdU/AN0= + +Name: res/drawable-hdpi/abs__ic_ab_back_holo_dark.png +SHA1-Digest: VDbZBKRiIQomKwJ0F40Cm1Sj5uY= + +Name: res/raw/wfd1080e.df2 +SHA1-Digest: sHEo1rEX5Mqidlpdt9sD+seOla4= + +Name: res/layout/music.xml +SHA1-Digest: 2OopLHtVH5gXjrASxOl9UjK1LCQ= + +Name: res/raw/tf.properties +SHA1-Digest: 6BRhUHhf+UzjzmmTNS1S4cucWWs= + +Name: res/drawable/abs__textfield_searchview_right_holo_dark.xml +SHA1-Digest: oipbNanAw9eMKi1Qw+sRRlUUi3k= + +Name: res/drawable-mdpi/abs__ab_bottom_solid_dark_holo.9.png +SHA1-Digest: p6tVNDTsfPGyFyOWCgiBaoFubkw= + +Name: res/drawable-xhdpi/delete_dark.png +SHA1-Digest: ceF15u3WmpNaJ05eNU1WQ4Dv01E= + +Name: res/drawable/abs__progress_medium_holo.xml +SHA1-Digest: trNhx12sy3B5XvcizljpAUZBHIk= + +Name: res/drawable-mdpi/abs__ab_solid_light_holo.9.png +SHA1-Digest: cc9HP9JERZ4SEB2R/uVFpxvb0wc= + +Name: res/layout/abs__search_view.xml +SHA1-Digest: Ndlm3XZmkd7Db9ZKJbWeJjSGt+A= + +Name: res/drawable-mdpi/icon.png +SHA1-Digest: 7AsZxVhBGvf4wPHtlmnWNGqIYVM= + +Name: res/drawable-ldpi/list.png +SHA1-Digest: /sqKL1CnKMdqxCPHVjUJmKsRDo4= + +Name: assets/zh_CN/02qsg_CHS.png +SHA1-Digest: uTDpSJvBQ15kSO1snJHPQaJFpdw= + +Name: res/drawable-xhdpi/settings_network.png +SHA1-Digest: KTUQfCPhDyIOe2Ppj1eDmaMrXFg= + +Name: res/drawable-xhdpi/settings_timer.png +SHA1-Digest: pHrM3ucxoitKzGY4w2E6Hkjyvks= + +Name: assets/de/04wifi_GR.png +SHA1-Digest: QXgViToZCxXJYiGeAt0jHJSbFnk= + +Name: res/drawable-ldpi/download_dark.png +SHA1-Digest: 2B3FtazIkI9m4lpPTtnCOS+Uqm0= + +Name: res/layout/abs__action_menu_item_layout.xml +SHA1-Digest: 93CV9NDXHj63/bMPoP4TODrHiNo= + +Name: res/drawable-mdpi/abs__list_focused_holo.9.png +SHA1-Digest: 1b4m7iHvagnqjBF0Gnh86BXoTCk= + +Name: res/drawable-xhdpi/splash.png +SHA1-Digest: LzyJobE3wHBtXSbxJxBg34YIRUo= + +Name: res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_light.pn + g +SHA1-Digest: 3HHEb108EIEBDzuTgU746xkNAyc= + +Name: res/drawable-xhdpi/network_wifi3.png +SHA1-Digest: FJnZsm9LSNIMpxAKW/BuXJonAy8= + +Name: assets/en/02qsg.png +SHA1-Digest: sEG/wup+akbOSY58s0hX7F6sG4U= + +Name: res/drawable-mdpi/abs__list_selector_disabled_holo_dark.9.png +SHA1-Digest: MmgEts7b+pXpZo60FkneU4V9Ikk= + +Name: res/drawable/abs__tab_indicator_ab_holo.xml +SHA1-Digest: b7UIuAS0Dejggi+d5oSd15fiAvo= + +Name: res/drawable/listselector_pressed.xml +SHA1-Digest: x1zv0qC+0wa+TN4MwSANxttsZCY= + +Name: res/drawable-hdpi/abs__ab_share_pack_holo_light.9.png +SHA1-Digest: +OAYzol7cPv79GCck1P8FViGZ6I= + +Name: res/drawable/file_png.png +SHA1-Digest: Xl0BUMo9fGAOXIPgPCV6v9tNihw= + +Name: res/drawable/file_audio.png +SHA1-Digest: lqiwfnPeLfN+K+IK9smgw9LdI6Y= + +Name: res/drawable-xhdpi/abs__ic_cab_done_holo_light.png +SHA1-Digest: K2TYdGXesGTqgwQKZZjUuYN+FKo= + +Name: res/drawable-xhdpi/notify_a02.png +SHA1-Digest: BDWoK0m9ZN//ZSTax3IjAhGF1Qs= + +Name: res/layout/wifi_password_alert.xml +SHA1-Digest: fzM4SEwg2trrkgPTwe9KnnY94wo= + +Name: res/drawable-hdpi/abs__menu_dropdown_panel_holo_light.9.png +SHA1-Digest: JtAGOrkjcRDhvzDp+tDWF0PB8Kg= + +Name: res/drawable-ldpi/create_folder.png +SHA1-Digest: 4EnTKjDSCifHHQLfIQuBjlPUCfo= + +Name: res/layout/directory_adapter_content.xml +SHA1-Digest: TUtHiiXlqbu950RmL1KxbLGcXOc= + +Name: res/drawable-xhdpi/abs__ic_ab_back_holo_dark.png +SHA1-Digest: lSv/xuS4TTivmon6OOoCf+LZ674= + +Name: res/drawable-hdpi/abs__progress_bg_holo_light.9.png +SHA1-Digest: CNd/vAB/oYwEmcSpXU/aAnYGokI= + +Name: res/drawable-hdpi/abs__progress_bg_holo_dark.9.png +SHA1-Digest: Iw89Sp82/2Wj0jf2QyfcdVW4ePg= + +Name: res/drawable-mdpi/abs__ic_voice_search.png +SHA1-Digest: 2cQ6aixRzb6Ul8O9p1mVDwf4ScA= + +Name: res/drawable-hdpi/abs__spinner_ab_focused_holo_dark.9.png +SHA1-Digest: 9Qy3cVDSKr4octE+oPpmMxc3WbE= + +Name: res/drawable-hdpi/abs__list_longpressed_holo.9.png +SHA1-Digest: ptbz3lQejuYwZajfM9QuW+tPTNo= + +Name: res/drawable-hdpi/abs__ic_menu_moreoverflow_normal_holo_dark.png +SHA1-Digest: jmiYAK3bhvluugEnQppgwzIaO1I= + +Name: res/drawable/medium_white.png +SHA1-Digest: O6bHBZhzTcLAtuTeFI5y+gm79Jg= + +Name: res/drawable/abs__item_background_holo_light.xml +SHA1-Digest: WA7mgT2GElk7GkfzrytZKY+AKoY= + +Name: res/drawable-xhdpi/play_notify +SHA1-Digest: owCE1vx8jJW2TwuANPXyPvF+3ec= + +Name: res/drawable-mdpi/abs__tab_selected_pressed_holo.9.png +SHA1-Digest: 8GgxToDPNPXEylKDthpLy4Ick+4= + +Name: res/drawable-hdpi/done.png +SHA1-Digest: d6dkBw8alNn6Id9nKA5gcknRaJI= + +Name: res/drawable-xhdpi/settings_security.png +SHA1-Digest: HvbKAuHdGu4756CjvqJiSdO5+iA= + +Name: res/drawable/abs__btn_cab_done_holo_light.xml +SHA1-Digest: b+Cr90laDoTc5pshyXL4QO1vuWE= + +Name: res/drawable-xhdpi/abs__ic_clear_disabled.png +SHA1-Digest: ON7Cgoqj1QbPTbGfYNzqsOG+Yc4= + +Name: res/drawable-hdpi/download_dark_green.png +SHA1-Digest: ZpkxcjGxOA8REafMEKrzIKaBS8I= + +Name: res/drawable-hdpi/abs__ab_bottom_solid_inverse_holo.9.png +SHA1-Digest: i/uYhSEBxB7ovRwrIQwhBn7UXxE= + +Name: res/drawable-hdpi/abs__tab_selected_pressed_holo.9.png +SHA1-Digest: Mf5vFOmXvP3L4a4yavvUzcmRIt8= + +Name: res/drawable-hdpi/abs__btn_cab_done_pressed_holo_dark.9.png +SHA1-Digest: TZEzVRjCGPdf7ndrvVIwkRdTh3c= + +Name: res/drawable-xhdpi/connected.png +SHA1-Digest: HREB+S4CHtoRyQ1u2/Jzp0H68yA= + +Name: res/drawable-ldpi/create_folder_dark.png +SHA1-Digest: LvKzNGKfgbfeARVTfJjhnuUgqZ8= + +Name: res/drawable-xhdpi/abs__ic_clear_search_api_disabled_holo_light. + png +SHA1-Digest: 4dxIw+kLWuioJNO5uLBGXvWElrE= + +Name: res/drawable/popup_shape2.xml +SHA1-Digest: U+KLl3TPDVOTOj/JnlH8HceMvrs= + +Name: res/drawable-mdpi/abs__textfield_search_right_default_holo_dark. + 9.png +SHA1-Digest: 8VagCEC6/bxS8EIG7vXlA3zIyLo= + +Name: res/drawable/blue.png +SHA1-Digest: gs/siuek95dKch+pAv8rphP+rho= + +Name: res/layout/music_land.xml +SHA1-Digest: EnbsCyHIpqnw/cpaYwzQWCIkFJM= + +Name: com/localytics/android/LICENSE +SHA1-Digest: 4BcmJZv12VBnnPvyPDfhtrzWRzQ= + +Name: res/drawable-hdpi/abs__ab_stacked_transparent_dark_holo.9.png +SHA1-Digest: GtmhIZtPpidOUSNn6lLVxhCaCCo= + +Name: res/layout/abs__list_menu_item_layout.xml +SHA1-Digest: D/6MKz0WdxdHUY3mQrOf25dDegU= + +Name: res/drawable-ldpi/download_green.png +SHA1-Digest: hJfnTiPcJw/DvBrbfuoH1jLmkf8= + +Name: res/drawable-xhdpi/abs__ab_stacked_solid_light_holo.9.png +SHA1-Digest: 42971/d6vUeJwpIgA/Gna2Xuny8= + +Name: res/layout/abs__list_menu_item_checkbox.xml +SHA1-Digest: 9geAr2WyoUVyLj8BV2Yu+r/k0LE= + +Name: res/drawable-mdpi/abs__spinner_ab_focused_holo_dark.9.png +SHA1-Digest: zgXeuD+vtHQLeG2Fx0Z+o3WNMdQ= + +Name: res/drawable-mdpi/splash.png +SHA1-Digest: lPdgz8+upRrYKwTC2CvqhbZHi0M= + +Name: res/drawable-hdpi/abs__textfield_search_right_default_holo_light + .9.png +SHA1-Digest: ULSjXVIfOXQcnuwbICfFh+SOOhw= + +Name: res/drawable-mdpi/abs__textfield_search_selected_holo_light.9.pn + g +SHA1-Digest: KGb4v13B/xvVShXDLo3AjuomrkY= + +Name: res/drawable/music_thumb.png +SHA1-Digest: cgE5iK2JXMxiWDvXz0Ki67YaOXg= + +Name: res/drawable-xhdpi/network_wifi3_s.png +SHA1-Digest: RWgn1emiga8Uhu7w1rUGse/iSnY= + +Name: res/drawable-ldpi/select_dark.png +SHA1-Digest: KPP11g/89Ew0LoUPxCDJwVRVDXM= + +Name: res/drawable-hdpi/play_notify.png +SHA1-Digest: YHAMAjbWFXrv1Eh1x2FxlPnFfk8= + +Name: res/drawable-xhdpi/abs__tab_selected_pressed_holo.9.png +SHA1-Digest: qE6ZWVBFFV5unAqK1PvQv1Ern7Q= + +Name: res/drawable-hdpi/abs__textfield_search_right_selected_holo_ligh + t.9.png +SHA1-Digest: ebcbPkpiwha21xEUChjWbqxLHS0= + +Name: res/drawable/abs__list_selector_holo_light.xml +SHA1-Digest: tB/l4CCgS0Wh5RIhmVPIYbk7RCA= + +Name: res/drawable-xhdpi/network_wifi4.png +SHA1-Digest: tuGik8Wx6scGg9Ii0eRQj+8vEtM= + +Name: res/drawable/a02s_grey.png +SHA1-Digest: 4FZw1xNuME04KC3S9kuIhbCXyEQ= + +Name: res/drawable-xlarge-hdpi/icon.png +SHA1-Digest: vAYOXfhLgLKl72MHOqpn4/Kfn+M= + +Name: res/drawable-xhdpi/wifi3.png +SHA1-Digest: bM1a2TY4H7myCHsfb8JsWFbk5gw= + +Name: res/drawable-hdpi/abs__dialog_full_holo_light.9.png +SHA1-Digest: ZCSC9S6+GRAUiRe/f4jJy7XdSL8= + +Name: res/layout/aircruzer_adapter_content_local.xml +SHA1-Digest: dkxhvXDAfYv+5/BiQLVbwQI2VSo= + +Name: res/drawable/charging_1.png +SHA1-Digest: 83AW2LewcgO5yl1cBbLFTn4R+fM= + +Name: res/drawable-xhdpi/settings.png +SHA1-Digest: bZkzyG0mdGDnG9zFWPR5dnQ6UM0= + +Name: res/drawable-ldpi/splash.png +SHA1-Digest: LlkmGY/uHgyRIExv+JK6VWn/jGQ= + +Name: res/drawable-xhdpi/abs__list_focused_holo.9.png +SHA1-Digest: 0mOu8ySPTJmpXlpXy7GxY1V24q4= + +Name: res/drawable-xhdpi/abs__list_pressed_holo_light.9.png +SHA1-Digest: PX78/hIq2CPfClViMSNz77lrsyQ= + +Name: res/drawable-xhdpi/abs__progress_secondary_holo_light.9.png +SHA1-Digest: cPjnoGeC0yi3ZMj8J8epbvvsY9I= + +Name: res/layout/abs__screen_simple_overlay_action_mode.xml +SHA1-Digest: JDBEQ53itxIur9vO2Atn+8yJ7c8= + +Name: res/drawable-mdpi/abs__btn_cab_done_pressed_holo_dark.9.png +SHA1-Digest: tNiemBq98Ef/8/SbxysQ0tq6SK4= + +Name: res/drawable-mdpi/create_folder.png +SHA1-Digest: O21GsKo5pCcYVBU6psPUHbPovbo= + +Name: res/drawable/abs__ic_menu_moreoverflow_holo_dark.xml +SHA1-Digest: yytAWQRt22+riAvgs/KwyMqUvQ4= + +Name: res/drawable-ldpi/grid.png +SHA1-Digest: iNXgBO748cIsUiLwbRftq2SXRds= + +Name: res/drawable-mdpi/device_grey.png +SHA1-Digest: RHXuHZm/A6qkIbhh92Nj1kpfyY0= + +Name: res/drawable-mdpi/play_notify.png +SHA1-Digest: 0NqdGg8tJvp/Yhr52YdXbLor7t8= + +Name: res/drawable-hdpi/abs__textfield_search_default_holo_dark.9.png +SHA1-Digest: LP7ewvwEXSoRqeZjIh4nOeaAtK8= + +Name: res/drawable-xhdpi/abs__tab_selected_focused_holo.9.png +SHA1-Digest: kRe4KL9tEOxTt3bkKH9ClWLAUCE= + +Name: res/drawable-ldpi/select.png +SHA1-Digest: 5RbbNoA818p1wtemKnXiPyU4qCg= + +Name: res/drawable-hdpi/delete.png +SHA1-Digest: 5Bq2Ic1TDFy9EDte4VlaQ9rn4XU= + +Name: res/drawable/battery_grey.png +SHA1-Digest: tsn4J4NlgqXxVjIp2W1wl0kXnIg= + +Name: res/xml/settings_about.xml +SHA1-Digest: oMSFlToKbNQlcNx9b7XqE1vFQ+c= + +Name: res/drawable-hdpi/abs__ic_go_search_api_holo_light.png +SHA1-Digest: 3vHQpcaPDNb6NwjQQWZxhxNJ+qc= + +Name: res/layout/aircruzer_adapter_content_none.xml +SHA1-Digest: g0S8lGEdmybe9pLERtYIr+QCaY4= + +Name: res/drawable-mdpi/abs__list_longpressed_holo.9.png +SHA1-Digest: ofVU9an1TNZwFC7R06NqpuPJPdQ= + +Name: res/drawable/abs__ic_clear_holo_light.xml +SHA1-Digest: sAhzgH2jM2Kc7Y2iY5oBJmCG5GE= + +Name: res/drawable-ldpi/notify_a02c.png +SHA1-Digest: SiX8FML4Qmck0hsqKpoXnJ7M/Sw= + +Name: res/drawable/check.png +SHA1-Digest: KSW+XCCpV+qwJVdjGhwKsFSwbS8= + +Name: res/layout/abs__action_menu_layout.xml +SHA1-Digest: mJKypCro6tPIH9JEh3UY3bEZGEI= + +Name: res/drawable/file_zip.png +SHA1-Digest: NUpT9WWHpc2+ynz12nSVJjwKd0w= + +Name: res/drawable-xhdpi/abs__ab_bottom_solid_light_holo.9.png +SHA1-Digest: Rk+UnlSVvdbnqPvNBdXZj8dcQQ0= + +Name: assets/es/01logo.png +SHA1-Digest: 6lO2tdvGxHwanoenLLbvEsh80mc= + +Name: res/drawable-xhdpi/abs__progress_secondary_holo_dark.9.png +SHA1-Digest: e5a8M4qM7fMxfi8+e2DXwULdfk0= + +Name: res/layout/sherlock_spinner_item.xml +SHA1-Digest: xi/7SS4dFtpNDXRM2jsbqgXEltM= + +Name: res/layout/hidden_network.xml +SHA1-Digest: hykpxnGRp26LCmYMH7WfD1+5ERw= + +Name: res/drawable-xhdpi/abs__ic_go.png +SHA1-Digest: tINOgi0AQI11mwL/d1BPQRmhUdY= + +Name: res/drawable-ldpi/pause_notify +SHA1-Digest: XiwedbO3Yy4d/iewdOxeAizPGII= + +Name: res/layout/splash.xml +SHA1-Digest: /WB8Z6fSj+6dJTUbNNjBMJ9fT3E= + +Name: res/drawable-xhdpi/download.png +SHA1-Digest: 3alYi8wYqlI5vcgPkrdg9IZElnY= + +Name: res/drawable-mdpi/abs__list_divider_holo_dark.9.png +SHA1-Digest: Gd+qeBN+Z3tgHThuwqx4TQqImNs= + +Name: res/drawable-xhdpi/settings_reset.png +SHA1-Digest: rLtEo4LohNmqxIh6jx9cRfbsvPQ= + +Name: res/drawable-mdpi/abs__tab_unselected_pressed_holo.9.png +SHA1-Digest: kPvBAWN9SqQ9WZ8eBXVYJN/XHP8= + +Name: res/drawable/next_disabled.png +SHA1-Digest: 4SrIAQ8IqbikAc/lXvPTTFA2sE0= + +Name: res/layout/abs__screen_simple.xml +SHA1-Digest: YdjPW96dc/dh7hiPo0SqCP+C/XQ= + +Name: res/drawable-xhdpi/abs__ab_bottom_transparent_dark_holo.9.png +SHA1-Digest: HaZOB2hoLzJiT9qTW+qyRWWKe88= + +Name: res/drawable-xhdpi/abs__ab_transparent_light_holo.9.png +SHA1-Digest: WImLTFqzDvKO744H1EGNHKmlvLU= + +Name: res/xml/settings_feedback.xml +SHA1-Digest: joazs6DwTqCGpix20gFyrqmfSmE= + +Name: res/drawable-xhdpi/abs__progress_primary_holo_dark.9.png +SHA1-Digest: HLr/+AacVzhb/bgm8wqo5lkMmdQ= + +Name: res/drawable-mdpi/abs__ic_clear_search_api_holo_light.png +SHA1-Digest: DKBAKHuPA9O+9U3MbN+9PMTd9xQ= + +Name: res/color/abs__primary_text_holo_light.xml +SHA1-Digest: TMBEJ/Z81lGmX1DQM1OFwc0XHPM= + +Name: res/drawable/charging_3.png +SHA1-Digest: xMFafkBI64FCG7RCF15slUvMvf4= + +Name: res/drawable-mdpi/abs__btn_cab_done_focused_holo_dark.9.png +SHA1-Digest: qbSomUVZ3g5AkIAMKg2tBPBu5vs= + +Name: res/drawable-hdpi/abs__ab_bottom_solid_light_holo.9.png +SHA1-Digest: FijKux+wp7sVe29uZWpywpBFs74= + +Name: res/drawable-xhdpi/settings_network_grey.png +SHA1-Digest: OTJeILm9xSIiD1ZZeDnzmx7uAPo= + +Name: res/drawable-mdpi/abs__ic_search_api_holo_light.png +SHA1-Digest: CsoOtUAuNL2i3uSajkq7Fj1fHQI= + +Name: res/drawable/file_video.png +SHA1-Digest: ZKhuBm15KrQQmnCDgYH9pXvxs+A= + +Name: res/drawable/prev_enabled.png +SHA1-Digest: 5GklvDtWPEtnzayUBXxC49h/igE= + +Name: res/layout/abs__action_bar_home.xml +SHA1-Digest: KIYReYcyBICFmvLPVImAr7hKrQc= + +Name: res/layout/pictures.xml +SHA1-Digest: Y+aGuOCtcygPgODqtlRDaLJ7rbM= + +Name: res/drawable/device_help.png +SHA1-Digest: 7oy7tO6OC6/alEjvkRoaRe7CNDQ= + +Name: res/layout/file_transfer.xml +SHA1-Digest: 5oSyGatb2Q33JeE/6jkaAYTIUa8= + +Name: res/layout-xlarge/abs__screen_action_bar_overlay.xml +SHA1-Digest: L4rSLNSmnZnrmxkMEDyoFZ7hTz8= + +Name: resources.arsc +SHA1-Digest: AOdcjOejlDj15vX8jZuEvNKoj0Y= + +Name: assets/ja/04wifi_JAP.png +SHA1-Digest: Gkr2IGTYf5L5HbWPl/4qpHBxv0s= + +Name: res/drawable-mdpi/list_dark.png +SHA1-Digest: HAgDWDwW1fCnKBvddNgdXRSrFFo= + +Name: res/drawable-xhdpi/abs__ab_bottom_transparent_light_holo.9.png +SHA1-Digest: dsRruh5Id/KSS3uk7sx/eDAJ6D8= + +Name: assets/fr/05content_FR.png +SHA1-Digest: WK6x6XeWxlkinLgf4mVFR2uYq9A= + +Name: res/drawable-xhdpi/select_dark.png +SHA1-Digest: D4teduTfSRTar2n/cFBMdzxMdQ0= + +Name: res/drawable-mdpi/abs__list_pressed_holo_light.9.png +SHA1-Digest: EhSQaJxdK46gwcaPHBdrPDX32g0= + +Name: res/drawable-hdpi/upload_green_dark.png +SHA1-Digest: Gp22qIgeqXjcrw0W5lfX+v4iCJE= + +Name: res/drawable-hdpi/notify_a01.png +SHA1-Digest: /9FXEmJVN4GfZwk4YF3uoIlEbS4= + +Name: res/drawable-xhdpi/wifi2.png +SHA1-Digest: 95pF+tdEjBmdjL1gviqVJw6lDlM= + +Name: res/drawable-mdpi/abs__spinner_ab_disabled_holo_dark.9.png +SHA1-Digest: pft58stbqE33Gn17frV/Ljb/Kzw= + +Name: assets/zh_TW/02qsg_CHT.png +SHA1-Digest: sz4F8DYtnO3Lj4KgCvCo2JoPTjY= + +Name: res/drawable/abs__progress_horizontal_holo_dark.xml +SHA1-Digest: /iEzfNZEugl/G6N8Qh681QQNPSc= + +Name: res/drawable-mdpi/abs__textfield_search_default_holo_light.9.png +SHA1-Digest: CQ6w/WUKC9TGwDG4iBNIfwygOEY= + +Name: res/drawable-xhdpi/abs__spinner_ab_default_holo_dark.9.png +SHA1-Digest: 4DLHmynxKoSzQ5KMSUXuBamO9Pk= + +Name: res/drawable/cancel_button.png +SHA1-Digest: 2N+HXAEPUZlZFnYjEcWfYHtFD94= + +Name: res/drawable-xhdpi/settings_security_grey.png +SHA1-Digest: N72L8sShlZ5DxtZwOqPAYxs9SbY= + +Name: res/drawable-mdpi/pause_notify.png +SHA1-Digest: RU//matac19t0QA3+vQ+N63x9wM= + +Name: res/layout/abs__action_mode_close_item.xml +SHA1-Digest: hwhqd7uq6RH+ijxf4Ab+Qk+IYXg= + +Name: res/drawable-ldpi/delete_dark.png +SHA1-Digest: JgGw77odr4HQh8vs/uP2/afN+hc= + +Name: res/drawable-xhdpi/abs__menu_dropdown_panel_holo_light.9.png +SHA1-Digest: pMm8lMp8FURZNb9srHCre3oiwJI= + +Name: res/drawable-hdpi/select_dark.png +SHA1-Digest: WaA/n5tW3BNOTC1MxTx+6TohJnQ= + +Name: res/drawable-hdpi/abs__ic_search_api_holo_light.png +SHA1-Digest: 15tQ2OsywNpdQGDL4yWxR3xWDMI= + +Name: res/drawable-mdpi/abs__spinner_48_outer_holo.png +SHA1-Digest: E8JKf9W+nZlbdfhR4O6pmB6q14c= + +Name: assets/zh_TW/01logo.png +SHA1-Digest: 0W1bsYYaXn4jKG5GA/iApSQvxGM= + +Name: res/drawable-xhdpi/abs__textfield_search_default_holo_dark.9.png +SHA1-Digest: pUJrNEalrEwaKjtoYc52KMFxCMI= + +Name: res/drawable-xhdpi/notify_a02s.png +SHA1-Digest: eQ47U1UQ29rnBMb/69rI2l3i+4I= + +Name: res/drawable-mdpi/abs__ic_ab_back_holo_light.png +SHA1-Digest: 10yFmnAzVd9nqe/1O6tP08Wez+8= + +Name: res/drawable-hdpi/abs__tab_unselected_pressed_holo.9.png +SHA1-Digest: Vpdsk41m+u+Wbl3upUMCWRcaeoY= + +Name: res/drawable-hdpi/abs__btn_cab_done_default_holo_dark.9.png +SHA1-Digest: 9GJ7L2ZtqG84hy6LHRjFWwcdE/k= + +Name: res/drawable-hdpi/splash.png +SHA1-Digest: 1Q50V2CQqHo3e85aCgLHO4grec8= + +Name: res/drawable-hdpi/abs__ic_menu_share_holo_dark.png +SHA1-Digest: zAKWgUZl3wPFGrOGVpY70sUWvy8= + +Name: res/drawable-xhdpi/wifi2_s.png +SHA1-Digest: 6q5ezoORs2l9OP8gvI08Uk13DBs= + +Name: res/drawable-hdpi/movie.png +SHA1-Digest: 9+CtEKfcIiye8Sdj37EYQiTkaac= + +Name: res/drawable-hdpi/abs__ic_cab_done_holo_dark.png +SHA1-Digest: Ero5pbYBER8pLL3KDqfMLnpZrB0= + +Name: res/drawable-xhdpi/create_folder.png +SHA1-Digest: 6PHv1VvAF8whY89yk+r21vi1YeY= + +Name: assets/en/03started.png +SHA1-Digest: YepkV8EGsV8FRDC1iK4W/5YTx24= + +Name: res/drawable-xhdpi/abs__ab_solid_shadow_holo.9.png +SHA1-Digest: FJZmzxRSPFoBpogPOl83SIHWqpA= + +Name: res/drawable-mdpi/abs__ab_bottom_solid_light_holo.9.png +SHA1-Digest: fOTKaFY42kIg155GSxafkHby9Ew= + +Name: res/drawable-xhdpi/abs__textfield_search_selected_holo_dark.9.pn + g +SHA1-Digest: A8dGiqWEuPdhlm8kq0ijFWmFcRE= + +Name: res/drawable-hdpi/abs__ab_bottom_transparent_light_holo.9.png +SHA1-Digest: 4WNj5DtsCo/3Ywz8axx5PibIeR4= + +Name: res/drawable-hdpi/upload2.png +SHA1-Digest: bZ7pi7b/pyEb0wVhSQapIn7OHXU= + +Name: res/drawable-hdpi/abs__spinner_ab_disabled_holo_light.9.png +SHA1-Digest: t0M0ZoitoGmS8/fuC3/iZHwUQjA= + +Name: res/xml/settings_debug.xml +SHA1-Digest: KIGMtGcGh0FMtnAm/36elR8mD+c= + +Name: res/drawable-xhdpi/abs__tab_selected_holo.9.png +SHA1-Digest: sCAniYVYx5jXdqQhumf4Kn8uoHk= + +Name: res/drawable-hdpi/abs__btn_cab_done_focused_holo_dark.9.png +SHA1-Digest: 4iHqV7E+BRvqEi6eouyDhUKu0/0= + +Name: res/drawable/abs__spinner_ab_holo_dark.xml +SHA1-Digest: urMnXXwa6vOhuZDQh0y2OXC/IGM= + +Name: res/drawable-mdpi/abs__spinner_ab_default_holo_light.9.png +SHA1-Digest: UMvtqC6hnVlluJzlyGv4xoHdabo= + +Name: assets/zh_CN/03started_CHS.png +SHA1-Digest: 24aEpnmdCqGUtLPJLQQVtlXjgUI= + +Name: res/drawable/file_pdf.png +SHA1-Digest: aX7qIO2ozG08Mnfv+Cltizw8al0= + +Name: res/drawable-hdpi/device_grey.png +SHA1-Digest: ooCJs95RM1AyB+zYQ2p6l4Cqq0U= + +Name: assets/ko/qsg.html +SHA1-Digest: e+SkNz6Jz3RFUYNR1viwovEWG/M= + +Name: res/drawable-large-hdpi/icon.png +SHA1-Digest: DHU4AKxG4eEU6+qYyaGR19OUEDY= + +Name: res/drawable/abs__progress_horizontal_holo_light.xml +SHA1-Digest: /L8kPO0mRknMvMwfLlIrUAaTTt8= + +Name: assets/ru/qsg.html +SHA1-Digest: GBsPynPcCrrCo3Poo15DMu5tJUE= + +Name: res/drawable-mdpi/abs__ab_stacked_transparent_light_holo.9.png +SHA1-Digest: EB0i/t/645Q1BJg7chPIn9oYscA= + +Name: res/drawable-xhdpi/abs__cab_background_bottom_holo_light.9.png +SHA1-Digest: 8WG4say21Rxg04ifomofY/O/rTM= + +Name: res/drawable-xhdpi/abs__ab_share_pack_holo_light.9.png +SHA1-Digest: umYg99YgbHOqlsvLBKv314XbJd4= + +Name: res/drawable-hdpi/settings_dark.png +SHA1-Digest: 25yJZ+6TAJwiV+CoZLER9RHyVqI= + +Name: res/drawable-hdpi/abs__ic_cab_done_holo_light.png +SHA1-Digest: zKfmdx+Pi5Y3QzyfnABhh0Y9JaM= + +Name: res/drawable/a01.png +SHA1-Digest: qswVdcK/Mkcz7n7sMxsN/APEWnw= + +Name: res/drawable-hdpi/create_folder.png +SHA1-Digest: UI9PaD3b04YPFzhQ8Y2J/e9hSK8= + +Name: res/layout/main.xml +SHA1-Digest: kYzSlOcQwsIusv6X48t2TMsLx5s= + +Name: res/drawable-xhdpi/abs__cab_background_top_holo_light.9.png +SHA1-Digest: 7wvjARiCpNkOl2QCtebZs8NrjLc= + +Name: res/drawable-ldpi/play_notify.png +SHA1-Digest: SpG2XuOdBqgWwz/e7th+Yvz/kV4= + +Name: res/color/abs__primary_text_holo_dark.xml +SHA1-Digest: HVRO2FBI+gYE9X5wemcGtM1oyaY= + +Name: res/drawable-xhdpi/grid_dark.png +SHA1-Digest: ikU16xRrTT//SbcSEqF2Alz7SII= + +Name: res/drawable-mdpi/select.png +SHA1-Digest: m8lLugXjSty3fTMFw/j1Pd0U808= + +Name: res/drawable-xhdpi/wifi0.png +SHA1-Digest: vE1dCQihcOwp1E0FLLXAP5OrU2s= + +Name: res/drawable-xhdpi/download_green.png +SHA1-Digest: /0uzvlJcozYhy15dMGyO2BTKn+o= + +Name: res/drawable/critical.png +SHA1-Digest: GDnLJjl5ZEsh/grYG2qqucxq03s= + +Name: res/drawable-xhdpi/settings_sidelink.png +SHA1-Digest: +4O2kFI+9KwZ/yWhZq8vZZC6s24= + +Name: res/drawable-mdpi/abs__textfield_search_default_holo_dark.9.png +SHA1-Digest: JgbWimYZh49npVxJzioTzJx4xwA= + +Name: res/drawable-xhdpi/abs__ab_stacked_transparent_light_holo.9.png +SHA1-Digest: 8H5fbl+EvKr+AasaFM+1NLJ2/8A= + +Name: res/color/abs__primary_text_disable_only_holo_light.xml +SHA1-Digest: 0heuKJ50dGM08+pzBXy7qx+4hLE= + +Name: res/drawable-mdpi/download_dark_green.png +SHA1-Digest: eKXyoxe0gMWi169cnUx4wLM6BAk= + +Name: res/drawable-xhdpi/abs__ic_menu_share_holo_dark.png +SHA1-Digest: SbXpQTQd3txNn3aJ9x68LoTCQ88= + +Name: res/drawable-ldpi/done.png +SHA1-Digest: sxs8KwhcexovGfsJ2H60BvZA8pw= + +Name: res/drawable-xhdpi/create_folder_dark.png +SHA1-Digest: o4GIGaz/KT/UdmdB+ZIg/Vx7N8s= + +Name: res/drawable-xhdpi/network_wifi0_s.png +SHA1-Digest: HLlFLOGbkebGqZ2sgSQNlyWAsjQ= + +Name: res/drawable-mdpi/abs__ic_cab_done_holo_dark.png +SHA1-Digest: EI7CPUaZ64UwAcjU3VG8arft8MA= + +Name: res/layout/picture_loading.xml +SHA1-Digest: iIrsj2N4XYlqAeaHNhUZPbTBLxk= + +Name: res/drawable/gallery.png +SHA1-Digest: GIU7SukIY04mEdoD86nS30nWrbQ= + +Name: res/drawable-xhdpi/settings_guide.png +SHA1-Digest: oCqrB34SPX9UDH1a6vOf0WGRTO0= + +Name: res/drawable-xhdpi/wifi4.png +SHA1-Digest: tgswmOaliCmfGroGHukJCElVUqI= + +Name: res/drawable-hdpi/abs__btn_cab_done_default_holo_light.9.png +SHA1-Digest: C3CVfhWItXYX5VuhOv3Tr987jDw= + +Name: res/drawable-hdpi/download_green.png +SHA1-Digest: QwU5fEV+RKZj4KW8Gkv/Gg1U7G8= + +Name: res/drawable-mdpi/abs__btn_cab_done_focused_holo_light.9.png +SHA1-Digest: Iv9+d8iSlqYeG85x2ip3PC+TXqI= + +Name: res/drawable-mdpi/abs__spinner_ab_pressed_holo_dark.9.png +SHA1-Digest: RpjH9X9l7RTj4O0/ZHPnjRGjhAs= + +Name: res/layout/settings_about_legal.xml +SHA1-Digest: bFk49aLNUT02gmUe7JByPrZ7fRg= + +Name: res/drawable/abs__ic_menu_moreoverflow_holo_light.xml +SHA1-Digest: Ja+gNbfydTTC7nwqz11DWUjWIB4= + +Name: res/drawable-mdpi/delete.png +SHA1-Digest: qU9mBiJ0EuVTFysrqEfWKMswSNU= + +Name: res/drawable-mdpi/grid.png +SHA1-Digest: 0vdcIGnE4OzuZY+a+LApbhbdF7g= + +Name: res/drawable-mdpi/abs__ab_share_pack_holo_dark.9.png +SHA1-Digest: 7bovMMzOcBf6/I9KeGe/Y4JP3PI= + +Name: res/drawable-mdpi/select_dark.png +SHA1-Digest: sDraxyImpg7m/4NY9t3shPh/Vo8= + +Name: res/layout/wifi_disable_alert.xml +SHA1-Digest: z24WubI/oVgvl3cuq4IrIElRQQ0= + +Name: res/layout/abs__simple_dropdown_hint.xml +SHA1-Digest: kp6SNocIx2R9JCEDdpWBBqwH8Wo= + +Name: res/drawable-mdpi/abs__ic_go_search_api_holo_light.png +SHA1-Digest: HZ81jf3SqGSNkfV8se4PJ1F8P+s= + +Name: res/drawable-hdpi/abs__ic_voice_search_api_holo_light.png +SHA1-Digest: URoLFR3cGwtdIWQqefx4S2slI0A= + +Name: res/xml/settings_security.xml +SHA1-Digest: VB8Ce9FvCDK7WIW86chUEw01LL8= + +Name: assets/zh_CN/01logo.png +SHA1-Digest: nR5HoS3HmNUT/kIzIpsnRFfSee0= + +Name: res/drawable-xhdpi/notify_a02c.png +SHA1-Digest: 0y+6sN1IBS2FJLTLeIx2rt7HVgw= + +Name: res/drawable-xhdpi/abs__textfield_search_selected_holo_light.9.p + ng +SHA1-Digest: /MUgBH/bN2XqWF5dFDTtW4fzSME= + +Name: res/layout-large/music.xml +SHA1-Digest: D40k3DT5SqOIMlGEqsO8Sq8yRSM= + +Name: res/layout/abs__action_bar_title_item.xml +SHA1-Digest: TsyxUMOCIBf9iqn7roo9cLWBpo4= + +Name: assets/es/02qsg_SP.png +SHA1-Digest: DkZwBnDajGj5zCec27LuZV+C9MM= + diff --git a/tests/common.TestCase b/tests/common.TestCase index 4739ddab..2285b67b 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -615,6 +615,27 @@ class CommonTest(unittest.TestCase): self.assertFalse(fdroidserver.common.verify_apk_signature(twosigapk)) self.assertIsNone(fdroidserver.common.verify_apks(sourceapk, twosigapk, self.tmpdir)) + def test_get_certificate_with_chain_sandisk(self): + """Test that APK signatures with a cert chain are parsed like apksigner. + + SanDisk signs their APKs with a X.509 certificate chain of + trust, so there are actually three certificates + included. apksigner only cares about the certificate in the + chain that actually signs the manifest. + + The correct value comes from: + apksigner verify --print-certs 883cbdae7aeb2e4b122e8ee8d89966c7062d0d49107a130235fa220a5b994a79.apk + + """ + cert = fdroidserver.common.get_certificate( + signature_block_file=Path('SANAPPSI.RSA').read_bytes(), + signature_file=Path('SANAPPSI.SF').read_bytes(), + ) + self.assertEqual( + 'ea0abbf2a142e4b167405d516b2cc408c4af4b29cd50ba281aa4470d4aab3e53', + fdroidserver.common.signer_fingerprint(cert), + ) + def test_write_to_config(self): with tempfile.TemporaryDirectory() as tmpPath: cfgPath = os.path.join(tmpPath, 'config.py') From ad9f0a90229850ecc407387272fb7a5799556b60 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 23 Apr 2024 18:03:24 +0200 Subject: [PATCH 9/9] include @obfusk's proof-of-concept APKs in test suite https://github.com/obfusk/fdroid-fakesigner-poc/releases/tag/poc-apks --- MANIFEST.in | 4 ++++ tests/common.TestCase | 24 ++++++++++++++++++++++++ tests/issue-1128-poc1.apk | Bin 0 -> 6896 bytes tests/issue-1128-poc2.apk | Bin 0 -> 9781 bytes tests/issue-1128-poc3a.apk | Bin 0 -> 8822 bytes tests/issue-1128-poc3b.apk | Bin 0 -> 8821 bytes 6 files changed, 28 insertions(+) create mode 100644 tests/issue-1128-poc1.apk create mode 100644 tests/issue-1128-poc2.apk create mode 100644 tests/issue-1128-poc3a.apk create mode 100644 tests/issue-1128-poc3b.apk diff --git a/MANIFEST.in b/MANIFEST.in index 1d7bd768..8d24dbf2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -592,6 +592,10 @@ include tests/init.TestCase include tests/install.TestCase include tests/IsMD5Disabled.java include tests/issue-1128-min-sdk-30-poc.apk +include tests/issue-1128-poc1.apk +include tests/issue-1128-poc2.apk +include tests/issue-1128-poc3a.apk +include tests/issue-1128-poc3b.apk include tests/janus.apk include tests/keystore.jks include tests/key-tricks.py diff --git a/tests/common.TestCase b/tests/common.TestCase index 2285b67b..24132297 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -1061,6 +1061,10 @@ class CommonTest(unittest.TestCase): ('org.bitbucket.tickytacky.mirrormirror_4.apk', 'org.bitbucket.tickytacky.mirrormirror', 4, '1.0.3'), ('org.dyndns.fules.ck_20.apk', 'org.dyndns.fules.ck', 20, 'v1.6pre2'), ('issue-1128-min-sdk-30-poc.apk', 'org.fdroid.ci', 1, '1.0'), + ('issue-1128-poc1.apk', 'android.appsecurity.cts.tinyapp', 10, '1.0'), + ('issue-1128-poc2.apk', 'android.appsecurity.cts.tinyapp', 10, '1.0'), + ('issue-1128-poc3a.apk', 'android.appsecurity.cts.tinyapp', 10, '1.0'), + ('issue-1128-poc3b.apk', 'android.appsecurity.cts.tinyapp', 10, '1.0'), ('urzip.apk', 'info.guardianproject.urzip', 100, '0.1'), ('urzip-badcert.apk', 'info.guardianproject.urzip', 100, '0.1'), ('urzip-badsig.apk', 'info.guardianproject.urzip', 100, '0.1'), @@ -1177,6 +1181,10 @@ class CommonTest(unittest.TestCase): self.assertEqual(4, get_minSdkVersion('bad-unicode-πÇÇ现代通用字-български-عربي1.apk')) self.assertEqual(30, get_minSdkVersion('issue-1128-min-sdk-30-poc.apk')) + self.assertEqual(29, get_minSdkVersion('issue-1128-poc1.apk')) + self.assertEqual(29, get_minSdkVersion('issue-1128-poc2.apk')) + self.assertEqual(23, get_minSdkVersion('issue-1128-poc3a.apk')) + self.assertEqual(23, get_minSdkVersion('issue-1128-poc3b.apk')) self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_1.apk')) self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_2.apk')) self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_3.apk')) @@ -2952,6 +2960,14 @@ APKS_WITH_JAR_SIGNATURES = ( 'bad-unicode-πÇÇ现代通用字-български-عربي1.apk', '32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6', ), + ( + 'issue-1128-poc3a.apk', + '1dbb8be012293e988a0820f7d455b07abd267d2c0b500fc793fcfd80141cb5ce', + ), + ( + 'issue-1128-poc3b.apk', + '1dbb8be012293e988a0820f7d455b07abd267d2c0b500fc793fcfd80141cb5ce', + ), ( 'janus.apk', 'ebb0fedf1942a099b287c3db00ff732162152481abb2b6c7cbcdb2ba5894a768', @@ -3058,6 +3074,14 @@ APKS_WITH_JAR_SIGNATURES = ( ), ) APKS_WITHOUT_JAR_SIGNATURES = ( + ( + 'issue-1128-poc1.apk', # APK v3 Signature only + '1dbb8be012293e988a0820f7d455b07abd267d2c0b500fc793fcfd80141cb5ce', + ), + ( + 'issue-1128-poc2.apk', # APK v3 Signature only + '1dbb8be012293e988a0820f7d455b07abd267d2c0b500fc793fcfd80141cb5ce', + ), ( 'issue-1128-min-sdk-30-poc.apk', # APK v3 Signature only '09350d5f3460a8a0ea5cf6b68ccd296a58754f7e683ba6aa08c19be8353504f3', diff --git a/tests/issue-1128-poc1.apk b/tests/issue-1128-poc1.apk new file mode 100644 index 0000000000000000000000000000000000000000..ba643f3d5262a087fba08af14910217c49bb6c60 GIT binary patch literal 6896 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 Pe;9xR*c5!E#z_AF7Z0Hn literal 0 HcmV?d00001 diff --git a/tests/issue-1128-poc2.apk b/tests/issue-1128-poc2.apk new file mode 100644 index 0000000000000000000000000000000000000000..b9947df8781d730d0c043325fbb526faee148261 GIT binary patch literal 9781 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 BOg{hs literal 0 HcmV?d00001 diff --git a/tests/issue-1128-poc3b.apk b/tests/issue-1128-poc3b.apk new file mode 100644 index 0000000000000000000000000000000000000000..91f536e35326d5dad5674f5e7f77cf24b559ff22 GIT binary patch literal 8821 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 BPjmnP literal 0 HcmV?d00001