summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java68
-rw-r--r--wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java5
-rw-r--r--wrappers/EduVpnCommon/tests/eduvpncommon/VerifyTests.java31
3 files changed, 104 insertions, 0 deletions
diff --git a/wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java b/wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java
new file mode 100644
index 0000000..6c27eee
--- /dev/null
+++ b/wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java
@@ -0,0 +1,68 @@
+package eduvpncommon;
+
+import com.sun.jna.*;
+
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.util.*;
+
+public class Discovery {
+ private static final String libName = "eduvpn_verify";
+ private static final NativeApi discovery = Native.load(libName, NativeApi.class);
+
+ /**
+ * Verifies the signature on the JSON server_list.json/organization_list.json file.
+ * If the function returns the signature is valid for the given file type.
+ *
+ * @param signature .minisig signature file contents.
+ * @param signedJson Signed .json file contents.
+ * @param expectedFileName The file type to be verified, one of {@code "server_list.json"} or {@code "organization_list.json"}.
+ * @param minSignTime Minimum time for signature. Should be set to at least the time in a previously retrieved file.
+ * @throws VerifyException If signature verification fails.
+ */
+ public static void verify(byte[] signature, byte[] signedJson, String expectedFileName, Instant minSignTime) throws VerifyException {
+ long err = discovery.Verify(NativeApi.GoSlice.make(signature), NativeApi.GoSlice.make(signedJson),
+ NativeApi.GoSlice.make(expectedFileName.getBytes(StandardCharsets.UTF_8)),
+ minSignTime.getEpochSecond());
+ if (err != 0) throw new VerifyException();
+ //TODO throw new IllegalArgumentException()
+ }
+
+ /**
+ * Use for testing only, see Go documentation.
+ */
+ // package-private
+ static void insecureTestingSetExtraKey(String keyString) {
+ discovery.InsecureTestingSetExtraKey(NativeApi.GoSlice.make(keyString.getBytes(StandardCharsets.UTF_8)));
+ }
+
+ private interface NativeApi extends Library {
+ class GoSlice extends Structure implements Structure.ByValue {
+ public Pointer data;
+ public long len, cap;
+
+ public GoSlice(Pointer data, long len, long cap) {
+ this.data = data;
+ this.len = len;
+ this.cap = cap;
+ }
+
+ public static GoSlice make(byte[] bytes) {
+ Memory memory = new Memory(bytes.length);
+ memory.write(0, bytes, 0, bytes.length);
+ return new GoSlice(memory, bytes.length, bytes.length);
+ }
+
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("data", "len", "cap");
+ }
+ }
+
+ long Verify(GoSlice signatureFileContent, GoSlice signedJson, GoSlice expectedFileName, long minSignTime);
+
+ void InsecureTestingSetExtraKey(GoSlice keyString);
+ }
+
+ private Discovery() {
+ }
+}
diff --git a/wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java b/wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java
new file mode 100644
index 0000000..a81aceb
--- /dev/null
+++ b/wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java
@@ -0,0 +1,5 @@
+package eduvpncommon;
+
+public class VerifyException extends Exception {
+ //TODO
+} \ No newline at end of file
diff --git a/wrappers/EduVpnCommon/tests/eduvpncommon/VerifyTests.java b/wrappers/EduVpnCommon/tests/eduvpncommon/VerifyTests.java
new file mode 100644
index 0000000..117f5ef
--- /dev/null
+++ b/wrappers/EduVpnCommon/tests/eduvpncommon/VerifyTests.java
@@ -0,0 +1,31 @@
+package eduvpncommon;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.Instant;
+
+class VerifyTests {
+ private static final Path testDataDir = Paths.get("../../test_data");
+
+ @BeforeAll
+ static void oneTimeSetup() throws IOException {
+ Discovery.insecureTestingSetExtraKey(Files.lines(testDataDir.resolve("dummy/public.key")).reduce((a, b) -> b).get());
+ }
+
+ @Test
+ void testValid() throws IOException, VerifyException {
+ Discovery.verify(
+ Files.readAllBytes(Paths.get("../../test_data/dummy/server_list.json.minisig")),
+ Files.readAllBytes(Paths.get("../../test_data/dummy/server_list.json")),
+ "server_list.json",
+ Instant.EPOCH
+ );
+ }
+
+ //TODO
+} \ No newline at end of file