diff --git a/pom.xml b/pom.xml
index 30800fb..c637bb0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.openautonomousconnection
Protocol
- 1.0.0-BETA.7.2
+ 1.0.0-BETA.7.3
Open Autonomous Connection
https://open-autonomous-connection.org/
diff --git a/src/main/java/org/openautonomousconnection/protocol/packets/v1_0_0/beta/AuthPacket.java b/src/main/java/org/openautonomousconnection/protocol/packets/v1_0_0/beta/AuthPacket.java
index c64dd7f..2498d23 100644
--- a/src/main/java/org/openautonomousconnection/protocol/packets/v1_0_0/beta/AuthPacket.java
+++ b/src/main/java/org/openautonomousconnection/protocol/packets/v1_0_0/beta/AuthPacket.java
@@ -13,6 +13,7 @@ import org.openautonomousconnection.protocol.side.server.CustomConnectedClient;
import org.openautonomousconnection.protocol.side.server.events.S_CustomClientConnectedEvent;
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSResponseStatus;
+import org.openautonomousconnection.protocol.versions.v1_0_0.beta.TOFUFeedback;
import java.io.*;
import java.util.UUID;
@@ -59,9 +60,7 @@ public final class AuthPacket extends OACPacket {
if (protocolBridge.isRunningAsINSServer()) {
objectOutputStream.writeUTF(protocolBridge.getProtocolVersion().name());
- String caKey = "N/A";
String caPem = "N/A";
- String caSrl = "N/A";
try {
String caPrefix = protocolBridge.getProtocolServer().getFolderStructure().getCaPrefix()
@@ -69,32 +68,19 @@ public final class AuthPacket extends OACPacket {
objectOutputStream.writeUTF(caPrefix);
- caKey = FileUtils.readFileFull(new File(
- protocolBridge.getProtocolServer().getFolderStructure().privateCAFolder,
- caPrefix + ".key"));
-
caPem = FileUtils.readFileFull(new File(
protocolBridge.getProtocolServer().getFolderStructure().publicCAFolder,
caPrefix + ".pem"));
-
- caSrl = FileUtils.readFileFull(new File(
- protocolBridge.getProtocolServer().getFolderStructure().publicCAFolder,
- caPrefix + ".srl"));
} catch (Exception exception) {
protocolBridge.getLogger().exception("Failed to read ca-files", exception);
setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED);
}
- objectOutputStream.writeUTF(caKey);
objectOutputStream.writeUTF(caPem);
- objectOutputStream.writeUTF(caSrl);
return;
}
if (protocolBridge.isRunningAsClient()) {
- // FIX: Send the connection id of the connection this auth is meant for.
- // If we are connecting/authing against INS, use INS connectionId.
- // Otherwise use Server connectionId.
UUID clientConnectionId = null;
if (protocolBridge.getProtocolClient() != null) {
@@ -161,27 +147,58 @@ public final class AuthPacket extends OACPacket {
setResponseCode(INSResponseStatus.RESPONSE_AUTH_SUCCESS);
String caPrefix = objectInputStream.readUTF();
-
- String caKey = objectInputStream.readUTF();
String caPem = objectInputStream.readUTF();
- String caSrl = objectInputStream.readUTF();
- if (caKey.equalsIgnoreCase("N/A") || caPem.equalsIgnoreCase("N/A") || caSrl.equalsIgnoreCase("N/A")) {
+ if (!caPrefix.matches("^[a-zA-Z0-9_-]+$")) {
+ setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED);
+ return;
+ }
+
+ if (caPem.equalsIgnoreCase("N/A")) {
setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED);
} else {
+
+ byte[] caBytes = caPem.getBytes(java.nio.charset.StandardCharsets.UTF_8);
+ java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256");
+ String fp = java.util.HexFormat.of().formatHex(md.digest(caBytes));
+
+
File caPemFile = new File(protocolBridge.getProtocolClient().getFolderStructure().publicCAFolder, caPrefix + ".pem");
- File caSrlFile = new File(protocolBridge.getProtocolClient().getFolderStructure().publicCAFolder, caPrefix + ".srl");
- File caKeyFile = new File(protocolBridge.getProtocolClient().getFolderStructure().privateCAFolder, caPrefix + ".key");
+
+ File fpFile = new File(
+ protocolBridge.getProtocolClient().getFolderStructure().publicCAFolder,
+ caPrefix + ".fp");
+
+ boolean allowWritePem = false;
+
+ if (fpFile.exists()) {
+ String existing = FileUtils.readFileFull(fpFile).trim();
+ TOFUFeedback feedback = protocolBridge.getProtocolClient().insFingerprintChanged(existing, fp);
+ if (feedback == TOFUFeedback.DISCONNECT) {
+ setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED);
+ protocolBridge.getProtocolClient().getClientINSConnection().disconnect();
+ return;
+ }
+ if (feedback == TOFUFeedback.TRUST) { FileUtils.writeFile(fpFile, fp + System.lineSeparator()); allowWritePem = true; }
+ } else {
+ TOFUFeedback feedback = protocolBridge.getProtocolClient().trustINS(fp);
+ if (feedback == TOFUFeedback.DISCONNECT) {
+ setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED);
+ protocolBridge.getProtocolClient().getClientINSConnection().disconnect();
+ return;
+ }
+ if (feedback == TOFUFeedback.TRUST) { FileUtils.writeFile(fpFile, fp + System.lineSeparator()); allowWritePem = true; }
+ }
+
+ if (!allowWritePem) {
+ setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED); return;
+ }
try {
if (!caPemFile.exists()) caPemFile.createNewFile();
- if (!caSrlFile.exists()) caSrlFile.createNewFile();
- if (!caKeyFile.exists()) caKeyFile.createNewFile();
// FIX: Correct file assignments.
FileUtils.writeFile(caPemFile, caPem);
- FileUtils.writeFile(caSrlFile, caSrl);
- FileUtils.writeFile(caKeyFile, caKey);
} catch (Exception exception) {
protocolBridge.getLogger().exception("Failed to create/save ca-files", exception);
setResponseCode(INSResponseStatus.RESPONSE_AUTH_FAILED);
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolClient.java b/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolClient.java
index 521ef10..12ba2eb 100644
--- a/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolClient.java
+++ b/src/main/java/org/openautonomousconnection/protocol/side/client/ProtocolClient.java
@@ -18,11 +18,8 @@ import org.openautonomousconnection.protocol.versions.ProtocolVersion;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecord;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecordType;
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSResponseStatus;
+import org.openautonomousconnection.protocol.versions.v1_0_0.beta.TOFUFeedback;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -320,7 +317,7 @@ public abstract class ProtocolClient extends EventListener {
onQuerySent(tln, name, sub, type);
}
- public final void disconnectFromServer() {
+ private final void disconnectFromServer() {
if (clientToServer != null) {
protocolBridge.getProtocolValues().eventManager.unregisterListener(this);
clientToServer.disconnect();
@@ -334,6 +331,9 @@ public abstract class ProtocolClient extends EventListener {
public void onQuerySent(String tln, String name, String sub, INSRecordType type) {
}
+ public abstract TOFUFeedback trustINS(String caFingerprint);
+ public abstract TOFUFeedback insFingerprintChanged(String oldCAFingerprint, String newCAFingerprint);
+
public static final class ClientCertificateFolderStructure {
public final File certificatesFolder;
diff --git a/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java b/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
index e22c9d8..55dd20e 100644
--- a/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
+++ b/src/main/java/org/openautonomousconnection/protocol/side/ins/ProtocolINSServer.java
@@ -1,8 +1,10 @@
package org.openautonomousconnection.protocol.side.ins;
import dev.unlegitdqrk.unlegitlibrary.file.ConfigurationManager;
+import dev.unlegitdqrk.unlegitlibrary.file.FileUtils;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.NetworkServer;
import dev.unlegitdqrk.unlegitlibrary.network.system.utils.ClientAuthMode;
+import dev.unlegitdqrk.unlegitlibrary.network.utils.NetworkUtils;
import lombok.Getter;
import org.openautonomousconnection.protocol.annotations.ProtocolInfo;
import org.openautonomousconnection.protocol.side.server.ProtocolCustomServer;
@@ -14,6 +16,7 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import java.io.File;
import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.List;
@@ -58,8 +61,17 @@ public abstract class ProtocolINSServer extends ProtocolCustomServer {
this.insFrontendSite = insFrontendSite;
}
- public void start(int tcpPort) throws IOException, InterruptedException {
+ public void start(int tcpPort) throws IOException, InterruptedException, NoSuchAlgorithmException {
getNetwork().start(tcpPort, -1);
+
+ String caPrefix = getFolderStructure().getCaPrefix() + NetworkUtils.getPublicIPAddress();
+ File caPemFile = new File(getFolderStructure().publicCAFolder, caPrefix + ".pem");
+
+ byte[] caBytes = FileUtils.readFileFull(caPemFile).getBytes(java.nio.charset.StandardCharsets.UTF_8);
+ java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256");
+ String fp = java.util.HexFormat.of().formatHex(md.digest(caBytes));
+
+ System.out.println("CA Fingerprint: " + fp);
}
/**
diff --git a/src/main/java/org/openautonomousconnection/protocol/versions/v1_0_0/beta/TOFUFeedback.java b/src/main/java/org/openautonomousconnection/protocol/versions/v1_0_0/beta/TOFUFeedback.java
new file mode 100644
index 0000000..449945f
--- /dev/null
+++ b/src/main/java/org/openautonomousconnection/protocol/versions/v1_0_0/beta/TOFUFeedback.java
@@ -0,0 +1,7 @@
+package org.openautonomousconnection.protocol.versions.v1_0_0.beta;
+
+public enum TOFUFeedback {
+
+ TRUST, TRUST_ONCE, DISCONNECT
+
+}