X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/0130585355b82eb10f8d8e836182d9877aa21ab8..10719a443a88d06ef5734f0e17f71316b1473edf:/src/main/java/org/asamk/textsecure/Manager.java diff --git a/src/main/java/org/asamk/textsecure/Manager.java b/src/main/java/org/asamk/textsecure/Manager.java index e5a77dcd..2d675170 100644 --- a/src/main/java/org/asamk/textsecure/Manager.java +++ b/src/main/java/org/asamk/textsecure/Manager.java @@ -24,25 +24,26 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; import org.asamk.TextSecure; -import org.whispersystems.libaxolotl.*; -import org.whispersystems.libaxolotl.ecc.Curve; -import org.whispersystems.libaxolotl.ecc.ECKeyPair; -import org.whispersystems.libaxolotl.state.PreKeyRecord; -import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; -import org.whispersystems.libaxolotl.util.KeyHelper; -import org.whispersystems.libaxolotl.util.Medium; -import org.whispersystems.libaxolotl.util.guava.Optional; -import org.whispersystems.textsecure.api.TextSecureAccountManager; -import org.whispersystems.textsecure.api.TextSecureMessagePipe; -import org.whispersystems.textsecure.api.TextSecureMessageReceiver; -import org.whispersystems.textsecure.api.TextSecureMessageSender; -import org.whispersystems.textsecure.api.crypto.TextSecureCipher; -import org.whispersystems.textsecure.api.messages.*; -import org.whispersystems.textsecure.api.push.TextSecureAddress; -import org.whispersystems.textsecure.api.push.TrustStore; -import org.whispersystems.textsecure.api.push.exceptions.EncapsulatedExceptions; -import org.whispersystems.textsecure.api.util.InvalidNumberException; -import org.whispersystems.textsecure.api.util.PhoneNumberFormatter; +import org.whispersystems.libsignal.*; +import org.whispersystems.libsignal.ecc.Curve; +import org.whispersystems.libsignal.ecc.ECKeyPair; +import org.whispersystems.libsignal.state.PreKeyRecord; +import org.whispersystems.libsignal.state.SignalProtocolStore; +import org.whispersystems.libsignal.state.SignedPreKeyRecord; +import org.whispersystems.libsignal.util.KeyHelper; +import org.whispersystems.libsignal.util.Medium; +import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.api.SignalServiceAccountManager; +import org.whispersystems.signalservice.api.SignalServiceMessagePipe; +import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; +import org.whispersystems.signalservice.api.SignalServiceMessageSender; +import org.whispersystems.signalservice.api.crypto.SignalServiceCipher; +import org.whispersystems.signalservice.api.messages.*; +import org.whispersystems.signalservice.api.push.SignalServiceAddress; +import org.whispersystems.signalservice.api.push.TrustStore; +import org.whispersystems.signalservice.api.push.exceptions.EncapsulatedExceptions; +import org.whispersystems.signalservice.api.util.InvalidNumberException; +import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import java.io.*; import java.nio.file.Files; @@ -52,7 +53,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; class Manager implements TextSecure { - private final static String URL = "https://textsecure-service.whispersystems.org"; + private final static String URL = "https://SignalService-service.whispersystems.org"; private final static TrustStore TRUST_STORE = new WhisperTrustStore(); public final static String PROJECT_NAME = Manager.class.getPackage().getImplementationTitle(); @@ -72,8 +73,8 @@ class Manager implements TextSecure { private boolean registered = false; - private JsonAxolotlStore axolotlStore; - private TextSecureAccountManager accountManager; + private SignalProtocolStore signalProtocolStore; + private SignalServiceAccountManager accountManager; private JsonGroupStore groupStore; public Manager(String username, String settingsPath) { @@ -99,7 +100,7 @@ class Manager implements TextSecure { } public boolean userHasKeys() { - return axolotlStore != null; + return signalProtocolStore != null; } private JsonNode getNotNullNode(JsonNode parent, String name) throws InvalidObjectException { @@ -129,7 +130,7 @@ class Manager implements TextSecure { } else { nextSignedPreKeyId = 0; } - axolotlStore = jsonProcessot.convertValue(getNotNullNode(rootNode, "axolotlStore"), JsonAxolotlStore.class); //new JsonAxolotlStore(in.getJSONObject("axolotlStore")); + signalProtocolStore = jsonProcessot.convertValue(getNotNullNode(rootNode, "axolotlStore"), JsonSignalProtocolStore.class); registered = getNotNullNode(rootNode, "registered").asBoolean(); JsonNode groupStoreNode = rootNode.get("groupStore"); if (groupStoreNode != null) { @@ -138,7 +139,7 @@ class Manager implements TextSecure { if (groupStore == null) { groupStore = new JsonGroupStore(); } - accountManager = new TextSecureAccountManager(URL, TRUST_STORE, username, password, USER_AGENT); + accountManager = new SignalServiceAccountManager(URL, TRUST_STORE, username, password, USER_AGENT); } private void save() { @@ -149,7 +150,7 @@ class Manager implements TextSecure { .put("preKeyIdOffset", preKeyIdOffset) .put("nextSignedPreKeyId", nextSignedPreKeyId) .put("registered", registered) - .putPOJO("axolotlStore", axolotlStore) + .putPOJO("axolotlStore", signalProtocolStore) .putPOJO("groupStore", groupStore) ; try { @@ -162,7 +163,7 @@ class Manager implements TextSecure { public void createNewIdentity() { IdentityKeyPair identityKey = KeyHelper.generateIdentityKeyPair(); int registrationId = KeyHelper.generateRegistrationId(false); - axolotlStore = new JsonAxolotlStore(identityKey, registrationId); + signalProtocolStore = new JsonSignalProtocolStore(identityKey, registrationId); groupStore = new JsonGroupStore(); registered = false; save(); @@ -175,7 +176,7 @@ class Manager implements TextSecure { public void register(boolean voiceVerication) throws IOException { password = Util.getSecret(18); - accountManager = new TextSecureAccountManager(URL, TRUST_STORE, username, password, USER_AGENT); + accountManager = new SignalServiceAccountManager(URL, TRUST_STORE, username, password, USER_AGENT); if (voiceVerication) accountManager.requestVoiceVerificationCode(); @@ -196,7 +197,7 @@ class Manager implements TextSecure { ECKeyPair keyPair = Curve.generateKeyPair(); PreKeyRecord record = new PreKeyRecord(preKeyId, keyPair); - axolotlStore.storePreKey(preKeyId, record); + signalProtocolStore.storePreKey(preKeyId, record); records.add(record); } @@ -207,18 +208,18 @@ class Manager implements TextSecure { } private PreKeyRecord generateLastResortPreKey() { - if (axolotlStore.containsPreKey(Medium.MAX_VALUE)) { + if (signalProtocolStore.containsPreKey(Medium.MAX_VALUE)) { try { - return axolotlStore.loadPreKey(Medium.MAX_VALUE); + return signalProtocolStore.loadPreKey(Medium.MAX_VALUE); } catch (InvalidKeyIdException e) { - axolotlStore.removePreKey(Medium.MAX_VALUE); + signalProtocolStore.removePreKey(Medium.MAX_VALUE); } } ECKeyPair keyPair = Curve.generateKeyPair(); PreKeyRecord record = new PreKeyRecord(Medium.MAX_VALUE, keyPair); - axolotlStore.storePreKey(Medium.MAX_VALUE, record); + signalProtocolStore.storePreKey(Medium.MAX_VALUE, record); save(); return record; @@ -230,7 +231,7 @@ class Manager implements TextSecure { byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize()); SignedPreKeyRecord record = new SignedPreKeyRecord(nextSignedPreKeyId, System.currentTimeMillis(), keyPair, signature); - axolotlStore.storeSignedPreKey(nextSignedPreKeyId, record); + signalProtocolStore.storeSignedPreKey(nextSignedPreKeyId, record); nextSignedPreKeyId = (nextSignedPreKeyId + 1) % Medium.MAX_VALUE; save(); @@ -243,7 +244,7 @@ class Manager implements TextSecure { public void verifyAccount(String verificationCode) throws IOException { verificationCode = verificationCode.replace("-", ""); signalingKey = Util.getSecret(52); - accountManager.verifyAccountWithCode(verificationCode, signalingKey, axolotlStore.getLocalRegistrationId(), false, true); + accountManager.verifyAccountWithCode(verificationCode, signalingKey, signalProtocolStore.getLocalRegistrationId(), false, true); //accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID))); registered = true; @@ -252,61 +253,61 @@ class Manager implements TextSecure { PreKeyRecord lastResortKey = generateLastResortPreKey(); - SignedPreKeyRecord signedPreKeyRecord = generateSignedPreKey(axolotlStore.getIdentityKeyPair()); + SignedPreKeyRecord signedPreKeyRecord = generateSignedPreKey(signalProtocolStore.getIdentityKeyPair()); - accountManager.setPreKeys(axolotlStore.getIdentityKeyPair().getPublicKey(), lastResortKey, signedPreKeyRecord, oneTimePreKeys); + accountManager.setPreKeys(signalProtocolStore.getIdentityKeyPair().getPublicKey(), lastResortKey, signedPreKeyRecord, oneTimePreKeys); save(); } - private static List getTextSecureAttachments(List attachments) throws AttachmentInvalidException { - List textSecureAttachments = null; + private static List getSignalServiceAttachments(List attachments) throws AttachmentInvalidException { + List SignalServiceAttachments = null; if (attachments != null) { - textSecureAttachments = new ArrayList<>(attachments.size()); + SignalServiceAttachments = new ArrayList<>(attachments.size()); for (String attachment : attachments) { try { - textSecureAttachments.add(createAttachment(attachment)); + SignalServiceAttachments.add(createAttachment(attachment)); } catch (IOException e) { throw new AttachmentInvalidException(attachment, e); } } } - return textSecureAttachments; + return SignalServiceAttachments; } - private static TextSecureAttachmentStream createAttachment(String attachment) throws IOException { + private static SignalServiceAttachmentStream createAttachment(String attachment) throws IOException { File attachmentFile = new File(attachment); InputStream attachmentStream = new FileInputStream(attachmentFile); final long attachmentSize = attachmentFile.length(); String mime = Files.probeContentType(Paths.get(attachment)); - return new TextSecureAttachmentStream(attachmentStream, mime, attachmentSize, null); + return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, null); } @Override public void sendGroupMessage(String messageText, List attachments, byte[] groupId) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException { - final TextSecureDataMessage.Builder messageBuilder = TextSecureDataMessage.newBuilder().withBody(messageText); + final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder().withBody(messageText); if (attachments != null) { - messageBuilder.withAttachments(getTextSecureAttachments(attachments)); + messageBuilder.withAttachments(getSignalServiceAttachments(attachments)); } if (groupId != null) { - TextSecureGroup group = TextSecureGroup.newBuilder(TextSecureGroup.Type.DELIVER) + SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.DELIVER) .withId(groupId) .build(); messageBuilder.asGroupMessage(group); } - TextSecureDataMessage message = messageBuilder.build(); + SignalServiceDataMessage message = messageBuilder.build(); sendMessage(message, groupStore.getGroup(groupId).members); } public void sendQuitGroupMessage(byte[] groupId) throws GroupNotFoundException, IOException, EncapsulatedExceptions { - TextSecureGroup group = TextSecureGroup.newBuilder(TextSecureGroup.Type.QUIT) + SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.QUIT) .withId(groupId) .build(); - TextSecureDataMessage message = TextSecureDataMessage.newBuilder() + SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() .asGroupMessage(group) .build(); @@ -339,7 +340,7 @@ class Manager implements TextSecure { } } - TextSecureGroup.Builder group = TextSecureGroup.newBuilder(TextSecureGroup.Type.UPDATE) + SignalServiceGroup.Builder group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.UPDATE) .withId(g.groupId) .withName(g.name) .withMembers(new ArrayList<>(g.members)); @@ -356,7 +357,7 @@ class Manager implements TextSecure { groupStore.updateGroup(g); - TextSecureDataMessage message = TextSecureDataMessage.newBuilder() + SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() .asGroupMessage(group.build()) .build(); @@ -376,30 +377,30 @@ class Manager implements TextSecure { public void sendMessage(String messageText, List attachments, List recipients) throws IOException, EncapsulatedExceptions, AttachmentInvalidException { - final TextSecureDataMessage.Builder messageBuilder = TextSecureDataMessage.newBuilder().withBody(messageText); + final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder().withBody(messageText); if (attachments != null) { - messageBuilder.withAttachments(getTextSecureAttachments(attachments)); + messageBuilder.withAttachments(getSignalServiceAttachments(attachments)); } - TextSecureDataMessage message = messageBuilder.build(); + SignalServiceDataMessage message = messageBuilder.build(); sendMessage(message, recipients); } @Override public void sendEndSessionMessage(List recipients) throws IOException, EncapsulatedExceptions { - TextSecureDataMessage message = TextSecureDataMessage.newBuilder() + SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() .asEndSessionMessage() .build(); sendMessage(message, recipients); } - private void sendMessage(TextSecureDataMessage message, Collection recipients) + private void sendMessage(SignalServiceDataMessage message, Collection recipients) throws IOException, EncapsulatedExceptions { - TextSecureMessageSender messageSender = new TextSecureMessageSender(URL, TRUST_STORE, username, password, - axolotlStore, USER_AGENT, Optional.absent()); + SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, username, password, + signalProtocolStore, USER_AGENT, Optional.absent()); - Set recipientsTS = new HashSet<>(recipients.size()); + Set recipientsTS = new HashSet<>(recipients.size()); for (String recipient : recipients) { try { recipientsTS.add(getPushAddress(recipient)); @@ -414,15 +415,15 @@ class Manager implements TextSecure { messageSender.sendMessage(new ArrayList<>(recipientsTS), message); if (message.isEndSession()) { - for (TextSecureAddress recipient : recipientsTS) { + for (SignalServiceAddress recipient : recipientsTS) { handleEndSession(recipient.getNumber()); } } save(); } - private TextSecureContent decryptMessage(TextSecureEnvelope envelope) { - TextSecureCipher cipher = new TextSecureCipher(new TextSecureAddress(username), axolotlStore); + private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) { + SignalServiceCipher cipher = new SignalServiceCipher(new SignalServiceAddress(username), signalProtocolStore); try { return cipher.decrypt(envelope); } catch (Exception e) { @@ -433,23 +434,23 @@ class Manager implements TextSecure { } private void handleEndSession(String source) { - axolotlStore.deleteAllSessions(source); + signalProtocolStore.deleteAllSessions(source); } public interface ReceiveMessageHandler { - void handleMessage(TextSecureEnvelope envelope, TextSecureContent decryptedContent, GroupInfo group); + void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent decryptedContent, GroupInfo group); } public void receiveMessages(int timeoutSeconds, boolean returnOnTimeout, ReceiveMessageHandler handler) throws IOException { - final TextSecureMessageReceiver messageReceiver = new TextSecureMessageReceiver(URL, TRUST_STORE, username, password, signalingKey, USER_AGENT); - TextSecureMessagePipe messagePipe = null; + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(URL, TRUST_STORE, username, password, signalingKey, USER_AGENT); + SignalServiceMessagePipe messagePipe = null; try { messagePipe = messageReceiver.createMessagePipe(); while (true) { - TextSecureEnvelope envelope; - TextSecureContent content = null; + SignalServiceEnvelope envelope; + SignalServiceContent content = null; GroupInfo group = null; try { envelope = messagePipe.read(timeoutSeconds, TimeUnit.SECONDS); @@ -457,9 +458,9 @@ class Manager implements TextSecure { content = decryptMessage(envelope); if (content != null) { if (content.getDataMessage().isPresent()) { - TextSecureDataMessage message = content.getDataMessage().get(); + SignalServiceDataMessage message = content.getDataMessage().get(); if (message.getGroupInfo().isPresent()) { - TextSecureGroup groupInfo = message.getGroupInfo().get(); + SignalServiceGroup groupInfo = message.getGroupInfo().get(); switch (groupInfo.getType()) { case UPDATE: try { @@ -469,7 +470,7 @@ class Manager implements TextSecure { } if (groupInfo.getAvatar().isPresent()) { - TextSecureAttachment avatar = groupInfo.getAvatar().get(); + SignalServiceAttachment avatar = groupInfo.getAvatar().get(); if (avatar.isPointer()) { long avatarId = avatar.asPointer().getId(); try { @@ -510,7 +511,7 @@ class Manager implements TextSecure { handleEndSession(envelope.getSource()); } if (message.getAttachments().isPresent()) { - for (TextSecureAttachment attachment : message.getAttachments().get()) { + for (SignalServiceAttachment attachment : message.getAttachments().get()) { if (attachment.isPointer()) { try { retrieveAttachment(attachment.asPointer()); @@ -542,8 +543,8 @@ class Manager implements TextSecure { return new File(attachmentsPath, attachmentId + ""); } - private File retrieveAttachment(TextSecureAttachmentPointer pointer) throws IOException, InvalidMessageException { - final TextSecureMessageReceiver messageReceiver = new TextSecureMessageReceiver(URL, TRUST_STORE, username, password, signalingKey, USER_AGENT); + private File retrieveAttachment(SignalServiceAttachmentPointer pointer) throws IOException, InvalidMessageException { + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(URL, TRUST_STORE, username, password, signalingKey, USER_AGENT); File tmpFile = File.createTempFile("ts_attach_" + pointer.getId(), ".tmp"); InputStream input = messageReceiver.retrieveAttachment(pointer, tmpFile); @@ -594,9 +595,9 @@ class Manager implements TextSecure { return PhoneNumberFormatter.formatNumber(number, localNumber); } - private TextSecureAddress getPushAddress(String number) throws InvalidNumberException { + private SignalServiceAddress getPushAddress(String number) throws InvalidNumberException { String e164number = canonicalizeNumber(number); - return new TextSecureAddress(e164number); + return new SignalServiceAddress(e164number); } @Override