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 + +}