浏览代码

refactor: certificate issuer detecting (#108)

Reviewed-on: https://gitea.angry.im/PeterCxy/OpenEUICC/pulls/108
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
septs 1 年之前
父节点
当前提交
06873545e2

+ 12 - 17
app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt

@@ -19,13 +19,12 @@ import im.angry.openeuicc.core.EuiccChannel
 import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.util.*
 import kotlinx.coroutines.launch
-import net.typeblog.lpac_jni.impl.DEFAULT_PKID_GSMA_RSP2_ROOT_CI1
+import net.typeblog.lpac_jni.impl.PKID_GSMA_LIVE_CI
 import net.typeblog.lpac_jni.impl.PKID_GSMA_TEST_CI
 
 class EuiccInfoActivity : BaseEuiccAccessActivity() {
     companion object {
         private val YES_NO = Pair(R.string.yes, R.string.no)
-        private val SUPPORTED_UNSUPPORTED = Pair(R.string.supported, R.string.unsupported)
     }
 
     private lateinit var swipeRefresh: SwipeRefreshLayout
@@ -107,21 +106,17 @@ class EuiccInfoActivity : BaseEuiccAccessActivity() {
             add(Pair(R.string.euicc_info_free_nvram, info?.freeNvram?.let(::formatFreeSpace)))
         }
         channel.lpa.euiccInfo2?.euiccCiPKIdListForSigning.orEmpty().let { signers ->
-            add(
-                Pair(
-                    R.string.euicc_info_gsma_prod,
-                    formatByBoolean(
-                        signers.contains(DEFAULT_PKID_GSMA_RSP2_ROOT_CI1),
-                        SUPPORTED_UNSUPPORTED
-                    )
-                )
-            )
-            add(
-                Pair(
-                    R.string.euicc_info_gsma_test,
-                    formatByBoolean(PKID_GSMA_TEST_CI.any(signers::contains), SUPPORTED_UNSUPPORTED)
-                )
-            )
+            // SGP.28 v1.0, eSIM CI Registration Criteria (Page 5 of 9, 2019-10-24)
+            // https://www.gsma.com/newsroom/wp-content/uploads/SGP.28-v1.0.pdf#page=5
+            // FS.27 v2.0, Security Guidelines for UICC Profiles (Page 25 of 27, 2024-01-30)
+            // https://www.gsma.com/solutions-and-impact/technologies/security/wp-content/uploads/2024/01/FS.27-Security-Guidelines-for-UICC-Credentials-v2.0-FINAL-23-July.pdf#page=25
+            val resId = when {
+                signers.isEmpty() -> R.string.unknown // the case is not mp, but it's is not common
+                PKID_GSMA_LIVE_CI.any(signers::contains) -> R.string.euicc_info_ci_gsma_live
+                PKID_GSMA_TEST_CI.any(signers::contains) -> R.string.euicc_info_ci_gsma_test
+                else -> R.string.euicc_info_ci_unknown
+            }
+            add(Pair(R.string.euicc_info_ci_type, getString(resId)))
         }
     }
 

+ 4 - 5
app-common/src/main/res/values/strings.xml

@@ -122,11 +122,10 @@
     <string name="euicc_info_sas_accreditation_number">SAS Accreditation Number</string>
     <string name="euicc_info_pp_version">Protected Profile Version</string>
     <string name="euicc_info_free_nvram">Free NVRAM (eSIM profile storage)</string>
-    <string name="euicc_info_gsma_prod">GSMA Production Certificate</string>
-    <string name="euicc_info_gsma_test">GSMA Test Certificate</string>
-
-    <string name="supported">Supported</string>
-    <string name="unsupported">Unsupported</string>
+    <string name="euicc_info_ci_type">Certificate Issuer</string>
+    <string name="euicc_info_ci_gsma_live">GSMA Live CI</string>
+    <string name="euicc_info_ci_gsma_test">GSMA Test CI</string>
+    <string name="euicc_info_ci_unknown">Unknown eSIM CA</string>
 
     <string name="yes">Yes</string>
     <string name="no">No</string>

+ 27 - 3
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/RootCertificates.kt

@@ -7,8 +7,32 @@ import java.security.cert.CertificateFactory
 
 const val DEFAULT_PKID_GSMA_RSP2_ROOT_CI1 = "81370f5125d0b1d408d4c3b232e6d25e795bebfb"
 
-val PKID_GSMA_TEST_CI =
-    arrayOf("34eecf13156518d48d30bdf06853404d115f955d", "2209f61cd9ec5c9c854e787341ff83ecf9776a5b")
+// SGP.28 v1.0, eSIM CI Registration Criteria (Page 5 of 9, 2019-10-24)
+// https://www.gsma.com/newsroom/wp-content/uploads/SGP.28-v1.0.pdf#page=5
+// FS.27 v2.0, Security Guidelines for UICC Profiles (Page 25 of 27, 2024-01-30)
+// https://www.gsma.com/solutions-and-impact/technologies/security/wp-content/uploads/2024/01/FS.27-Security-Guidelines-for-UICC-Credentials-v2.0-FINAL-23-July.pdf#page=25
+
+// List of GSMA Live CIs
+// https://www.gsma.com/solutions-and-impact/technologies/esim/gsma-root-ci/
+val PKID_GSMA_LIVE_CI = arrayOf(
+    // GSMA RSP2 Root CI1 (SGP.22 v2+v3, CA: DigiCert)
+    // https://euicc-manual.osmocom.org/docs/pki/ci/files/81370f.txt
+    DEFAULT_PKID_GSMA_RSP2_ROOT_CI1,
+    // OISITE GSMA CI G1 (SGP.22 v2+v3, CA: WISeKey)
+    // https://euicc-manual.osmocom.org/docs/pki/ci/files/4c2796.txt
+    "4c27967ad20c14b391e9601e41e604ad57c0222f",
+)
+
+// SGP.26 v3.0, 2023-12-01
+// https://www.gsma.com/solutions-and-impact/technologies/esim/wp-content/uploads/2023/12/SGP.26-v3.0.pdf
+val PKID_GSMA_TEST_CI = arrayOf(
+    // Test CI (SGP.26, NIST P256)
+    // https://euicc-manual.osmocom.org/docs/pki/ci/files/34eecf.txt
+    "34eecf13156518d48d30bdf06853404d115f955d",
+    // Test CI (SGP.26, BRP P256r1)
+    // https://euicc-manual.osmocom.org/docs/pki/ci/files/2209f6.txt
+    "2209f61cd9ec5c9c854e787341ff83ecf9776a5b",
+)
 
 private fun getCertificate(keyId: String): Certificate? =
     KNOWN_CI_CERTS[keyId]?.toByteArray()?.let { cert ->
@@ -60,7 +84,7 @@ internal val KNOWN_CI_CERTS = hashMapOf(
         -----END CERTIFICATE-----
     """.trimIndent(),
     // OISITE GSMA CI G1 (CA: WISeKey)
-    // Specs: SGP.21 and SGP.22 version 3
+    // Specs: SGP.21 and SGP.22 version 2 and version 3
     "4c27967ad20c14b391e9601e41e604ad57c0222f" to """
         -----BEGIN CERTIFICATE-----
         MIIB9zCCAZ2gAwIBAgIUSpBSCCDYPOEG/IFHUCKpZ2pIAQMwCgYIKoZIzj0EAwIw