|
1 | 1 | package org.schabi.newpipe.util |
2 | 2 |
|
3 | 3 | import android.content.pm.PackageManager |
4 | | -import android.content.pm.Signature |
5 | 4 | import androidx.core.content.pm.PackageInfoCompat |
6 | 5 | import org.schabi.newpipe.App |
7 | 6 | import org.schabi.newpipe.error.ErrorInfo |
8 | 7 | import org.schabi.newpipe.error.ErrorUtil.Companion.createNotification |
9 | 8 | import org.schabi.newpipe.error.UserAction |
10 | | -import java.security.MessageDigest |
11 | | -import java.security.NoSuchAlgorithmException |
12 | | -import java.security.cert.CertificateEncodingException |
13 | | -import java.security.cert.CertificateException |
14 | | -import java.security.cert.CertificateFactory |
15 | | -import java.security.cert.X509Certificate |
16 | 9 | import java.time.Instant |
17 | 10 | import java.time.ZonedDateTime |
18 | 11 | import java.time.format.DateTimeFormatter |
19 | 12 |
|
20 | 13 | object ReleaseVersionUtil { |
21 | 14 | // Public key of the certificate that is used in NewPipe release versions |
22 | | - private const val RELEASE_CERT_PUBLIC_KEY_SHA1 = |
23 | | - "B0:2E:90:7C:1C:D6:FC:57:C3:35:F0:88:D0:8F:50:5F:94:E4:D2:15" |
| 15 | + private const val RELEASE_CERT_PUBLIC_KEY_SHA256 = |
| 16 | + "cb84069bd68116bafae5ee4ee5b08a567aa6d898404e7cb12f9e756df5cf5cab" |
24 | 17 |
|
25 | 18 | @JvmStatic |
26 | 19 | fun isReleaseApk(): Boolean { |
27 | | - return certificateSHA1Fingerprint == RELEASE_CERT_PUBLIC_KEY_SHA1 |
28 | | - } |
29 | | - |
30 | | - /** |
31 | | - * Method to get the APK's SHA1 key. See https://stackoverflow.com/questions/9293019/#22506133. |
32 | | - * |
33 | | - * @return String with the APK's SHA1 fingerprint in hexadecimal |
34 | | - */ |
35 | | - private val certificateSHA1Fingerprint: String |
36 | | - get() { |
37 | | - val app = App.getApp() |
38 | | - val signatures: List<Signature> = try { |
39 | | - PackageInfoCompat.getSignatures(app.packageManager, app.packageName) |
40 | | - } catch (e: PackageManager.NameNotFoundException) { |
41 | | - showRequestError(app, e, "Could not find package info") |
42 | | - return "" |
43 | | - } |
44 | | - if (signatures.isEmpty()) { |
45 | | - return "" |
46 | | - } |
47 | | - val x509cert = try { |
48 | | - val cf = CertificateFactory.getInstance("X509") |
49 | | - cf.generateCertificate(signatures[0].toByteArray().inputStream()) as X509Certificate |
50 | | - } catch (e: CertificateException) { |
51 | | - showRequestError(app, e, "Certificate error") |
52 | | - return "" |
53 | | - } |
54 | | - |
55 | | - return try { |
56 | | - val md = MessageDigest.getInstance("SHA1") |
57 | | - val publicKey = md.digest(x509cert.encoded) |
58 | | - byte2HexFormatted(publicKey) |
59 | | - } catch (e: NoSuchAlgorithmException) { |
60 | | - showRequestError(app, e, "Could not retrieve SHA1 key") |
61 | | - "" |
62 | | - } catch (e: CertificateEncodingException) { |
63 | | - showRequestError(app, e, "Could not retrieve SHA1 key") |
64 | | - "" |
65 | | - } |
66 | | - } |
67 | | - |
68 | | - private fun byte2HexFormatted(arr: ByteArray): String { |
69 | | - val str = StringBuilder(arr.size * 2) |
70 | | - for (i in arr.indices) { |
71 | | - var h = Integer.toHexString(arr[i].toInt()) |
72 | | - val l = h.length |
73 | | - if (l == 1) { |
74 | | - h = "0$h" |
75 | | - } |
76 | | - if (l > 2) { |
77 | | - h = h.substring(l - 2, l) |
78 | | - } |
79 | | - str.append(h.uppercase()) |
80 | | - if (i < arr.size - 1) { |
81 | | - str.append(':') |
82 | | - } |
83 | | - } |
84 | | - return str.toString() |
85 | | - } |
86 | | - |
87 | | - private fun showRequestError(app: App, e: Exception, request: String) { |
88 | | - createNotification( |
89 | | - app, ErrorInfo(e, UserAction.CHECK_FOR_NEW_APP_VERSION, request) |
| 20 | + @Suppress("NewApi") |
| 21 | + val certificates = mapOf( |
| 22 | + RELEASE_CERT_PUBLIC_KEY_SHA256.toByteArray() to PackageManager.CERT_INPUT_SHA256 |
90 | 23 | ) |
| 24 | + val app = App.getApp() |
| 25 | + return try { |
| 26 | + PackageInfoCompat.hasSignatures(app.packageManager, app.packageName, certificates, false) |
| 27 | + } catch (e: PackageManager.NameNotFoundException) { |
| 28 | + createNotification( |
| 29 | + app, ErrorInfo(e, UserAction.CHECK_FOR_NEW_APP_VERSION, "Could not find package info") |
| 30 | + ) |
| 31 | + false |
| 32 | + } |
91 | 33 | } |
92 | 34 |
|
93 | 35 | fun isLastUpdateCheckExpired(expiry: Long): Boolean { |
94 | | - return Instant.ofEpochSecond(expiry).isBefore(Instant.now()) |
| 36 | + return Instant.ofEpochSecond(expiry) < Instant.now() |
95 | 37 | } |
96 | 38 |
|
97 | 39 | /** |
|
0 commit comments