summaryrefslogtreecommitdiff
path: root/wrappers/EduVpnCommon/src/eduvpncommon/Discovery.java
blob: 6c27eeefab8390fcc8a6960633012e511739ac44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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() {
    }
}