]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/DeviceLinkInfo.java
Reduce direct use of recipient store
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / DeviceLinkInfo.java
1 package org.asamk.signal.manager;
2
3 import org.asamk.signal.manager.api.InvalidDeviceLinkException;
4 import org.asamk.signal.manager.util.Utils;
5 import org.signal.libsignal.protocol.InvalidKeyException;
6 import org.signal.libsignal.protocol.ecc.Curve;
7 import org.signal.libsignal.protocol.ecc.ECPublicKey;
8
9 import java.net.URI;
10 import java.net.URISyntaxException;
11 import java.net.URLEncoder;
12 import java.nio.charset.StandardCharsets;
13 import java.util.Base64;
14
15 import static org.whispersystems.signalservice.internal.util.Util.isEmpty;
16
17 public record DeviceLinkInfo(String deviceIdentifier, ECPublicKey deviceKey) {
18
19 public static DeviceLinkInfo parseDeviceLinkUri(URI linkUri) throws InvalidDeviceLinkException {
20 final var rawQuery = linkUri.getRawQuery();
21 if (isEmpty(rawQuery)) {
22 throw new RuntimeException("Invalid device link uri");
23 }
24
25 var query = Utils.getQueryMap(rawQuery);
26 var deviceIdentifier = query.get("uuid");
27 var publicKeyEncoded = query.get("pub_key");
28
29 if (isEmpty(deviceIdentifier) || isEmpty(publicKeyEncoded)) {
30 throw new InvalidDeviceLinkException("Invalid device link uri");
31 }
32
33 final byte[] publicKeyBytes;
34 try {
35 publicKeyBytes = Base64.getDecoder().decode(publicKeyEncoded);
36 } catch (IllegalArgumentException e) {
37 throw new InvalidDeviceLinkException("Invalid device link uri", e);
38 }
39 ECPublicKey deviceKey;
40 try {
41 deviceKey = Curve.decodePoint(publicKeyBytes, 0);
42 } catch (InvalidKeyException e) {
43 throw new InvalidDeviceLinkException("Invalid device link", e);
44 }
45
46 return new DeviceLinkInfo(deviceIdentifier, deviceKey);
47 }
48
49 public URI createDeviceLinkUri() {
50 final var deviceKeyString = Base64.getEncoder().encodeToString(deviceKey.serialize()).replace("=", "");
51 try {
52 return new URI("sgnl://linkdevice?uuid="
53 + URLEncoder.encode(deviceIdentifier, StandardCharsets.UTF_8)
54 + "&pub_key="
55 + URLEncoder.encode(deviceKeyString, StandardCharsets.UTF_8));
56 } catch (URISyntaxException e) {
57 throw new AssertionError(e);
58 }
59 }
60 }