Skip to content

Commit

Permalink
Manual sort certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
vvb2060 committed Nov 16, 2023
1 parent 6af8785 commit 9d262fb
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@

import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.security.cert.CertPath;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import co.nstant.in.cbor.CborDecoder;
Expand Down Expand Up @@ -207,4 +209,68 @@ public static AttestationResult parseCertificateChain(List<X509Certificate> cert

return AttestationResult.form(infoList);
}

private static List<X509Certificate> sortCerts(List<X509Certificate> certs) {
if (certs.size() < 2) {
return certs;
}

var issuer = certs.get(0).getIssuerX500Principal();
boolean okay = true;
for (var cert : certs) {
var subject = cert.getSubjectX500Principal();
if (issuer.equals(subject)) {
issuer = subject;
} else {
okay = false;
break;
}
}
if (okay) {
return certs;
}

var newList = new ArrayList<X509Certificate>(certs.size());
for (var cert : certs) {
boolean found = false;
var subject = cert.getSubjectX500Principal();
for (var c : certs) {
if (c == cert) continue;
if (c.getIssuerX500Principal().equals(subject)) {
found = true;
break;
}
}
if (!found) {
newList.add(cert);
}
}
if (newList.size() != 1) {
return certs;
}

var oldList = new LinkedList<>(certs);
oldList.remove(newList.get(0));
for (int i = 0; i < newList.size(); i++) {
issuer = newList.get(i).getIssuerX500Principal();
for (var it = oldList.iterator(); it.hasNext(); ) {
var cert = it.next();
if (cert.getSubjectX500Principal().equals(issuer)) {
newList.add(cert);
it.remove();
break;
}
}
}
if (!oldList.isEmpty()) {
return certs;
}
return newList;
}

public static AttestationResult parseCertificateChain(CertPath certPath) {
// noinspection unchecked
var certs = (List<X509Certificate>) certPath.getCertificates();
return parseCertificateChain(sortCerts(certs));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,16 @@ class HomeViewModel(pm: PackageManager, private val sp: SharedPreferences) : Vie
val certPath = BufferedInputStream(cr.openInputStream(uri)).use {
try {
it.mark(8192)
cf.generateCertPath(it, "PKCS7")
cf.generateCertPath(it, "PkiPath")
} catch (_: CertificateException) {
it.reset()
cf.generateCertPath(it, "PkiPath")
cf.generateCertPath(it, "PKCS7")
}
}
val certs = certPath.certificates
if (certs.isEmpty()) throw CertificateParsingException("No certificate found")
@Suppress("UNCHECKED_CAST")
val attestationResult = parseCertificateChain(certs as List<X509Certificate>)
Resource.success(attestationResult)
if (certPath.certificates.isEmpty()) {
throw CertificateParsingException("No certificate found")
}
Resource.success(parseCertificateChain(certPath))
} catch (e: Throwable) {
val cause = if (e is AttestationException) e.cause else e
Log.w(AppApplication.TAG, "Load attestation error.", cause)
Expand Down

0 comments on commit 9d262fb

Please sign in to comment.