Move PreKey ids to be Mediums, generate in circular buffer.

This commit is contained in:
Moxie Marlinspike
2013-08-19 10:07:07 -07:00
parent edb89ee3e9
commit d1969412fb
14 changed files with 153 additions and 43 deletions

View File

@@ -32,7 +32,7 @@ import android.widget.TextView;
import org.whispersystems.textsecure.crypto.InvalidKeyException;
import org.thoughtcrime.securesms.crypto.InvalidVersionException;
import org.thoughtcrime.securesms.crypto.KeyExchangeMessage;
import org.thoughtcrime.securesms.crypto.protocol.KeyExchangeMessage;
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessor;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import org.thoughtcrime.securesms.crypto.protocol.KeyExchangeMessage;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.EncryptingSmsDatabase;
import org.thoughtcrime.securesms.database.MmsDatabase;

View File

@@ -22,6 +22,7 @@ import android.content.DialogInterface;
import android.util.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.crypto.protocol.KeyExchangeMessage;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.sms.OutgoingKeyExchangeMessage;

View File

@@ -20,9 +20,13 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
import org.thoughtcrime.securesms.crypto.protocol.KeyExchangeMessage;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.whispersystems.textsecure.crypto.IdentityKey;
import org.whispersystems.textsecure.crypto.KeyUtil;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.crypto.PublicKey;
import org.whispersystems.textsecure.push.PreKeyEntity;
import org.whispersystems.textsecure.storage.LocalKeyRecord;
import org.whispersystems.textsecure.storage.RemoteKeyRecord;
import org.whispersystems.textsecure.storage.SessionRecord;
@@ -65,8 +69,12 @@ public class KeyExchangeProcessor {
return false;
}
return isTrusted(message.getIdentityKey());
}
public boolean isTrusted(IdentityKey identityKey) {
return DatabaseFactory.getIdentityDatabase(context).isValidIdentity(masterSecret, recipient,
message.getIdentityKey());
identityKey);
}
public boolean hasInitiatedSession() {
@@ -86,7 +94,25 @@ public class KeyExchangeProcessor {
(localKeyRecord.getCurrentKeyPair() != null && localKeyRecord.getCurrentKeyPair().getId() != responseKeyId);
}
public boolean processKeyExchangeMessage(KeyExchangeMessage message, long threadId) {
public void processKeyExchangeMessage(PreKeyEntity message) {
PublicKey remoteKey = new PublicKey(message.getKeyId(), message.getPublicKey());
remoteKeyRecord.setCurrentRemoteKey(remoteKey);
remoteKeyRecord.setLastRemoteKey(remoteKey);
remoteKeyRecord.save();
localKeyRecord = KeyUtil.initializeRecordFor(recipient, context, masterSecret);
sessionRecord.setSessionId(localKeyRecord.getCurrentKeyPair().getPublicKey().getFingerprintBytes(),
remoteKeyRecord.getCurrentRemoteKey().getFingerprintBytes());
sessionRecord.setIdentityKey(message.getIdentityKey());
sessionRecord.setSessionVersion(Message.SUPPORTED_VERSION);
sessionRecord.save();
DatabaseFactory.getIdentityDatabase(context)
.saveIdentity(masterSecret, recipient, message.getIdentityKey());
}
public void processKeyExchangeMessage(KeyExchangeMessage message, long threadId) {
int initiateKeyId = Conversions.lowBitsToMedium(message.getPublicKey().getId());
message.getPublicKey().setId(initiateKeyId);
@@ -123,8 +149,6 @@ public class KeyExchangeProcessor {
intent.putExtra("thread_id", threadId);
intent.setPackage(context.getPackageName());
context.sendBroadcast(intent, KeyCachingService.KEY_PERMISSION);
return true;
}
}

View File

@@ -14,11 +14,13 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.thoughtcrime.securesms.crypto;
package org.thoughtcrime.securesms.crypto.protocol;
import android.content.Context;
import android.util.Log;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.crypto.InvalidVersionException;
import org.whispersystems.textsecure.crypto.IdentityKey;
import org.whispersystems.textsecure.crypto.InvalidKeyException;
import org.whispersystems.textsecure.crypto.MasterSecret;
@@ -58,9 +60,9 @@ public class KeyExchangeMessage {
private final int messageVersion;
private final int supportedVersion;
private final PublicKey publicKey;
private final PublicKey publicKey;
private final String serialized;
private IdentityKey identityKey;
private IdentityKey identityKey;
public KeyExchangeMessage(Context context, MasterSecret masterSecret, int messageVersion, LocalKeyRecord record, int highIdBits) {
this.publicKey = new PublicKey(record.getCurrentKeyPair().getPublicKey());

View File

@@ -24,7 +24,7 @@ import android.util.Pair;
import org.thoughtcrime.securesms.crypto.DecryptingQueue;
import org.whispersystems.textsecure.crypto.InvalidKeyException;
import org.thoughtcrime.securesms.crypto.InvalidVersionException;
import org.thoughtcrime.securesms.crypto.KeyExchangeMessage;
import org.thoughtcrime.securesms.crypto.protocol.KeyExchangeMessage;
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessor;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;

View File

@@ -3,14 +3,20 @@ package org.thoughtcrime.securesms.transport;
import android.content.Context;
import android.util.Log;
import org.thoughtcrime.securesms.crypto.KeyExchangeProcessor;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.sms.SmsTransportDetails;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
import org.thoughtcrime.securesms.mms.PartParser;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.textsecure.crypto.SessionCipher;
import org.whispersystems.textsecure.push.PreKeyEntity;
import org.whispersystems.textsecure.push.PushAttachmentData;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
import org.whispersystems.textsecure.storage.SessionRecord;
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
import java.io.IOException;
@@ -37,10 +43,22 @@ public class PushTransport extends BaseTransport {
String password = TextSecurePreferences.getPushServerPassword(context);
PushServiceSocket socket = new PushServiceSocket(context, localNumber, password);
String recipientNumber = message.getIndividualRecipient().getNumber();
String recipientCanonicalNumber = PhoneNumberFormatter.formatNumber(recipientNumber,
Recipient recipient = message.getIndividualRecipient();
String plaintext = message.getBody().getBody();
String recipientCanonicalNumber = PhoneNumberFormatter.formatNumber(recipient.getNumber(),
localNumber);
// if (SessionRecord.hasSession(context, recipient)) {
// byte[] cipherText = getEncryptedMessageForExistingSession(recipient, plaintext);
// socket.sendMessage(recipientCanonicalNumber, new String(cipherText));
// } else {
// byte[] cipherText = getEncryptedMessageForNewSession(socket, recipient,
// recipientCanonicalNumber,
// plaintext);
// socket.sendMessage(recipientCanonicalNumber, new String(cipherText));
// }
socket.sendMessage(recipientCanonicalNumber, message.getBody().getBody());
context.sendBroadcast(constructSentIntent(context, message.getId(), message.getType()));
@@ -82,4 +100,23 @@ public class PushTransport extends BaseTransport {
return attachments;
}
private byte[] getEncryptedMessageForNewSession(PushServiceSocket socket, Recipient recipient, String canonicalRecipientNumber, String plaintext) throws IOException {
PreKeyEntity preKey = socket.getPreKey(canonicalRecipientNumber);
KeyExchangeProcessor processor = new KeyExchangeProcessor(context, masterSecret, recipient);
processor.processKeyExchangeMessage(preKey);
synchronized (SessionCipher.CIPHER_LOCK) {
SessionCipher sessionCipher = new SessionCipher(context, masterSecret, recipient, new SmsTransportDetails());
return sessionCipher.encryptMessage(plaintext.getBytes());
}
}
private byte[] getEncryptedMessageForExistingSession(Recipient recipient, String plaintext) {
synchronized (SessionCipher.CIPHER_LOCK) {
SessionCipher sessionCipher = new SessionCipher(context, masterSecret, recipient, new SmsTransportDetails());
return sessionCipher.encryptMessage(plaintext.getBytes());
}
}
}