From 1e13dac952d8f6cce7964aef27e98fa2e9da1eb7 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Fri, 3 Apr 2026 16:59:04 -0500 Subject: Release 1.4.0 Add richer SSL/TLS inspection details including negotiated TLS version, cipher suite, full certificate chain display, crt.sh lookup, and HSTS preload status. Persist HSTS preload in history/export and run the preload check in parallel with the SSL lookup. --- DomainDig/ContentView.swift | 62 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) (limited to 'DomainDig/ContentView.swift') diff --git a/DomainDig/ContentView.swift b/DomainDig/ContentView.swift index 87d8a85..c44f871 100644 --- a/DomainDig/ContentView.swift +++ b/DomainDig/ContentView.swift @@ -433,13 +433,13 @@ struct ContentView: View { } else if let error = viewModel.sslError { errorLabel(error) } else if let info = viewModel.sslInfo { - sslDetail(info) + sslDetail(info, domain: viewModel.searchedDomain) } } .padding(.top, 16) } - private func sslDetail(_ info: SSLCertificateInfo) -> some View { + private func sslDetail(_ info: SSLCertificateInfo, domain: String) -> some View { horizontallyScrollableCard(spacing: 8) { certRow("Common Name", info.commonName) certRow("Issuer", info.issuer) @@ -471,6 +471,41 @@ struct ContentView: View { } certRow("Chain Depth", "\(info.chainDepth)") + if viewModel.hstsLoading { + hstsLoadingRow + } else if let hstsPreloaded = viewModel.hstsPreloaded { + hstsStatusRow(hstsPreloaded) + } + if let tlsVersion = info.tlsVersion { + certRow("TLS Version", tlsVersion) + } + if let cipherSuite = info.cipherSuite { + certRow("Cipher Suite", cipherSuite) + } + if !info.chain.isEmpty { + VStack(alignment: .leading, spacing: 6) { + Text("Certificate Chain") + .font(.system(.caption2, design: .monospaced)) + .foregroundStyle(.secondary) + ForEach(Array(info.chain.enumerated()), id: \.offset) { index, certificate in + DisclosureGroup { + Text(certificate.issuer) + .font(.system(.caption, design: .monospaced)) + .foregroundStyle(.secondary) + .textSelection(.enabled) + } label: { + Text(certificate.subject) + .font(.system(.caption, design: .monospaced)) + .foregroundStyle(.primary) + .textSelection(.enabled) + } + .tint(index == 0 ? .cyan : .secondary) + } + } + } + Link("View on crt.sh →", destination: URL(string: "https://crt.sh/?q=\(domain)")!) + .font(.system(.caption, design: .monospaced)) + .foregroundStyle(.cyan) } } @@ -628,6 +663,29 @@ struct ContentView: View { } } + private var hstsLoadingRow: some View { + HStack { + Text("HSTS Preload") + .font(.system(.caption2, design: .monospaced)) + .foregroundStyle(.secondary) + Spacer() + ProgressView() + .controlSize(.small) + } + } + + private func hstsStatusRow(_ isPreloaded: Bool) -> some View { + HStack { + Text("HSTS Preload") + .font(.system(.caption2, design: .monospaced)) + .foregroundStyle(.secondary) + Spacer() + Text(isPreloaded ? "Preloaded" : "Not preloaded") + .font(.system(.caption, design: .monospaced)) + .foregroundStyle(isPreloaded ? .green : .secondary) + } + } + private func horizontallyScrollableCard( spacing: CGFloat = 4, @ViewBuilder content: () -> Content -- cgit v1.2.3