]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/manager/DeviceLinkInfo.java
Convert gradle scripts to kotlin
[signal-cli] / src / main / java / org / asamk / signal / manager / DeviceLinkInfo.java
1 package org.asamk.signal.manager;
2
3 import org.whispersystems.libsignal.InvalidKeyException;
4 import org.whispersystems.libsignal.ecc.Curve;
5 import org.whispersystems.libsignal.ecc.ECPublicKey;
6
7 import java.net.URI;
8 import java.net.URLDecoder;
9 import java.net.URLEncoder;
10 import java.nio.charset.StandardCharsets;
11 import java.util.Base64;
12 import java.util.HashMap;
13 import java.util.Map;
14
15 import static org.whispersystems.signalservice.internal.util.Util.isEmpty;
16
17 public class DeviceLinkInfo {
18
19 final String deviceIdentifier;
20 final ECPublicKey deviceKey;
21
22 public static DeviceLinkInfo parseDeviceLinkUri(URI linkUri) throws InvalidKeyException {
23 final String rawQuery = linkUri.getRawQuery();
24 if (isEmpty(rawQuery)) {
25 throw new RuntimeException("Invalid device link uri");
26 }
27
28 Map<String, String> query = getQueryMap(rawQuery);
29 String deviceIdentifier = query.get("uuid");
30 String publicKeyEncoded = query.get("pub_key");
31
32 if (isEmpty(deviceIdentifier) || isEmpty(publicKeyEncoded)) {
33 throw new RuntimeException("Invalid device link uri");
34 }
35
36 final byte[] publicKeyBytes;
37 try {
38 publicKeyBytes = Base64.getDecoder().decode(publicKeyEncoded);
39 } catch (IllegalArgumentException e) {
40 throw new RuntimeException("Invalid device link uri", e);
41 }
42 ECPublicKey deviceKey = Curve.decodePoint(publicKeyBytes, 0);
43
44 return new DeviceLinkInfo(deviceIdentifier, deviceKey);
45 }
46
47 private static Map<String, String> getQueryMap(String query) {
48 String[] params = query.split("&");
49 Map<String, String> map = new HashMap<>();
50 for (String param : params) {
51 final String[] paramParts = param.split("=");
52 String name = URLDecoder.decode(paramParts[0], StandardCharsets.UTF_8);
53 String value = URLDecoder.decode(paramParts[1], StandardCharsets.UTF_8);
54 map.put(name, value);
55 }
56 return map;
57 }
58
59 public DeviceLinkInfo(final String deviceIdentifier, final ECPublicKey deviceKey) {
60 this.deviceIdentifier = deviceIdentifier;
61 this.deviceKey = deviceKey;
62 }
63
64 public String createDeviceLinkUri() {
65 final String deviceKeyString = Base64.getEncoder().encodeToString(deviceKey.serialize()).replace("=", "");
66 return "tsdevice:/?uuid="
67 + URLEncoder.encode(deviceIdentifier, StandardCharsets.UTF_8)
68 + "&pub_key="
69 + URLEncoder.encode(deviceKeyString, StandardCharsets.UTF_8);
70 }
71 }