Skip to content

Commit 1d9f72f

Browse files
committed
Update to version to 2.4.7
2 parents a6dd3d6 + b63f97c commit 1d9f72f

25 files changed

+1111
-372
lines changed

README.md

+44-39
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ of your key and session information to durable media.
1010

1111
## Creating keys
1212

13-
`````
13+
`````java
1414
IdentityKeyPair identityKey = KeyHelper.generateIdentityKeyPair();
15-
List<PreKeyRecord> oneTimePreKeys = KeyHelper.generatePreKeys(100);
15+
List<PreKeyRecord> oneTimePreKeys = KeyHelper.generatePreKeys(0, 100);
16+
PreKeyRecord lastResortKey = KeyHelper.generateLastResortPreKey();
1617
SignedPreKeyRecord signedPreKeyRecord = KeyHelper.generateSignedPreKey(identityKey, signedPreKeyId);
1718
`````
1819

@@ -22,78 +23,82 @@ The above are then stored locally so that they're available for load via the `Si
2223

2324
At install time, clients need to register with the Signal server.
2425

25-
`````
26+
`````java
2627
private final String URL = "https://my.signal.server.com";
2728
private final TrustStore TRUST_STORE = new MyTrustStoreImpl();
2829
private final String USERNAME = "+14151231234";
2930
private final String PASSWORD = generateRandomPassword();
31+
private final String USER_AGENT = "[FILL_IN]";
3032

3133
SignalServiceAccountManager accountManager = new SignalServiceAccountManager(URL, TRUST_STORE,
32-
USERNAME, PASSWORD);
34+
USERNAME, PASSWORD, USER_AGENT);
3335

3436
accountManager.requestSmsVerificationCode();
35-
accountManager.verifyAccount(receivedSmsVerificationCode, generateRandomSignalingKey(),
36-
false, generateRandomInstallId());
37+
accountManager.verifyAccountWithCode(receivedSmsVerificationCode, generateRandomSignalingKey(),
38+
generateRandomInstallId(), false);
3739
accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID)));
38-
accountManager.setPreKeys(identityKey.getPublic(), lastResortKey, signedPreKey, oneTimePreKeys);
40+
accountManager.setPreKeys(identityKey.getPublicKey(), lastResortKey, signedPreKeyRecord, oneTimePreKeys);
3941
`````
4042

4143
## Sending text messages
4244

43-
`````
45+
`````java
4446
SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, USERNAME, PASSWORD,
45-
localRecipientId, new MySignalProtocolStore(),
46-
Optional.absent());
47+
new MySignalProtocolStore(),
48+
USER_AGENT, Optional.absent());
4749

48-
messageSender.sendMessage(new SignalProtocolAddress("+14159998888"),
49-
SignalProtocolMessage.newBuilder()
50-
.withBody("Hello, world!")
51-
.build());
50+
messageSender.sendMessage(new SignalServiceAddress("+14159998888"),
51+
SignalServiceDataMessage.newBuilder()
52+
.withBody("Hello, world!")
53+
.build());
5254
`````
5355

5456
## Sending media messages
5557

56-
`````
58+
`````java
5759
SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, USERNAME, PASSWORD,
58-
localRecipientId, new MySignalProtocolStore(),
59-
Optional.absent());
60-
61-
File myAttachment = new File("/path/to/my.attachment");
62-
FileInputStream attachmentStream = new FileInputStream(myAttachment);
63-
TextSecureAttachment attachment = SignalServiceAttachment.newStreamBuilder()
64-
.withStream(attachmentStream)
65-
.withContentType("image/png")
66-
.withLength(myAttachment.size())
67-
.build();
68-
69-
messageSender.sendMessage(new SignalProtocolAddress("+14159998888"),
70-
SignalProtocolMessage.newBuilder()
71-
.withBody("An attachment!")
72-
.withAttachment(attachment)
73-
.build());
60+
new MySignalProtocolStore(),
61+
USER_AGENT, Optional.absent());
62+
63+
File myAttachment = new File("/path/to/my.attachment");
64+
FileInputStream attachmentStream = new FileInputStream(myAttachment);
65+
SignalServiceAttachment attachment = SignalServiceAttachment.newStreamBuilder()
66+
.withStream(attachmentStream)
67+
.withContentType("image/png")
68+
.withLength(myAttachment.length())
69+
.build();
70+
71+
messageSender.sendMessage(new SignalServiceAddress("+14159998888"),
72+
SignalServiceDataMessage.newBuilder()
73+
.withBody("An attachment!")
74+
.withAttachment(attachment)
75+
.build());
7476

7577
`````
7678

7779
## Receiving messages
7880

79-
`````
80-
SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(URL, TRUST_STORE, USERNAME, PASSWORD, mySignalingKey);
81-
SignalServiceMessagePipe messagePipe;
81+
`````java
82+
SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(URL, TRUST_STORE, USERNAME,
83+
PASSWORD, mySignalingKey,
84+
USER_AGENT);
85+
SignalServiceMessagePipe messagePipe = null;
8286

8387
try {
84-
messagePipe = messageReciever.createMessagePipe();
88+
messagePipe = messageReceiver.createMessagePipe();
8589

8690
while (listeningForMessages) {
8791
SignalServiceEnvelope envelope = messagePipe.read(timeout, timeoutTimeUnit);
88-
SignalServiceCipher cipher = new SignalServiceCipher(new MySignalProtocolStore());
89-
SignalServiceMessage message = cipher.decrypt(envelope);
92+
SignalServiceCipher cipher = new SignalServiceCipher(new SignalServiceAddress(USERNAME),
93+
new MySignalProtocolStore());
94+
SignalServiceContent message = cipher.decrypt(envelope);
9095

91-
System.out.println("Received message: " + message.getBody().get());
96+
System.out.println("Received message: " + message.getDataMessage().get().getBody().get());
9297
}
9398

9499
} finally {
95100
if (messagePipe != null)
96-
messagePipe.close();
101+
messagePipe.shutdown();
97102
}
98103
`````
99104

android/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ apply plugin: 'maven'
1313
apply plugin: 'signing'
1414

1515
archivesBaseName = "signal-service-android"
16-
version = "2.1.1"
16+
version = "2.4.7"
1717
group = "org.whispersystems"
1818

