Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
import io.github.vvb2060.keyattestation.AppApplication;

public class RootPublicKey {
public enum TestKey {
NONE,
RSA2048,
RSA4096,
RSA8192,
}
public enum Status {
NULL,
FAILED,
Expand Down Expand Up @@ -106,6 +112,38 @@ private static Set<PublicKey> getOemPublicKey() {
return set;
}

private static byte[] hexToBytes(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
}
return data;
}

/**
* Detect if verifiedBootKey matches known AVB test public keys by SHA-256 digest.
*/
public static TestKey checkVbmetaTestKeyBySha256(byte[] verifiedBootKey) {
if (verifiedBootKey == null) return TestKey.NONE;

// Known SHA-256 fingerprints for AVB test keys
final String SHA256_RSA2048 = "22de3994532196f61c039e90260d78a93a4c57362c7e789be928036e80b77c8c";
final String SHA256_RSA4096 = "7728e30f50bfa5cea165f473175a08803f6a8346642b5aa10913e9d9e6defef6";
final String SHA256_RSA8192 = "e15e2365469ce672a91d02cc8d9c2f29b787481e574d3b56ac774153d7ced614";

var sha256_2048 = hexToBytes(SHA256_RSA2048);
var sha256_4096 = hexToBytes(SHA256_RSA4096);
var sha256_8192 = hexToBytes(SHA256_RSA8192);

if (Arrays.equals(verifiedBootKey, sha256_2048)) return TestKey.RSA2048;
if (Arrays.equals(verifiedBootKey, sha256_4096)) return TestKey.RSA4096;
if (Arrays.equals(verifiedBootKey, sha256_8192)) return TestKey.RSA8192;

return TestKey.NONE;
}

public static Status check(byte[] publicKey) {
if (Arrays.equals(publicKey, googleKey)) {
return Status.GOOGLE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,41 @@ class HomeAdapter(listener: Listener) : IdBasedRecyclerViewAdapter() {
private fun updateData(attestationData: AttestationData) {
addItemAt(1, BootStateViewHolder.CREATOR, attestationData, ID_BOOT_STATUS)

// If verifiedBootKey matches known AVB test keys (by SHA-1), show a warning header
var testKeyShown = false
attestationData.rootOfTrust?.verifiedBootKey?.let { vbk ->
when (RootPublicKey.checkVbmetaTestKeyBySha256(vbk)) {
RootPublicKey.TestKey.RSA2048 -> {
addItemAt(2, HeaderViewHolder.CREATOR, HeaderData(
R.string.vbmeta_testkey,
R.string.vbmeta_testkey_rsa2048_summary,
R.drawable.ic_error_outline_24,
rikka.material.R.attr.colorAlert
), ID_VB_TESTKEY_WARNING)
testKeyShown = true
}
RootPublicKey.TestKey.RSA4096 -> {
addItemAt(2, HeaderViewHolder.CREATOR, HeaderData(
R.string.vbmeta_testkey,
R.string.vbmeta_testkey_rsa4096_summary,
R.drawable.ic_error_outline_24,
rikka.material.R.attr.colorAlert
), ID_VB_TESTKEY_WARNING)
testKeyShown = true
}
RootPublicKey.TestKey.RSA8192 -> {
addItemAt(2, HeaderViewHolder.CREATOR, HeaderData(
R.string.vbmeta_testkey,
R.string.vbmeta_testkey_rsa8192_summary,
R.drawable.ic_error_outline_24,
rikka.material.R.attr.colorAlert
), ID_VB_TESTKEY_WARNING)
testKeyShown = true
}
else -> {}
}
}

var id = ID_DESCRIPTION_START
val attestation = attestationData.showAttestation ?: return
addItem(CommonItemViewHolder.SECURITY_LEVEL_CREATOR, SecurityLevelData(
Expand Down Expand Up @@ -270,6 +305,7 @@ class HomeAdapter(listener: Listener) : IdBasedRecyclerViewAdapter() {
private const val ID_ERROR = 0L
private const val ID_CERT_STATUS = 1L
private const val ID_BOOT_STATUS = 2L
private const val ID_VB_TESTKEY_WARNING = 3L
private const val ID_CERT_INFO_START = 1000L
private const val ID_RKP_HOSTNAME = 2000L
private const val ID_DESCRIPTION_START = 3000L
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
<string name="oem_root_cert">设备制造商的根证书</string>
<string name="oem_root_cert_summary">此设备信任该根证书,但它可能不被其它人信任。</string>

<string name="vbmeta_testkey">vbmeta 被测试密钥签名</string>
<string name="vbmeta_testkey_rsa2048_summary">verifiedBootKey 是 testkey_rsa2048</string>
<string name="vbmeta_testkey_rsa4096_summary">verifiedBootKey 是 testkey_rsa4096</string>
<string name="vbmeta_testkey_rsa8192_summary">verifiedBootKey 是 testkey_rsa8192</string>

<string name="cert_chain">证书链</string>
<string name="cert_chain_description">证书链是用于验证密钥的证书列表。从该密钥的证书开始,每个证书均由链中下一个证书签名,到根证书为止。认证的可信度取决于证书链的根证书。</string>
<string name="cert_info">证书信息</string>
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
<string name="oem_root_cert">OEM root certificate</string>
<string name="oem_root_cert_summary">This device trusts this root certificate, but it may not be trusted by others.</string>

<string name="vbmeta_testkey">VBMeta signed with test key</string>
<string name="vbmeta_testkey_rsa2048_summary">verifiedBootKey is testkey_rsa2048</string>
<string name="vbmeta_testkey_rsa4096_summary">verifiedBootKey is testkey_rsa4096</string>
<string name="vbmeta_testkey_rsa8192_summary">verifiedBootKey is testkey_rsa8192</string>

<string name="cert_chain">Certificate chain</string>
<string name="cert_chain_description">Certificate chain is a list of certificates used to authenticate a key. The chain starts with the certificate associated with that key, and each certificate is signed by the next in the chain. The chain ends with a root certificate, and the trustworthiness of the attestation depends on the root certificate of the chain..</string>
<string name="cert_info">Certificate info</string>
Expand Down