diff --git a/app/src/main/java/io/github/vvb2060/keyattestation/repository/AttestationRepository.java b/app/src/main/java/io/github/vvb2060/keyattestation/repository/AttestationRepository.java index bfcf264..8d1ea8e 100644 --- a/app/src/main/java/io/github/vvb2060/keyattestation/repository/AttestationRepository.java +++ b/app/src/main/java/io/github/vvb2060/keyattestation/repository/AttestationRepository.java @@ -269,15 +269,26 @@ public Resource loadCerts(ParcelFileDescriptor pfd, boolean preferRsa) // 2a. Filter to RSA certs only if (parsedBinary && preferRsa && !currentCerts.isEmpty()) { - List rsaCerts = new ArrayList<>(); + int leafCount = 0; for (X509Certificate cert : currentCerts) { - if (cert.getPublicKey().getAlgorithm().equalsIgnoreCase("RSA")) { - rsaCerts.add(cert); - } + if (cert.getBasicConstraints() == -1) leafCount++; } - if (!rsaCerts.isEmpty()) { - currentCerts.clear(); - currentCerts.addAll(rsaCerts); + // A single end-entity cert == single chain, which may legitimately mix + // algorithms (EC leaf under the RSA root) + // Leave it intact and let the key type check below report any mismatch + if (leafCount > 1) { + List rsaCerts = new ArrayList<>(); + boolean hasLeaf = false; + for (X509Certificate cert : currentCerts) { + if (cert.getPublicKey().getAlgorithm().equalsIgnoreCase("RSA")) { + rsaCerts.add(cert); + if (cert.getBasicConstraints() == -1) hasLeaf = true; + } + } + if (hasLeaf) { + currentCerts.clear(); + currentCerts.addAll(rsaCerts); + } } } @@ -355,17 +366,26 @@ public Resource loadCerts(ParcelFileDescriptor pfd, boolean preferRsa) // Same algorithm filter as the binary path (2a) // the parser doesn't distinguish key blocks, so a mixed-algorithm keybox would // otherwise concatenate two unrelated chains into one list - if (!currentCerts.isEmpty()) { + int leafCount = 0; + for (X509Certificate cert : currentCerts) { + if (cert.getBasicConstraints() == -1) leafCount++; + } + // A single end-entity cert == single chain, which may legitimately mix + // algorithms (EC leaf under the RSA root) + // Leave it intact and let the key type check below report any mismatch + if (leafCount > 1) { List matching = new ArrayList<>(); + boolean hasLeaf = false; for (X509Certificate cert : currentCerts) { var algo = cert.getPublicKey().getAlgorithm(); if (algo.equalsIgnoreCase(preferRsa ? "RSA" : "EC") || (!preferRsa && algo.equalsIgnoreCase("ECDSA")) ) { matching.add(cert); + if (cert.getBasicConstraints() == -1) hasLeaf = true; } } - if (!matching.isEmpty()) { + if (hasLeaf) { currentCerts.clear(); currentCerts.addAll(matching); }