Skip to content

Commit 63d85d6

Browse files
committed
feat: allow set custom keybox to OMK
Signed-off-by: qwq233 <[email protected]>
1 parent 78e5f21 commit 63d85d6

File tree

5 files changed

+65
-15
lines changed

5 files changed

+65
-15
lines changed

service/src/main/aidl/top/qwq2333/ohmykeymint/IOhMyKsService.aidl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package top.qwq2333.ohmykeymint;
22

33
import android.hardware.security.keymint.SecurityLevel;
4+
import android.hardware.security.keymint.Certificate;
45
import android.hardware.security.keymint.Tag;
56
import android.system.keystore2.Domain;
67
import android.system.keystore2.IKeystoreSecurityLevel;
@@ -41,6 +42,9 @@ interface IOhMyKsService {
4142
KeyDescriptor[] listEntriesBatched(in @nullable CallerInfo ctx, in Domain domain, in long nspace,
4243
in @nullable String startingPastAlias);
4344

44-
4545
byte[] getSupplementaryAttestationInfo(in Tag tag);
46+
47+
void updateEcKeybox(in byte[] key, in List<Certificate> chain);
48+
49+
void updateRsaKeybox(in byte[] key, in List<Certificate> chain);
4650
}

service/src/main/java/io/github/a13e300/tricky_store/Config.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ object Config {
4343
}
4444