1919
repositories {
@@ -22,7 +22,7 @@ repositories {
2222
}
2323

2424
dependencies {
25-
compile "org.whispersystems:signal-protocol-android:2.2.0"
25+
compile "org.whispersystems:signal-protocol-android:2.4.0"
2626
compile (project(':java')) {
2727
exclude group: 'org.whispersystems', module: 'signal-protocol-java'
2828
exclude group: 'org.apache.httpcomponents', module: 'httpclient'

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
subprojects {
2-
ext.version_number = "2.3.1"
2+
ext.version_number = "2.4.7"
33
ext.group_info = "org.whispersystems"
4-
ext.signal_version = "2.2.0"
4+
ext.signal_version = "2.4.0"
55

66
if (JavaVersion.current().isJava8Compatible()) {
77
allprojects {

java/build.gradle

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ apply plugin: 'signing'
44

55
sourceCompatibility = 1.7
66
archivesBaseName = "signal-service-java"
7-
version = "2.1.1"
7+
version = "2.4.7"
88
group = "org.whispersystems"
99

1010
repositories {
@@ -14,14 +14,15 @@ repositories {
1414

1515
dependencies {
1616
compile 'com.google.protobuf:protobuf-java:2.5.0'
17-
compile 'com.googlecode.libphonenumber:libphonenumber:7.1.0'
17+
compile 'com.googlecode.libphonenumber:libphonenumber:8.0.0'
1818
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.0'
1919

20-
compile "org.whispersystems:signal-protocol-java:2.2.0"
21-
compile 'com.squareup.okhttp:okhttp:2.2.0'
20+
compile "org.whispersystems:signal-protocol-java:2.4.0"
21+
compile 'com.squareup.okhttp3:okhttp:3.5.0'
2222
compile 'org.apache.httpcomponents:httpclient:4.4'
2323

2424
testCompile 'junit:junit:3.8.2'
25+
testCompile 'org.assertj:assertj-core:1.7.1'
2526
}
2627

2728
tasks.whenTaskAdded { task ->

java/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java

+16-18
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.whispersystems.signalservice.api.push.TrustStore;
2323
import org.whispersystems.signalservice.internal.crypto.ProvisioningCipher;
2424
import org.whispersystems.signalservice.internal.push.PushServiceSocket;
25+
import org.whispersystems.signalservice.internal.push.SignalServiceUrl;
2526
import org.whispersystems.signalservice.internal.util.Base64;
2627
import org.whispersystems.signalservice.internal.util.StaticCredentialsProvider;
2728
import org.whispersystems.signalservice.internal.util.Util;
@@ -52,17 +53,16 @@ public class SignalServiceAccountManager {
5253
/**
5354
* Construct a SignalServiceAccountManager.
5455
*
55-
* @param url The URL for the Signal Service.
56-
* @param trustStore The {@link org.whispersystems.signalservice.api.push.TrustStore} for the SignalService server's TLS certificate.
56+
* @param urls The URL for the Signal Service.
5757
* @param user A Signal Service phone number.
5858
* @param password A Signal Service password.
5959
* @param userAgent A string which identifies the client software.
6060
*/
61-
public SignalServiceAccountManager(String url, TrustStore trustStore,
61+
public SignalServiceAccountManager(SignalServiceUrl[] urls,
6262
String user, String password,
6363
String userAgent)
6464
{
65-
this.pushServiceSocket = new PushServiceSocket(url, trustStore, new StaticCredentialsProvider(user, password, null), userAgent);
65+
this.pushServiceSocket = new PushServiceSocket(urls, new StaticCredentialsProvider(user, password, null), userAgent);
6666
this.user = user;
6767
this.userAgent = userAgent;
6868
}
@@ -112,9 +112,9 @@ public void requestVoiceVerificationCode() throws IOException {
112112
* @param fetchesMessages A boolean that indicates whether the client supports fetching messages
113113
* (websockets)
114114
* @param signalProtocolRegistrationId A random 14-bit number that identifies this Signal install.
115-
* This value should remain consistent across registrations for the
116-
* same install, but probabilistically differ across registrations
117-
* for separate installs.
115+
* This value should remain consistent across registrations for the
116+
* same install, but probabilistically differ across registrations
117+
* for separate installs.
118118
* @param voice A boolean that indicates whether the client supports secure voice (RedPhone) calls.
119119
*
120120
* @throws IOException
@@ -136,20 +136,18 @@ public void verifyAccountWithCode(String verificationCode, String signalingKey,
136136
* concatenated.
137137
* @param fetchesMessages A boolean that indicates whether the client supports fetching messages
138138
* (websockets)
139-
* @param axolotlRegistrationId A random 14-bit number that identifies this Signal install.
140-
* This value should remain consistent across registrations for the
141-
* same install, but probabilistically differ across registrations
142-
* for separate installs.
139+
* @param signalProtocolRegistrationId A random 14-bit number that identifies this Signal install.
140+
* This value should remain consistent across registrations for the
141+
* same install, but probabilistically differ across registrations
142+
* for separate installs.
143143
* @param voice A boolean that indicates whether the client supports secure voice (RedPhone) calls.
144144
*
145145
* @throws IOException
146146
*/
147-
public void verifyAccountWithToken(String verificationToken, String signalingKey, boolean fetchesMessages,
148-
int axolotlRegistrationId, boolean voice)
147+
public void verifyAccountWithToken(String verificationToken, String signalingKey, boolean fetchesMessages, int signalProtocolRegistrationId, boolean voice)
149148
throws IOException
150149
{
151-
this.pushServiceSocket.verifyAccountToken(verificationToken, signalingKey,
152-
fetchesMessages, axolotlRegistrationId, voice);
150+
this.pushServiceSocket.verifyAccountToken(verificationToken, signalingKey, fetchesMessages, signalProtocolRegistrationId, voice);
153151
}
154152

155153
/**
@@ -159,9 +157,9 @@ public void verifyAccountWithToken(String verificationToken, String signalingKey
159157
* @param fetchesMessages A boolean that indicates whether the client supports fetching messages
160158
* (websockets)
161159
* @param signalProtocolRegistrationId A random 14-bit number that identifies this Signal install.
162-
* This value should remain consistent across registrations for the same
163-
* install, but probabilistically differ across registrations for
164-
* separate installs.
160+
* This value should remain consistent across registrations for the same
161+
* install, but probabilistically differ across registrations for
162+
* separate installs.
165163
* @param voice A boolean that indicates whether the client supports secure voice (RedPhone)
166164
*
167165
* @throws IOException

java/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessagePipe.java

+37
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,22 @@
66

77
package org.whispersystems.signalservice.api;
88

9+
import com.google.protobuf.ByteString;
10+
911
import org.whispersystems.libsignal.InvalidVersionException;
12+
import org.whispersystems.libsignal.util.Pair;
1013
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
1114
import org.whispersystems.signalservice.api.util.CredentialsProvider;
15+
import org.whispersystems.signalservice.internal.push.OutgoingPushMessageList;
16+
import org.whispersystems.signalservice.internal.push.SendMessageResponse;
17+
import org.whispersystems.signalservice.internal.util.JsonUtil;
18+
import org.whispersystems.signalservice.internal.util.Util;
1219
import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
1320

1421
import java.io.IOException;
22+
import java.security.NoSuchAlgorithmException;
23+
import java.security.SecureRandom;
24+
import java.util.concurrent.ExecutionException;
1525
import java.util.concurrent.TimeUnit;
1626
import java.util.concurrent.TimeoutException;
1727

@@ -25,6 +35,8 @@
2535
*/
2636
public class SignalServiceMessagePipe {
2737

38+
private static final String TAG = SignalServiceMessagePipe.class.getName();
39+
2840
private final WebSocketConnection websocket;
2941
private final CredentialsProvider credentialsProvider;
3042

@@ -92,6 +104,31 @@ public SignalServiceEnvelope read(long timeout, TimeUnit unit, MessagePipeCallba
92104
}
93105
}
94106

107+
public SendMessageResponse send(OutgoingPushMessageList list) throws IOException {
108+
try {
109+
WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder()
110+
.setId(SecureRandom.getInstance("SHA1PRNG").nextLong())
111+
.setVerb("PUT")
112+
.setPath(String.format("/v1/messages/%s", list.getDestination()))
113+
.addHeaders("content-type:application/json")
114+
.setBody(ByteString.copyFrom(JsonUtil.toJson(list).getBytes()))
115+
.build();
116+
117+
Pair<Integer, String> response = websocket.sendRequest(requestMessage).get(10, TimeUnit.SECONDS);
118+
119+
if (response.first() < 200 || response.first() >= 300) {
120+
throw new IOException("Non-successful response: " + response.first());
121+
}
122+
123+
if (Util.isEmpty(response.second())) return new SendMessageResponse(false);
124+
else return JsonUtil.fromJson(response.second(), SendMessageResponse.class);
125+
} catch (NoSuchAlgorithmException e) {
126+
throw new AssertionError(e);
127+
} catch (InterruptedException | ExecutionException | TimeoutException e) {
128+
throw new IOException(e);
129+
}
130+
}
131+
95132
/**
96133
* Close this connection to the server.
97134
*/

0 commit comments

Comments
 (0)