public NewDeviceLinkResult FinishNewDeviceRegistration(IdentityKeyPair tempIdentity, string signalingKey, string password, bool sms, bool fetches, int regid, string name) { ProvisionMessage pm = ProvisioningSocket.GetProvisioningMessage(tempIdentity); string provisioningCode = pm.ProvisioningCode; byte[] publicKeyBytes = pm.IdentityKeyPublic.ToByteArray(); if (publicKeyBytes.Length == 32) { byte[] type = { Curve.DJB_TYPE }; publicKeyBytes = ByteUtil.combine(type, publicKeyBytes); } ECPublicKey publicKey = Curve.decodePoint(publicKeyBytes, 0); byte[] privateKeyBytes = pm.IdentityKeyPrivate.ToByteArray(); ECPrivateKey privateKey = Curve.decodePrivatePoint(privateKeyBytes); IdentityKeyPair identity = new IdentityKeyPair(new IdentityKey(publicKey), privateKey); pushServiceSocket = new PushServiceSocket(Urls, new StaticCredentialsProvider(pm.Number, password, null, -1), userAgent); int deviceId = pushServiceSocket.finishNewDeviceRegistration(provisioningCode, signalingKey, sms, fetches, regid, name); return(new NewDeviceLinkResult() { DeviceId = deviceId, Identity = identity, Number = pm.Number }); }
private async Task HandleMismatchedDevices(CancellationToken token, PushServiceSocket socket, SignalServiceAddress recipient, MismatchedDevices mismatchedDevices) { try { foreach (uint extraDeviceId in mismatchedDevices.ExtraDevices) { store.DeleteSession(new SignalProtocolAddress(recipient.E164number, extraDeviceId)); } foreach (uint missingDeviceId in mismatchedDevices.MissingDevices) { PreKeyBundle preKey = await socket.GetPreKey(token, recipient, missingDeviceId); try { SessionBuilder sessionBuilder = new SessionBuilder(store, new SignalProtocolAddress(recipient.E164number, missingDeviceId)); sessionBuilder.process(preKey); } catch (libsignal.exceptions.UntrustedIdentityException) { throw new UntrustedIdentityException("Untrusted identity key!", recipient.E164number, preKey.getIdentityKey()); } } } catch (InvalidKeyException e) { throw new Exception(e.Message); } }
private async Task <OutgoingPushMessageList> GetEncryptedMessages(CancellationToken token, PushServiceSocket socket, SignalServiceAddress recipient, long timestamp, byte[] plaintext, bool silent) { List <OutgoingPushMessage> messages = new List <OutgoingPushMessage>(); bool myself = recipient.Equals(localAddress); if (!myself || CredentialsProvider.DeviceId != SignalServiceAddress.DEFAULT_DEVICE_ID) { messages.Add(await GetEncryptedMessage(token, socket, recipient, SignalServiceAddress.DEFAULT_DEVICE_ID, plaintext, silent)); } foreach (uint deviceId in store.GetSubDeviceSessions(recipient.E164number)) { if (!myself || deviceId != CredentialsProvider.DeviceId) { if (store.ContainsSession(new SignalProtocolAddress(recipient.E164number, deviceId))) { messages.Add(await GetEncryptedMessage(token, socket, recipient, deviceId, plaintext, silent)); } } } return(new OutgoingPushMessageList(recipient.E164number, (ulong)timestamp, recipient.Relay, messages)); }
/// <summary> /// Construct a SignalServivceAccountManager. /// </summary> /// <param name="urls">The URL for the Signal Service.</param> /// <param name="user">A Signal Service phone number</param> /// <param name="password">A Signal Service password.</param> /// <param name="userAgent">A string which identifies the client software.</param> public SignalServiceAccountManager(SignalServiceUrl[] urls, string user, string password, string userAgent) { this.pushServiceSocket = new PushServiceSocket(urls, new StaticCredentialsProvider(user, password, null), userAgent); this.user = user; this.userAgent = userAgent; }
private void handleMismatchedDevices(PushServiceSocket socket, SignalServiceAddress recipient, MismatchedDevices mismatchedDevices) { try { foreach (uint extraDeviceId in mismatchedDevices.getExtraDevices()) { store.DeleteSession(new SignalProtocolAddress(recipient.getNumber(), extraDeviceId)); } foreach (uint missingDeviceId in mismatchedDevices.getMissingDevices()) { PreKeyBundle preKey = socket.getPreKey(recipient, missingDeviceId); try { SessionBuilder sessionBuilder = new SessionBuilder(store, new SignalProtocolAddress(recipient.getNumber(), missingDeviceId)); sessionBuilder.process(preKey); } catch (libsignal.exceptions.UntrustedIdentityException e) { throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey()); } } } catch (InvalidKeyException e) { throw new Exception(e.Message); } }
private OutgoingPushMessageList getEncryptedMessages(PushServiceSocket socket, SignalServiceAddress recipient, long timestamp, byte[] plaintext, bool legacy, bool silent) { List <OutgoingPushMessage> messages = new List <OutgoingPushMessage>(); bool myself = recipient.Equals(localAddress); if (!myself || CredentialsProvider.GetDeviceId() != SignalServiceAddress.DEFAULT_DEVICE_ID) { messages.Add(getEncryptedMessage(socket, recipient, SignalServiceAddress.DEFAULT_DEVICE_ID, plaintext, legacy, silent)); } foreach (uint deviceId in store.GetSubDeviceSessions(recipient.getNumber())) { if (!myself || deviceId != CredentialsProvider.GetDeviceId()) { messages.Add(getEncryptedMessage(socket, recipient, deviceId, plaintext, legacy, silent)); } } return(new OutgoingPushMessageList(recipient.getNumber(), (ulong)timestamp, recipient.getRelay().HasValue ? recipient.getRelay().ForceGetValue() : null, messages)); }
/** * Construct a TextSecureAccountManager. * * @param url The URL for the TextSecure server. * @param trustStore The {@link org.whispersystems.textsecure.api.push.TrustStore} for the TextSecure server's TLS certificate. * @param user A TextSecure phone number. * @param password A TextSecure password. */ public TextSecureAccountManager(String url, TrustStore trustStore, String user, String password, string userAgent) { this.pushServiceSocket = new PushServiceSocket(url, trustStore, new StaticCredentialsProvider(user, password, null), userAgent); this.user = user; this.userAgent = userAgent; }
/// <summary> /// Construct a SignalServiceMessageReceiver. /// </summary> /// <param name="urls">The URL of the Signal Service.</param> /// <param name="credentials">The Signal Service user's credentials</param> /// <param name="userAgent"></param> public SignalServiceMessageReceiver(SignalServiceConfiguration urls, ICredentialsProvider credentials, string userAgent, HttpClient httpClient) { Urls = urls; CredentialsProvider = credentials; Socket = new PushServiceSocket(urls, credentials, userAgent, httpClient); UserAgent = userAgent; }
/// <summary> /// Construct a SignalServivceAccountManager /// </summary> /// <param name="configuration">The URL configuration for the Signal Service</param> /// <param name="user">A Signal Service phone number</param> /// <param name="password">A Signal Service password</param> /// <param name="deviceId">A Signal Service device id</param> /// <param name="userAgent">A string which identifies the client software</param> public SignalServiceAccountManager(SignalServiceConfiguration configuration, string user, string password, int deviceId, string userAgent) { PushServiceSocket = new PushServiceSocket(configuration, new StaticCredentialsProvider(user, password, null, deviceId), userAgent); User = user; UserAgent = userAgent; }
/// <summary> /// Construct a SignalServiceMessageReceiver. /// </summary> /// <param name="urls">The URL of the Signal Service.</param> /// <param name="credentials">The Signal Service user's credentials</param> /// <param name="userAgent"></param> public SignalServiceMessageReceiver(SignalServiceUrl[] urls, CredentialsProvider credentials, string userAgent) { this.urls = urls; this.credentialsProvider = credentials; this.socket = new PushServiceSocket(urls, credentials, userAgent); this.userAgent = userAgent; }
/// <summary> /// Construct a SignalServiceAccountManager for linking as a slave device /// </summary> /// <param name="configuration">The URL configuration for the Signal Service</param> /// <param name="userAgent">A string which identifies the client software</param> /// <param name="webSocketFactory">A factory which creates websocket connection objects</param> public SignalServiceAccountManager(SignalServiceConfiguration configuration, string userAgent, HttpClient httpClient, ISignalWebSocketFactory webSocketFactory) { this.httpClient = httpClient; this.configuration = configuration; this.userAgent = userAgent; credentials = new StaticCredentialsProvider(null, null, null, (int)SignalServiceAddress.DEFAULT_DEVICE_ID); pushServiceSocket = new PushServiceSocket(configuration, credentials, userAgent, httpClient); }
/** * Construct a TextSecureMessageReceiver. * * @param url The URL of the TextSecure server. * @param trustStore The {@link org.whispersystems.textsecure.api.push.TrustStore} containing * the server's TLS signing certificate. * @param credentials The TextSecure user's credentials. */ public TextSecureMessageReceiver(String url, TrustStore trustStore, CredentialsProvider credentials, string userAgent) { this.url = url; this.trustStore = trustStore; this.credentialsProvider = credentials; this.socket = new PushServiceSocket(url, trustStore, credentials, userAgent); this.userAgent = userAgent; }
/** * Construct a TextSecureMessageSender. * * @param url The URL of the TextSecure server. * @param trustStore The trust store containing the TextSecure server's signing TLS certificate. * @param user The TextSecure username (eg phone number). * @param password The TextSecure user's password. * @param store The AxolotlStore. * @param eventListener An optional event listener, which fires whenever sessions are * setup or torn down for a recipient. */ public TextSecureMessageSender(String url, TrustStore trustStore, String user, String password, AxolotlStore store, May <EventListener> eventListener, String userAgent) { this.socket = new PushServiceSocket(url, trustStore, new StaticCredentialsProvider(user, password, null), userAgent); this.store = store; this.localAddress = new TextSecureAddress(user); this.eventListener = eventListener; }
public SignalServiceAccountManager(SignalServiceConfiguration configuration, ICredentialsProvider credentialsProvider, string signalAgent, HttpClient httpClient) { this.pushServiceSocket = new PushServiceSocket(configuration, credentialsProvider, signalAgent, httpClient); this.configuration = configuration; this.credentials = credentialsProvider; this.userAgent = signalAgent; this.httpClient = httpClient; }
private async Task <OutgoingPushMessage> GetEncryptedMessage(CancellationToken token, PushServiceSocket socket, SignalServiceAddress recipient, UnidentifiedAccess?unidentifiedAccess, uint deviceId, byte[] plaintext) { SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.E164number, deviceId); SignalServiceCipher cipher = new SignalServiceCipher(LocalAddress, Store, null); if (!Store.ContainsSession(signalProtocolAddress)) { try { List <PreKeyBundle> preKeys = await socket.GetPreKeys(token, recipient, unidentifiedAccess, deviceId); foreach (PreKeyBundle preKey in preKeys) { if (CredentialsProvider.User.Equals(recipient.E164number) && CredentialsProvider.DeviceId == preKey.getDeviceId()) { continue; } try { SignalProtocolAddress preKeyAddress = new SignalProtocolAddress(recipient.E164number, preKey.getDeviceId()); SessionBuilder sessionBuilder = new SessionBuilder(Store, preKeyAddress); sessionBuilder.process(preKey); } catch (libsignal.exceptions.UntrustedIdentityException) { throw new UntrustedIdentityException("Untrusted identity key!", recipient.E164number, preKey.getIdentityKey()); } } if (EventListener != null) { EventListener.OnSecurityEvent(recipient); } } catch (InvalidKeyException e) { throw new Exception(e.Message); } } try { return(cipher.Encrypt(signalProtocolAddress, unidentifiedAccess, plaintext)); } catch (libsignal.exceptions.UntrustedIdentityException e) { throw new UntrustedIdentityException("Untrusted on send", e.getName(), e.getUntrustedIdentity()); } }
/// <summary> /// Finishes a registration as a new device. /// Called by the new device. This method blocks until the already verified device has verified this device. /// </summary> /// <param name="token"></param> /// <param name="provisionMessage"></param> /// <param name="signalingKey"></param> /// <param name="password"></param> /// <param name="sms"></param> /// <param name="fetches"></param> /// <param name="regid"></param> /// <param name="name"></param> /// <returns>Device id</returns> public async Task <int> FinishNewDeviceRegistration(CancellationToken token, SignalServiceProvisionMessage provisionMessage, string signalingKey, string password, bool sms, bool fetches, int regid, string name) { pushServiceSocket = new PushServiceSocket(configuration, new StaticCredentialsProvider(provisionMessage.Number, password, null, -1), userAgent, httpClient); // update credentials and pushServiceSocket to keep internal state consistent int deviceId = await pushServiceSocket.FinishNewDeviceRegistration(token, provisionMessage.Code, signalingKey, sms, fetches, regid, name); credentials = new StaticCredentialsProvider(provisionMessage.Number, password, null, deviceId); pushServiceSocket = new PushServiceSocket(configuration, credentials, userAgent, httpClient); return(deviceId); }
/// <summary> /// Construct a SignalServiceMessageSender /// </summary> /// <param name="urls">The URL of the Signal Service.</param> /// <param name="user">The Signal Service username (eg phone number).</param> /// <param name="password">The Signal Service user password</param> /// <param name="store">The SignalProtocolStore.</param> /// <param name="eventListener">An optional event listener, which fires whenever sessions are /// setup or torn down for a recipient.</param> /// <param name="userAgent"></param> public SignalServiceMessageSender(SignalServiceUrl[] urls, string user, string password, SignalProtocolStore store, May <SignalServiceMessagePipe> pipe, May <EventListener> eventListener, string userAgent) { this.socket = new PushServiceSocket(urls, new StaticCredentialsProvider(user, password, null), userAgent); this.store = store; this.localAddress = new SignalServiceAddress(user); this.pipe = pipe; this.eventListener = eventListener; }
/// <summary> /// Construct a SignalServiceMessageSender /// </summary> /// <param name="token">A CancellationToken to cancel the sender's operations</param> /// <param name="urls">The URL of the Signal Service.</param> /// <param name="user">The Signal Service username (eg phone number).</param> /// <param name="password">The Signal Service user password</param> /// <param name="deviceId">Tbe Signal Service device id</param> /// <param name="store">The SignalProtocolStore.</param> /// <param name="pipe">An optional SignalServiceMessagePipe</param> /// <param name="eventListener">An optional event listener, which fires whenever sessions are /// setup or torn down for a recipient.</param> /// <param name="userAgent"></param> public SignalServiceMessageSender(CancellationToken token, SignalServiceConfiguration urls, string user, string password, int deviceId, SignalProtocolStore store, SignalServiceMessagePipe pipe, IEventListener eventListener, string userAgent) { Token = token; CredentialsProvider = new StaticCredentialsProvider(user, password, null, deviceId); this.socket = new PushServiceSocket(urls, CredentialsProvider, userAgent); this.store = store; this.localAddress = new SignalServiceAddress(user); this.pipe = pipe; this.eventListener = eventListener; }
/// <summary> /// Construct a SignalServiceMessageSender /// </summary> /// <param name="token">A CancellationToken to cancel the sender's operations</param> /// <param name="urls">The URL of the Signal Service.</param> /// <param name="user">The Signal Service username (eg phone number).</param> /// <param name="password">The Signal Service user password</param> /// <param name="deviceId">Tbe Signal Service device id</param> /// <param name="store">The SignalProtocolStore.</param> /// <param name="pipe">An optional SignalServiceMessagePipe</param> /// <param name="unidentifiedPipe"></param> /// <param name="eventListener">An optional event listener, which fires whenever sessions are /// setup or torn down for a recipient.</param> /// <param name="userAgent"></param> /// <param name="isMultiDevice"></param> public SignalServiceMessageSender(CancellationToken token, SignalServiceConfiguration urls, string user, string password, int deviceId, SignalProtocolStore store, string userAgent, bool isMultiDevice, SignalServiceMessagePipe?pipe, SignalServiceMessagePipe?unidentifiedPipe, IEventListener eventListener) { Token = token; CredentialsProvider = new StaticCredentialsProvider(user, password, null, deviceId); Socket = new PushServiceSocket(urls, CredentialsProvider, userAgent); Store = store; LocalAddress = new SignalServiceAddress(user); Pipe = pipe; UnidentifiedPipe = unidentifiedPipe; IsMultiDevice = isMultiDevice; EventListener = eventListener; }
private OutgoingPushMessage getEncryptedMessage(PushServiceSocket socket, SignalServiceAddress recipient, uint deviceId, byte[] plaintext, bool legacy, bool silent) { SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.getNumber(), deviceId); SignalServiceCipher cipher = new SignalServiceCipher(localAddress, store); if (!store.ContainsSession(signalProtocolAddress)) { try { List <PreKeyBundle> preKeys = socket.getPreKeys(recipient, deviceId); foreach (PreKeyBundle preKey in preKeys) { if (CredentialsProvider.GetUser().Equals(recipient.getNumber()) && CredentialsProvider.GetDeviceId() == preKey.getDeviceId()) { continue; } try { SignalProtocolAddress preKeyAddress = new SignalProtocolAddress(recipient.getNumber(), preKey.getDeviceId()); SessionBuilder sessionBuilder = new SessionBuilder(store, preKeyAddress); sessionBuilder.process(preKey); } catch (libsignal.exceptions.UntrustedIdentityException e) { throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey()); } } if (eventListener != null) { eventListener.onSecurityEvent(recipient); } } catch (InvalidKeyException e) { throw new Exception(e.Message); } } return(cipher.encrypt(signalProtocolAddress, plaintext, legacy, silent)); }
private async Task <OutgoingPushMessageList> getEncryptedMessages(PushServiceSocket socket, TextSecureAddress recipient, ulong timestamp, byte[] plaintext, bool legacy) { List <OutgoingPushMessage> messages = new List <OutgoingPushMessage>(); if (!recipient.Equals(localAddress)) { messages.Add(await getEncryptedMessage(socket, recipient, TextSecureAddress.DEFAULT_DEVICE_ID, plaintext, legacy)); } foreach (uint deviceId in store.GetSubDeviceSessions(recipient.getNumber())) { messages.Add(await getEncryptedMessage(socket, recipient, deviceId, plaintext, legacy)); } return(new OutgoingPushMessageList(recipient.getNumber(), timestamp, recipient.getRelay().HasValue ? recipient.getRelay().ForceGetValue() : null, messages)); }
private async Task <OutgoingPushMessage> getEncryptedMessage(PushServiceSocket socket, TextSecureAddress recipient, uint deviceId, byte[] plaintext, bool legacy) { AxolotlAddress axolotlAddress = new AxolotlAddress(recipient.getNumber(), deviceId); TextSecureCipher cipher = new TextSecureCipher(localAddress, store); if (!store.ContainsSession(axolotlAddress)) { try { List <PreKeyBundle> preKeys = await socket.getPreKeys(recipient, deviceId); foreach (PreKeyBundle preKey in preKeys) { try { AxolotlAddress preKeyAddress = new AxolotlAddress(recipient.getNumber(), preKey.getDeviceId()); SessionBuilder sessionBuilder = new SessionBuilder(store, preKeyAddress); sessionBuilder.process(preKey); } catch (libaxolotl.exceptions.UntrustedIdentityException e) { throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey()); } } if (eventListener.HasValue) { eventListener.ForceGetValue().onSecurityEvent(recipient); } } catch (InvalidKeyException e) { throw new Exception(e.Message); } } return(cipher.encrypt(axolotlAddress, plaintext, legacy)); }
public SignalServiceAccountManager(SignalServiceUrl[] urls, CancellationToken token, string userAgent) { Urls = urls; ProvisioningSocket = new ProvisioningSocket(urls[0].getUrl(), token); pushServiceSocket = new PushServiceSocket(urls, new StaticCredentialsProvider(null, null, null, (int)SignalServiceAddress.DEFAULT_DEVICE_ID), userAgent); }
/// <summary> /// Finishes a registration as a new device. /// Called by the new device. This method blocks until the already verified device has verified this device. /// </summary> /// <param name="token"></param> /// <param name="provisionMessage"></param> /// <param name="signalingKey"></param> /// <param name="password"></param> /// <param name="sms"></param> /// <param name="fetches"></param> /// <param name="regid"></param> /// <param name="name"></param> /// <returns></returns> public async Task <int> FinishNewDeviceRegistration(CancellationToken token, SignalServiceProvisionMessage provisionMessage, string signalingKey, string password, bool sms, bool fetches, int regid, string name) { PushServiceSocket = new PushServiceSocket(Configuration, new StaticCredentialsProvider(provisionMessage.Number, password, null, -1), UserAgent); return(await PushServiceSocket.FinishNewDeviceRegistration(token, provisionMessage.Code, signalingKey, sms, fetches, regid, name)); }
/// <summary> /// Construct a SignalServiceAccountManager for linking as a slave device /// </summary> /// <param name="configuration">The URL configuration for the Signal Service</param> /// <param name="userAgent">A string which identifies the client software</param> /// <param name="webSocketFactory">A factory which creates websocket connection objects</param> public SignalServiceAccountManager(SignalServiceConfiguration configuration, string userAgent, ISignalWebSocketFactory webSocketFactory) { Configuration = configuration; UserAgent = userAgent; PushServiceSocket = new PushServiceSocket(configuration, new StaticCredentialsProvider(null, null, null, (int)SignalServiceAddress.DEFAULT_DEVICE_ID), userAgent); }