4545
private fun updateKeyBox(f: File?) = runCatching {
46-
CertHack.readFromXml(f?.readText())
46+
CertHack.readFromXml(f?.readText(), getOmk())
4747
}.onFailure {
4848
Logger.e("failed to update keybox", it)
4949
}
@@ -129,6 +129,7 @@ object Config {
129129

130130
private val omkDeathRecipient = object : IBinder.DeathRecipient {
131131
override fun binderDied() {
132+
Logger.e("OMK process exited. Reset OMK to null.")
132133
(omk as? IInterface)?.asBinder()?.unlinkToDeath(this, 0)
133134
omk = null
134135
}
@@ -139,6 +140,7 @@ object Config {
139140
val binder = ServiceManager.getService("omk") ?: return null
140141
binder.linkToDeath(omkDeathRecipient, 0)
141142
omk = IOhMyKsService.Stub.asInterface(binder)
143+
updateKeyBox(File(root, KEYBOX_FILE))
142144
}
143145
return omk
144146
}

service/src/main/java/io/github/a13e300/tricky_store/KeystoreInterceptor.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,18 @@ object KeystoreInterceptor : BinderInterceptor() {
4545
val omk = getOmk()
4646
Logger.d("KeystoreInceptor onPreTransact code=$code")
4747
when (code) {
48-
getSecurityLevelTransaction -> {
49-
omk ?: return Skip
50-
51-
val level = data.readInt()
52-
53-
Parcel.obtain().apply {
54-
writeNoException()
55-
writeStrongBinder(omk.getSecurityLevel(level).asBinder())
56-
}.run {
57-
return OverrideReply(0, this)
58-
}
59-
}
48+
/* getSecurityLevelTransaction -> {
49+
omk ?: return Skip
50+
51+
val level = data.readInt()
52+
53+
Parcel.obtain().apply {
54+
writeNoException()
55+
writeStrongBinder(omk.getSecurityLevel(level).asBinder())
56+
}.run {
57+
return OverrideReply(0, this)
58+
}
59+
}*/
6060
getKeyEntryTransaction -> {
6161
Logger.d("KeystoreInceptor getKeyEntryTransaction pre $target uid=$callingUid pid=$callingPid dataSz=${data.dataSize()}")
6262
if (Config.needGenerate(callingUid))

service/src/main/java/io/github/a13e300/tricky_store/keystore/CertHack.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import java.security.spec.RSAKeyGenParameterSpec;
5959
import java.util.ArrayList;
6060
import java.util.Arrays;
61+
import java.util.Base64;
6162
import java.util.Comparator;
6263
import java.util.Date;
6364
import java.util.HashMap;
@@ -75,6 +76,7 @@
7576
import io.github.a13e300.tricky_store.Config;
7677
import io.github.a13e300.tricky_store.Logger;
7778
import io.github.a13e300.tricky_store.UtilKt;
79+
import top.qwq2333.ohmykeymint.IOhMyKsService;
7880

7981
public final class CertHack {
8082
private static final ASN1ObjectIdentifier OID = new ASN1ObjectIdentifier("1.3.6.1.4.1.11129.2.1.17");
@@ -124,7 +126,7 @@ private static byte[] getByteArrayFromAsn1(ASN1Encodable asn1Encodable) throws C
124126
return derOctectString.getOctets();
125127
}
126128

127-
public static void readFromXml(String data) {
129+
public static void readFromXml(String data, IOhMyKsService omk) {
128130
keyboxes.clear();
129131
if (data == null) {
130132
Logger.i("clear all keyboxes");
@@ -159,6 +161,37 @@ public static void readFromXml(String data) {
159161
var pemKp = parseKeyPair(privateKey);
160162
var kp = new JcaPEMKeyConverter().getKeyPair(pemKp);
161163
keyboxes.put(algo, new KeyBox(pemKp, kp, certificateChain));
164+
165+
if (omk != null) {
166+
try {
167+
if (keyboxAlgorithm.equalsIgnoreCase("ecdsa")) {
168+
ArrayList<android.hardware.security.keymint.Certificate> list = new ArrayList<>();
169+
170+
for (int j = 0; j < numberOfCertificates; j++) {
171+
Map<String, String> certData = xmlParser.obtainPath(
172+
"AndroidAttestation.Keybox.Key[" + i + "].CertificateChain.Certificate[" + j + "]");
173+
var cert = new android.hardware.security.keymint.Certificate();
174+
cert.encodedCertificate = Base64.getDecoder().decode(UtilKt.parsePemToBase64(certData.get("text")));
175+
list.add(cert);
176+
}
177+
178+
omk.updateEcKeybox(Base64.getDecoder().decode(UtilKt.parsePemToBase64(privateKey)), list);
179+
} else if (keyboxAlgorithm.equalsIgnoreCase("rsa")) {
180+
ArrayList<android.hardware.security.keymint.Certificate> list = new ArrayList<>();
181+
for (int j = 0; j < numberOfCertificates; j++) {
182+
Map<String, String> certData = xmlParser.obtainPath(
183+
"AndroidAttestation.Keybox.Key[" + i + "].CertificateChain.Certificate[" + j + "]");
184+
var cert = new android.hardware.security.keymint.Certificate();
185+
cert.encodedCertificate = Base64.getDecoder().decode(UtilKt.parsePemToBase64(certData.get("text")));
186+
list.add(cert);
187+
}
188+
189+
omk.updateRsaKeybox(Base64.getDecoder().decode(UtilKt.parsePemToBase64(privateKey)), list);
190+
}
191+
} catch (Exception e) {
192+
Logger.e("Unable to update keybox to OMK", e);
193+
}
194+
}
162195
}
163196
Logger.i("update " + numberOfKeyboxes + " keyboxes");
164197
} catch (Throwable t) {

service/src/main/java/io/github/a13e300/tricky_store/util.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,17 @@ fun String.toDER() = DEROctetString(this.toByteArray())
126126
fun DEROctetString.toTaggedObj(tag: Int, explicit: Boolean = true) = DERTaggedObject(explicit, tag, this)
127127
fun String.trimLine() = trim().split("\n").joinToString("\n") { it.trim() }
128128

129+
const val BEGIN = "-----BEGIN.*?-----"
130+
const val END = "-----END.*?-----"
131+
132+
fun parsePemToBase64(str: String): String {
133+
val result = str.trimLine()
134+
.replace(BEGIN.toRegex(RegexOption.MULTILINE), "")
135+
.replace(END.toRegex(RegexOption.MULTILINE), "")
136+
.replace("\n", "")
137+
return result
138+
}
139+
129140
fun Parcelable.toBytes(): ByteArray {
130141
val p = Parcel.obtain()
131142
return try {

0 commit comments

Comments
 (0)