Calendar Lite 1.6: bundled TLS 1.2, renamed from GingerCal, new icons, English months #1

Merged
xocko merged 8 commits from bundled-tls into main 2026-10-19 17:11:39 +00:00
Showing only changes of commit 5eeaf0f519 - Show all commits
+14 -6
View File
@@ -49,9 +49,11 @@ public final class CertVerifier {
public static final class Untrusted extends IOException {
public final String fingerprint, subject, issuer, expires;
public final boolean changed; // a pin was set and this is a different certificate
public final List<byte[]> chain; // as the server sent it, leaf first
Untrusted(String fp, String subject, String issuer, String expires, boolean changed) {
Untrusted(String fp, String subject, String issuer, String expires, boolean changed, List<byte[]> chain) {
super("untrusted certificate " + fp);
this.chain = chain;
this.fingerprint = fp;
this.subject = subject;
this.issuer = issuer;
@@ -93,7 +95,8 @@ public final class CertVerifier {
}
}
private static Untrusted untrusted(byte[] leafDer, boolean changed) {
private static Untrusted untrusted(List<byte[]> chainDer, boolean changed) {
byte[] leafDer = chainDer.get(0);
String subject = "?", issuer = "?", expires = "?";
try {
Certificate c = Certificate.getInstance(leafDer);
@@ -101,7 +104,7 @@ public final class CertVerifier {
issuer = String.valueOf(c.getIssuer());
expires = new java.text.SimpleDateFormat("yyyy-MM-dd", Locale.US).format(c.getEndDate().getDate());
} catch (Exception ignored) {}
return new Untrusted(sha256(leafDer), subject, issuer, expires, changed);
return new Untrusted(sha256(leafDer), subject, issuer, expires, changed, chainDer);
}
/** Lookup of trusted root certificates (DER) by the DER encoding of their subject name. */
@@ -130,7 +133,7 @@ public final class CertVerifier {
if (p.length() > 0) {
// a pinned server: exactly that certificate, whatever its name or issuer
if (norm(sha256(chainDer.get(0))).equals(p)) return;
throw untrusted(chainDer.get(0), true);
throw untrusted(chainDer, true);
}
if (roots == null) throw new IOException("No trust store configured");
java.io.ByteArrayOutputStream all = new java.io.ByteArrayOutputStream();
@@ -149,6 +152,7 @@ public final class CertVerifier {
}
private static void verifyFully(List<byte[]> chainDer, String host) throws IOException {
final List<byte[]> chain0 = chainDer;
List<Certificate> chain = new ArrayList<Certificate>();
for (int i = 0; i < chainDer.size(); i++) chain.add(Certificate.getInstance(chainDer.get(i)));
@@ -171,9 +175,13 @@ public final class CertVerifier {
// 1. Anchored directly by a trusted root?
List<byte[]> anchors = roots.find(issuerDer);
if (anchors != null) {
byte[] currentDer = current.getEncoded(ASN1Encoding.DER);
for (int i = 0; i < anchors.size(); i++) {
// the very certificate the user chose to trust (e.g. self-signed)
if (java.util.Arrays.equals(anchors.get(i), currentDer)) return;
Certificate root = Certificate.getInstance(anchors.get(i));
if (signatureValid(current, root)) return; // trusted
// anything that signs must be a CA: a trusted site's own certificate can't vouch for another
if (isCa(root) && signatureValid(current, root)) return; // trusted
}
}
@@ -186,7 +194,7 @@ public final class CertVerifier {
if (!isCa(cand)) continue;
if (signatureValid(current, cand)) { next = cand; break; }
}
if (next == null) throw untrusted(chainDer.get(0), false);
if (next == null) throw untrusted(chain0, false);
current = next;
}
throw new IOException("Certificate chain too long");