Skip to content

Commit 05c895f

Browse files
minaripenguinchiteroman
authored andcommitted
Keystore: Spoof locked bootloader on local attestations
based from: https://github.com/chiteroman/BootloaderSpoofer Squashed: From: minaripenguin <minaripenguin@users.noreply.github.com> Date: Tue, 5 Dec 2023 19:56:07 +0800 Subject: fixup! Keystore: Spoof locked bootloader on local attestations * as reported by sir shamik without this fixup, bootloader is detected as unlocked on keystore attestation app. * thanks to ghostrider-reborn for the references and clarification about the injection reference: RisingTechOSS/android_frameworks_base@d57f22f#r134217184 test: m confirmed that key attestation 1.5.0 detects device bootloader state as locked Signed-off-by: minaripenguin <minaripenguin@users.noreply.github.com> Co-authored-by: chiteroman <98092901+chiteroman@users.noreply.github.com> Signed-off-by: minaripenguin <minaripenguin@users.noreply.github.com> Signed-off-by: Pranav Vashi <neobuddy89@gmail.com> Change-Id: I5e26589555d903d626bbc2fa60daec405ad09f6b Signed-off-by: clarencelol <clarencekuiek@proton.me> Signed-off-by: NRanjan-17 <nalinishranjan05@gmail.com>
1 parent 68606fe commit 05c895f

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java

+33-7
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import java.util.Enumeration;
8888
import java.util.Iterator;
8989
import java.util.List;
90+
import java.util.Locale;
9091
import java.util.NoSuchElementException;
9192

9293
import javax.crypto.SecretKey;
@@ -177,6 +178,20 @@ private KeyEntryResponse getKeyMetadata(String alias) {
177178
}
178179
}
179180

181+
private static int indexOf(byte[] array) {
182+
final byte[] PATTERN = {48, 74, 4, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 10, 1, 2};
183+
outer:
184+
for (int i = 0; i < array.length - PATTERN.length + 1; i++) {
185+
for (int j = 0; j < PATTERN.length; j++) {
186+
if (array[i + j] != PATTERN[j]) {
187+
continue outer;
188+
}
189+
}
190+
return i;
191+
}
192+
return -1;
193+
}
194+
180195
@Override
181196
public Certificate[] engineGetCertificateChain(String alias) {
182197
PropImitationHooks.onEngineGetCertificateChain();
@@ -192,15 +207,28 @@ public Certificate[] engineGetCertificateChain(String alias) {
192207
return null;
193208
}
194209

195-
final Certificate[] caList;
210+
X509Certificate modLeaf = leaf;
211+
try {
212+
byte[] bytes = leaf.getEncoded();
213+
if (bytes != null && bytes.length > 0) {
214+
int index = indexOf(bytes);
215+
if (index != -1) {
216+
bytes[index + 38] = 1;
217+
bytes[index + 41] = 0;
218+
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
219+
X509Certificate modCert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(bytes));
220+
modLeaf = modCert;
221+
}
222+
}
223+
} catch (CertificateException e) {
224+
return null;
225+
}
196226

197227
final byte[] caBytes = response.metadata.certificateChain;
198-
228+
final Certificate[] caList;
199229
if (caBytes != null) {
200230
final Collection<X509Certificate> caChain = toCertificates(caBytes);
201-
202231
caList = new Certificate[caChain.size() + 1];
203-
204232
final Iterator<X509Certificate> it = caChain.iterator();
205233
int i = 1;
206234
while (it.hasNext()) {
@@ -209,9 +237,7 @@ public Certificate[] engineGetCertificateChain(String alias) {
209237
} else {
210238
caList = new Certificate[1];
211239
}
212-
213-
caList[0] = leaf;
214-
240+
caList[0] = modLeaf;
215241
return caList;
216242
}
217243

0 commit comments

Comments
 (0)