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
.URLDecoder
;
9 import java
.net
.URLEncoder
;
10 import java
.nio
.charset
.StandardCharsets
;
11 import java
.util
.Base64
;
12 import java
.util
.HashMap
;
15 import static org
.whispersystems
.signalservice
.internal
.util
.Util
.isEmpty
;
17 public class DeviceLinkInfo
{
19 final String deviceIdentifier
;
20 final ECPublicKey deviceKey
;
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");
28 Map
<String
, String
> query
= getQueryMap(rawQuery
);
29 String deviceIdentifier
= query
.get("uuid");
30 String publicKeyEncoded
= query
.get("pub_key");
32 if (isEmpty(deviceIdentifier
) || isEmpty(publicKeyEncoded
)) {
33 throw new RuntimeException("Invalid device link uri");
36 final byte[] publicKeyBytes
;
38 publicKeyBytes
= Base64
.getDecoder().decode(publicKeyEncoded
);
39 } catch (IllegalArgumentException e
) {
40 throw new RuntimeException("Invalid device link uri", e
);
42 ECPublicKey deviceKey
= Curve
.decodePoint(publicKeyBytes
, 0);
44 return new DeviceLinkInfo(deviceIdentifier
, deviceKey
);
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
);
59 public DeviceLinkInfo(final String deviceIdentifier
, final ECPublicKey deviceKey
) {
60 this.deviceIdentifier
= deviceIdentifier
;
61 this.deviceKey
= deviceKey
;
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
)
69 + URLEncoder
.encode(deviceKeyString
, StandardCharsets
.UTF_8
);