1 package org
.asamk
.signal
.manager
;
3 import org
.whispersystems
.libsignal
.InvalidKeyException
;
4 import org
.whispersystems
.libsignal
.ecc
.Curve
;
5 import org
.whispersystems
.libsignal
.ecc
.ECPublicKey
;
8 import java
.net
.URISyntaxException
;
9 import java
.net
.URLDecoder
;
10 import java
.net
.URLEncoder
;
11 import java
.nio
.charset
.StandardCharsets
;
12 import java
.util
.Base64
;
13 import java
.util
.HashMap
;
16 import static org
.whispersystems
.signalservice
.internal
.util
.Util
.isEmpty
;
18 public class DeviceLinkInfo
{
20 final String deviceIdentifier
;
21 final ECPublicKey deviceKey
;
23 public static DeviceLinkInfo
parseDeviceLinkUri(URI linkUri
) throws InvalidKeyException
{
24 final var rawQuery
= linkUri
.getRawQuery();
25 if (isEmpty(rawQuery
)) {
26 throw new RuntimeException("Invalid device link uri");
29 var query
= getQueryMap(rawQuery
);
30 var deviceIdentifier
= query
.get("uuid");
31 var publicKeyEncoded
= query
.get("pub_key");
33 if (isEmpty(deviceIdentifier
) || isEmpty(publicKeyEncoded
)) {
34 throw new RuntimeException("Invalid device link uri");
37 final byte[] publicKeyBytes
;
39 publicKeyBytes
= Base64
.getDecoder().decode(publicKeyEncoded
);
40 } catch (IllegalArgumentException e
) {
41 throw new RuntimeException("Invalid device link uri", e
);
43 var deviceKey
= Curve
.decodePoint(publicKeyBytes
, 0);
45 return new DeviceLinkInfo(deviceIdentifier
, deviceKey
);
48 private static Map
<String
, String
> getQueryMap(String query
) {
49 var params
= query
.split("&");
50 var map
= new HashMap
<String
, String
>();
51 for (var param
: params
) {
52 final var paramParts
= param
.split("=");
53 var name
= URLDecoder
.decode(paramParts
[0], StandardCharsets
.UTF_8
);
54 var value
= URLDecoder
.decode(paramParts
[1], StandardCharsets
.UTF_8
);
60 public DeviceLinkInfo(final String deviceIdentifier
, final ECPublicKey deviceKey
) {
61 this.deviceIdentifier
= deviceIdentifier
;
62 this.deviceKey
= deviceKey
;
65 public URI
createDeviceLinkUri() {
66 final var deviceKeyString
= Base64
.getEncoder().encodeToString(deviceKey
.serialize()).replace("=", "");
68 return new URI("tsdevice:/?uuid="
69 + URLEncoder
.encode(deviceIdentifier
, StandardCharsets
.UTF_8
)
71 + URLEncoder
.encode(deviceKeyString
, StandardCharsets
.UTF_8
));
72 } catch (URISyntaxException e
) {
73 throw new AssertionError(e
);