Skip to content

Commit 5c8de7e

Browse files
committed
Refactor provisioning
Make all provisioning functions truly async, split FinishNewDeviceRegistration into two functions
1 parent d8e4701 commit 5c8de7e

File tree

6 files changed

+106
-80
lines changed

6 files changed

+106
-80
lines changed

libsignal-service-dotnet/SignalServiceAccountManager.cs

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Collections.Generic;
1717
using System.Text;
1818
using System.Threading;
19+
using System.Threading.Tasks;
1920

2021
namespace libsignalservice
2122
{
@@ -57,7 +58,7 @@ public SignalServiceAccountManager(SignalServiceConfiguration configuration, Can
5758
{
5859
Configuration = configuration;
5960
UserAgent = userAgent;
60-
ProvisioningSocket = new ProvisioningSocket(configuration.SignalServiceUrls[0].Url, token);
61+
ProvisioningSocket = new ProvisioningSocket(configuration.SignalServiceUrls[0].Url);
6162
PushServiceSocket = new PushServiceSocket(configuration, new StaticCredentialsProvider(null, null, null, (int)SignalServiceAddress.DEFAULT_DEVICE_ID), userAgent);
6263
}
6364

@@ -224,10 +225,10 @@ public List<ContactTokenDetails> GetContacts(IList<string> e164numbers)
224225
/// </summary>
225226
/// <param name="token">The UUID, Base64 encoded</param>
226227
/// <returns></returns>
227-
public string GetNewDeviceUuid(CancellationToken token)
228+
public async Task<string> GetNewDeviceUuid(CancellationToken token)
228229
{
229-
ProvisioningSocket = new ProvisioningSocket(Configuration.SignalServiceUrls[0].Url, token);
230-
return ProvisioningSocket.GetProvisioningUuid().Uuid;
230+
ProvisioningSocket = new ProvisioningSocket(Configuration.SignalServiceUrls[0].Url);
231+
return (await ProvisioningSocket.GetProvisioningUuid(token)).Uuid;
231232
}
232233

233234
/// <summary>
@@ -241,41 +242,52 @@ public string GetNewDeviceVerificationCode()// throws IOException
241242
}
242243

243244
/// <summary>
244-
/// Finishes a registration as a new device.
245-
/// Called by the new device. This method blocks until the already verified device has verified this device.
245+
/// Fetch a ProvisionMessage from the server.
246246
/// </summary>
247+
/// <param name="token"></param>
247248
/// <param name="tempIdentity"></param>
248-
/// <param name="signalingKey"></param>
249-
/// <param name="password"></param>
250-
/// <param name="sms"></param>
251-
/// <param name="fetches"></param>
252-
/// <param name="regid"></param>
253-
/// <param name="name"></param>
254249
/// <returns></returns>
255-
public NewDeviceLinkResult FinishNewDeviceRegistration(IdentityKeyPair tempIdentity, string signalingKey, string password, bool sms, bool fetches, int regid, string name)
250+
public async Task<SignalServiceProvisionMessage> GetProvisioningMessage(CancellationToken token, IdentityKeyPair tempIdentity)
256251
{
257-
ProvisionMessage pm = ProvisioningSocket.GetProvisioningMessage(tempIdentity);
258-
string provisioningCode = pm.ProvisioningCode;
259-
byte[] publicKeyBytes = pm.IdentityKeyPublic.ToByteArray();
252+
ProvisionMessage protoPm = await ProvisioningSocket.GetProvisioningMessage(token, tempIdentity);
253+
string provisioningCode = protoPm.ProvisioningCode;
254+
byte[] publicKeyBytes = protoPm.IdentityKeyPublic.ToByteArray();
260255
if (publicKeyBytes.Length == 32)
261256
{
262257
byte[] type = { Curve.DJB_TYPE };
263258
publicKeyBytes = ByteUtil.combine(type, publicKeyBytes);
264259
}
265260
ECPublicKey publicKey = Curve.decodePoint(publicKeyBytes, 0);
266-
byte[] privateKeyBytes = pm.IdentityKeyPrivate.ToByteArray();
261+
byte[] privateKeyBytes = protoPm.IdentityKeyPrivate.ToByteArray();
267262
ECPrivateKey privateKey = Curve.decodePrivatePoint(privateKeyBytes);
268263
IdentityKeyPair identity = new IdentityKeyPair(new IdentityKey(publicKey), privateKey);
269-
PushServiceSocket = new PushServiceSocket(Configuration, new StaticCredentialsProvider(pm.Number, password, null, -1), UserAgent);
270-
int deviceId = PushServiceSocket.FinishNewDeviceRegistration(provisioningCode, signalingKey, sms, fetches, regid, name);
271-
return new NewDeviceLinkResult()
264+
return new SignalServiceProvisionMessage()
272265
{
273-
DeviceId = deviceId,
266+
Number = protoPm.Number,
274267
Identity = identity,
275-
Number = pm.Number
268+
Code = protoPm.ProvisioningCode
276269
};
277270
}
278271

272+
/// <summary>
273+
/// Finishes a registration as a new device.
274+
/// Called by the new device. This method blocks until the already verified device has verified this device.
275+
/// </summary>
276+
/// <param name="token"></param>
277+
/// <param name="provisionMessage"></param>
278+
/// <param name="signalingKey"></param>
279+
/// <param name="password"></param>
280+
/// <param name="sms"></param>
281+
/// <param name="fetches"></param>
282+
/// <param name="regid"></param>
283+
/// <param name="name"></param>
284+
/// <returns></returns>
285+
public async Task<int> FinishNewDeviceRegistration(CancellationToken token, SignalServiceProvisionMessage provisionMessage, string signalingKey, string password, bool sms, bool fetches, int regid, string name)
286+
{
287+
PushServiceSocket = new PushServiceSocket(Configuration, new StaticCredentialsProvider(provisionMessage.Number, password, null, -1), UserAgent);
288+
return await PushServiceSocket.FinishNewDeviceRegistration(token, provisionMessage.Code, signalingKey, sms, fetches, regid, name);
289+
}
290+
279291
/// <summary>
280292
/// TODO
281293
/// </summary>
@@ -414,11 +426,11 @@ private IDictionary<string, string> CreateDirectoryServerTokenMap(IList<string>
414426

415427

416428
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
417-
public class NewDeviceLinkResult
429+
public class SignalServiceProvisionMessage
418430
{
419-
public IdentityKeyPair Identity { get; set; }
420-
public int DeviceId { get; set; }
421-
public string Number { get; set; }
431+
public IdentityKeyPair Identity { get; internal set; }
432+
public string Number { get; internal set; }
433+
public string Code { get; internal set; }
422434
}
423435
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
424436
}

libsignal-service-dotnet/SignalServiceMessagePipe.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal SignalServiceMessagePipe(CancellationToken token, SignalWebSocketConnec
3232
this.Token = token;
3333
this.Websocket = websocket;
3434
this.CredentialsProvider = credentialsProvider;
35-
this.Websocket.Connect();
35+
this.Websocket.Connect(token).Wait();
3636
}
3737

3838
/// <summary>

libsignal-service-dotnet/push/ProvisioningSocket.cs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,42 @@
44
using libsignalservice.websocket;
55
using System.Collections.Concurrent;
66
using System.Threading;
7-
7+
using System.Threading.Tasks;
8+
89
namespace libsignal.push
910
{
10-
public class ProvisioningSocket
11+
internal class ProvisioningSocket
1112
{
1213
private WebSocketWrapper WebSocket;
1314
private string WsUri;
14-
private CancellationToken Token;
1515
private readonly BlockingCollection<byte[]> IncomingRequests = new BlockingCollection<byte[]>(new ConcurrentQueue<byte[]>());
1616

17-
public ProvisioningSocket(string httpUri, CancellationToken token)
17+
public ProvisioningSocket(string httpUri)
1818
{
19-
Token = token;
2019
WsUri = httpUri.Replace("https://", "wss://")
2120
.Replace("http://", "ws://") + "/v1/websocket/provisioning/";
22-
WebSocket = new WebSocketWrapper(WsUri, token);
21+
WebSocket = new WebSocketWrapper(WsUri);
2322
WebSocket.OnMessage(Connection_OnMessage);
23+
}
24+
25+
private async Task<byte[]> TakeAsync(CancellationToken token)
26+
{
27+
return await Task.Run(() =>
28+
{
29+
return IncomingRequests.Take(token); //TODO don't block
30+
});
2431
}
2532

26-
public ProvisioningUuid GetProvisioningUuid()
33+
public async Task<ProvisioningUuid> GetProvisioningUuid(CancellationToken token)
2734
{
28-
WebSocket.Connect();
29-
byte[] raw = IncomingRequests.Take(Token);
35+
await WebSocket.Connect(token);
36+
byte[] raw = await TakeAsync(token);
3037
return ProvisioningUuid.Parser.ParseFrom(WebSocketMessage.Parser.ParseFrom(raw).Request.Body);
3138
}
3239

33-
public ProvisionMessage GetProvisioningMessage(IdentityKeyPair tmpIdentity)
40+
public async Task<ProvisionMessage> GetProvisioningMessage(CancellationToken token, IdentityKeyPair tmpIdentity)
3441
{
35-
byte[] raw = IncomingRequests.Take(Token);
42+
byte[] raw = await TakeAsync(token);
3643
WebSocketMessage msg = WebSocketMessage.Parser.ParseFrom(raw);
3744
return new ProvisioningCipher(null).Decrypt(tmpIdentity, msg.Request.Body.ToByteArray());
3845
}

libsignal-service-dotnet/push/PushServiceSocket.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
using System.Security.Cryptography;
2626
using System.Security.Cryptography.X509Certificates;
2727
using System.Text;
28+
using System.Threading;
2829
using System.Threading.Tasks;
2930
using static libsignalservice.messages.SignalServiceAttachment;
3031

@@ -91,11 +92,11 @@ public bool SetAccountAttributes(string signalingKey, uint registrationId, bool
9192
return true;
9293
}
9394

94-
public int FinishNewDeviceRegistration(String code, String signalingKey, bool supportsSms, bool fetchesMessages, int registrationId, String deviceName)
95+
public async Task<int> FinishNewDeviceRegistration(CancellationToken token, String code, String signalingKey, bool supportsSms, bool fetchesMessages, int registrationId, String deviceName)
9596
{
9697
ConfirmCodeMessage javaJson = new ConfirmCodeMessage(signalingKey, supportsSms, fetchesMessages, registrationId, deviceName);
9798
string json = JsonUtil.toJson(javaJson);
98-
string responseText = MakeServiceRequest(string.Format(DEVICE_PATH, code), "PUT", json);
99+
string responseText = await MakeServiceRequestAsync(string.Format(DEVICE_PATH, code), "PUT", json);
99100
DeviceId response = JsonUtil.FromJson<DeviceId>(responseText);
100101
return response.NewDeviceId;
101102
}
@@ -612,6 +613,10 @@ private byte[] UploadAttachment(string method, string url, Stream data, long dat
612613
}
613614

614615
private string MakeServiceRequest(string urlFragment, string method, string body)
616+
{
617+
return MakeServiceRequestAsync(urlFragment, method, body).Result;
618+
}
619+
private async Task<string> MakeServiceRequestAsync(string urlFragment, string method, string body)
615620
//throws NonSuccessfulResponseCodeException, PushNetworkException
616621
{
617622
HttpResponseMessage connection = GetServiceConnection(urlFragment, method, body);
@@ -623,7 +628,8 @@ private string MakeServiceRequest(string urlFragment, string method, string body
623628
{
624629
responseCode = connection.StatusCode;
625630
responseMessage = connection.ReasonPhrase;
626-
responseBody = connection.Content.ReadAsStringAsync().Result;
631+
Debug.WriteLine(SynchronizationContext.Current);
632+
responseBody = await connection.Content.ReadAsStringAsync();
627633
}
628634
catch (Exception ioe)
629635
{

libsignal-service-dotnet/websocket/SignalWebSocketConnection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,15 @@ internal SignalWebSocketConnection(CancellationToken token, string httpUri, Cred
4545
.Replace("http://", "ws://") + $"/v1/websocket/?login={credentialsProvider.GetUser()}.{credentialsProvider.GetDeviceId()}&password={credentialsProvider.GetPassword()}";
4646
}
4747
UserAgent = userAgent;
48-
WebSocket = new WebSocketWrapper(WsUri, token);
48+
WebSocket = new WebSocketWrapper(WsUri);
4949
WebSocket.OnConnect(Connection_OnOpened);
5050
WebSocket.OnMessage(Connection_OnMessage);
5151
}
5252

53-
public void Connect()
53+
public async Task Connect(CancellationToken token)
5454
{
5555
Listener?.OnConnecting();
56-
WebSocket.Connect();
56+
await WebSocket.Connect(token);
5757
}
5858

5959
private void Connection_OnOpened()

0 commit comments

Comments
 (0)