summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStevenWdV <stevenwdv@gmail.com>2021-11-29 00:12:42 +0100
committerStevenWdV <stevenwdv@gmail.com>2021-11-29 00:12:42 +0100
commitf463d4c1a550c4b3dfc0be362f0b0a723a88122d (patch)
tree9b85337f1d9eda3d7070cd57d952712cfe2ae6cc
parent60658378f68cc7c67cbea2758c6aef455c115c05 (diff)
Improve Java wrapper: add all tests, link correct libraries, use Maven, add Makefile & GitHub workflow. Fix make clean targets.
-rw-r--r--.github/workflows/test.yml4
-rw-r--r--Makefile24
-rw-r--r--wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java5
-rw-r--r--wrappers/EduVpnCommon/tests/eduvpncommon/VerifyTests.java31
-rw-r--r--wrappers/java/.gitignore1
-rw-r--r--wrappers/java/Makefile14
-rw-r--r--wrappers/java/README.md31
-rw-r--r--wrappers/java/pom.xml102
-rw-r--r--wrappers/java/src/main/java/nl/eduvpn/common/Discovery.java (renamed from wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java)20
-rw-r--r--wrappers/java/src/main/java/nl/eduvpn/common/VerifyException.java9
-rw-r--r--wrappers/java/src/test/java/nl/eduvpn/common/VerifyTests.java78
-rw-r--r--wrappers/python/Makefile3
12 files changed, 267 insertions, 55 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index b96901f..ab46a47 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -26,4 +26,8 @@ jobs:
- uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
+ - uses: actions/setup-java@v2
+ with:
+ distribution: temurin
+ java-version: 9
- run: make test-wrappers
diff --git a/Makefile b/Makefile
index ba9756d..a19af3e 100644
--- a/Makefile
+++ b/Makefile
@@ -8,16 +8,24 @@ test: test-go test-wrappers
test-go:
go test
+wrappers = $(wildcard wrappers/*/)
+
# Enable parallelism if -j is specified
test-wrappers: build
- $(MAKE) .test-csharp .test-python
-
-.test-csharp:
- $(MAKE) -C wrappers/csharp test
-
-.test-python:
- $(MAKE) -C wrappers/python test
+ $(MAKE) $(foreach wrapper,$(wrappers),.test_$(wrapper))
clean:
$(MAKE) -C exports clean
- $(MAKE) -C wrappers/csharp clean
+ $(MAKE) .clean_libs $(foreach wrapper,$(wrappers),.clean_$(wrapper) )
+
+.clean_libs:
+ $(MAKE) -C exports clean
+
+define wrapper_targets
+.test_$(1):
+ $(MAKE) -C $(1) test
+.clean_$(1):
+ $(MAKE) -C $(1) clean
+endef
+
+$(foreach wrapper,$(wrappers),$(eval $(call wrapper_targets,$(wrapper))))
diff --git a/wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java b/wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java
deleted file mode 100644
index a81aceb..0000000
--- a/wrappers/EduVpnCommon/src/eduvpncommon/VerifyException.java
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 117f5ef..0000000
--- a/wrappers/EduVpnCommon/tests/eduvpncommon/VerifyTests.java
+++ /dev/null
@@ -1,31 +0,0 @@
-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
diff --git a/wrappers/java/.gitignore b/wrappers/java/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/wrappers/java/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/wrappers/java/Makefile b/wrappers/java/Makefile
new file mode 100644
index 0000000..03e7d88
--- /dev/null
+++ b/wrappers/java/Makefile
@@ -0,0 +1,14 @@
+.PHONY: build pack test clean
+
+build:
+ mvn compile
+
+pack:
+ mvn package
+
+test:
+ $(MAKE) -C ../../exports
+ mvn test
+
+clean:
+ mvn clean
diff --git a/wrappers/java/README.md b/wrappers/java/README.md
new file mode 100644
index 0000000..87cdd49
--- /dev/null
+++ b/wrappers/java/README.md
@@ -0,0 +1,31 @@
+# Java wrapper
+
+## Requirements
+
+You will need to install JDK 8 or later ([Adoptium](https://adoptium.net/)
+or [Oracle](https://www.oracle.com/java/technologies/downloads/)). To easily compile the project, you should
+download [Maven](https://maven.apache.org/).
+
+## Build & test
+
+First build the shared Go library. Next:
+
+Build `EduVpnCommon`:
+
+```shell
+make
+```
+
+Build as JAR, including eduvpn_verify library:
+
+```shell
+make pack
+```
+
+The JAR will include all versions of the library that are built in the `exports` folder.
+
+Test:
+
+```shell
+make test
+```
diff --git a/wrappers/java/pom.xml b/wrappers/java/pom.xml
new file mode 100644
index 0000000..bd9f721
--- /dev/null
+++ b/wrappers/java/pom.xml
@@ -0,0 +1,102 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>nl.eduvpn.common</groupId>
+ <version>0.1.0</version>
+ <packaging>jar</packaging>
+
+ <artifactId>eduvpncommon</artifactId>
+ <name>eduVPN common library</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>net.java.dev.jna</groupId>
+ <artifactId>jna</artifactId>
+ <version>5.10.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-api</artifactId>
+ <version>5.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>5.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <!-- See com.sun.jna.Platform#getNativeLibraryResourcePrefix -->
+
+ <resource>
+ <directory>../../exports/linux/amd64</directory>
+ <includes>
+ <include>*.so</include>
+ </includes>
+ <targetPath>linux-x86-64</targetPath>
+ </resource>
+ <resource>
+ <directory>../../exports/linux/arm</directory>
+ <includes>
+ <include>*.so</include>
+ </includes>
+ <targetPath>linux-arm</targetPath>
+ </resource>
+ <resource>
+ <directory>../../exports/linux/arm64</directory>
+ <includes>
+ <include>*.so</include>
+ </includes>
+ <targetPath>linux-arm64</targetPath>
+ </resource>
+
+ <resource>
+ <directory>../../exports/windows/amd64</directory>
+ <includes>
+ <include>*.dll</include>
+ </includes>
+ <targetPath>win32-x86-64</targetPath>
+ </resource>
+ <resource>
+ <directory>../../exports/windows/386</directory>
+ <includes>
+ <include>*.dll</include>
+ </includes>
+ <targetPath>win32-x86</targetPath>
+ </resource>
+ <resource>
+ <directory>../../exports/windows/arm</directory>
+ <includes>
+ <include>*.dll</include>
+ </includes>
+ <targetPath>win32-arm</targetPath>
+ </resource>
+ <resource>
+ <directory>../../exports/windows/arm64</directory>
+ <includes>
+ <include>*.dll</include>
+ </includes>
+ <targetPath>win32-arm64</targetPath>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.22.1</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+
diff --git a/wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java b/wrappers/java/src/main/java/nl/eduvpn/common/Discovery.java
index 6c27eee..d73a3d2 100644
--- a/wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java
+++ b/wrappers/java/src/main/java/nl/eduvpn/common/Discovery.java
@@ -1,14 +1,12 @@
-package eduvpncommon;
+package nl.eduvpn.common;
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);
+ private static final NativeApi discovery = Native.load("eduvpn_verify", NativeApi.class);
/**
* Verifies the signature on the JSON server_list.json/organization_list.json file.
@@ -18,14 +16,17 @@ public class Discovery {
* @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.
+ * @throws IllegalArgumentException If {@code expectedFileName} is not one of the allowed values or one of the parameters is empty.
+ * @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()
+ if (err != 0) {
+ if (err == 1) throw new IllegalArgumentException("Unknown excpectedFileName");
+ throw new VerifyException(err);
+ }
}
/**
@@ -37,6 +38,7 @@ public class Discovery {
}
private interface NativeApi extends Library {
+ @Structure.FieldOrder({"data", "len", "cap"})
class GoSlice extends Structure implements Structure.ByValue {
public Pointer data;
public long len, cap;
@@ -52,10 +54,6 @@ public class Discovery {
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);
diff --git a/wrappers/java/src/main/java/nl/eduvpn/common/VerifyException.java b/wrappers/java/src/main/java/nl/eduvpn/common/VerifyException.java
new file mode 100644
index 0000000..83dffb1
--- /dev/null
+++ b/wrappers/java/src/main/java/nl/eduvpn/common/VerifyException.java
@@ -0,0 +1,9 @@
+package nl.eduvpn.common;
+
+public class VerifyException extends Exception {
+ public final long code; //TODO not use plain long
+
+ public VerifyException(long code) {
+ this.code = code;
+ }
+} \ No newline at end of file
diff --git a/wrappers/java/src/test/java/nl/eduvpn/common/VerifyTests.java b/wrappers/java/src/test/java/nl/eduvpn/common/VerifyTests.java
new file mode 100644
index 0000000..b4767a5
--- /dev/null
+++ b/wrappers/java/src/test/java/nl/eduvpn/common/VerifyTests.java
@@ -0,0 +1,78 @@
+package nl.eduvpn.common;
+
+import org.junit.jupiter.api.Assertions;
+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;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class VerifyTests {
+ private static final Path testDataDir = Paths.get("../../test_data");
+
+ @SuppressWarnings("OptionalGetWithoutIsPresent")
+ @BeforeAll
+ static void oneTimeSetup() throws IOException {
+ Discovery.insecureTestingSetExtraKey(Files.lines(testDataDir.resolve("dummy/public.key")).reduce((a, b) -> b).get());
+ }
+
+ @Test
+ void testValid() {
+ assertDoesNotThrow(() ->
+ Discovery.verify(
+ Files.readAllBytes(testDataDir.resolve("dummy/server_list.json.minisig")),
+ Files.readAllBytes(testDataDir.resolve("dummy/server_list.json")),
+ "server_list.json",
+ Instant.EPOCH
+ ));
+ }
+
+ @Test
+ void testInvalidSignature() {
+ Assertions.assertEquals(2, assertThrows(VerifyException.class, () ->
+ Discovery.verify(
+ Files.readAllBytes(testDataDir.resolve("dummy/random.txt")),
+ Files.readAllBytes(testDataDir.resolve("dummy/server_list.json")),
+ "server_list.json",
+ Instant.EPOCH
+ )).code);
+ }
+
+ @Test
+ void testWrongKey() {
+ assertEquals(3, assertThrows(VerifyException.class, () ->
+ Discovery.verify(
+ Files.readAllBytes(testDataDir.resolve("dummy/server_list.json.wrong_key.minisig")),
+ Files.readAllBytes(testDataDir.resolve("dummy/server_list.json")),
+ "server_list.json",
+ Instant.EPOCH
+ )).code);
+ }
+
+ @Test
+ void testOldSignature() {
+ assertEquals(4, assertThrows(VerifyException.class, () ->
+ Discovery.verify(
+ Files.readAllBytes(testDataDir.resolve("dummy/server_list.json.minisig")),
+ Files.readAllBytes(testDataDir.resolve("dummy/server_list.json")),
+ "server_list.json",
+ Instant.MAX
+ )).code);
+ }
+
+ @Test
+ void testUnknownExpectedFile() {
+ assertThrows(IllegalArgumentException.class, () ->
+ Discovery.verify(
+ Files.readAllBytes(testDataDir.resolve("dummy/other_list.json.minisig")),
+ Files.readAllBytes(testDataDir.resolve("dummy/other_list.json")),
+ "other_list.json",
+ Instant.EPOCH
+ ));
+ }
+} \ No newline at end of file
diff --git a/wrappers/python/Makefile b/wrappers/python/Makefile
index 77c620e..690901f 100644
--- a/wrappers/python/Makefile
+++ b/wrappers/python/Makefile
@@ -6,3 +6,6 @@ compile:
test:
$(MAKE) -C ../../exports
python3 -m unittest test_discovery
+
+clean:
+ # Nothing to do