2 Copyright (C) 2015-2020 AsamK and contributors
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org
.asamk
.signal
.manager
;
19 import org
.asamk
.signal
.UserAlreadyExists
;
20 import org
.asamk
.signal
.storage
.SignalAccount
;
21 import org
.signal
.zkgroup
.InvalidInputException
;
22 import org
.signal
.zkgroup
.profiles
.ProfileKey
;
23 import org
.whispersystems
.libsignal
.IdentityKeyPair
;
24 import org
.whispersystems
.libsignal
.InvalidKeyException
;
25 import org
.whispersystems
.libsignal
.util
.KeyHelper
;
26 import org
.whispersystems
.signalservice
.api
.SignalServiceAccountManager
;
27 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
28 import org
.whispersystems
.signalservice
.api
.util
.SleepTimer
;
29 import org
.whispersystems
.signalservice
.api
.util
.UptimeSleepTimer
;
30 import org
.whispersystems
.signalservice
.internal
.configuration
.SignalServiceConfiguration
;
32 import java
.io
.IOException
;
33 import java
.util
.concurrent
.TimeoutException
;
35 public class ProvisioningManager
{
37 private final PathConfig pathConfig
;
38 private final SignalServiceConfiguration serviceConfiguration
;
39 private final String userAgent
;
41 private final SignalServiceAccountManager accountManager
;
42 private final IdentityKeyPair identityKey
;
43 private final int registrationId
;
44 private final String password
;
46 public ProvisioningManager(String settingsPath
, SignalServiceConfiguration serviceConfiguration
, String userAgent
) {
47 this.pathConfig
= PathConfig
.createDefault(settingsPath
);
48 this.serviceConfiguration
= serviceConfiguration
;
49 this.userAgent
= userAgent
;
51 identityKey
= KeyHelper
.generateIdentityKeyPair();
52 registrationId
= KeyHelper
.generateRegistrationId(false);
53 password
= KeyUtils
.createPassword();
54 final SleepTimer timer
= new UptimeSleepTimer();
55 accountManager
= new SignalServiceAccountManager(serviceConfiguration
, null, null, password
, SignalServiceAddress
.DEFAULT_DEVICE_ID
, userAgent
, timer
);
58 public String
getDeviceLinkUri() throws TimeoutException
, IOException
{
59 String deviceUuid
= accountManager
.getNewDeviceUuid();
61 return Utils
.createDeviceLinkUri(new Utils
.DeviceLinkInfo(deviceUuid
, identityKey
.getPublicKey().getPublicKey()));
64 public String
finishDeviceLink(String deviceName
) throws IOException
, InvalidKeyException
, TimeoutException
, UserAlreadyExists
{
65 String signalingKey
= KeyUtils
.createSignalingKey();
66 SignalServiceAccountManager
.NewDeviceRegistrationReturn ret
= accountManager
.finishNewDeviceRegistration(identityKey
, signalingKey
, false, true, registrationId
, deviceName
);
68 String username
= ret
.getNumber();
69 // TODO do this check before actually registering
70 if (SignalAccount
.userExists(pathConfig
.getDataPath(), username
)) {
71 throw new UserAlreadyExists(username
, SignalAccount
.getFileName(pathConfig
.getDataPath(), username
));
74 // Create new account with the synced identity
75 byte[] profileKeyBytes
= ret
.getProfileKey();
76 ProfileKey profileKey
;
77 if (profileKeyBytes
== null) {
78 profileKey
= KeyUtils
.createProfileKey();
81 profileKey
= new ProfileKey(profileKeyBytes
);
82 } catch (InvalidInputException e
) {
83 throw new IOException("Received invalid profileKey", e
);
86 SignalAccount account
= SignalAccount
.createLinkedAccount(pathConfig
.getDataPath(), username
, ret
.getUuid(), password
, ret
.getDeviceId(), ret
.getIdentity(), registrationId
, signalingKey
, profileKey
);
89 Manager m
= new Manager(account
, pathConfig
, serviceConfiguration
, userAgent
);
93 m
.requestSyncGroups();
94 m
.requestSyncContacts();
95 m
.requestSyncBlocked();
96 m
.requestSyncConfiguration();