android: Adding tlsa verification v1

This commit is contained in:
Nathan Woodburn 2023-08-30 13:38:32 +10:00
parent 358d5e75af
commit 612b9f27e0
Signed by: nathanwoodburn
GPG Key ID: 203B000478AD0EF1
12 changed files with 84 additions and 10 deletions

Binary file not shown.

View File

@ -39,6 +39,7 @@ dependencies {
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
implementation("androidx.webkit:webkit:1.3.0")
implementation("androidx.core:core-splashscreen:1.0.0")
implementation("androidx.webkit:webkit:1.7.0")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("dnsjava:dnsjava:2.1.8")
}

View File

@ -3,8 +3,8 @@ package com.woodburn.hnsbrowser;
import androidx.appcompat.app.AppCompatActivity;
import androidx.webkit.ProxyConfig;
import androidx.webkit.ProxyController;
import android.net.http.SslError;
import android.os.AsyncTask;
import android.os.Bundle;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
@ -12,19 +12,27 @@ import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import java.net.InetAddress;
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.util.List;
import java.util.concurrent.Executor;
import android.net.DnsResolver;
import org.xbill.DNS.*;
public class WebActivity extends AppCompatActivity {
boolean sslError = false;
String url = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web);
Bundle bundle = getIntent().getExtras();
String url = bundle.getString("url");
url = bundle.getString("url");
// Validate
if (url == null || url.isEmpty()) {
// Display toast
@ -46,12 +54,77 @@ public class WebActivity extends AppCompatActivity {
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
if (!sslError) {
Toast.makeText(WebActivity.this, "SSL error", Toast.LENGTH_SHORT).show();
Toast.makeText(WebActivity.this, "Make sure you have installed the SSL certificate", Toast.LENGTH_SHORT).show();
}
sslError = true;
handler.proceed(); // Ignore SSL certificate errors
new Thread(new Runnable() {
@Override
public void run() {
boolean validSSL = false;
try {
Certificate certificate = error.getCertificate().getX509Certificate();
byte[] publicKeyBytes = certificate.getPublicKey().getEncoded();
MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256");
byte[] sha256Hash = sha256Digest.digest(publicKeyBytes);
// Print the hash in hexadecimal format
StringBuilder hexString = new StringBuilder();
for (byte b : sha256Hash) {
hexString.append(String.format("%02X", b));
}
// Get TLSA hash via DIG
String siteHash = hexString.toString();
String domain = url.replace("https://", "");
if (domain.contains("/")) {
domain = domain.substring(0, domain.indexOf("/"));
}
domain = "_443._tcp." + domain;
SimpleResolver resolver = new SimpleResolver("152.69.186.119");
Lookup lookup = new Lookup(domain, Type.TLSA);
lookup.setResolver(resolver);
Record[] records = lookup.run();
if (lookup.getResult() == Lookup.SUCCESSFUL) {
for (Record record : records) {
if (record instanceof TLSARecord) {
// Verify TLSA hash
TLSARecord tlsaRecord = (TLSARecord) record;
String tlsaHash = tlsaRecord.getCertificateAssociationData().toString().replace(" ", "");
runOnUiThread(() -> {
Toast.makeText(WebActivity.this, "TLSA: " + tlsaHash, Toast.LENGTH_SHORT).show();
Toast.makeText(WebActivity.this, "SITE: " + siteHash, Toast.LENGTH_SHORT).show();
});
if (tlsaHash.equals(siteHash)) {
validSSL = true;
}
}
}
} else
{
runOnUiThread(() -> {
Toast.makeText(WebActivity.this, "TLSA Lookup Failed!", Toast.LENGTH_SHORT).show();
Toast.makeText(WebActivity.this, lookup.getErrorString(), Toast.LENGTH_SHORT).show();
});
}
} catch (Exception e) {
runOnUiThread(() -> {
Toast.makeText(WebActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
});
}
if (!validSSL) {
sslError = true;
runOnUiThread(() -> {
Toast.makeText(WebActivity.this, "SSL NOT VALID!", Toast.LENGTH_SHORT).show();
});
} else {
runOnUiThread(() -> {
Toast.makeText(WebActivity.this, "SSL VALID!", Toast.LENGTH_SHORT).show();
});
}
}
}).start();
}
});
setProxy();