From 0c32001fe40b2b321a02c13d11ec6e0fa64108e7 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Mon, 19 Jan 2015 20:24:10 -0800 Subject: [PATCH] Support for multi-device provisioning flow. // FREEBIE --- AndroidManifest.xml | 10 + .../protobuf/IncomingPushMessageSignal.proto | 16 +- libtextsecure/protobuf/Makefile | 2 +- libtextsecure/protobuf/Provisioning.proto | 16 + .../api/TextSecureAccountManager.java | 38 +- .../api/TextSecureMessageSender.java | 69 +- .../textsecure/api/push/PushAddress.java | 30 +- .../internal/crypto/ProvisioningCipher.java | 75 + .../textsecure/internal/push/DeviceCode.java | 10 + .../internal/push/OutgoingPushMessage.java | 4 +- .../internal/push/ProvisioningMessage.java | 11 + .../internal/push/ProvisioningProtos.java | 1375 +++++++++++++++++ .../internal/push/PushMessageProtos.java | 804 +++++++++- .../internal/push/PushServiceSocket.java | 30 +- .../internal/push/SendMessageResponse.java | 16 + .../textsecure/internal/util/Util.java | 13 + res/layout/device_provisioning_activity.xml | 46 + .../securesms/DeviceProvisioningActivity.java | 124 ++ .../TextSecureCommunicationModule.java | 26 +- .../securesms/jobs/DeliveryReceiptJob.java | 2 +- .../securesms/jobs/PushSendJob.java | 7 +- .../service/RegistrationService.java | 32 +- 22 files changed, 2668 insertions(+), 88 deletions(-) create mode 100644 libtextsecure/protobuf/Provisioning.proto create mode 100644 libtextsecure/src/main/java/org/whispersystems/textsecure/internal/crypto/ProvisioningCipher.java create mode 100644 libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/DeviceCode.java create mode 100644 libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningMessage.java create mode 100644 libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningProtos.java create mode 100644 libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/SendMessageResponse.java create mode 100644 res/layout/device_provisioning_activity.xml create mode 100644 src/org/thoughtcrime/securesms/DeviceProvisioningActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 88b62fd085..e5b79e0d2a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -94,6 +94,16 @@ android:theme="@style/TextSecure.Light.Dialog" android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/> + + + + + + + + + diff --git a/libtextsecure/protobuf/IncomingPushMessageSignal.proto b/libtextsecure/protobuf/IncomingPushMessageSignal.proto index 15b6898e93..4dd54b1200 100644 --- a/libtextsecure/protobuf/IncomingPushMessageSignal.proto +++ b/libtextsecure/protobuf/IncomingPushMessageSignal.proto @@ -42,12 +42,18 @@ message PushMessageContent { optional AttachmentPointer avatar = 5; } + message SyncMessageContext { + optional string destination = 1; + optional uint64 timestamp = 2; + } + enum Flags { END_SESSION = 1; } - optional string body = 1; - repeated AttachmentPointer attachments = 2; - optional GroupContext group = 3; - optional uint32 flags = 4; -} \ No newline at end of file + optional string body = 1; + repeated AttachmentPointer attachments = 2; + optional GroupContext group = 3; + optional uint32 flags = 4; + optional SyncMessageContext sync = 5; +} diff --git a/libtextsecure/protobuf/Makefile b/libtextsecure/protobuf/Makefile index c9b2b6bfcd..f14d635b20 100644 --- a/libtextsecure/protobuf/Makefile +++ b/libtextsecure/protobuf/Makefile @@ -1,3 +1,3 @@ all: - protoc --java_out=../src/main/java/ IncomingPushMessageSignal.proto + protoc --java_out=../src/main/java/ IncomingPushMessageSignal.proto Provisioning.proto diff --git a/libtextsecure/protobuf/Provisioning.proto b/libtextsecure/protobuf/Provisioning.proto new file mode 100644 index 0000000000..776877c344 --- /dev/null +++ b/libtextsecure/protobuf/Provisioning.proto @@ -0,0 +1,16 @@ +package textsecure; + +option java_package = "org.whispersystems.textsecure.internal.push"; +option java_outer_classname = "ProvisioningProtos"; + +message ProvisionEnvelope { + optional bytes publicKey = 1; + optional bytes body = 2; // Encrypted ProvisionMessage +} + +message ProvisionMessage { + optional bytes identityKeyPublic = 1; + optional bytes identityKeyPrivate = 2; + optional string number = 3; + optional string provisioningCode = 4; +} diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java index 03b397c027..acd27015f0 100644 --- a/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureAccountManager.java @@ -16,29 +16,37 @@ */ package org.whispersystems.textsecure.api; +import com.google.protobuf.ByteString; + import org.whispersystems.libaxolotl.IdentityKey; +import org.whispersystems.libaxolotl.IdentityKeyPair; +import org.whispersystems.libaxolotl.InvalidKeyException; +import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import org.whispersystems.libaxolotl.util.guava.Optional; import org.whispersystems.textsecure.api.push.ContactTokenDetails; -import org.whispersystems.textsecure.api.push.TrustStore; -import org.whispersystems.textsecure.api.push.exceptions.NonSuccessfulResponseCodeException; -import org.whispersystems.textsecure.api.push.exceptions.PushNetworkException; -import org.whispersystems.textsecure.internal.push.PushServiceSocket; import org.whispersystems.textsecure.api.push.SignedPreKeyEntity; +import org.whispersystems.textsecure.api.push.TrustStore; +import org.whispersystems.textsecure.internal.crypto.ProvisioningCipher; +import org.whispersystems.textsecure.internal.push.PushServiceSocket; import java.io.IOException; import java.util.List; import java.util.Set; +import static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage; + public class TextSecureAccountManager { private final PushServiceSocket pushServiceSocket; + private final String user; public TextSecureAccountManager(String url, TrustStore trustStore, String user, String password) { this.pushServiceSocket = new PushServiceSocket(url, trustStore, user, password); + this.user = user; } public void setGcmId(Optional gcmRegistrationId) throws IOException { @@ -94,4 +102,26 @@ public class TextSecureAccountManager { return this.pushServiceSocket.retrieveDirectory(contactTokens); } + public String getNewDeviceVerificationCode() throws IOException { + return this.pushServiceSocket.getNewDeviceVerificationCode(); + } + + public void addDevice(String deviceIdentifier, + ECPublicKey deviceKey, + IdentityKeyPair identityKeyPair, + String code) + throws InvalidKeyException, IOException + { + ProvisioningCipher cipher = new ProvisioningCipher(deviceKey); + ProvisionMessage message = ProvisionMessage.newBuilder() + .setIdentityKeyPublic(ByteString.copyFrom(identityKeyPair.getPublicKey().serialize())) + .setIdentityKeyPrivate(ByteString.copyFrom(identityKeyPair.getPrivateKey().serialize())) + .setNumber(user) + .setProvisioningCode(code) + .build(); + + byte[] ciphertext = cipher.encrypt(message); + this.pushServiceSocket.sendProvisioningMessage(deviceIdentifier, ciphertext); + } + } diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java index 045b1b9422..c033e94dd3 100644 --- a/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/api/TextSecureMessageSender.java @@ -19,6 +19,7 @@ package org.whispersystems.textsecure.api; import android.util.Log; import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; import org.whispersystems.libaxolotl.InvalidKeyException; import org.whispersystems.libaxolotl.SessionBuilder; @@ -40,6 +41,7 @@ import org.whispersystems.textsecure.internal.push.OutgoingPushMessageList; import org.whispersystems.textsecure.internal.push.PushAttachmentData; import org.whispersystems.textsecure.internal.push.PushBody; import org.whispersystems.textsecure.internal.push.PushServiceSocket; +import org.whispersystems.textsecure.internal.push.SendMessageResponse; import org.whispersystems.textsecure.internal.push.StaleDevices; import org.whispersystems.textsecure.api.push.exceptions.UnregisteredUserException; import org.whispersystems.textsecure.api.push.exceptions.EncapsulatedExceptions; @@ -62,14 +64,17 @@ public class TextSecureMessageSender { private final PushServiceSocket socket; private final AxolotlStore store; + private final PushAddress syncAddress; private final Optional eventListener; public TextSecureMessageSender(String url, TrustStore trustStore, - String user, String password, AxolotlStore store, + String user, String password, + long userId, AxolotlStore store, Optional eventListener) { this.socket = new PushServiceSocket(url, trustStore, user, password); this.store = store; + this.syncAddress = new PushAddress(userId, user, null); this.eventListener = eventListener; } @@ -80,8 +85,14 @@ public class TextSecureMessageSender { public void sendMessage(PushAddress recipient, TextSecureMessage message) throws UntrustedIdentityException, IOException { - byte[] content = createMessageContent(message); - sendMessage(recipient, message.getTimestamp(), content); + byte[] content = createMessageContent(message); + long timestamp = message.getTimestamp(); + SendMessageResponse response = sendMessage(recipient, timestamp, content); + + if (response != null && response.getNeedsSync()) { + byte[] syncMessage = createSyncMessageContent(content, recipient, timestamp); + sendMessage(syncAddress, timestamp, syncMessage); + } if (message.isEndSession()) { store.deleteAllSessions(recipient.getRecipientId()); @@ -122,6 +133,20 @@ public class TextSecureMessageSender { return builder.build().toByteArray(); } + private byte[] createSyncMessageContent(byte[] content, PushAddress recipient, long timestamp) { + try { + PushMessageContent.Builder builder = PushMessageContent.parseFrom(content).toBuilder(); + builder.setSync(PushMessageContent.SyncMessageContext.newBuilder() + .setDestination(recipient.getNumber()) + .setTimestamp(timestamp) + .build()); + + return builder.build().toByteArray(); + } catch (InvalidProtocolBufferException e) { + throw new AssertionError(e); + } + } + private GroupContext createGroupContent(TextSecureGroup group) throws IOException { GroupContext.Builder builder = GroupContext.newBuilder(); builder.setId(ByteString.copyFrom(group.getGroupId())); @@ -168,15 +193,13 @@ public class TextSecureMessageSender { } } - private void sendMessage(PushAddress recipient, long timestamp, byte[] content) + private SendMessageResponse sendMessage(PushAddress recipient, long timestamp, byte[] content) throws UntrustedIdentityException, IOException { for (int i=0;i<3;i++) { try { OutgoingPushMessageList messages = getEncryptedMessages(socket, recipient, timestamp, content); - socket.sendMessage(messages); - - return; + return socket.sendMessage(messages); } catch (MismatchedDevicesException mde) { Log.w(TAG, mde); handleMismatchedDevices(socket, recipient, mde.getMismatchedDevices()); @@ -185,6 +208,8 @@ public class TextSecureMessageSender { handleStaleDevices(recipient, ste.getStaleDevices()); } } + + throw new IOException("Failed to resolve conflicts after 3 attempts!"); } private List createAttachmentPointers(Optional> attachments) throws IOException { @@ -230,31 +255,31 @@ public class TextSecureMessageSender { byte[] plaintext) throws IOException, UntrustedIdentityException { - PushBody masterBody = getEncryptedMessage(socket, recipient, plaintext); - List messages = new LinkedList<>(); - messages.add(new OutgoingPushMessage(recipient, masterBody)); + + if (!recipient.equals(syncAddress)) { + PushBody masterBody = getEncryptedMessage(socket, recipient, PushAddress.DEFAULT_DEVICE_ID, plaintext); + messages.add(new OutgoingPushMessage(recipient, PushAddress.DEFAULT_DEVICE_ID, masterBody)); + } for (int deviceId : store.getSubDeviceSessions(recipient.getRecipientId())) { - PushAddress device = new PushAddress(recipient.getRecipientId(), recipient.getNumber(), deviceId, recipient.getRelay()); - PushBody body = getEncryptedMessage(socket, device, plaintext); - - messages.add(new OutgoingPushMessage(device, body)); + PushBody body = getEncryptedMessage(socket, recipient, deviceId, plaintext); + messages.add(new OutgoingPushMessage(recipient, deviceId, body)); } return new OutgoingPushMessageList(recipient.getNumber(), timestamp, recipient.getRelay(), messages); } - private PushBody getEncryptedMessage(PushServiceSocket socket, PushAddress recipient, byte[] plaintext) + private PushBody getEncryptedMessage(PushServiceSocket socket, PushAddress recipient, int deviceId, byte[] plaintext) throws IOException, UntrustedIdentityException { - if (!store.containsSession(recipient.getRecipientId(), recipient.getDeviceId())) { + if (!store.containsSession(recipient.getRecipientId(), deviceId)) { try { - List preKeys = socket.getPreKeys(recipient); + List preKeys = socket.getPreKeys(recipient, deviceId); for (PreKeyBundle preKey : preKeys) { try { - SessionBuilder sessionBuilder = new SessionBuilder(store, recipient.getRecipientId(), recipient.getDeviceId()); + SessionBuilder sessionBuilder = new SessionBuilder(store, recipient.getRecipientId(), deviceId); sessionBuilder.process(preKey); } catch (org.whispersystems.libaxolotl.UntrustedIdentityException e) { throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey()); @@ -269,7 +294,7 @@ public class TextSecureMessageSender { } } - TextSecureCipher cipher = new TextSecureCipher(store, recipient.getRecipientId(), recipient.getDeviceId()); + TextSecureCipher cipher = new TextSecureCipher(store, recipient.getRecipientId(), deviceId); CiphertextMessage message = cipher.encrypt(plaintext); int remoteRegistrationId = cipher.getRemoteRegistrationId(); @@ -292,12 +317,10 @@ public class TextSecureMessageSender { } for (int missingDeviceId : mismatchedDevices.getMissingDevices()) { - PushAddress device = new PushAddress(recipient.getRecipientId(), recipient.getNumber(), - missingDeviceId, recipient.getRelay()); - PreKeyBundle preKey = socket.getPreKey(device); + PreKeyBundle preKey = socket.getPreKey(recipient, missingDeviceId); try { - SessionBuilder sessionBuilder = new SessionBuilder(store, device.getRecipientId(), device.getDeviceId()); + SessionBuilder sessionBuilder = new SessionBuilder(store, recipient.getRecipientId(), missingDeviceId); sessionBuilder.process(preKey); } catch (org.whispersystems.libaxolotl.UntrustedIdentityException e) { throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey()); diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/api/push/PushAddress.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/api/push/PushAddress.java index bc2c6041fe..f33d4a5710 100644 --- a/libtextsecure/src/main/java/org/whispersystems/textsecure/api/push/PushAddress.java +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/api/push/PushAddress.java @@ -22,13 +22,11 @@ public class PushAddress { private final long recipientId; private final String e164number; - private final int deviceId; private final String relay; - public PushAddress(long recipientId, String e164number, int deviceId, String relay) { + public PushAddress(long recipientId, String e164number, String relay) { this.recipientId = recipientId; this.e164number = e164number; - this.deviceId = deviceId; this.relay = relay; } @@ -44,7 +42,29 @@ public class PushAddress { return recipientId; } - public int getDeviceId() { - return deviceId; + @Override + public boolean equals(Object other) { + if (other == null || !(other instanceof PushAddress)) return false; + + PushAddress that = (PushAddress)other; + + return this.recipientId == that.recipientId && + equals(this.e164number, that.e164number) && + equals(this.relay, that.relay); + } + + @Override + public int hashCode() { + int hashCode = (int)this.recipientId; + + if (this.e164number != null) hashCode ^= this.e164number.hashCode(); + if (this.relay != null) hashCode ^= this.relay.hashCode(); + + return hashCode; + } + + private boolean equals(String one, String two) { + if (one == null) return two == null; + return one.equals(two); } } diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/crypto/ProvisioningCipher.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/crypto/ProvisioningCipher.java new file mode 100644 index 0000000000..f9586c5d5f --- /dev/null +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/crypto/ProvisioningCipher.java @@ -0,0 +1,75 @@ +package org.whispersystems.textsecure.internal.crypto; + +import com.google.protobuf.ByteString; + +import org.whispersystems.libaxolotl.InvalidKeyException; +import org.whispersystems.libaxolotl.ecc.Curve; +import org.whispersystems.libaxolotl.ecc.ECKeyPair; +import org.whispersystems.libaxolotl.ecc.ECPublicKey; +import org.whispersystems.libaxolotl.kdf.HKDFv3; +import org.whispersystems.textsecure.internal.util.Util; + +import java.security.NoSuchAlgorithmException; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.Mac; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; + +import static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope; +import static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage; + + +public class ProvisioningCipher { + + private static final String TAG = ProvisioningCipher.class.getSimpleName(); + + private final ECPublicKey theirPublicKey; + + public ProvisioningCipher(ECPublicKey theirPublicKey) { + this.theirPublicKey = theirPublicKey; + } + + public byte[] encrypt(ProvisionMessage message) throws InvalidKeyException { + ECKeyPair ourKeyPair = Curve.generateKeyPair(); + byte[] sharedSecret = Curve.calculateAgreement(theirPublicKey, ourKeyPair.getPrivateKey()); + byte[] derivedSecret = new HKDFv3().deriveSecrets(sharedSecret, "TextSecure Provisioning Message".getBytes(), 64); + byte[][] parts = Util.split(derivedSecret, 32, 32); + + byte[] version = {0x01}; + byte[] ciphertext = getCiphertext(parts[0], message.toByteArray()); + byte[] mac = getMac(parts[1], Util.join(version, ciphertext)); + byte[] body = Util.join(version, ciphertext, mac); + + return ProvisionEnvelope.newBuilder() + .setPublicKey(ByteString.copyFrom(ourKeyPair.getPublicKey().serialize())) + .setBody(ByteString.copyFrom(body)) + .build() + .toByteArray(); + } + + private byte[] getCiphertext(byte[] key, byte[] message) { + try { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES")); + + return Util.join(cipher.getIV(), cipher.doFinal(message)); + } catch (NoSuchAlgorithmException | NoSuchPaddingException | java.security.InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { + throw new AssertionError(e); + } + } + + private byte[] getMac(byte[] key, byte[] message) { + try { + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(new SecretKeySpec(key, "HmacSHA256")); + + return mac.doFinal(message); + } catch (NoSuchAlgorithmException | java.security.InvalidKeyException e) { + throw new AssertionError(e); + } + } + +} diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/DeviceCode.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/DeviceCode.java new file mode 100644 index 0000000000..d2fc463ad8 --- /dev/null +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/DeviceCode.java @@ -0,0 +1,10 @@ +package org.whispersystems.textsecure.internal.push; + +public class DeviceCode { + + private String verificationCode; + + public String getVerificationCode() { + return verificationCode; + } +} diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/OutgoingPushMessage.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/OutgoingPushMessage.java index 4dece5999c..434de88ca9 100644 --- a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/OutgoingPushMessage.java +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/OutgoingPushMessage.java @@ -27,9 +27,9 @@ public class OutgoingPushMessage { private int destinationRegistrationId; private String body; - public OutgoingPushMessage(PushAddress address, PushBody body) { + public OutgoingPushMessage(PushAddress address, int deviceId, PushBody body) { this.type = body.getType(); - this.destinationDeviceId = address.getDeviceId(); + this.destinationDeviceId = deviceId; this.destinationRegistrationId = body.getRemoteRegistrationId(); this.body = Base64.encodeBytes(body.getBody()); } diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningMessage.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningMessage.java new file mode 100644 index 0000000000..3034f522f2 --- /dev/null +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningMessage.java @@ -0,0 +1,11 @@ +package org.whispersystems.textsecure.internal.push; + +public class ProvisioningMessage { + + private String body; + + public ProvisioningMessage(String body) { + this.body = body; + } + +} diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningProtos.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningProtos.java new file mode 100644 index 0000000000..3271914320 --- /dev/null +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/ProvisioningProtos.java @@ -0,0 +1,1375 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Provisioning.proto + +package org.whispersystems.textsecure.internal.push; + +public final class ProvisioningProtos { + private ProvisioningProtos() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface ProvisionEnvelopeOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes publicKey = 1; + /** + * optional bytes publicKey = 1; + */ + boolean hasPublicKey(); + /** + * optional bytes publicKey = 1; + */ + com.google.protobuf.ByteString getPublicKey(); + + // optional bytes body = 2; + /** + * optional bytes body = 2; + * + *
+     * Encrypted ProvisionMessage
+     * 
+ */ + boolean hasBody(); + /** + * optional bytes body = 2; + * + *
+     * Encrypted ProvisionMessage
+     * 
+ */ + com.google.protobuf.ByteString getBody(); + } + /** + * Protobuf type {@code textsecure.ProvisionEnvelope} + */ + public static final class ProvisionEnvelope extends + com.google.protobuf.GeneratedMessage + implements ProvisionEnvelopeOrBuilder { + // Use ProvisionEnvelope.newBuilder() to construct. + private ProvisionEnvelope(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ProvisionEnvelope(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ProvisionEnvelope defaultInstance; + public static ProvisionEnvelope getDefaultInstance() { + return defaultInstance; + } + + public ProvisionEnvelope getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ProvisionEnvelope( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + publicKey_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + body_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionEnvelope_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionEnvelope_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope.class, org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ProvisionEnvelope parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ProvisionEnvelope(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes publicKey = 1; + public static final int PUBLICKEY_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString publicKey_; + /** + * optional bytes publicKey = 1; + */ + public boolean hasPublicKey() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional bytes publicKey = 1; + */ + public com.google.protobuf.ByteString getPublicKey() { + return publicKey_; + } + + // optional bytes body = 2; + public static final int BODY_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString body_; + /** + * optional bytes body = 2; + * + *
+     * Encrypted ProvisionMessage
+     * 
+ */ + public boolean hasBody() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bytes body = 2; + * + *
+     * Encrypted ProvisionMessage
+     * 
+ */ + public com.google.protobuf.ByteString getBody() { + return body_; + } + + private void initFields() { + publicKey_ = com.google.protobuf.ByteString.EMPTY; + body_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, publicKey_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, body_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, publicKey_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, body_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code textsecure.ProvisionEnvelope} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelopeOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionEnvelope_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionEnvelope_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope.class, org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope.Builder.class); + } + + // Construct using org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + publicKey_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + body_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionEnvelope_descriptor; + } + + public org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope getDefaultInstanceForType() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope.getDefaultInstance(); + } + + public org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope build() { + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope buildPartial() { + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope result = new org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.publicKey_ = publicKey_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.body_ = body_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope) { + return mergeFrom((org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope other) { + if (other == org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope.getDefaultInstance()) return this; + if (other.hasPublicKey()) { + setPublicKey(other.getPublicKey()); + } + if (other.hasBody()) { + setBody(other.getBody()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionEnvelope) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes publicKey = 1; + private com.google.protobuf.ByteString publicKey_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes publicKey = 1; + */ + public boolean hasPublicKey() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional bytes publicKey = 1; + */ + public com.google.protobuf.ByteString getPublicKey() { + return publicKey_; + } + /** + * optional bytes publicKey = 1; + */ + public Builder setPublicKey(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + publicKey_ = value; + onChanged(); + return this; + } + /** + * optional bytes publicKey = 1; + */ + public Builder clearPublicKey() { + bitField0_ = (bitField0_ & ~0x00000001); + publicKey_ = getDefaultInstance().getPublicKey(); + onChanged(); + return this; + } + + // optional bytes body = 2; + private com.google.protobuf.ByteString body_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes body = 2; + * + *
+       * Encrypted ProvisionMessage
+       * 
+ */ + public boolean hasBody() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bytes body = 2; + * + *
+       * Encrypted ProvisionMessage
+       * 
+ */ + public com.google.protobuf.ByteString getBody() { + return body_; + } + /** + * optional bytes body = 2; + * + *
+       * Encrypted ProvisionMessage
+       * 
+ */ + public Builder setBody(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + body_ = value; + onChanged(); + return this; + } + /** + * optional bytes body = 2; + * + *
+       * Encrypted ProvisionMessage
+       * 
+ */ + public Builder clearBody() { + bitField0_ = (bitField0_ & ~0x00000002); + body_ = getDefaultInstance().getBody(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:textsecure.ProvisionEnvelope) + } + + static { + defaultInstance = new ProvisionEnvelope(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:textsecure.ProvisionEnvelope) + } + + public interface ProvisionMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes identityKeyPublic = 1; + /** + * optional bytes identityKeyPublic = 1; + */ + boolean hasIdentityKeyPublic(); + /** + * optional bytes identityKeyPublic = 1; + */ + com.google.protobuf.ByteString getIdentityKeyPublic(); + + // optional bytes identityKeyPrivate = 2; + /** + * optional bytes identityKeyPrivate = 2; + */ + boolean hasIdentityKeyPrivate(); + /** + * optional bytes identityKeyPrivate = 2; + */ + com.google.protobuf.ByteString getIdentityKeyPrivate(); + + // optional string number = 3; + /** + * optional string number = 3; + */ + boolean hasNumber(); + /** + * optional string number = 3; + */ + java.lang.String getNumber(); + /** + * optional string number = 3; + */ + com.google.protobuf.ByteString + getNumberBytes(); + + // optional string provisioningCode = 4; + /** + * optional string provisioningCode = 4; + */ + boolean hasProvisioningCode(); + /** + * optional string provisioningCode = 4; + */ + java.lang.String getProvisioningCode(); + /** + * optional string provisioningCode = 4; + */ + com.google.protobuf.ByteString + getProvisioningCodeBytes(); + } + /** + * Protobuf type {@code textsecure.ProvisionMessage} + */ + public static final class ProvisionMessage extends + com.google.protobuf.GeneratedMessage + implements ProvisionMessageOrBuilder { + // Use ProvisionMessage.newBuilder() to construct. + private ProvisionMessage(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ProvisionMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ProvisionMessage defaultInstance; + public static ProvisionMessage getDefaultInstance() { + return defaultInstance; + } + + public ProvisionMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ProvisionMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + identityKeyPublic_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + identityKeyPrivate_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + number_ = input.readBytes(); + break; + } + case 34: { + bitField0_ |= 0x00000008; + provisioningCode_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage.class, org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public ProvisionMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ProvisionMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes identityKeyPublic = 1; + public static final int IDENTITYKEYPUBLIC_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString identityKeyPublic_; + /** + * optional bytes identityKeyPublic = 1; + */ + public boolean hasIdentityKeyPublic() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional bytes identityKeyPublic = 1; + */ + public com.google.protobuf.ByteString getIdentityKeyPublic() { + return identityKeyPublic_; + } + + // optional bytes identityKeyPrivate = 2; + public static final int IDENTITYKEYPRIVATE_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString identityKeyPrivate_; + /** + * optional bytes identityKeyPrivate = 2; + */ + public boolean hasIdentityKeyPrivate() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bytes identityKeyPrivate = 2; + */ + public com.google.protobuf.ByteString getIdentityKeyPrivate() { + return identityKeyPrivate_; + } + + // optional string number = 3; + public static final int NUMBER_FIELD_NUMBER = 3; + private java.lang.Object number_; + /** + * optional string number = 3; + */ + public boolean hasNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string number = 3; + */ + public java.lang.String getNumber() { + java.lang.Object ref = number_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + number_ = s; + } + return s; + } + } + /** + * optional string number = 3; + */ + public com.google.protobuf.ByteString + getNumberBytes() { + java.lang.Object ref = number_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + number_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional string provisioningCode = 4; + public static final int PROVISIONINGCODE_FIELD_NUMBER = 4; + private java.lang.Object provisioningCode_; + /** + * optional string provisioningCode = 4; + */ + public boolean hasProvisioningCode() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional string provisioningCode = 4; + */ + public java.lang.String getProvisioningCode() { + java.lang.Object ref = provisioningCode_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + provisioningCode_ = s; + } + return s; + } + } + /** + * optional string provisioningCode = 4; + */ + public com.google.protobuf.ByteString + getProvisioningCodeBytes() { + java.lang.Object ref = provisioningCode_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + provisioningCode_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + identityKeyPublic_ = com.google.protobuf.ByteString.EMPTY; + identityKeyPrivate_ = com.google.protobuf.ByteString.EMPTY; + number_ = ""; + provisioningCode_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, identityKeyPublic_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, identityKeyPrivate_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, getNumberBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(4, getProvisioningCodeBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, identityKeyPublic_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, identityKeyPrivate_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, getNumberBytes()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, getProvisioningCodeBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code textsecure.ProvisionMessage} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage.class, org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage.Builder.class); + } + + // Construct using org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + identityKeyPublic_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + identityKeyPrivate_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + number_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + provisioningCode_ = ""; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.internal_static_textsecure_ProvisionMessage_descriptor; + } + + public org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage getDefaultInstanceForType() { + return org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage.getDefaultInstance(); + } + + public org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage build() { + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage buildPartial() { + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage result = new org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.identityKeyPublic_ = identityKeyPublic_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.identityKeyPrivate_ = identityKeyPrivate_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.number_ = number_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.provisioningCode_ = provisioningCode_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage) { + return mergeFrom((org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage other) { + if (other == org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage.getDefaultInstance()) return this; + if (other.hasIdentityKeyPublic()) { + setIdentityKeyPublic(other.getIdentityKeyPublic()); + } + if (other.hasIdentityKeyPrivate()) { + setIdentityKeyPrivate(other.getIdentityKeyPrivate()); + } + if (other.hasNumber()) { + bitField0_ |= 0x00000004; + number_ = other.number_; + onChanged(); + } + if (other.hasProvisioningCode()) { + bitField0_ |= 0x00000008; + provisioningCode_ = other.provisioningCode_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.whispersystems.textsecure.internal.push.ProvisioningProtos.ProvisionMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes identityKeyPublic = 1; + private com.google.protobuf.ByteString identityKeyPublic_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes identityKeyPublic = 1; + */ + public boolean hasIdentityKeyPublic() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional bytes identityKeyPublic = 1; + */ + public com.google.protobuf.ByteString getIdentityKeyPublic() { + return identityKeyPublic_; + } + /** + * optional bytes identityKeyPublic = 1; + */ + public Builder setIdentityKeyPublic(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + identityKeyPublic_ = value; + onChanged(); + return this; + } + /** + * optional bytes identityKeyPublic = 1; + */ + public Builder clearIdentityKeyPublic() { + bitField0_ = (bitField0_ & ~0x00000001); + identityKeyPublic_ = getDefaultInstance().getIdentityKeyPublic(); + onChanged(); + return this; + } + + // optional bytes identityKeyPrivate = 2; + private com.google.protobuf.ByteString identityKeyPrivate_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes identityKeyPrivate = 2; + */ + public boolean hasIdentityKeyPrivate() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bytes identityKeyPrivate = 2; + */ + public com.google.protobuf.ByteString getIdentityKeyPrivate() { + return identityKeyPrivate_; + } + /** + * optional bytes identityKeyPrivate = 2; + */ + public Builder setIdentityKeyPrivate(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + identityKeyPrivate_ = value; + onChanged(); + return this; + } + /** + * optional bytes identityKeyPrivate = 2; + */ + public Builder clearIdentityKeyPrivate() { + bitField0_ = (bitField0_ & ~0x00000002); + identityKeyPrivate_ = getDefaultInstance().getIdentityKeyPrivate(); + onChanged(); + return this; + } + + // optional string number = 3; + private java.lang.Object number_ = ""; + /** + * optional string number = 3; + */ + public boolean hasNumber() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional string number = 3; + */ + public java.lang.String getNumber() { + java.lang.Object ref = number_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + number_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string number = 3; + */ + public com.google.protobuf.ByteString + getNumberBytes() { + java.lang.Object ref = number_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + number_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string number = 3; + */ + public Builder setNumber( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + number_ = value; + onChanged(); + return this; + } + /** + * optional string number = 3; + */ + public Builder clearNumber() { + bitField0_ = (bitField0_ & ~0x00000004); + number_ = getDefaultInstance().getNumber(); + onChanged(); + return this; + } + /** + * optional string number = 3; + */ + public Builder setNumberBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + number_ = value; + onChanged(); + return this; + } + + // optional string provisioningCode = 4; + private java.lang.Object provisioningCode_ = ""; + /** + * optional string provisioningCode = 4; + */ + public boolean hasProvisioningCode() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional string provisioningCode = 4; + */ + public java.lang.String getProvisioningCode() { + java.lang.Object ref = provisioningCode_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + provisioningCode_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string provisioningCode = 4; + */ + public com.google.protobuf.ByteString + getProvisioningCodeBytes() { + java.lang.Object ref = provisioningCode_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + provisioningCode_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string provisioningCode = 4; + */ + public Builder setProvisioningCode( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + provisioningCode_ = value; + onChanged(); + return this; + } + /** + * optional string provisioningCode = 4; + */ + public Builder clearProvisioningCode() { + bitField0_ = (bitField0_ & ~0x00000008); + provisioningCode_ = getDefaultInstance().getProvisioningCode(); + onChanged(); + return this; + } + /** + * optional string provisioningCode = 4; + */ + public Builder setProvisioningCodeBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + provisioningCode_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:textsecure.ProvisionMessage) + } + + static { + defaultInstance = new ProvisionMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:textsecure.ProvisionMessage) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_textsecure_ProvisionEnvelope_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_textsecure_ProvisionEnvelope_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_textsecure_ProvisionMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_textsecure_ProvisionMessage_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\022Provisioning.proto\022\ntextsecure\"4\n\021Prov" + + "isionEnvelope\022\021\n\tpublicKey\030\001 \001(\014\022\014\n\004body" + + "\030\002 \001(\014\"s\n\020ProvisionMessage\022\031\n\021identityKe" + + "yPublic\030\001 \001(\014\022\032\n\022identityKeyPrivate\030\002 \001(" + + "\014\022\016\n\006number\030\003 \001(\t\022\030\n\020provisioningCode\030\004 " + + "\001(\tBA\n+org.whispersystems.textsecure.int" + + "ernal.pushB\022ProvisioningProtos" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_textsecure_ProvisionEnvelope_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_textsecure_ProvisionEnvelope_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_textsecure_ProvisionEnvelope_descriptor, + new java.lang.String[] { "PublicKey", "Body", }); + internal_static_textsecure_ProvisionMessage_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_textsecure_ProvisionMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_textsecure_ProvisionMessage_descriptor, + new java.lang.String[] { "IdentityKeyPublic", "IdentityKeyPrivate", "Number", "ProvisioningCode", }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushMessageProtos.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushMessageProtos.java index 8c8b78034a..e720e132f7 100644 --- a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushMessageProtos.java +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushMessageProtos.java @@ -244,6 +244,10 @@ public final class PushMessageProtos { * RECEIPT = 5; */ RECEIPT(5, 5), + /** + * COPY = 6; + */ + COPY(6, 6), ; /** @@ -270,6 +274,10 @@ public final class PushMessageProtos { * RECEIPT = 5; */ public static final int RECEIPT_VALUE = 5; + /** + * COPY = 6; + */ + public static final int COPY_VALUE = 6; public final int getNumber() { return value; } @@ -282,6 +290,7 @@ public final class PushMessageProtos { case 3: return PREKEY_BUNDLE; case 4: return PLAINTEXT; case 5: return RECEIPT; + case 6: return COPY; default: return null; } } @@ -1187,6 +1196,20 @@ public final class PushMessageProtos { * optional uint32 flags = 4; */ int getFlags(); + + // optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + boolean hasSync(); + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext getSync(); + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContextOrBuilder getSyncOrBuilder(); } /** * Protobuf type {@code textsecure.PushMessageContent} @@ -1270,6 +1293,19 @@ public final class PushMessageProtos { flags_ = input.readUInt32(); break; } + case 42: { + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + subBuilder = sync_.toBuilder(); + } + sync_ = input.readMessage(org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(sync_); + sync_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -3143,6 +3179,558 @@ public final class PushMessageProtos { // @@protoc_insertion_point(class_scope:textsecure.PushMessageContent.GroupContext) } + public interface SyncMessageContextOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string destination = 1; + /** + * optional string destination = 1; + */ + boolean hasDestination(); + /** + * optional string destination = 1; + */ + java.lang.String getDestination(); + /** + * optional string destination = 1; + */ + com.google.protobuf.ByteString + getDestinationBytes(); + + // optional uint64 timestamp = 2; + /** + * optional uint64 timestamp = 2; + */ + boolean hasTimestamp(); + /** + * optional uint64 timestamp = 2; + */ + long getTimestamp(); + } + /** + * Protobuf type {@code textsecure.PushMessageContent.SyncMessageContext} + */ + public static final class SyncMessageContext extends + com.google.protobuf.GeneratedMessage + implements SyncMessageContextOrBuilder { + // Use SyncMessageContext.newBuilder() to construct. + private SyncMessageContext(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private SyncMessageContext(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final SyncMessageContext defaultInstance; + public static SyncMessageContext getDefaultInstance() { + return defaultInstance; + } + + public SyncMessageContext getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SyncMessageContext( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + destination_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + timestamp_ = input.readUInt64(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.whispersystems.textsecure.internal.push.PushMessageProtos.internal_static_textsecure_PushMessageContent_SyncMessageContext_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.whispersystems.textsecure.internal.push.PushMessageProtos.internal_static_textsecure_PushMessageContent_SyncMessageContext_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.class, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public SyncMessageContext parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SyncMessageContext(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string destination = 1; + public static final int DESTINATION_FIELD_NUMBER = 1; + private java.lang.Object destination_; + /** + * optional string destination = 1; + */ + public boolean hasDestination() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string destination = 1; + */ + public java.lang.String getDestination() { + java.lang.Object ref = destination_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + destination_ = s; + } + return s; + } + } + /** + * optional string destination = 1; + */ + public com.google.protobuf.ByteString + getDestinationBytes() { + java.lang.Object ref = destination_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + destination_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional uint64 timestamp = 2; + public static final int TIMESTAMP_FIELD_NUMBER = 2; + private long timestamp_; + /** + * optional uint64 timestamp = 2; + */ + public boolean hasTimestamp() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional uint64 timestamp = 2; + */ + public long getTimestamp() { + return timestamp_; + } + + private void initFields() { + destination_ = ""; + timestamp_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getDestinationBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeUInt64(2, timestamp_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getDestinationBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, timestamp_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code textsecure.PushMessageContent.SyncMessageContext} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContextOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.whispersystems.textsecure.internal.push.PushMessageProtos.internal_static_textsecure_PushMessageContent_SyncMessageContext_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.whispersystems.textsecure.internal.push.PushMessageProtos.internal_static_textsecure_PushMessageContent_SyncMessageContext_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.class, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder.class); + } + + // Construct using org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + destination_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + timestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.whispersystems.textsecure.internal.push.PushMessageProtos.internal_static_textsecure_PushMessageContent_SyncMessageContext_descriptor; + } + + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext getDefaultInstanceForType() { + return org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.getDefaultInstance(); + } + + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext build() { + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext buildPartial() { + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext result = new org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.destination_ = destination_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.timestamp_ = timestamp_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext) { + return mergeFrom((org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext other) { + if (other == org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.getDefaultInstance()) return this; + if (other.hasDestination()) { + bitField0_ |= 0x00000001; + destination_ = other.destination_; + onChanged(); + } + if (other.hasTimestamp()) { + setTimestamp(other.getTimestamp()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string destination = 1; + private java.lang.Object destination_ = ""; + /** + * optional string destination = 1; + */ + public boolean hasDestination() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string destination = 1; + */ + public java.lang.String getDestination() { + java.lang.Object ref = destination_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + destination_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string destination = 1; + */ + public com.google.protobuf.ByteString + getDestinationBytes() { + java.lang.Object ref = destination_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + destination_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string destination = 1; + */ + public Builder setDestination( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + destination_ = value; + onChanged(); + return this; + } + /** + * optional string destination = 1; + */ + public Builder clearDestination() { + bitField0_ = (bitField0_ & ~0x00000001); + destination_ = getDefaultInstance().getDestination(); + onChanged(); + return this; + } + /** + * optional string destination = 1; + */ + public Builder setDestinationBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + destination_ = value; + onChanged(); + return this; + } + + // optional uint64 timestamp = 2; + private long timestamp_ ; + /** + * optional uint64 timestamp = 2; + */ + public boolean hasTimestamp() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional uint64 timestamp = 2; + */ + public long getTimestamp() { + return timestamp_; + } + /** + * optional uint64 timestamp = 2; + */ + public Builder setTimestamp(long value) { + bitField0_ |= 0x00000002; + timestamp_ = value; + onChanged(); + return this; + } + /** + * optional uint64 timestamp = 2; + */ + public Builder clearTimestamp() { + bitField0_ = (bitField0_ & ~0x00000002); + timestamp_ = 0L; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:textsecure.PushMessageContent.SyncMessageContext) + } + + static { + defaultInstance = new SyncMessageContext(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:textsecure.PushMessageContent.SyncMessageContext) + } + private int bitField0_; // optional string body = 1; public static final int BODY_FIELD_NUMBER = 1; @@ -3261,11 +3849,34 @@ public final class PushMessageProtos { return flags_; } + // optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + public static final int SYNC_FIELD_NUMBER = 5; + private org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext sync_; + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public boolean hasSync() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext getSync() { + return sync_; + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContextOrBuilder getSyncOrBuilder() { + return sync_; + } + private void initFields() { body_ = ""; attachments_ = java.util.Collections.emptyList(); group_ = org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.GroupContext.getDefaultInstance(); flags_ = 0; + sync_ = org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.getDefaultInstance(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -3291,6 +3902,9 @@ public final class PushMessageProtos { if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeUInt32(4, flags_); } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(5, sync_); + } getUnknownFields().writeTo(output); } @@ -3316,6 +3930,10 @@ public final class PushMessageProtos { size += com.google.protobuf.CodedOutputStream .computeUInt32Size(4, flags_); } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, sync_); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -3426,6 +4044,7 @@ public final class PushMessageProtos { if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { getAttachmentsFieldBuilder(); getGroupFieldBuilder(); + getSyncFieldBuilder(); } } private static Builder create() { @@ -3450,6 +4069,12 @@ public final class PushMessageProtos { bitField0_ = (bitField0_ & ~0x00000004); flags_ = 0; bitField0_ = (bitField0_ & ~0x00000008); + if (syncBuilder_ == null) { + sync_ = org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.getDefaultInstance(); + } else { + syncBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000010); return this; } @@ -3503,6 +4128,14 @@ public final class PushMessageProtos { to_bitField0_ |= 0x00000004; } result.flags_ = flags_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000008; + } + if (syncBuilder_ == null) { + result.sync_ = sync_; + } else { + result.sync_ = syncBuilder_.build(); + } result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -3556,6 +4189,9 @@ public final class PushMessageProtos { if (other.hasFlags()) { setFlags(other.getFlags()); } + if (other.hasSync()) { + mergeSync(other.getSync()); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -4047,6 +4683,123 @@ public final class PushMessageProtos { return this; } + // optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + private org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext sync_ = org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContextOrBuilder> syncBuilder_; + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public boolean hasSync() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext getSync() { + if (syncBuilder_ == null) { + return sync_; + } else { + return syncBuilder_.getMessage(); + } + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public Builder setSync(org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext value) { + if (syncBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + sync_ = value; + onChanged(); + } else { + syncBuilder_.setMessage(value); + } + bitField0_ |= 0x00000010; + return this; + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public Builder setSync( + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder builderForValue) { + if (syncBuilder_ == null) { + sync_ = builderForValue.build(); + onChanged(); + } else { + syncBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000010; + return this; + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public Builder mergeSync(org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext value) { + if (syncBuilder_ == null) { + if (((bitField0_ & 0x00000010) == 0x00000010) && + sync_ != org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.getDefaultInstance()) { + sync_ = + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.newBuilder(sync_).mergeFrom(value).buildPartial(); + } else { + sync_ = value; + } + onChanged(); + } else { + syncBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000010; + return this; + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public Builder clearSync() { + if (syncBuilder_ == null) { + sync_ = org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.getDefaultInstance(); + onChanged(); + } else { + syncBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder getSyncBuilder() { + bitField0_ |= 0x00000010; + onChanged(); + return getSyncFieldBuilder().getBuilder(); + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + public org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContextOrBuilder getSyncOrBuilder() { + if (syncBuilder_ != null) { + return syncBuilder_.getMessageOrBuilder(); + } else { + return sync_; + } + } + /** + * optional .textsecure.PushMessageContent.SyncMessageContext sync = 5; + */ + private com.google.protobuf.SingleFieldBuilder< + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContextOrBuilder> + getSyncFieldBuilder() { + if (syncBuilder_ == null) { + syncBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContext.Builder, org.whispersystems.textsecure.internal.push.PushMessageProtos.PushMessageContent.SyncMessageContextOrBuilder>( + sync_, + getParentForChildren(), + isClean()); + sync_ = null; + } + return syncBuilder_; + } + // @@protoc_insertion_point(builder_scope:textsecure.PushMessageContent) } @@ -4078,6 +4831,11 @@ public final class PushMessageProtos { private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_textsecure_PushMessageContent_GroupContext_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_textsecure_PushMessageContent_SyncMessageContext_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_textsecure_PushMessageContent_SyncMessageContext_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { @@ -4088,28 +4846,32 @@ public final class PushMessageProtos { static { java.lang.String[] descriptorData = { "\n\037IncomingPushMessageSignal.proto\022\ntexts" + - "ecure\"\224\002\n\031IncomingPushMessageSignal\0228\n\004t" + + "ecure\"\236\002\n\031IncomingPushMessageSignal\0228\n\004t" + "ype\030\001 \001(\0162*.textsecure.IncomingPushMessa" + "geSignal.Type\022\016\n\006source\030\002 \001(\t\022\024\n\014sourceD" + "evice\030\007 \001(\r\022\r\n\005relay\030\003 \001(\t\022\021\n\ttimestamp\030" + - "\005 \001(\004\022\017\n\007message\030\006 \001(\014\"d\n\004Type\022\013\n\007UNKNOW" + + "\005 \001(\004\022\017\n\007message\030\006 \001(\014\"n\n\004Type\022\013\n\007UNKNOW" + "N\020\000\022\016\n\nCIPHERTEXT\020\001\022\020\n\014KEY_EXCHANGE\020\002\022\021\n" + "\rPREKEY_BUNDLE\020\003\022\r\n\tPLAINTEXT\020\004\022\013\n\007RECEI" + - "PT\020\005\"\207\004\n\022PushMessageContent\022\014\n\004body\030\001 \001(" + - "\t\022E\n\013attachments\030\002 \003(\01320.textsecure.Push", - "MessageContent.AttachmentPointer\022:\n\005grou" + - "p\030\003 \001(\0132+.textsecure.PushMessageContent." + - "GroupContext\022\r\n\005flags\030\004 \001(\r\032A\n\021Attachmen" + - "tPointer\022\n\n\002id\030\001 \001(\006\022\023\n\013contentType\030\002 \001(" + - "\t\022\013\n\003key\030\003 \001(\014\032\363\001\n\014GroupContext\022\n\n\002id\030\001 " + - "\001(\014\022>\n\004type\030\002 \001(\01620.textsecure.PushMessa" + - "geContent.GroupContext.Type\022\014\n\004name\030\003 \001(" + - "\t\022\017\n\007members\030\004 \003(\t\022@\n\006avatar\030\005 \001(\01320.tex" + - "tsecure.PushMessageContent.AttachmentPoi" + - "nter\"6\n\004Type\022\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001\022\013\n", - "\007DELIVER\020\002\022\010\n\004QUIT\020\003\"\030\n\005Flags\022\017\n\013END_SES" + - "SION\020\001B@\n+org.whispersystems.textsecure." + - "internal.pushB\021PushMessageProtos" + "PT\020\005\022\010\n\004COPY\020\006\"\206\005\n\022PushMessageContent\022\014\n" + + "\004body\030\001 \001(\t\022E\n\013attachments\030\002 \003(\01320.texts", + "ecure.PushMessageContent.AttachmentPoint" + + "er\022:\n\005group\030\003 \001(\0132+.textsecure.PushMessa" + + "geContent.GroupContext\022\r\n\005flags\030\004 \001(\r\022?\n" + + "\004sync\030\005 \001(\01321.textsecure.PushMessageCont" + + "ent.SyncMessageContext\032A\n\021AttachmentPoin" + + "ter\022\n\n\002id\030\001 \001(\006\022\023\n\013contentType\030\002 \001(\t\022\013\n\003" + + "key\030\003 \001(\014\032\363\001\n\014GroupContext\022\n\n\002id\030\001 \001(\014\022>" + + "\n\004type\030\002 \001(\01620.textsecure.PushMessageCon" + + "tent.GroupContext.Type\022\014\n\004name\030\003 \001(\t\022\017\n\007" + + "members\030\004 \003(\t\022@\n\006avatar\030\005 \001(\01320.textsecu", + "re.PushMessageContent.AttachmentPointer\"" + + "6\n\004Type\022\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001\022\013\n\007DELI" + + "VER\020\002\022\010\n\004QUIT\020\003\032<\n\022SyncMessageContext\022\023\n" + + "\013destination\030\001 \001(\t\022\021\n\ttimestamp\030\002 \001(\004\"\030\n" + + "\005Flags\022\017\n\013END_SESSION\020\001B@\n+org.whispersy" + + "stems.textsecure.internal.pushB\021PushMess" + + "ageProtos" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -4127,7 +4889,7 @@ public final class PushMessageProtos { internal_static_textsecure_PushMessageContent_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_textsecure_PushMessageContent_descriptor, - new java.lang.String[] { "Body", "Attachments", "Group", "Flags", }); + new java.lang.String[] { "Body", "Attachments", "Group", "Flags", "Sync", }); internal_static_textsecure_PushMessageContent_AttachmentPointer_descriptor = internal_static_textsecure_PushMessageContent_descriptor.getNestedTypes().get(0); internal_static_textsecure_PushMessageContent_AttachmentPointer_fieldAccessorTable = new @@ -4140,6 +4902,12 @@ public final class PushMessageProtos { com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_textsecure_PushMessageContent_GroupContext_descriptor, new java.lang.String[] { "Id", "Type", "Name", "Members", "Avatar", }); + internal_static_textsecure_PushMessageContent_SyncMessageContext_descriptor = + internal_static_textsecure_PushMessageContent_descriptor.getNestedTypes().get(2); + internal_static_textsecure_PushMessageContent_SyncMessageContext_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_textsecure_PushMessageContent_SyncMessageContext_descriptor, + new java.lang.String[] { "Destination", "Timestamp", }); return null; } }; diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java index b4febc940a..142dad4955 100644 --- a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/PushServiceSocket.java @@ -79,11 +79,15 @@ public class PushServiceSocket { private static final String CREATE_ACCOUNT_VOICE_PATH = "/v1/accounts/voice/code/%s"; private static final String VERIFY_ACCOUNT_PATH = "/v1/accounts/code/%s"; private static final String REGISTER_GCM_PATH = "/v1/accounts/gcm/"; + private static final String PREKEY_METADATA_PATH = "/v2/keys/"; private static final String PREKEY_PATH = "/v2/keys/%s"; private static final String PREKEY_DEVICE_PATH = "/v2/keys/%s/%s"; private static final String SIGNED_PREKEY_PATH = "/v2/keys/signed"; + private static final String PROVISIONING_CODE_PATH = "/v1/devices/provisioning/code"; + private static final String PROVISIONING_MESSAGE_PATH = "/v1/provisioning/%s"; + private static final String DIRECTORY_TOKENS_PATH = "/v1/directory/tokens"; private static final String DIRECTORY_VERIFY_PATH = "/v1/directory/%s"; private static final String MESSAGE_PATH = "/v1/messages/%s"; @@ -120,6 +124,16 @@ public class PushServiceSocket { "PUT", new Gson().toJson(signalingKeyEntity)); } + public String getNewDeviceVerificationCode() throws IOException { + String responseText = makeRequest(PROVISIONING_CODE_PATH, "GET", null); + return new Gson().fromJson(responseText, DeviceCode.class).getVerificationCode(); + } + + public void sendProvisioningMessage(String destination, byte[] body) throws IOException { + makeRequest(String.format(PROVISIONING_MESSAGE_PATH, destination), "PUT", + new Gson().toJson(new ProvisioningMessage(Base64.encodeBytes(body)))); + } + public void sendReceipt(String destination, long messageId, String relay) throws IOException { String path = String.format(RECEIPT_PATH, destination, messageId); @@ -139,11 +153,15 @@ public class PushServiceSocket { makeRequest(REGISTER_GCM_PATH, "DELETE", null); } - public void sendMessage(OutgoingPushMessageList bundle) + public SendMessageResponse sendMessage(OutgoingPushMessageList bundle) throws IOException { try { - makeRequest(String.format(MESSAGE_PATH, bundle.getDestination()), "PUT", new Gson().toJson(bundle)); + String responseText = makeRequest(String.format(MESSAGE_PATH, bundle.getDestination()), "PUT", new Gson().toJson(bundle)); + + if (responseText == null) return new SendMessageResponse(false); + else return new Gson().fromJson(responseText, SendMessageResponse.class); + } catch (NotFoundException nfe) { throw new UnregisteredUserException(bundle.getDestination(), nfe); } @@ -183,9 +201,9 @@ public class PushServiceSocket { return preKeyStatus.getCount(); } - public List getPreKeys(PushAddress destination) throws IOException { + public List getPreKeys(PushAddress destination, int deviceIdInteger) throws IOException { try { - String deviceId = String.valueOf(destination.getDeviceId()); + String deviceId = String.valueOf(deviceIdInteger); if (deviceId.equals("1")) deviceId = "*"; @@ -231,10 +249,10 @@ public class PushServiceSocket { } } - public PreKeyBundle getPreKey(PushAddress destination) throws IOException { + public PreKeyBundle getPreKey(PushAddress destination, int deviceId) throws IOException { try { String path = String.format(PREKEY_DEVICE_PATH, destination.getNumber(), - String.valueOf(destination.getDeviceId())); + String.valueOf(deviceId)); if (!Util.isEmpty(destination.getRelay())) { path = path + "?relay=" + destination.getRelay(); diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/SendMessageResponse.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/SendMessageResponse.java new file mode 100644 index 0000000000..9b8c1e5cf2 --- /dev/null +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/push/SendMessageResponse.java @@ -0,0 +1,16 @@ +package org.whispersystems.textsecure.internal.push; + +public class SendMessageResponse { + + private boolean needsSync; + + public SendMessageResponse() {} + + public SendMessageResponse(boolean needsSync) { + this.needsSync = needsSync; + } + + public boolean getNeedsSync() { + return needsSync; + } +} diff --git a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/util/Util.java b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/util/Util.java index ba59cafc4f..63eb5b7174 100644 --- a/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/util/Util.java +++ b/libtextsecure/src/main/java/org/whispersystems/textsecure/internal/util/Util.java @@ -25,6 +25,19 @@ import java.security.SecureRandom; public class Util { + public static byte[] join(byte[]... input) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + for (byte[] part : input) { + baos.write(part); + } + + return baos.toByteArray(); + } catch (IOException e) { + throw new AssertionError(e); + } + } + public static byte[][] split(byte[] input, int firstLength, int secondLength) { byte[][] parts = new byte[2][]; diff --git a/res/layout/device_provisioning_activity.xml b/res/layout/device_provisioning_activity.xml new file mode 100644 index 0000000000..3f33d55179 --- /dev/null +++ b/res/layout/device_provisioning_activity.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + +