Rename 'device key' to 'signed prekey'.

This commit is contained in:
Moxie Marlinspike 2014-07-11 10:35:41 -07:00
parent 07fd17ccda
commit 0d532afd8e
26 changed files with 573 additions and 574 deletions

View File

@ -35,9 +35,9 @@ message SessionStructure {
} }
message PendingPreKey { message PendingPreKey {
optional uint32 preKeyId = 1; optional uint32 preKeyId = 1;
optional int32 deviceKeyId = 3; optional int32 signedPreKeyId = 3;
optional bytes baseKey = 2; optional bytes baseKey = 2;
} }
optional uint32 sessionVersion = 1; optional uint32 sessionVersion = 1;
@ -72,7 +72,7 @@ message PreKeyRecordStructure {
optional bytes privateKey = 3; optional bytes privateKey = 3;
} }
message DeviceKeyRecordStructure { message SignedPreKeyRecordStructure {
optional uint32 id = 1; optional uint32 id = 1;
optional bytes publicKey = 2; optional bytes publicKey = 2;
optional bytes privateKey = 3; optional bytes privateKey = 3;

View File

@ -13,7 +13,7 @@ message WhisperMessage {
message PreKeyWhisperMessage { message PreKeyWhisperMessage {
optional uint32 registrationId = 5; optional uint32 registrationId = 5;
optional uint32 preKeyId = 1; optional uint32 preKeyId = 1;
optional uint32 deviceKeyId = 6; optional uint32 signedPreKeyId = 6;
optional bytes baseKey = 2; optional bytes baseKey = 2;
optional bytes identityKey = 3; optional bytes identityKey = 3;
optional bytes verification = 7; optional bytes verification = 7;

View File

@ -1,58 +0,0 @@
package org.whispersystems.test;
import org.whispersystems.libaxolotl.InvalidKeyIdException;
import org.whispersystems.libaxolotl.state.DeviceKeyRecord;
import org.whispersystems.libaxolotl.state.DeviceKeyStore;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class InMemoryDeviceKeyStore implements DeviceKeyStore {
private final Map<Integer, byte[]> store = new HashMap<>();
@Override
public DeviceKeyRecord loadDeviceKey(int deviceKeyId) throws InvalidKeyIdException {
try {
if (!store.containsKey(deviceKeyId)) {
throw new InvalidKeyIdException("No such devicekeyrecord!");
}
return new DeviceKeyRecord(store.get(deviceKeyId));
} catch (IOException e) {
throw new AssertionError(e);
}
}
public List<DeviceKeyRecord> loadDeviceKeys() {
try {
List<DeviceKeyRecord> results = new LinkedList<>();
for (byte[] serialized : store.values()) {
results.add(new DeviceKeyRecord(serialized));
}
return results;
} catch (IOException e) {
throw new AssertionError(e);
}
}
@Override
public void storeDeviceKey(int deviceKeyId, DeviceKeyRecord record) {
store.put(deviceKeyId, record.serialize());
}
@Override
public boolean containsDeviceKey(int deviceKeyId) {
return store.containsKey(deviceKeyId);
}
@Override
public void removeDeviceKey(int deviceKeyId) {
store.remove(deviceKeyId);
}
}

View File

@ -0,0 +1,59 @@
package org.whispersystems.test;
import org.whispersystems.libaxolotl.InvalidKeyIdException;
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class InMemorySignedPreKeyStore implements SignedPreKeyStore {
private final Map<Integer, byte[]> store = new HashMap<>();
@Override
public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException {
try {
if (!store.containsKey(signedPreKeyId)) {
throw new InvalidKeyIdException("No such signedprekeyrecord!");
}
return new SignedPreKeyRecord(store.get(signedPreKeyId));
} catch (IOException e) {
throw new AssertionError(e);
}
}
@Override
public List<SignedPreKeyRecord> loadSignedPreKeys() {
try {
List<SignedPreKeyRecord> results = new LinkedList<>();
for (byte[] serialized : store.values()) {
results.add(new SignedPreKeyRecord(serialized));
}
return results;
} catch (IOException e) {
throw new AssertionError(e);
}
}
@Override
public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record) {
store.put(signedPreKeyId, record.serialize());
}
@Override
public boolean containsSignedPreKey(int signedPreKeyId) {
return store.containsKey(signedPreKeyId);
}
@Override
public void removeSignedPreKey(int signedPreKeyId) {
store.remove(signedPreKeyId);
}
}

View File

@ -17,8 +17,8 @@ import org.whispersystems.libaxolotl.ecc.ECKeyPair;
import org.whispersystems.libaxolotl.protocol.CiphertextMessage; import org.whispersystems.libaxolotl.protocol.CiphertextMessage;
import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage; import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage;
import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage; import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage;
import org.whispersystems.libaxolotl.state.DeviceKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.DeviceKeyStore; import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.libaxolotl.state.IdentityKeyStore; import org.whispersystems.libaxolotl.state.IdentityKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyBundle; import org.whispersystems.libaxolotl.state.PreKeyBundle;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
@ -36,29 +36,29 @@ public class SessionBuilderTest extends AndroidTestCase {
public void testBasicPreKeyV2() public void testBasicPreKeyV2()
throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException { throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
SessionStore bobSessionStore = new InMemorySessionStore(); SessionStore bobSessionStore = new InMemorySessionStore();
PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore bobDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore, SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore,
bobDeviceKeyStore, bobSignedPreKeyStore,
bobIdentityKeyStore, bobIdentityKeyStore,
ALICE_RECIPIENT_ID, 1); ALICE_RECIPIENT_ID, 1);
ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true);
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(), 31337, bobPreKeyPair.getPublicKey(),
0, null, null, 0, null, null,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
aliceSessionBuilder.process(bobPreKey); aliceSessionBuilder.process(bobPreKey);
@ -95,7 +95,7 @@ public class SessionBuilderTest extends AndroidTestCase {
aliceSessionStore = new InMemorySessionStore(); aliceSessionStore = new InMemorySessionStore();
aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
aliceSessionCipher = new SessionCipher(aliceSessionStore, BOB_RECIPIENT_ID, 1); aliceSessionCipher = new SessionCipher(aliceSessionStore, BOB_RECIPIENT_ID, 1);
@ -137,31 +137,31 @@ public class SessionBuilderTest extends AndroidTestCase {
public void testBasicPreKeyV3() public void testBasicPreKeyV3()
throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException { throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
SessionStore bobSessionStore = new InMemorySessionStore(); SessionStore bobSessionStore = new InMemorySessionStore();
PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore bobDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore, SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore,
bobDeviceKeyStore, bobSignedPreKeyStore,
bobIdentityKeyStore, bobIdentityKeyStore,
ALICE_RECIPIENT_ID, 1); ALICE_RECIPIENT_ID, 1);
ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true);
ECKeyPair bobDeviceKeyPair = Curve.generateKeyPair(true); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(true);
byte[] bobDeviceKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(),
bobDeviceKeyPair.getPublicKey().serialize()); bobSignedPreKeyPair.getPublicKey().serialize());
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(), 31337, bobPreKeyPair.getPublicKey(),
22, bobDeviceKeyPair.getPublicKey(), bobDeviceKeySignature, 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
aliceSessionBuilder.process(bobPreKey); aliceSessionBuilder.process(bobPreKey);
@ -178,7 +178,7 @@ public class SessionBuilderTest extends AndroidTestCase {
PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessage.serialize()); PreKeyWhisperMessage incomingMessage = new PreKeyWhisperMessage(outgoingMessage.serialize());
bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
bobDeviceKeyStore.storeDeviceKey(22, new DeviceKeyRecord(22, System.currentTimeMillis(), bobDeviceKeyPair, bobDeviceKeySignature)); bobSignedPreKeyStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
bobSessionBuilder.process(incomingMessage); bobSessionBuilder.process(incomingMessage);
assertTrue(bobSessionStore.containsSession(ALICE_RECIPIENT_ID, 1)); assertTrue(bobSessionStore.containsSession(ALICE_RECIPIENT_ID, 1));
@ -201,21 +201,21 @@ public class SessionBuilderTest extends AndroidTestCase {
aliceSessionStore = new InMemorySessionStore(); aliceSessionStore = new InMemorySessionStore();
aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
aliceSessionCipher = new SessionCipher(aliceSessionStore, BOB_RECIPIENT_ID, 1); aliceSessionCipher = new SessionCipher(aliceSessionStore, BOB_RECIPIENT_ID, 1);
bobPreKeyPair = Curve.generateKeyPair(true); bobPreKeyPair = Curve.generateKeyPair(true);
bobDeviceKeyPair = Curve.generateKeyPair(true); bobSignedPreKeyPair = Curve.generateKeyPair(true);
bobDeviceKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), bobDeviceKeyPair.getPublicKey().serialize()); bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), bobSignedPreKeyPair.getPublicKey().serialize());
bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(),
1, 31338, bobPreKeyPair.getPublicKey(), 1, 31338, bobPreKeyPair.getPublicKey(),
23, bobDeviceKeyPair.getPublicKey(), bobDeviceKeySignature, 23, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
bobPreKeyStore.storePreKey(31338, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobPreKeyStore.storePreKey(31338, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
bobDeviceKeyStore.storeDeviceKey(23, new DeviceKeyRecord(23, System.currentTimeMillis(), bobDeviceKeyPair, bobDeviceKeySignature)); bobSignedPreKeyStore.storeSignedPreKey(23, new SignedPreKeyRecord(23, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
aliceSessionBuilder.process(bobPreKey); aliceSessionBuilder.process(bobPreKey);
outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes()); outgoingMessage = aliceSessionCipher.encrypt(originalMessage.getBytes());
@ -233,7 +233,7 @@ public class SessionBuilderTest extends AndroidTestCase {
bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, Curve.generateKeyPair(true).getPublicKey(), 31337, Curve.generateKeyPair(true).getPublicKey(),
23, bobDeviceKeyPair.getPublicKey(), bobDeviceKeySignature, 23, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
aliceIdentityKeyStore.getIdentityKeyPair().getPublicKey()); aliceIdentityKeyStore.getIdentityKeyPair().getPublicKey());
try { try {
@ -244,33 +244,33 @@ public class SessionBuilderTest extends AndroidTestCase {
} }
} }
public void testBadDeviceKeySignature() throws InvalidKeyException, UntrustedIdentityException { public void testBadSignedPreKeySignature() throws InvalidKeyException, UntrustedIdentityException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true);
ECKeyPair bobDeviceKeyPair = Curve.generateKeyPair(true); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(true);
byte[] bobDeviceKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(),
bobDeviceKeyPair.getPublicKey().serialize()); bobSignedPreKeyPair.getPublicKey().serialize());
for (int i=0;i<bobDeviceKeySignature.length * 8;i++) { for (int i=0;i<bobSignedPreKeySignature.length * 8;i++) {
byte[] modifiedSignature = new byte[bobDeviceKeySignature.length]; byte[] modifiedSignature = new byte[bobSignedPreKeySignature.length];
System.arraycopy(bobDeviceKeySignature, 0, modifiedSignature, 0, modifiedSignature.length); System.arraycopy(bobSignedPreKeySignature, 0, modifiedSignature, 0, modifiedSignature.length);
modifiedSignature[i/8] ^= (0x01 << (i % 8)); modifiedSignature[i/8] ^= (0x01 << (i % 8));
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(), 31337, bobPreKeyPair.getPublicKey(),
22, bobDeviceKeyPair.getPublicKey(), modifiedSignature, 22, bobSignedPreKeyPair.getPublicKey(), modifiedSignature,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
try { try {
@ -283,7 +283,7 @@ public class SessionBuilderTest extends AndroidTestCase {
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(), 31337, bobPreKeyPair.getPublicKey(),
22, bobDeviceKeyPair.getPublicKey(), bobDeviceKeySignature, 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
aliceSessionBuilder.process(bobPreKey); aliceSessionBuilder.process(bobPreKey);
@ -291,27 +291,27 @@ public class SessionBuilderTest extends AndroidTestCase {
public void testRepeatBundleMessageV2() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException { public void testRepeatBundleMessageV2() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
SessionStore bobSessionStore = new InMemorySessionStore(); SessionStore bobSessionStore = new InMemorySessionStore();
PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore bobDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore, SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore,
bobDeviceKeyStore, bobSignedPreKeyStore,
bobIdentityKeyStore, bobIdentityKeyStore,
ALICE_RECIPIENT_ID, 1); ALICE_RECIPIENT_ID, 1);
ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true);
ECKeyPair bobDeviceKeyPair = Curve.generateKeyPair(true); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(true);
byte[] bobDeviceKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(),
bobDeviceKeyPair.getPublicKey().serialize()); bobSignedPreKeyPair.getPublicKey().serialize());
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(), 31337, bobPreKeyPair.getPublicKey(),
@ -319,7 +319,7 @@ public class SessionBuilderTest extends AndroidTestCase {
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
bobDeviceKeyStore.storeDeviceKey(22, new DeviceKeyRecord(22, System.currentTimeMillis(), bobDeviceKeyPair, bobDeviceKeySignature)); bobSignedPreKeyStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
aliceSessionBuilder.process(bobPreKey); aliceSessionBuilder.process(bobPreKey);
@ -359,35 +359,35 @@ public class SessionBuilderTest extends AndroidTestCase {
public void testRepeatBundleMessageV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException { public void testRepeatBundleMessageV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
SessionStore bobSessionStore = new InMemorySessionStore(); SessionStore bobSessionStore = new InMemorySessionStore();
PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore bobDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore, SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore,
bobDeviceKeyStore, bobSignedPreKeyStore,
bobIdentityKeyStore, bobIdentityKeyStore,
ALICE_RECIPIENT_ID, 1); ALICE_RECIPIENT_ID, 1);
ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true);
ECKeyPair bobDeviceKeyPair = Curve.generateKeyPair(true); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(true);
byte[] bobDeviceKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(),
bobDeviceKeyPair.getPublicKey().serialize()); bobSignedPreKeyPair.getPublicKey().serialize());
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(), 31337, bobPreKeyPair.getPublicKey(),
22, bobDeviceKeyPair.getPublicKey(), bobDeviceKeySignature, 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
bobDeviceKeyStore.storeDeviceKey(22, new DeviceKeyRecord(22, System.currentTimeMillis(), bobDeviceKeyPair, bobDeviceKeySignature)); bobSignedPreKeyStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
aliceSessionBuilder.process(bobPreKey); aliceSessionBuilder.process(bobPreKey);
@ -427,35 +427,35 @@ public class SessionBuilderTest extends AndroidTestCase {
public void testBadVerificationTagV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException { public void testBadVerificationTagV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
SessionStore bobSessionStore = new InMemorySessionStore(); SessionStore bobSessionStore = new InMemorySessionStore();
PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore bobDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore, SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore,
bobDeviceKeyStore, bobSignedPreKeyStore,
bobIdentityKeyStore, bobIdentityKeyStore,
ALICE_RECIPIENT_ID, 1); ALICE_RECIPIENT_ID, 1);
ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true); ECKeyPair bobPreKeyPair = Curve.generateKeyPair(true);
ECKeyPair bobDeviceKeyPair = Curve.generateKeyPair(true); ECKeyPair bobSignedPreKeyPair = Curve.generateKeyPair(true);
byte[] bobDeviceKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(), byte[] bobSignedPreKeySignature = Curve.calculateSignature(bobIdentityKeyStore.getIdentityKeyPair().getPrivateKey(),
bobDeviceKeyPair.getPublicKey().serialize()); bobSignedPreKeyPair.getPublicKey().serialize());
PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1, PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.getLocalRegistrationId(), 1,
31337, bobPreKeyPair.getPublicKey(), 31337, bobPreKeyPair.getPublicKey(),
22, bobDeviceKeyPair.getPublicKey(), bobDeviceKeySignature, 22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
bobIdentityKeyStore.getIdentityKeyPair().getPublicKey()); bobIdentityKeyStore.getIdentityKeyPair().getPublicKey());
bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair)); bobPreKeyStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
bobDeviceKeyStore.storeDeviceKey(22, new DeviceKeyRecord(22, System.currentTimeMillis(), bobDeviceKeyPair, bobDeviceKeySignature)); bobSignedPreKeyStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
aliceSessionBuilder.process(bobPreKey); aliceSessionBuilder.process(bobPreKey);
@ -474,7 +474,7 @@ public class SessionBuilderTest extends AndroidTestCase {
PreKeyWhisperMessage modifiedMessage = new PreKeyWhisperMessage(incomingMessage.getMessageVersion(), PreKeyWhisperMessage modifiedMessage = new PreKeyWhisperMessage(incomingMessage.getMessageVersion(),
incomingMessage.getRegistrationId(), incomingMessage.getRegistrationId(),
incomingMessage.getPreKeyId(), incomingMessage.getPreKeyId(),
incomingMessage.getDeviceKeyId(), incomingMessage.getSignedPreKeyId(),
incomingMessage.getBaseKey(), incomingMessage.getBaseKey(),
incomingMessage.getIdentityKey(), incomingMessage.getIdentityKey(),
modifiedVerification, modifiedVerification,
@ -491,7 +491,7 @@ public class SessionBuilderTest extends AndroidTestCase {
PreKeyWhisperMessage unmodifiedMessage = new PreKeyWhisperMessage(incomingMessage.getMessageVersion(), PreKeyWhisperMessage unmodifiedMessage = new PreKeyWhisperMessage(incomingMessage.getMessageVersion(),
incomingMessage.getRegistrationId(), incomingMessage.getRegistrationId(),
incomingMessage.getPreKeyId(), incomingMessage.getPreKeyId(),
incomingMessage.getDeviceKeyId(), incomingMessage.getSignedPreKeyId(),
incomingMessage.getBaseKey(), incomingMessage.getBaseKey(),
incomingMessage.getIdentityKey(), incomingMessage.getIdentityKey(),
incomingMessage.getVerification(), incomingMessage.getVerification(),
@ -504,19 +504,19 @@ public class SessionBuilderTest extends AndroidTestCase {
public void testBasicKeyExchange() throws InvalidKeyException, LegacyMessageException, InvalidMessageException, DuplicateMessageException, UntrustedIdentityException, StaleKeyExchangeException, InvalidVersionException { public void testBasicKeyExchange() throws InvalidKeyException, LegacyMessageException, InvalidMessageException, DuplicateMessageException, UntrustedIdentityException, StaleKeyExchangeException, InvalidVersionException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
SessionStore bobSessionStore = new InMemorySessionStore(); SessionStore bobSessionStore = new InMemorySessionStore();
PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore bobDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore, SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore,
bobDeviceKeyStore, bobSignedPreKeyStore,
bobIdentityKeyStore, bobIdentityKeyStore,
ALICE_RECIPIENT_ID, 1); ALICE_RECIPIENT_ID, 1);
@ -540,7 +540,7 @@ public class SessionBuilderTest extends AndroidTestCase {
aliceSessionStore = new InMemorySessionStore(); aliceSessionStore = new InMemorySessionStore();
aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, BOB_RECIPIENT_ID, 1); aliceIdentityKeyStore, BOB_RECIPIENT_ID, 1);
aliceKeyExchangeMessage = aliceSessionBuilder.process(); aliceKeyExchangeMessage = aliceSessionBuilder.process();
@ -561,19 +561,19 @@ public class SessionBuilderTest extends AndroidTestCase {
throws InvalidKeyException, DuplicateMessageException, LegacyMessageException, InvalidMessageException, UntrustedIdentityException, StaleKeyExchangeException { throws InvalidKeyException, DuplicateMessageException, LegacyMessageException, InvalidMessageException, UntrustedIdentityException, StaleKeyExchangeException {
SessionStore aliceSessionStore = new InMemorySessionStore(); SessionStore aliceSessionStore = new InMemorySessionStore();
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore(); PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore aliceIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore,
aliceDeviceKeyStore, aliceSignedPreKeyStore,
aliceIdentityKeyStore, aliceIdentityKeyStore,
BOB_RECIPIENT_ID, 1); BOB_RECIPIENT_ID, 1);
SessionStore bobSessionStore = new InMemorySessionStore(); SessionStore bobSessionStore = new InMemorySessionStore();
PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore(); PreKeyStore bobPreKeyStore = new InMemoryPreKeyStore();
DeviceKeyStore bobDeviceKeyStore = new InMemoryDeviceKeyStore(); SignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();
IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore(); IdentityKeyStore bobIdentityKeyStore = new InMemoryIdentityKeyStore();
SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore, SessionBuilder bobSessionBuilder = new SessionBuilder(bobSessionStore, bobPreKeyStore,
bobDeviceKeyStore, bobSignedPreKeyStore,
bobIdentityKeyStore, bobIdentityKeyStore,
ALICE_RECIPIENT_ID, 1); ALICE_RECIPIENT_ID, 1);

View File

@ -9,7 +9,7 @@ import org.whispersystems.libaxolotl.protocol.CiphertextMessage;
import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage; import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage;
import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage; import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage;
import org.whispersystems.libaxolotl.ratchet.RatchetingSession; import org.whispersystems.libaxolotl.ratchet.RatchetingSession;
import org.whispersystems.libaxolotl.state.DeviceKeyStore; import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.libaxolotl.state.IdentityKeyStore; import org.whispersystems.libaxolotl.state.IdentityKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyBundle; import org.whispersystems.libaxolotl.state.PreKeyBundle;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
@ -43,12 +43,12 @@ public class SessionBuilder {
private static final String TAG = SessionBuilder.class.getSimpleName(); private static final String TAG = SessionBuilder.class.getSimpleName();
private final SessionStore sessionStore; private final SessionStore sessionStore;
private final PreKeyStore preKeyStore; private final PreKeyStore preKeyStore;
private final DeviceKeyStore deviceKeyStore; private final SignedPreKeyStore signedPreKeyStore;
private final IdentityKeyStore identityKeyStore; private final IdentityKeyStore identityKeyStore;
private final long recipientId; private final long recipientId;
private final int deviceId; private final int deviceId;
/** /**
* Constructs a SessionBuilder. * Constructs a SessionBuilder.
@ -61,16 +61,16 @@ public class SessionBuilder {
*/ */
public SessionBuilder(SessionStore sessionStore, public SessionBuilder(SessionStore sessionStore,
PreKeyStore preKeyStore, PreKeyStore preKeyStore,
DeviceKeyStore deviceKeyStore, SignedPreKeyStore signedPreKeyStore,
IdentityKeyStore identityKeyStore, IdentityKeyStore identityKeyStore,
long recipientId, int deviceId) long recipientId, int deviceId)
{ {
this.sessionStore = sessionStore; this.sessionStore = sessionStore;
this.preKeyStore = preKeyStore; this.preKeyStore = preKeyStore;
this.deviceKeyStore = deviceKeyStore; this.signedPreKeyStore = signedPreKeyStore;
this.identityKeyStore = identityKeyStore; this.identityKeyStore = identityKeyStore;
this.recipientId = recipientId; this.recipientId = recipientId;
this.deviceId = deviceId; this.deviceId = deviceId;
} }
/** /**
@ -109,7 +109,7 @@ public class SessionBuilder {
{ {
SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId); SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId);
int preKeyId = message.getPreKeyId(); int preKeyId = message.getPreKeyId();
int deviceKeyId = message.getDeviceKeyId(); int signedPreKeyId = message.getSignedPreKeyId();
ECPublicKey theirBaseKey = message.getBaseKey(); ECPublicKey theirBaseKey = message.getBaseKey();
ECPublicKey theirEphemeralKey = message.getWhisperMessage().getSenderEphemeral(); ECPublicKey theirEphemeralKey = message.getWhisperMessage().getSenderEphemeral();
IdentityKey theirIdentityKey = message.getIdentityKey(); IdentityKey theirIdentityKey = message.getIdentityKey();
@ -122,10 +122,10 @@ public class SessionBuilder {
if (preKeyId >=0 && !preKeyStore.containsPreKey(preKeyId)) if (preKeyId >=0 && !preKeyStore.containsPreKey(preKeyId))
throw new InvalidKeyIdException("No such prekey: " + preKeyId); throw new InvalidKeyIdException("No such prekey: " + preKeyId);
if (!deviceKeyStore.containsDeviceKey(deviceKeyId)) if (!signedPreKeyStore.containsSignedPreKey(signedPreKeyId))
throw new InvalidKeyIdException("No such device key: " + deviceKeyId); throw new InvalidKeyIdException("No such device key: " + signedPreKeyId);
ECKeyPair ourBaseKey = deviceKeyStore.loadDeviceKey(deviceKeyId).getKeyPair(); ECKeyPair ourBaseKey = signedPreKeyStore.loadSignedPreKey(signedPreKeyId).getKeyPair();
ECKeyPair ourEphemeralKey = ourBaseKey; ECKeyPair ourEphemeralKey = ourBaseKey;
ECKeyPair ourPreKey = preKeyId < 0 ? ourBaseKey : preKeyStore.loadPreKey(preKeyId).getKeyPair(); ECKeyPair ourPreKey = preKeyId < 0 ? ourBaseKey : preKeyStore.loadPreKey(preKeyId).getKeyPair();
ECPublicKey theirPreKey = theirBaseKey; ECPublicKey theirPreKey = theirBaseKey;
@ -222,10 +222,10 @@ public class SessionBuilder {
throw new UntrustedIdentityException(); throw new UntrustedIdentityException();
} }
if (preKey.getDeviceKey() != null && if (preKey.getSignedPreKey() != null &&
!Curve.verifySignature(preKey.getIdentityKey().getPublicKey(), !Curve.verifySignature(preKey.getIdentityKey().getPublicKey(),
preKey.getDeviceKey().serialize(), preKey.getSignedPreKey().serialize(),
preKey.getDeviceKeySignature())) preKey.getSignedPreKeySignature()))
{ {
throw new InvalidKeyException("Invalid signature on device key!"); throw new InvalidKeyException("Invalid signature on device key!");
} }
@ -238,19 +238,19 @@ public class SessionBuilder {
IdentityKey theirIdentityKey = preKey.getIdentityKey(); IdentityKey theirIdentityKey = preKey.getIdentityKey();
ECPublicKey theirPreKey = preKey.getPreKey(); ECPublicKey theirPreKey = preKey.getPreKey();
ECPublicKey theirBaseKey = preKey.getDeviceKey() == null ? preKey.getPreKey() : preKey.getDeviceKey(); ECPublicKey theirBaseKey = preKey.getSignedPreKey() == null ? preKey.getPreKey() : preKey.getSignedPreKey();
ECPublicKey theirEphemeralKey = theirBaseKey; ECPublicKey theirEphemeralKey = theirBaseKey;
if (sessionRecord.getSessionState().getNeedsRefresh()) sessionRecord.archiveCurrentState(); if (sessionRecord.getSessionState().getNeedsRefresh()) sessionRecord.archiveCurrentState();
else sessionRecord.reset(); else sessionRecord.reset();
RatchetingSession.initializeSession(sessionRecord.getSessionState(), RatchetingSession.initializeSession(sessionRecord.getSessionState(),
preKey.getDeviceKey() == null ? 2 : 3, preKey.getSignedPreKey() == null ? 2 : 3,
ourBaseKey, theirBaseKey, ourEphemeralKey, ourBaseKey, theirBaseKey, ourEphemeralKey,
theirEphemeralKey, ourPreKey, theirPreKey, theirEphemeralKey, ourPreKey, theirPreKey,
ourIdentityKey, theirIdentityKey); ourIdentityKey, theirIdentityKey);
sessionRecord.getSessionState().setPendingPreKey(preKey.getPreKeyId(), preKey.getDeviceKeyId(), ourBaseKey.getPublicKey()); sessionRecord.getSessionState().setPendingPreKey(preKey.getPreKeyId(), preKey.getSignedPreKeyId(), ourBaseKey.getPublicKey());
sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId()); sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId());
sessionRecord.getSessionState().setRemoteRegistrationId(preKey.getRegistrationId()); sessionRecord.getSessionState().setRemoteRegistrationId(preKey.getRegistrationId());

View File

@ -97,14 +97,14 @@ public class SessionCipher {
previousCounter, ciphertextBody); previousCounter, ciphertextBody);
if (sessionState.hasPendingPreKey()) { if (sessionState.hasPendingPreKey()) {
int pendingPreKeyId = sessionState.getPendingPreKeyId(); int pendingPreKeyId = sessionState.getPendingPreKeyId();
int pendingDeviceKeyId = sessionState.getPendingDeviceKeyId(); int pendingSignedPreKeyId = sessionState.getPendingSignedPreKeyId();
ECPublicKey pendingBaseKey = sessionState.getPendingBaseKey(); ECPublicKey pendingBaseKey = sessionState.getPendingBaseKey();
int localRegistrationId = sessionState.getLocalRegistrationId(); int localRegistrationId = sessionState.getLocalRegistrationId();
ciphertextMessage = new PreKeyWhisperMessage(sessionVersion, ciphertextMessage = new PreKeyWhisperMessage(sessionVersion,
localRegistrationId, pendingPreKeyId, localRegistrationId, pendingPreKeyId,
pendingDeviceKeyId, pendingBaseKey, pendingSignedPreKeyId, pendingBaseKey,
sessionState.getLocalIdentityKey(), sessionState.getLocalIdentityKey(),
sessionState.getVerification(), sessionState.getVerification(),
(WhisperMessage) ciphertextMessage); (WhisperMessage) ciphertextMessage);

View File

@ -34,7 +34,7 @@ public class PreKeyWhisperMessage implements CiphertextMessage {
private final int version; private final int version;
private final int registrationId; private final int registrationId;
private final int preKeyId; private final int preKeyId;
private final int deviceKeyId; private final int signedPreKeyId;
private final ECPublicKey baseKey; private final ECPublicKey baseKey;
private final IdentityKey identityKey; private final IdentityKey identityKey;
private final byte[] verification; private final byte[] verification;
@ -55,11 +55,11 @@ public class PreKeyWhisperMessage implements CiphertextMessage {
= WhisperProtos.PreKeyWhisperMessage.parseFrom(ByteString.copyFrom(serialized, 1, = WhisperProtos.PreKeyWhisperMessage.parseFrom(ByteString.copyFrom(serialized, 1,
serialized.length-1)); serialized.length-1));
if ((version == 2 && !preKeyWhisperMessage.hasPreKeyId()) || if ((version == 2 && !preKeyWhisperMessage.hasPreKeyId()) ||
(version == 3 && !preKeyWhisperMessage.hasDeviceKeyId()) || (version == 3 && !preKeyWhisperMessage.hasSignedPreKeyId()) ||
(version == 3 && !preKeyWhisperMessage.hasVerification()) || (version == 3 && !preKeyWhisperMessage.hasVerification()) ||
!preKeyWhisperMessage.hasBaseKey() || !preKeyWhisperMessage.hasBaseKey() ||
!preKeyWhisperMessage.hasIdentityKey() || !preKeyWhisperMessage.hasIdentityKey() ||
!preKeyWhisperMessage.hasMessage()) !preKeyWhisperMessage.hasMessage())
{ {
throw new InvalidMessageException("Incomplete message."); throw new InvalidMessageException("Incomplete message.");
@ -68,7 +68,7 @@ public class PreKeyWhisperMessage implements CiphertextMessage {
this.serialized = serialized; this.serialized = serialized;
this.registrationId = preKeyWhisperMessage.getRegistrationId(); this.registrationId = preKeyWhisperMessage.getRegistrationId();
this.preKeyId = preKeyWhisperMessage.hasPreKeyId() ? preKeyWhisperMessage.getPreKeyId() : -1; this.preKeyId = preKeyWhisperMessage.hasPreKeyId() ? preKeyWhisperMessage.getPreKeyId() : -1;
this.deviceKeyId = preKeyWhisperMessage.hasDeviceKeyId() ? preKeyWhisperMessage.getDeviceKeyId() : -1; this.signedPreKeyId = preKeyWhisperMessage.hasSignedPreKeyId() ? preKeyWhisperMessage.getSignedPreKeyId() : -1;
this.baseKey = Curve.decodePoint(preKeyWhisperMessage.getBaseKey().toByteArray(), 0); this.baseKey = Curve.decodePoint(preKeyWhisperMessage.getBaseKey().toByteArray(), 0);
this.identityKey = new IdentityKey(Curve.decodePoint(preKeyWhisperMessage.getIdentityKey().toByteArray(), 0)); this.identityKey = new IdentityKey(Curve.decodePoint(preKeyWhisperMessage.getIdentityKey().toByteArray(), 0));
this.verification = preKeyWhisperMessage.getVerification().toByteArray(); this.verification = preKeyWhisperMessage.getVerification().toByteArray();
@ -78,14 +78,14 @@ public class PreKeyWhisperMessage implements CiphertextMessage {
} }
} }
public PreKeyWhisperMessage(int messageVersion, int registrationId, int preKeyId, int deviceKeyId, public PreKeyWhisperMessage(int messageVersion, int registrationId, int preKeyId, int signedPreKeyId,
ECPublicKey baseKey, IdentityKey identityKey, byte[] verification, ECPublicKey baseKey, IdentityKey identityKey, byte[] verification,
WhisperMessage message) WhisperMessage message)
{ {
this.version = messageVersion; this.version = messageVersion;
this.registrationId = registrationId; this.registrationId = registrationId;
this.preKeyId = preKeyId; this.preKeyId = preKeyId;
this.deviceKeyId = deviceKeyId; this.signedPreKeyId = signedPreKeyId;
this.baseKey = baseKey; this.baseKey = baseKey;
this.identityKey = identityKey; this.identityKey = identityKey;
this.verification = verification; this.verification = verification;
@ -94,7 +94,7 @@ public class PreKeyWhisperMessage implements CiphertextMessage {
byte[] versionBytes = {ByteUtil.intsToByteHighAndLow(this.version, CURRENT_VERSION)}; byte[] versionBytes = {ByteUtil.intsToByteHighAndLow(this.version, CURRENT_VERSION)};
byte[] messageBytes = WhisperProtos.PreKeyWhisperMessage.newBuilder() byte[] messageBytes = WhisperProtos.PreKeyWhisperMessage.newBuilder()
.setPreKeyId(preKeyId) .setPreKeyId(preKeyId)
.setDeviceKeyId(deviceKeyId) .setSignedPreKeyId(signedPreKeyId)
.setBaseKey(ByteString.copyFrom(baseKey.serialize())) .setBaseKey(ByteString.copyFrom(baseKey.serialize()))
.setIdentityKey(ByteString.copyFrom(identityKey.serialize())) .setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
.setVerification(ByteString.copyFrom(verification)) .setVerification(ByteString.copyFrom(verification))
@ -121,8 +121,8 @@ public class PreKeyWhisperMessage implements CiphertextMessage {
return preKeyId; return preKeyId;
} }
public int getDeviceKeyId() { public int getSignedPreKeyId() {
return deviceKeyId; return signedPreKeyId;
} }
public ECPublicKey getBaseKey() { public ECPublicKey getBaseKey() {

View File

@ -676,15 +676,15 @@ public final class WhisperProtos {
*/ */
int getPreKeyId(); int getPreKeyId();
// optional uint32 deviceKeyId = 6; // optional uint32 signedPreKeyId = 6;
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
boolean hasDeviceKeyId(); boolean hasSignedPreKeyId();
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
int getDeviceKeyId(); int getSignedPreKeyId();
// optional bytes baseKey = 2; // optional bytes baseKey = 2;
/** /**
@ -812,7 +812,7 @@ public final class WhisperProtos {
} }
case 48: { case 48: {
bitField0_ |= 0x00000004; bitField0_ |= 0x00000004;
deviceKeyId_ = input.readUInt32(); signedPreKeyId_ = input.readUInt32();
break; break;
} }
case 58: { case 58: {
@ -892,20 +892,20 @@ public final class WhisperProtos {
return preKeyId_; return preKeyId_;
} }
// optional uint32 deviceKeyId = 6; // optional uint32 signedPreKeyId = 6;
public static final int DEVICEKEYID_FIELD_NUMBER = 6; public static final int SIGNEDPREKEYID_FIELD_NUMBER = 6;
private int deviceKeyId_; private int signedPreKeyId_;
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
public boolean hasDeviceKeyId() { public boolean hasSignedPreKeyId() {
return ((bitField0_ & 0x00000004) == 0x00000004); return ((bitField0_ & 0x00000004) == 0x00000004);
} }
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
public int getDeviceKeyId() { public int getSignedPreKeyId() {
return deviceKeyId_; return signedPreKeyId_;
} }
// optional bytes baseKey = 2; // optional bytes baseKey = 2;
@ -983,7 +983,7 @@ public final class WhisperProtos {
private void initFields() { private void initFields() {
registrationId_ = 0; registrationId_ = 0;
preKeyId_ = 0; preKeyId_ = 0;
deviceKeyId_ = 0; signedPreKeyId_ = 0;
baseKey_ = com.google.protobuf.ByteString.EMPTY; baseKey_ = com.google.protobuf.ByteString.EMPTY;
identityKey_ = com.google.protobuf.ByteString.EMPTY; identityKey_ = com.google.protobuf.ByteString.EMPTY;
verification_ = com.google.protobuf.ByteString.EMPTY; verification_ = com.google.protobuf.ByteString.EMPTY;
@ -1017,7 +1017,7 @@ public final class WhisperProtos {
output.writeUInt32(5, registrationId_); output.writeUInt32(5, registrationId_);
} }
if (((bitField0_ & 0x00000004) == 0x00000004)) { if (((bitField0_ & 0x00000004) == 0x00000004)) {
output.writeUInt32(6, deviceKeyId_); output.writeUInt32(6, signedPreKeyId_);
} }
if (((bitField0_ & 0x00000020) == 0x00000020)) { if (((bitField0_ & 0x00000020) == 0x00000020)) {
output.writeBytes(7, verification_); output.writeBytes(7, verification_);
@ -1053,7 +1053,7 @@ public final class WhisperProtos {
} }
if (((bitField0_ & 0x00000004) == 0x00000004)) { if (((bitField0_ & 0x00000004) == 0x00000004)) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(6, deviceKeyId_); .computeUInt32Size(6, signedPreKeyId_);
} }
if (((bitField0_ & 0x00000020) == 0x00000020)) { if (((bitField0_ & 0x00000020) == 0x00000020)) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
@ -1179,7 +1179,7 @@ public final class WhisperProtos {
bitField0_ = (bitField0_ & ~0x00000001); bitField0_ = (bitField0_ & ~0x00000001);
preKeyId_ = 0; preKeyId_ = 0;
bitField0_ = (bitField0_ & ~0x00000002); bitField0_ = (bitField0_ & ~0x00000002);
deviceKeyId_ = 0; signedPreKeyId_ = 0;
bitField0_ = (bitField0_ & ~0x00000004); bitField0_ = (bitField0_ & ~0x00000004);
baseKey_ = com.google.protobuf.ByteString.EMPTY; baseKey_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000008); bitField0_ = (bitField0_ & ~0x00000008);
@ -1228,7 +1228,7 @@ public final class WhisperProtos {
if (((from_bitField0_ & 0x00000004) == 0x00000004)) { if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
to_bitField0_ |= 0x00000004; to_bitField0_ |= 0x00000004;
} }
result.deviceKeyId_ = deviceKeyId_; result.signedPreKeyId_ = signedPreKeyId_;
if (((from_bitField0_ & 0x00000008) == 0x00000008)) { if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
to_bitField0_ |= 0x00000008; to_bitField0_ |= 0x00000008;
} }
@ -1267,8 +1267,8 @@ public final class WhisperProtos {
if (other.hasPreKeyId()) { if (other.hasPreKeyId()) {
setPreKeyId(other.getPreKeyId()); setPreKeyId(other.getPreKeyId());
} }
if (other.hasDeviceKeyId()) { if (other.hasSignedPreKeyId()) {
setDeviceKeyId(other.getDeviceKeyId()); setSignedPreKeyId(other.getSignedPreKeyId());
} }
if (other.hasBaseKey()) { if (other.hasBaseKey()) {
setBaseKey(other.getBaseKey()); setBaseKey(other.getBaseKey());
@ -1375,35 +1375,35 @@ public final class WhisperProtos {
return this; return this;
} }
// optional uint32 deviceKeyId = 6; // optional uint32 signedPreKeyId = 6;
private int deviceKeyId_ ; private int signedPreKeyId_ ;
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
public boolean hasDeviceKeyId() { public boolean hasSignedPreKeyId() {
return ((bitField0_ & 0x00000004) == 0x00000004); return ((bitField0_ & 0x00000004) == 0x00000004);
} }
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
public int getDeviceKeyId() { public int getSignedPreKeyId() {
return deviceKeyId_; return signedPreKeyId_;
} }
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
public Builder setDeviceKeyId(int value) { public Builder setSignedPreKeyId(int value) {
bitField0_ |= 0x00000004; bitField0_ |= 0x00000004;
deviceKeyId_ = value; signedPreKeyId_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>optional uint32 deviceKeyId = 6;</code> * <code>optional uint32 signedPreKeyId = 6;</code>
*/ */
public Builder clearDeviceKeyId() { public Builder clearSignedPreKeyId() {
bitField0_ = (bitField0_ & ~0x00000004); bitField0_ = (bitField0_ & ~0x00000004);
deviceKeyId_ = 0; signedPreKeyId_ = 0;
onChanged(); onChanged();
return this; return this;
} }
@ -2422,16 +2422,16 @@ public final class WhisperProtos {
"\n\031WhisperTextProtocol.proto\022\ntextsecure\"" + "\n\031WhisperTextProtocol.proto\022\ntextsecure\"" +
"d\n\016WhisperMessage\022\024\n\014ephemeralKey\030\001 \001(\014\022" + "d\n\016WhisperMessage\022\024\n\014ephemeralKey\030\001 \001(\014\022" +
"\017\n\007counter\030\002 \001(\r\022\027\n\017previousCounter\030\003 \001(" + "\017\n\007counter\030\002 \001(\r\022\027\n\017previousCounter\030\003 \001(" +
"\r\022\022\n\nciphertext\030\004 \001(\014\"\242\001\n\024PreKeyWhisperM" + "\r\022\022\n\nciphertext\030\004 \001(\014\"\245\001\n\024PreKeyWhisperM" +
"essage\022\026\n\016registrationId\030\005 \001(\r\022\020\n\010preKey" + "essage\022\026\n\016registrationId\030\005 \001(\r\022\020\n\010preKey" +
"Id\030\001 \001(\r\022\023\n\013deviceKeyId\030\006 \001(\r\022\017\n\007baseKey" + "Id\030\001 \001(\r\022\026\n\016signedPreKeyId\030\006 \001(\r\022\017\n\007base" +
"\030\002 \001(\014\022\023\n\013identityKey\030\003 \001(\014\022\024\n\014verificat" + "Key\030\002 \001(\014\022\023\n\013identityKey\030\003 \001(\014\022\024\n\014verifi" +
"ion\030\007 \001(\014\022\017\n\007message\030\004 \001(\014\"\214\001\n\022KeyExchan" + "cation\030\007 \001(\014\022\017\n\007message\030\004 \001(\014\"\214\001\n\022KeyExc" +
"geMessage\022\n\n\002id\030\001 \001(\r\022\017\n\007baseKey\030\002 \001(\014\022\024" + "hangeMessage\022\n\n\002id\030\001 \001(\r\022\017\n\007baseKey\030\002 \001(" +
"\n\014ephemeralKey\030\003 \001(\014\022\023\n\013identityKey\030\004 \001(", "\014\022\024\n\014ephemeralKey\030\003 \001(\014\022\023\n\013identityKey\030\004",
"\014\022\030\n\020baseKeySignature\030\005 \001(\014\022\024\n\014verificat" + " \001(\014\022\030\n\020baseKeySignature\030\005 \001(\014\022\024\n\014verifi" +
"ion\030\006 \001(\014B7\n&org.whispersystems.libaxolo" + "cation\030\006 \001(\014B7\n&org.whispersystems.libax" +
"tl.protocolB\rWhisperProtos" "olotl.protocolB\rWhisperProtos"
}; };
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@ -2449,7 +2449,7 @@ public final class WhisperProtos {
internal_static_textsecure_PreKeyWhisperMessage_fieldAccessorTable = new internal_static_textsecure_PreKeyWhisperMessage_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_PreKeyWhisperMessage_descriptor, internal_static_textsecure_PreKeyWhisperMessage_descriptor,
new java.lang.String[] { "RegistrationId", "PreKeyId", "DeviceKeyId", "BaseKey", "IdentityKey", "Verification", "Message", }); new java.lang.String[] { "RegistrationId", "PreKeyId", "SignedPreKeyId", "BaseKey", "IdentityKey", "Verification", "Message", });
internal_static_textsecure_KeyExchangeMessage_descriptor = internal_static_textsecure_KeyExchangeMessage_descriptor =
getDescriptor().getMessageTypes().get(2); getDescriptor().getMessageTypes().get(2);
internal_static_textsecure_KeyExchangeMessage_fieldAccessorTable = new internal_static_textsecure_KeyExchangeMessage_fieldAccessorTable = new

View File

@ -1,47 +0,0 @@
package org.whispersystems.libaxolotl.state;
import org.whispersystems.libaxolotl.InvalidKeyIdException;
import java.util.List;
public interface DeviceKeyStore {
/**
* Load a local DeviceKeyRecord.
*
* @param deviceKeyId the ID of the local DeviceKeyRecord.
* @return the corresponding DeviceKeyRecord.
* @throws InvalidKeyIdException when there is no corresponding DeviceKeyRecord.
*/
public DeviceKeyRecord loadDeviceKey(int deviceKeyId) throws InvalidKeyIdException;
/**
* Load all local DeviceKeyRecords.
*
* @return All stored DeviceKeyRecords.
*/
public List<DeviceKeyRecord> loadDeviceKeys();
/**
* Store a local DeviceKeyRecord.
*
* @param deviceKeyId the ID of the DeviceKeyRecord to store.
* @param record the DeviceKeyRecord.
*/
public void storeDeviceKey(int deviceKeyId, DeviceKeyRecord record);
/**
* @param deviceKeyId A DeviceKeyRecord ID.
* @return true if the store has a record for the deviceKeyId, otherwise false.
*/
public boolean containsDeviceKey(int deviceKeyId);
/**
* Delete a DeviceKeyRecord from local storage.
*
* @param deviceKeyId The ID of the PreKeyRecord to remove.
*/
public void removeDeviceKey(int deviceKeyId);
}

View File

@ -13,29 +13,29 @@ public class PreKeyBundle {
private int registrationId; private int registrationId;
private int deviceId; private int deviceId;
private int preKeyId; private int preKeyId;
private ECPublicKey preKeyPublic; private ECPublicKey preKeyPublic;
private int deviceKeyId; private int signedPreKeyId;
private ECPublicKey deviceKeyPublic; private ECPublicKey signedPreKeyPublic;
private byte[] deviceKeySignature; private byte[] signedPreKeySignature;
private IdentityKey identityKey; private IdentityKey identityKey;
public PreKeyBundle(int registrationId, int deviceId, int preKeyId, ECPublicKey preKeyPublic, public PreKeyBundle(int registrationId, int deviceId, int preKeyId, ECPublicKey preKeyPublic,
int deviceKeyId, ECPublicKey deviceKeyPublic, byte[] deviceKeySignature, int signedPreKeyId, ECPublicKey signedPreKeyPublic, byte[] signedPreKeySignature,
IdentityKey identityKey) IdentityKey identityKey)
{ {
this.registrationId = registrationId; this.registrationId = registrationId;
this.deviceId = deviceId; this.deviceId = deviceId;
this.preKeyId = preKeyId; this.preKeyId = preKeyId;
this.preKeyPublic = preKeyPublic; this.preKeyPublic = preKeyPublic;
this.deviceKeyId = deviceKeyId; this.signedPreKeyId = signedPreKeyId;
this.deviceKeyPublic = deviceKeyPublic; this.signedPreKeyPublic = signedPreKeyPublic;
this.deviceKeySignature = deviceKeySignature; this.signedPreKeySignature = signedPreKeySignature;
this.identityKey = identityKey; this.identityKey = identityKey;
} }
/** /**
@ -60,24 +60,24 @@ public class PreKeyBundle {
} }
/** /**
* @return the unique key ID for this DeviceKey. * @return the unique key ID for this signed prekey.
*/ */
public int getDeviceKeyId() { public int getSignedPreKeyId() {
return deviceKeyId; return signedPreKeyId;
} }
/** /**
* @return the device key for this PreKey. * @return the signed prekey for this PreKeyBundle.
*/ */
public ECPublicKey getDeviceKey() { public ECPublicKey getSignedPreKey() {
return deviceKeyPublic; return signedPreKeyPublic;
} }
/** /**
* @return the signature over the device key. * @return the signature over the signed prekey.
*/ */
public byte[] getDeviceKeySignature() { public byte[] getSignedPreKeySignature() {
return deviceKeySignature; return signedPreKeySignature;
} }
/** /**

View File

@ -423,10 +423,10 @@ public class SessionState {
return sessionStructure.hasPendingKeyExchange(); return sessionStructure.hasPendingKeyExchange();
} }
public void setPendingPreKey(int preKeyId, int deviceKeyId, ECPublicKey baseKey) { public void setPendingPreKey(int preKeyId, int signedPreKeyId, ECPublicKey baseKey) {
PendingPreKey pending = PendingPreKey.newBuilder() PendingPreKey pending = PendingPreKey.newBuilder()
.setPreKeyId(preKeyId) .setPreKeyId(preKeyId)
.setDeviceKeyId(deviceKeyId) .setSignedPreKeyId(signedPreKeyId)
.setBaseKey(ByteString.copyFrom(baseKey.serialize())) .setBaseKey(ByteString.copyFrom(baseKey.serialize()))
.build(); .build();
@ -443,8 +443,8 @@ public class SessionState {
return sessionStructure.getPendingPreKey().getPreKeyId(); return sessionStructure.getPendingPreKey().getPreKeyId();
} }
public int getPendingDeviceKeyId() { public int getPendingSignedPreKeyId() {
return sessionStructure.getPendingPreKey().getDeviceKeyId(); return sessionStructure.getPendingPreKey().getSignedPreKeyId();
} }
public ECPublicKey getPendingBaseKey() { public ECPublicKey getPendingBaseKey() {

View File

@ -10,26 +10,26 @@ import org.whispersystems.libaxolotl.ecc.ECPublicKey;
import java.io.IOException; import java.io.IOException;
import static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure; import static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure;
public class DeviceKeyRecord { public class SignedPreKeyRecord {
private DeviceKeyRecordStructure structure; private SignedPreKeyRecordStructure structure;
public DeviceKeyRecord(int id, long timestamp, ECKeyPair keyPair, byte[] signature) { public SignedPreKeyRecord(int id, long timestamp, ECKeyPair keyPair, byte[] signature) {
this.structure = DeviceKeyRecordStructure.newBuilder() this.structure = SignedPreKeyRecordStructure.newBuilder()
.setId(id) .setId(id)
.setPublicKey(ByteString.copyFrom(keyPair.getPublicKey() .setPublicKey(ByteString.copyFrom(keyPair.getPublicKey()
.serialize())) .serialize()))
.setPrivateKey(ByteString.copyFrom(keyPair.getPrivateKey() .setPrivateKey(ByteString.copyFrom(keyPair.getPrivateKey()
.serialize())) .serialize()))
.setSignature(ByteString.copyFrom(signature)) .setSignature(ByteString.copyFrom(signature))
.setTimestamp(timestamp) .setTimestamp(timestamp)
.build(); .build();
} }
public DeviceKeyRecord(byte[] serialized) throws IOException { public SignedPreKeyRecord(byte[] serialized) throws IOException {
this.structure = DeviceKeyRecordStructure.parseFrom(serialized); this.structure = SignedPreKeyRecordStructure.parseFrom(serialized);
} }
public int getId() { public int getId() {

View File

@ -0,0 +1,47 @@
package org.whispersystems.libaxolotl.state;
import org.whispersystems.libaxolotl.InvalidKeyIdException;
import java.util.List;
public interface SignedPreKeyStore {
/**
* Load a local SignedPreKeyRecord.
*
* @param signedPreKeyId the ID of the local SignedPreKeyRecord.
* @return the corresponding SignedPreKeyRecord.
* @throws InvalidKeyIdException when there is no corresponding SignedPreKeyRecord.
*/
public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException;
/**
* Load all local SignedPreKeyRecords.
*
* @return All stored SignedPreKeyRecords.
*/
public List<SignedPreKeyRecord> loadSignedPreKeys();
/**
* Store a local SignedPreKeyRecord.
*
* @param signedPreKeyId the ID of the SignedPreKeyRecord to store.
* @param record the SignedPreKeyRecord.
*/
public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record);
/**
* @param signedPreKeyId A SignedPreKeyRecord ID.
* @return true if the store has a record for the signedPreKeyId, otherwise false.
*/
public boolean containsSignedPreKey(int signedPreKeyId);
/**
* Delete a SignedPreKeyRecord from local storage.
*
* @param signedPreKeyId The ID of the SignedPreKeyRecord to remove.
*/
public void removeSignedPreKey(int signedPreKeyId);
}

View File

@ -3362,15 +3362,15 @@ public final class StorageProtos {
*/ */
int getPreKeyId(); int getPreKeyId();
// optional int32 deviceKeyId = 3; // optional int32 signedPreKeyId = 3;
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
boolean hasDeviceKeyId(); boolean hasSignedPreKeyId();
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
int getDeviceKeyId(); int getSignedPreKeyId();
// optional bytes baseKey = 2; // optional bytes baseKey = 2;
/** /**
@ -3445,7 +3445,7 @@ public final class StorageProtos {
} }
case 24: { case 24: {
bitField0_ |= 0x00000002; bitField0_ |= 0x00000002;
deviceKeyId_ = input.readInt32(); signedPreKeyId_ = input.readInt32();
break; break;
} }
} }
@ -3504,20 +3504,20 @@ public final class StorageProtos {
return preKeyId_; return preKeyId_;
} }
// optional int32 deviceKeyId = 3; // optional int32 signedPreKeyId = 3;
public static final int DEVICEKEYID_FIELD_NUMBER = 3; public static final int SIGNEDPREKEYID_FIELD_NUMBER = 3;
private int deviceKeyId_; private int signedPreKeyId_;
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
public boolean hasDeviceKeyId() { public boolean hasSignedPreKeyId() {
return ((bitField0_ & 0x00000002) == 0x00000002); return ((bitField0_ & 0x00000002) == 0x00000002);
} }
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
public int getDeviceKeyId() { public int getSignedPreKeyId() {
return deviceKeyId_; return signedPreKeyId_;
} }
// optional bytes baseKey = 2; // optional bytes baseKey = 2;
@ -3538,7 +3538,7 @@ public final class StorageProtos {
private void initFields() { private void initFields() {
preKeyId_ = 0; preKeyId_ = 0;
deviceKeyId_ = 0; signedPreKeyId_ = 0;
baseKey_ = com.google.protobuf.ByteString.EMPTY; baseKey_ = com.google.protobuf.ByteString.EMPTY;
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
@ -3560,7 +3560,7 @@ public final class StorageProtos {
output.writeBytes(2, baseKey_); output.writeBytes(2, baseKey_);
} }
if (((bitField0_ & 0x00000002) == 0x00000002)) { if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeInt32(3, deviceKeyId_); output.writeInt32(3, signedPreKeyId_);
} }
getUnknownFields().writeTo(output); getUnknownFields().writeTo(output);
} }
@ -3581,7 +3581,7 @@ public final class StorageProtos {
} }
if (((bitField0_ & 0x00000002) == 0x00000002)) { if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeInt32Size(3, deviceKeyId_); .computeInt32Size(3, signedPreKeyId_);
} }
size += getUnknownFields().getSerializedSize(); size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size; memoizedSerializedSize = size;
@ -3701,7 +3701,7 @@ public final class StorageProtos {
super.clear(); super.clear();
preKeyId_ = 0; preKeyId_ = 0;
bitField0_ = (bitField0_ & ~0x00000001); bitField0_ = (bitField0_ & ~0x00000001);
deviceKeyId_ = 0; signedPreKeyId_ = 0;
bitField0_ = (bitField0_ & ~0x00000002); bitField0_ = (bitField0_ & ~0x00000002);
baseKey_ = com.google.protobuf.ByteString.EMPTY; baseKey_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000004); bitField0_ = (bitField0_ & ~0x00000004);
@ -3740,7 +3740,7 @@ public final class StorageProtos {
if (((from_bitField0_ & 0x00000002) == 0x00000002)) { if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
to_bitField0_ |= 0x00000002; to_bitField0_ |= 0x00000002;
} }
result.deviceKeyId_ = deviceKeyId_; result.signedPreKeyId_ = signedPreKeyId_;
if (((from_bitField0_ & 0x00000004) == 0x00000004)) { if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
to_bitField0_ |= 0x00000004; to_bitField0_ |= 0x00000004;
} }
@ -3764,8 +3764,8 @@ public final class StorageProtos {
if (other.hasPreKeyId()) { if (other.hasPreKeyId()) {
setPreKeyId(other.getPreKeyId()); setPreKeyId(other.getPreKeyId());
} }
if (other.hasDeviceKeyId()) { if (other.hasSignedPreKeyId()) {
setDeviceKeyId(other.getDeviceKeyId()); setSignedPreKeyId(other.getSignedPreKeyId());
} }
if (other.hasBaseKey()) { if (other.hasBaseKey()) {
setBaseKey(other.getBaseKey()); setBaseKey(other.getBaseKey());
@ -3830,35 +3830,35 @@ public final class StorageProtos {
return this; return this;
} }
// optional int32 deviceKeyId = 3; // optional int32 signedPreKeyId = 3;
private int deviceKeyId_ ; private int signedPreKeyId_ ;
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
public boolean hasDeviceKeyId() { public boolean hasSignedPreKeyId() {
return ((bitField0_ & 0x00000002) == 0x00000002); return ((bitField0_ & 0x00000002) == 0x00000002);
} }
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
public int getDeviceKeyId() { public int getSignedPreKeyId() {
return deviceKeyId_; return signedPreKeyId_;
} }
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
public Builder setDeviceKeyId(int value) { public Builder setSignedPreKeyId(int value) {
bitField0_ |= 0x00000002; bitField0_ |= 0x00000002;
deviceKeyId_ = value; signedPreKeyId_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>optional int32 deviceKeyId = 3;</code> * <code>optional int32 signedPreKeyId = 3;</code>
*/ */
public Builder clearDeviceKeyId() { public Builder clearSignedPreKeyId() {
bitField0_ = (bitField0_ & ~0x00000002); bitField0_ = (bitField0_ & ~0x00000002);
deviceKeyId_ = 0; signedPreKeyId_ = 0;
onChanged(); onChanged();
return this; return this;
} }
@ -7061,7 +7061,7 @@ public final class StorageProtos {
// @@protoc_insertion_point(class_scope:textsecure.PreKeyRecordStructure) // @@protoc_insertion_point(class_scope:textsecure.PreKeyRecordStructure)
} }
public interface DeviceKeyRecordStructureOrBuilder public interface SignedPreKeyRecordStructureOrBuilder
extends com.google.protobuf.MessageOrBuilder { extends com.google.protobuf.MessageOrBuilder {
// optional uint32 id = 1; // optional uint32 id = 1;
@ -7115,24 +7115,24 @@ public final class StorageProtos {
long getTimestamp(); long getTimestamp();
} }
/** /**
* Protobuf type {@code textsecure.DeviceKeyRecordStructure} * Protobuf type {@code textsecure.SignedPreKeyRecordStructure}
*/ */
public static final class DeviceKeyRecordStructure extends public static final class SignedPreKeyRecordStructure extends
com.google.protobuf.GeneratedMessage com.google.protobuf.GeneratedMessage
implements DeviceKeyRecordStructureOrBuilder { implements SignedPreKeyRecordStructureOrBuilder {
// Use DeviceKeyRecordStructure.newBuilder() to construct. // Use SignedPreKeyRecordStructure.newBuilder() to construct.
private DeviceKeyRecordStructure(com.google.protobuf.GeneratedMessage.Builder<?> builder) { private SignedPreKeyRecordStructure(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
super(builder); super(builder);
this.unknownFields = builder.getUnknownFields(); this.unknownFields = builder.getUnknownFields();
} }
private DeviceKeyRecordStructure(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } private SignedPreKeyRecordStructure(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
private static final DeviceKeyRecordStructure defaultInstance; private static final SignedPreKeyRecordStructure defaultInstance;
public static DeviceKeyRecordStructure getDefaultInstance() { public static SignedPreKeyRecordStructure getDefaultInstance() {
return defaultInstance; return defaultInstance;
} }
public DeviceKeyRecordStructure getDefaultInstanceForType() { public SignedPreKeyRecordStructure getDefaultInstanceForType() {
return defaultInstance; return defaultInstance;
} }
@ -7142,7 +7142,7 @@ public final class StorageProtos {
getUnknownFields() { getUnknownFields() {
return this.unknownFields; return this.unknownFields;
} }
private DeviceKeyRecordStructure( private SignedPreKeyRecordStructure(
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
@ -7204,28 +7204,28 @@ public final class StorageProtos {
} }
public static final com.google.protobuf.Descriptors.Descriptor public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() { getDescriptor() {
return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_DeviceKeyRecordStructure_descriptor; return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_SignedPreKeyRecordStructure_descriptor;
} }
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() { internalGetFieldAccessorTable() {
return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_DeviceKeyRecordStructure_fieldAccessorTable return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_SignedPreKeyRecordStructure_fieldAccessorTable
.ensureFieldAccessorsInitialized( .ensureFieldAccessorsInitialized(
org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure.class, org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure.Builder.class); org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure.class, org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure.Builder.class);
} }
public static com.google.protobuf.Parser<DeviceKeyRecordStructure> PARSER = public static com.google.protobuf.Parser<SignedPreKeyRecordStructure> PARSER =
new com.google.protobuf.AbstractParser<DeviceKeyRecordStructure>() { new com.google.protobuf.AbstractParser<SignedPreKeyRecordStructure>() {
public DeviceKeyRecordStructure parsePartialFrom( public SignedPreKeyRecordStructure parsePartialFrom(
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return new DeviceKeyRecordStructure(input, extensionRegistry); return new SignedPreKeyRecordStructure(input, extensionRegistry);
} }
}; };
@java.lang.Override @java.lang.Override
public com.google.protobuf.Parser<DeviceKeyRecordStructure> getParserForType() { public com.google.protobuf.Parser<SignedPreKeyRecordStructure> getParserForType() {
return PARSER; return PARSER;
} }
@ -7385,53 +7385,53 @@ public final class StorageProtos {
return super.writeReplace(); return super.writeReplace();
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom( public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(
com.google.protobuf.ByteString data) com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data); return PARSER.parseFrom(data);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom( public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(
com.google.protobuf.ByteString data, com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry); return PARSER.parseFrom(data, extensionRegistry);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom(byte[] data) public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data); return PARSER.parseFrom(data);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom( public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(
byte[] data, byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException { throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry); return PARSER.parseFrom(data, extensionRegistry);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom(java.io.InputStream input) public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(java.io.InputStream input)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseFrom(input); return PARSER.parseFrom(input);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom( public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(
java.io.InputStream input, java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseFrom(input, extensionRegistry); return PARSER.parseFrom(input, extensionRegistry);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseDelimitedFrom(java.io.InputStream input) public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseDelimitedFrom(input); return PARSER.parseDelimitedFrom(input);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseDelimitedFrom( public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseDelimitedFrom(
java.io.InputStream input, java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseDelimitedFrom(input, extensionRegistry); return PARSER.parseDelimitedFrom(input, extensionRegistry);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom( public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(
com.google.protobuf.CodedInputStream input) com.google.protobuf.CodedInputStream input)
throws java.io.IOException { throws java.io.IOException {
return PARSER.parseFrom(input); return PARSER.parseFrom(input);
} }
public static org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parseFrom( public static org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parseFrom(
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
@ -7440,7 +7440,7 @@ public final class StorageProtos {
public static Builder newBuilder() { return Builder.create(); } public static Builder newBuilder() { return Builder.create(); }
public Builder newBuilderForType() { return newBuilder(); } public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure prototype) { public static Builder newBuilder(org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure prototype) {
return newBuilder().mergeFrom(prototype); return newBuilder().mergeFrom(prototype);
} }
public Builder toBuilder() { return newBuilder(this); } public Builder toBuilder() { return newBuilder(this); }
@ -7452,24 +7452,24 @@ public final class StorageProtos {
return builder; return builder;
} }
/** /**
* Protobuf type {@code textsecure.DeviceKeyRecordStructure} * Protobuf type {@code textsecure.SignedPreKeyRecordStructure}
*/ */
public static final class Builder extends public static final class Builder extends
com.google.protobuf.GeneratedMessage.Builder<Builder> com.google.protobuf.GeneratedMessage.Builder<Builder>
implements org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructureOrBuilder { implements org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructureOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() { getDescriptor() {
return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_DeviceKeyRecordStructure_descriptor; return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_SignedPreKeyRecordStructure_descriptor;
} }
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() { internalGetFieldAccessorTable() {
return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_DeviceKeyRecordStructure_fieldAccessorTable return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_SignedPreKeyRecordStructure_fieldAccessorTable
.ensureFieldAccessorsInitialized( .ensureFieldAccessorsInitialized(
org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure.class, org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure.Builder.class); org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure.class, org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure.Builder.class);
} }
// Construct using org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure.newBuilder() // Construct using org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure.newBuilder()
private Builder() { private Builder() {
maybeForceBuilderInitialization(); maybeForceBuilderInitialization();
} }
@ -7508,23 +7508,23 @@ public final class StorageProtos {
public com.google.protobuf.Descriptors.Descriptor public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() { getDescriptorForType() {
return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_DeviceKeyRecordStructure_descriptor; return org.whispersystems.libaxolotl.state.StorageProtos.internal_static_textsecure_SignedPreKeyRecordStructure_descriptor;
} }
public org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure getDefaultInstanceForType() { public org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure getDefaultInstanceForType() {
return org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure.getDefaultInstance(); return org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure.getDefaultInstance();
} }
public org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure build() { public org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure build() {
org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure result = buildPartial(); org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure result = buildPartial();
if (!result.isInitialized()) { if (!result.isInitialized()) {
throw newUninitializedMessageException(result); throw newUninitializedMessageException(result);
} }
return result; return result;
} }
public org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure buildPartial() { public org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure buildPartial() {
org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure result = new org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure(this); org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure result = new org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure(this);
int from_bitField0_ = bitField0_; int from_bitField0_ = bitField0_;
int to_bitField0_ = 0; int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) == 0x00000001)) { if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
@ -7553,16 +7553,16 @@ public final class StorageProtos {
} }
public Builder mergeFrom(com.google.protobuf.Message other) { public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure) { if (other instanceof org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure) {
return mergeFrom((org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure)other); return mergeFrom((org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure)other);
} else { } else {
super.mergeFrom(other); super.mergeFrom(other);
return this; return this;
} }
} }
public Builder mergeFrom(org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure other) { public Builder mergeFrom(org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure other) {
if (other == org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure.getDefaultInstance()) return this; if (other == org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure.getDefaultInstance()) return this;
if (other.hasId()) { if (other.hasId()) {
setId(other.getId()); setId(other.getId());
} }
@ -7590,11 +7590,11 @@ public final class StorageProtos {
com.google.protobuf.CodedInputStream input, com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry) com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException { throws java.io.IOException {
org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure parsedMessage = null; org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure parsedMessage = null;
try { try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) { } catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.whispersystems.libaxolotl.state.StorageProtos.DeviceKeyRecordStructure) e.getUnfinishedMessage(); parsedMessage = (org.whispersystems.libaxolotl.state.StorageProtos.SignedPreKeyRecordStructure) e.getUnfinishedMessage();
throw e; throw e;
} finally { } finally {
if (parsedMessage != null) { if (parsedMessage != null) {
@ -7779,15 +7779,15 @@ public final class StorageProtos {
return this; return this;
} }
// @@protoc_insertion_point(builder_scope:textsecure.DeviceKeyRecordStructure) // @@protoc_insertion_point(builder_scope:textsecure.SignedPreKeyRecordStructure)
} }
static { static {
defaultInstance = new DeviceKeyRecordStructure(true); defaultInstance = new SignedPreKeyRecordStructure(true);
defaultInstance.initFields(); defaultInstance.initFields();
} }
// @@protoc_insertion_point(class_scope:textsecure.DeviceKeyRecordStructure) // @@protoc_insertion_point(class_scope:textsecure.SignedPreKeyRecordStructure)
} }
public interface IdentityKeyPairStructureOrBuilder public interface IdentityKeyPairStructureOrBuilder
@ -8314,10 +8314,10 @@ public final class StorageProtos {
com.google.protobuf.GeneratedMessage.FieldAccessorTable com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_textsecure_PreKeyRecordStructure_fieldAccessorTable; internal_static_textsecure_PreKeyRecordStructure_fieldAccessorTable;
private static com.google.protobuf.Descriptors.Descriptor private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_DeviceKeyRecordStructure_descriptor; internal_static_textsecure_SignedPreKeyRecordStructure_descriptor;
private static private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_textsecure_DeviceKeyRecordStructure_fieldAccessorTable; internal_static_textsecure_SignedPreKeyRecordStructure_fieldAccessorTable;
private static com.google.protobuf.Descriptors.Descriptor private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_IdentityKeyPairStructure_descriptor; internal_static_textsecure_IdentityKeyPairStructure_descriptor;
private static private static
@ -8333,7 +8333,7 @@ public final class StorageProtos {
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\032LocalStorageProtocol.proto\022\ntextsecure" + "\n\032LocalStorageProtocol.proto\022\ntextsecure" +
"\"\334\010\n\020SessionStructure\022\026\n\016sessionVersion\030" + "\"\337\010\n\020SessionStructure\022\026\n\016sessionVersion\030" +
"\001 \001(\r\022\033\n\023localIdentityPublic\030\002 \001(\014\022\034\n\024re" + "\001 \001(\r\022\033\n\023localIdentityPublic\030\002 \001(\014\022\034\n\024re" +
"moteIdentityPublic\030\003 \001(\014\022\017\n\007rootKey\030\004 \001(" + "moteIdentityPublic\030\003 \001(\014\022\017\n\007rootKey\030\004 \001(" +
"\014\022\027\n\017previousCounter\030\005 \001(\r\0227\n\013senderChai" + "\014\022\027\n\017previousCounter\030\005 \001(\r\0227\n\013senderChai" +
@ -8359,20 +8359,20 @@ public final class StorageProtos {
"\030\003 \001(\014\022\031\n\021localEphemeralKey\030\004 \001(\014\022 \n\030loc" + "\030\003 \001(\014\022\031\n\021localEphemeralKey\030\004 \001(\014\022 \n\030loc" +
"alEphemeralKeyPrivate\030\005 \001(\014\022\030\n\020localIden" + "alEphemeralKeyPrivate\030\005 \001(\014\022\030\n\020localIden" +
"tityKey\030\007 \001(\014\022\037\n\027localIdentityKeyPrivate" + "tityKey\030\007 \001(\014\022\037\n\027localIdentityKeyPrivate" +
"\030\010 \001(\014\032G\n\rPendingPreKey\022\020\n\010preKeyId\030\001 \001(" + "\030\010 \001(\014\032J\n\rPendingPreKey\022\020\n\010preKeyId\030\001 \001(" +
"\r\022\023\n\013deviceKeyId\030\003 \001(\005\022\017\n\007baseKey\030\002 \001(\014\"" + "\r\022\026\n\016signedPreKeyId\030\003 \001(\005\022\017\n\007baseKey\030\002 \001" +
"\177\n\017RecordStructure\0224\n\016currentSession\030\001 \001", "(\014\"\177\n\017RecordStructure\0224\n\016currentSession\030",
"(\0132\034.textsecure.SessionStructure\0226\n\020prev" + "\001 \001(\0132\034.textsecure.SessionStructure\0226\n\020p" +
"iousSessions\030\002 \003(\0132\034.textsecure.SessionS" + "reviousSessions\030\002 \003(\0132\034.textsecure.Sessi" +
"tructure\"J\n\025PreKeyRecordStructure\022\n\n\002id\030" + "onStructure\"J\n\025PreKeyRecordStructure\022\n\n\002" +
"\001 \001(\r\022\021\n\tpublicKey\030\002 \001(\014\022\022\n\nprivateKey\030\003" + "id\030\001 \001(\r\022\021\n\tpublicKey\030\002 \001(\014\022\022\n\nprivateKe" +
" \001(\014\"s\n\030DeviceKeyRecordStructure\022\n\n\002id\030\001" + "y\030\003 \001(\014\"v\n\033SignedPreKeyRecordStructure\022\n" +
" \001(\r\022\021\n\tpublicKey\030\002 \001(\014\022\022\n\nprivateKey\030\003 " + "\n\002id\030\001 \001(\r\022\021\n\tpublicKey\030\002 \001(\014\022\022\n\nprivate" +
"\001(\014\022\021\n\tsignature\030\004 \001(\014\022\021\n\ttimestamp\030\005 \001(" + "Key\030\003 \001(\014\022\021\n\tsignature\030\004 \001(\014\022\021\n\ttimestam" +
"\006\"A\n\030IdentityKeyPairStructure\022\021\n\tpublicK" + "p\030\005 \001(\006\"A\n\030IdentityKeyPairStructure\022\021\n\tp" +
"ey\030\001 \001(\014\022\022\n\nprivateKey\030\002 \001(\014B4\n#org.whis" + "ublicKey\030\001 \001(\014\022\022\n\nprivateKey\030\002 \001(\014B4\n#or" +
"persystems.libaxolotl.stateB\rStorageProt", "g.whispersystems.libaxolotl.stateB\rStora",
"os" "geProtos"
}; };
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@ -8414,7 +8414,7 @@ public final class StorageProtos {
internal_static_textsecure_SessionStructure_PendingPreKey_fieldAccessorTable = new internal_static_textsecure_SessionStructure_PendingPreKey_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_SessionStructure_PendingPreKey_descriptor, internal_static_textsecure_SessionStructure_PendingPreKey_descriptor,
new java.lang.String[] { "PreKeyId", "DeviceKeyId", "BaseKey", }); new java.lang.String[] { "PreKeyId", "SignedPreKeyId", "BaseKey", });
internal_static_textsecure_RecordStructure_descriptor = internal_static_textsecure_RecordStructure_descriptor =
getDescriptor().getMessageTypes().get(1); getDescriptor().getMessageTypes().get(1);
internal_static_textsecure_RecordStructure_fieldAccessorTable = new internal_static_textsecure_RecordStructure_fieldAccessorTable = new
@ -8427,11 +8427,11 @@ public final class StorageProtos {
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_PreKeyRecordStructure_descriptor, internal_static_textsecure_PreKeyRecordStructure_descriptor,
new java.lang.String[] { "Id", "PublicKey", "PrivateKey", }); new java.lang.String[] { "Id", "PublicKey", "PrivateKey", });
internal_static_textsecure_DeviceKeyRecordStructure_descriptor = internal_static_textsecure_SignedPreKeyRecordStructure_descriptor =
getDescriptor().getMessageTypes().get(3); getDescriptor().getMessageTypes().get(3);
internal_static_textsecure_DeviceKeyRecordStructure_fieldAccessorTable = new internal_static_textsecure_SignedPreKeyRecordStructure_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable( com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_textsecure_DeviceKeyRecordStructure_descriptor, internal_static_textsecure_SignedPreKeyRecordStructure_descriptor,
new java.lang.String[] { "Id", "PublicKey", "PrivateKey", "Signature", "Timestamp", }); new java.lang.String[] { "Id", "PublicKey", "PrivateKey", "Signature", "Timestamp", });
internal_static_textsecure_IdentityKeyPairStructure_descriptor = internal_static_textsecure_IdentityKeyPairStructure_descriptor =
getDescriptor().getMessageTypes().get(4); getDescriptor().getMessageTypes().get(4);

View File

@ -28,8 +28,8 @@ import org.whispersystems.libaxolotl.InvalidKeyIdException;
import org.whispersystems.libaxolotl.ecc.Curve; import org.whispersystems.libaxolotl.ecc.Curve;
import org.whispersystems.libaxolotl.ecc.Curve25519; import org.whispersystems.libaxolotl.ecc.Curve25519;
import org.whispersystems.libaxolotl.ecc.ECKeyPair; import org.whispersystems.libaxolotl.ecc.ECKeyPair;
import org.whispersystems.libaxolotl.state.DeviceKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.DeviceKeyStore; import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
import org.whispersystems.libaxolotl.state.PreKeyStore; import org.whispersystems.libaxolotl.state.PreKeyStore;
import org.whispersystems.libaxolotl.util.Medium; import org.whispersystems.libaxolotl.util.Medium;
@ -66,18 +66,18 @@ public class PreKeyUtil {
return records; return records;
} }
public static DeviceKeyRecord generateDeviceKey(Context context, MasterSecret masterSecret, public static SignedPreKeyRecord generateSignedPreKey(Context context, MasterSecret masterSecret,
IdentityKeyPair identityKeyPair) IdentityKeyPair identityKeyPair)
{ {
try { try {
DeviceKeyStore deviceKeyStore = new TextSecurePreKeyStore(context, masterSecret); SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context, masterSecret);
int deviceKeyId = getNextDeviceKeyId(context); int signedPreKeyId = getNextSignedPreKeyId(context);
ECKeyPair keyPair = Curve25519.generateKeyPair(true); ECKeyPair keyPair = Curve25519.generateKeyPair(true);
byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize()); byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
DeviceKeyRecord record = new DeviceKeyRecord(deviceKeyId, System.currentTimeMillis(), keyPair, signature); SignedPreKeyRecord record = new SignedPreKeyRecord(signedPreKeyId, System.currentTimeMillis(), keyPair, signature);
deviceKeyStore.storeDeviceKey(deviceKeyId, record); signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record);
setNextDeviceKeyId(context, (deviceKeyId + 1) % Medium.MAX_VALUE); setNextSignedPreKeyId(context, (signedPreKeyId + 1) % Medium.MAX_VALUE);
return record; return record;
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
@ -116,11 +116,11 @@ public class PreKeyUtil {
} }
} }
private static void setNextDeviceKeyId(Context context, int id) { private static void setNextSignedPreKeyId(Context context, int id) {
try { try {
File nextFile = new File(getDeviceKeysDirectory(context), DeviceKeyIndex.FILE_NAME); File nextFile = new File(getSignedPreKeysDirectory(context), SignedPreKeyIndex.FILE_NAME);
FileOutputStream fout = new FileOutputStream(nextFile); FileOutputStream fout = new FileOutputStream(nextFile);
fout.write(new Gson().toJson(new DeviceKeyIndex(id)).getBytes()); fout.write(new Gson().toJson(new SignedPreKeyIndex(id)).getBytes());
fout.close(); fout.close();
} catch (IOException e) { } catch (IOException e) {
Log.w("PreKeyUtil", e); Log.w("PreKeyUtil", e);
@ -145,17 +145,17 @@ public class PreKeyUtil {
} }
} }
private static int getNextDeviceKeyId(Context context) { private static int getNextSignedPreKeyId(Context context) {
try { try {
File nextFile = new File(getDeviceKeysDirectory(context), DeviceKeyIndex.FILE_NAME); File nextFile = new File(getSignedPreKeysDirectory(context), SignedPreKeyIndex.FILE_NAME);
if (!nextFile.exists()) { if (!nextFile.exists()) {
return Util.getSecureRandom().nextInt(Medium.MAX_VALUE); return Util.getSecureRandom().nextInt(Medium.MAX_VALUE);
} else { } else {
InputStreamReader reader = new InputStreamReader(new FileInputStream(nextFile)); InputStreamReader reader = new InputStreamReader(new FileInputStream(nextFile));
DeviceKeyIndex index = new Gson().fromJson(reader, DeviceKeyIndex.class); SignedPreKeyIndex index = new Gson().fromJson(reader, SignedPreKeyIndex.class);
reader.close(); reader.close();
return index.nextDeviceKeyId; return index.nextSignedPreKeyId;
} }
} catch (IOException e) { } catch (IOException e) {
Log.w("PreKeyUtil", e); Log.w("PreKeyUtil", e);
@ -167,8 +167,8 @@ public class PreKeyUtil {
return getKeysDirectory(context, TextSecurePreKeyStore.PREKEY_DIRECTORY); return getKeysDirectory(context, TextSecurePreKeyStore.PREKEY_DIRECTORY);
} }
private static File getDeviceKeysDirectory(Context context) { private static File getSignedPreKeysDirectory(Context context) {
return getKeysDirectory(context, TextSecurePreKeyStore.DEVICE_KEY_DIRECTORY); return getKeysDirectory(context, TextSecurePreKeyStore.SIGNED_PREKEY_DIRECTORY);
} }
private static File getKeysDirectory(Context context, String name) { private static File getKeysDirectory(Context context, String name) {
@ -192,15 +192,15 @@ public class PreKeyUtil {
} }
} }
private static class DeviceKeyIndex { private static class SignedPreKeyIndex {
public static final String FILE_NAME = "index.dat"; public static final String FILE_NAME = "index.dat";
private int nextDeviceKeyId; private int nextSignedPreKeyId;
public DeviceKeyIndex() {} public SignedPreKeyIndex() {}
public DeviceKeyIndex(int nextDeviceKeyId) { public SignedPreKeyIndex(int nextSignedPreKeyId) {
this.nextDeviceKeyId = nextDeviceKeyId; this.nextSignedPreKeyId = nextSignedPreKeyId;
} }
} }

View File

@ -4,10 +4,10 @@ import com.google.thoughtcrimegson.GsonBuilder;
public class PreKeyResponseItem { public class PreKeyResponseItem {
private int deviceId; private int deviceId;
private int registrationId; private int registrationId;
private DeviceKeyEntity deviceKey; private SignedPreKeyEntity signedPreKey;
private PreKeyEntity preKey; private PreKeyEntity preKey;
public int getDeviceId() { public int getDeviceId() {
return deviceId; return deviceId;
@ -17,8 +17,8 @@ public class PreKeyResponseItem {
return registrationId; return registrationId;
} }
public DeviceKeyEntity getDeviceKey() { public SignedPreKeyEntity getSignedPreKey() {
return deviceKey; return signedPreKey;
} }
public PreKeyEntity getPreKey() { public PreKeyEntity getPreKey() {
@ -26,6 +26,6 @@ public class PreKeyResponseItem {
} }
public static GsonBuilder forBuilder(GsonBuilder builder) { public static GsonBuilder forBuilder(GsonBuilder builder) {
return DeviceKeyEntity.forBuilder(builder); return SignedPreKeyEntity.forBuilder(builder);
} }
} }

View File

@ -11,21 +11,21 @@ public class PreKeyState {
private IdentityKey identityKey; private IdentityKey identityKey;
private List<PreKeyEntity> preKeys; private List<PreKeyEntity> preKeys;
private PreKeyEntity lastResortKey; private PreKeyEntity lastResortKey;
private DeviceKeyEntity deviceKey; private SignedPreKeyEntity signedPreKey;
public PreKeyState(List<PreKeyEntity> preKeys, PreKeyEntity lastResortKey, public PreKeyState(List<PreKeyEntity> preKeys, PreKeyEntity lastResortKey,
DeviceKeyEntity deviceKey, IdentityKey identityKey) SignedPreKeyEntity signedPreKey, IdentityKey identityKey)
{ {
this.preKeys = preKeys; this.preKeys = preKeys;
this.lastResortKey = lastResortKey; this.lastResortKey = lastResortKey;
this.deviceKey = deviceKey; this.signedPreKey = signedPreKey;
this.identityKey = identityKey; this.identityKey = identityKey;
} }
public static String toJson(PreKeyState state) { public static String toJson(PreKeyState state) {
GsonBuilder builder = new GsonBuilder(); GsonBuilder builder = new GsonBuilder();
return DeviceKeyEntity.forBuilder(builder) return SignedPreKeyEntity.forBuilder(builder)
.registerTypeAdapter(IdentityKey.class, new PreKeyResponse.IdentityKeyJsonAdapter()) .registerTypeAdapter(IdentityKey.class, new PreKeyResponse.IdentityKeyJsonAdapter())
.create().toJson(state); .create().toJson(state);
} }

View File

@ -25,7 +25,7 @@ import com.google.thoughtcrimegson.JsonParseException;
import org.apache.http.conn.ssl.StrictHostnameVerifier; import org.apache.http.conn.ssl.StrictHostnameVerifier;
import org.whispersystems.libaxolotl.IdentityKey; import org.whispersystems.libaxolotl.IdentityKey;
import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.ecc.ECPublicKey;
import org.whispersystems.libaxolotl.state.DeviceKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.PreKeyBundle; import org.whispersystems.libaxolotl.state.PreKeyBundle;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
import org.whispersystems.textsecure.util.Base64; import org.whispersystems.textsecure.util.Base64;
@ -129,7 +129,7 @@ public class PushServiceSocket {
public void registerPreKeys(IdentityKey identityKey, public void registerPreKeys(IdentityKey identityKey,
PreKeyRecord lastResortKey, PreKeyRecord lastResortKey,
DeviceKeyRecord deviceKey, SignedPreKeyRecord signedPreKey,
List<PreKeyRecord> records) List<PreKeyRecord> records)
throws IOException throws IOException
{ {
@ -145,12 +145,13 @@ public class PushServiceSocket {
PreKeyEntity lastResortEntity = new PreKeyEntity(lastResortKey.getId(), PreKeyEntity lastResortEntity = new PreKeyEntity(lastResortKey.getId(),
lastResortKey.getKeyPair().getPublicKey()); lastResortKey.getKeyPair().getPublicKey());
DeviceKeyEntity deviceKeyEntity = new DeviceKeyEntity(deviceKey.getId(), SignedPreKeyEntity signedPreKeyEntity = new SignedPreKeyEntity(signedPreKey.getId(),
deviceKey.getKeyPair().getPublicKey(), signedPreKey.getKeyPair().getPublicKey(),
deviceKey.getSignature()); signedPreKey.getSignature());
makeRequest(String.format(PREKEY_PATH, ""), "PUT", makeRequest(String.format(PREKEY_PATH, ""), "PUT",
PreKeyState.toJson(new PreKeyState(entities, lastResortEntity, deviceKeyEntity, identityKey))); PreKeyState.toJson(new PreKeyState(entities, lastResortEntity,
signedPreKeyEntity, identityKey)));
} }
public int getAvailablePreKeys() throws IOException { public int getAvailablePreKeys() throws IOException {
@ -178,16 +179,16 @@ public class PushServiceSocket {
List<PreKeyBundle> bundles = new LinkedList<>(); List<PreKeyBundle> bundles = new LinkedList<>();
for (PreKeyResponseItem device : response.getDevices()) { for (PreKeyResponseItem device : response.getDevices()) {
ECPublicKey preKey = null; ECPublicKey preKey = null;
ECPublicKey deviceKey = null; ECPublicKey signedPreKey = null;
byte[] deviceKeySignature = null; byte[] signedPreKeySignature = null;
int preKeyId = -1; int preKeyId = -1;
int deviceKeyId = -1; int signedPreKeyId = -1;
if (device.getDeviceKey() != null) { if (device.getSignedPreKey() != null) {
deviceKey = device.getDeviceKey().getPublicKey(); signedPreKey = device.getSignedPreKey().getPublicKey();
deviceKeyId = device.getDeviceKey().getKeyId(); signedPreKeyId = device.getSignedPreKey().getKeyId();
deviceKeySignature = device.getDeviceKey().getSignature(); signedPreKeySignature = device.getSignedPreKey().getSignature();
} }
if (device.getPreKey() != null) { if (device.getPreKey() != null) {
@ -196,7 +197,7 @@ public class PushServiceSocket {
} }
bundles.add(new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId, bundles.add(new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId,
preKey, deviceKeyId, deviceKey, deviceKeySignature, preKey, signedPreKeyId, signedPreKey, signedPreKeySignature,
response.getIdentityKey())); response.getIdentityKey()));
} }
@ -223,26 +224,26 @@ public class PushServiceSocket {
if (response.getDevices() == null || response.getDevices().size() < 1) if (response.getDevices() == null || response.getDevices().size() < 1)
throw new IOException("Empty prekey list"); throw new IOException("Empty prekey list");
PreKeyResponseItem device = response.getDevices().get(0); PreKeyResponseItem device = response.getDevices().get(0);
ECPublicKey preKey = null; ECPublicKey preKey = null;
ECPublicKey deviceKey = null; ECPublicKey signedPreKey = null;
byte[] deviceKeySignature = null; byte[] signedPreKeySignature = null;
int preKeyId = -1; int preKeyId = -1;
int deviceKeyId = -1; int signedPreKeyId = -1;
if (device.getPreKey() != null) { if (device.getPreKey() != null) {
preKeyId = device.getPreKey().getKeyId(); preKeyId = device.getPreKey().getKeyId();
preKey = device.getPreKey().getPublicKey(); preKey = device.getPreKey().getPublicKey();
} }
if (device.getDeviceKey() != null) { if (device.getSignedPreKey() != null) {
deviceKeyId = device.getDeviceKey().getKeyId(); signedPreKeyId = device.getSignedPreKey().getKeyId();
deviceKey = device.getDeviceKey().getPublicKey(); signedPreKey = device.getSignedPreKey().getPublicKey();
deviceKeySignature = device.getDeviceKey().getSignature(); signedPreKeySignature = device.getSignedPreKey().getSignature();
} }
return new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId, preKey, return new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId, preKey,
deviceKeyId, deviceKey, deviceKeySignature, response.getIdentityKey()); signedPreKeyId, signedPreKey, signedPreKeySignature, response.getIdentityKey());
} catch (JsonParseException e) { } catch (JsonParseException e) {
throw new IOException(e); throw new IOException(e);
} catch (NotFoundException nfe) { } catch (NotFoundException nfe) {

View File

@ -15,13 +15,13 @@ import org.whispersystems.textsecure.util.Base64;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
public class DeviceKeyEntity extends PreKeyEntity { public class SignedPreKeyEntity extends PreKeyEntity {
private byte[] signature; private byte[] signature;
public DeviceKeyEntity() {} public SignedPreKeyEntity() {}
public DeviceKeyEntity(int keyId, ECPublicKey publicKey, byte[] signature) { public SignedPreKeyEntity(int keyId, ECPublicKey publicKey, byte[] signature) {
super(keyId, publicKey); super(keyId, publicKey);
this.signature = signature; this.signature = signature;
} }

View File

@ -5,8 +5,8 @@ import android.util.Log;
import org.whispersystems.libaxolotl.InvalidKeyIdException; import org.whispersystems.libaxolotl.InvalidKeyIdException;
import org.whispersystems.libaxolotl.InvalidMessageException; import org.whispersystems.libaxolotl.InvalidMessageException;
import org.whispersystems.libaxolotl.state.DeviceKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.DeviceKeyStore; import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
import org.whispersystems.libaxolotl.state.PreKeyStore; import org.whispersystems.libaxolotl.state.PreKeyStore;
import org.whispersystems.textsecure.crypto.MasterCipher; import org.whispersystems.textsecure.crypto.MasterCipher;
@ -22,10 +22,10 @@ import java.nio.channels.FileChannel;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
public class TextSecurePreKeyStore implements PreKeyStore, DeviceKeyStore { public class TextSecurePreKeyStore implements PreKeyStore, SignedPreKeyStore {
public static final String PREKEY_DIRECTORY = "prekeys"; public static final String PREKEY_DIRECTORY = "prekeys";
public static final String DEVICE_KEY_DIRECTORY = "device_keys"; public static final String SIGNED_PREKEY_DIRECTORY = "signed_prekeys";
private static final int CURRENT_VERSION_MARKER = 1; private static final int CURRENT_VERSION_MARKER = 1;
@ -53,10 +53,10 @@ public class TextSecurePreKeyStore implements PreKeyStore, DeviceKeyStore {
} }
@Override @Override
public DeviceKeyRecord loadDeviceKey(int deviceKeyId) throws InvalidKeyIdException { public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
try { try {
return new DeviceKeyRecord(loadSerializedRecord(getDeviceKeyFile(deviceKeyId))); return new SignedPreKeyRecord(loadSerializedRecord(getSignedPreKeyFile(signedPreKeyId)));
} catch (IOException | InvalidMessageException e) { } catch (IOException | InvalidMessageException e) {
Log.w(TAG, e); Log.w(TAG, e);
throw new InvalidKeyIdException(e); throw new InvalidKeyIdException(e);
@ -65,14 +65,14 @@ public class TextSecurePreKeyStore implements PreKeyStore, DeviceKeyStore {
} }
@Override @Override
public List<DeviceKeyRecord> loadDeviceKeys() { public List<SignedPreKeyRecord> loadSignedPreKeys() {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
File directory = getDeviceKeyDirectory(); File directory = getSignedPreKeyDirectory();
List<DeviceKeyRecord> results = new LinkedList<>(); List<SignedPreKeyRecord> results = new LinkedList<>();
for (File deviceKeyFile : directory.listFiles()) { for (File signedPreKeyFile : directory.listFiles()) {
try { try {
results.add(new DeviceKeyRecord(loadSerializedRecord(deviceKeyFile))); results.add(new SignedPreKeyRecord(loadSerializedRecord(signedPreKeyFile)));
} catch (IOException | InvalidMessageException e) { } catch (IOException | InvalidMessageException e) {
Log.w(TAG, e); Log.w(TAG, e);
} }
@ -94,10 +94,10 @@ public class TextSecurePreKeyStore implements PreKeyStore, DeviceKeyStore {
} }
@Override @Override
public void storeDeviceKey(int deviceKeyId, DeviceKeyRecord record) { public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record) {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
try { try {
storeSerializedRecord(getDeviceKeyFile(deviceKeyId), record.serialize()); storeSerializedRecord(getSignedPreKeyFile(signedPreKeyId), record.serialize());
} catch (IOException e) { } catch (IOException e) {
throw new AssertionError(e); throw new AssertionError(e);
} }
@ -111,8 +111,8 @@ public class TextSecurePreKeyStore implements PreKeyStore, DeviceKeyStore {
} }
@Override @Override
public boolean containsDeviceKey(int deviceKeyId) { public boolean containsSignedPreKey(int signedPreKeyId) {
File record = getDeviceKeyFile(deviceKeyId); File record = getSignedPreKeyFile(signedPreKeyId);
return record.exists(); return record.exists();
} }
@ -124,8 +124,8 @@ public class TextSecurePreKeyStore implements PreKeyStore, DeviceKeyStore {
} }
@Override @Override
public void removeDeviceKey(int deviceKeyId) { public void removeSignedPreKey(int signedPreKeyId) {
File record = getDeviceKeyFile(deviceKeyId); File record = getSignedPreKeyFile(signedPreKeyId);
record.delete(); record.delete();
} }
@ -159,16 +159,16 @@ public class TextSecurePreKeyStore implements PreKeyStore, DeviceKeyStore {
return new File(getPreKeyDirectory(), String.valueOf(preKeyId)); return new File(getPreKeyDirectory(), String.valueOf(preKeyId));
} }
private File getDeviceKeyFile(int deviceKeyId) { private File getSignedPreKeyFile(int signedPreKeyId) {
return new File(getDeviceKeyDirectory(), String.valueOf(deviceKeyId)); return new File(getSignedPreKeyDirectory(), String.valueOf(signedPreKeyId));
} }
private File getPreKeyDirectory() { private File getPreKeyDirectory() {
return getRecordsDirectory(PREKEY_DIRECTORY); return getRecordsDirectory(PREKEY_DIRECTORY);
} }
private File getDeviceKeyDirectory() { private File getSignedPreKeyDirectory() {
return getRecordsDirectory(DEVICE_KEY_DIRECTORY); return getRecordsDirectory(SIGNED_PREKEY_DIRECTORY);
} }
private File getRecordsDirectory(String directoryName) { private File getRecordsDirectory(String directoryName) {

View File

@ -4,5 +4,4 @@ public class Release {
public static final String PUSH_URL = "https://textsecure-service.whispersystems.org"; public static final String PUSH_URL = "https://textsecure-service.whispersystems.org";
// public static final String PUSH_URL = "http://192.168.1.135:8080"; // public static final String PUSH_URL = "http://192.168.1.135:8080";
} }

View File

@ -28,7 +28,7 @@ import org.thoughtcrime.securesms.sms.OutgoingKeyExchangeMessage;
import org.thoughtcrime.securesms.util.Dialogs; import org.thoughtcrime.securesms.util.Dialogs;
import org.whispersystems.libaxolotl.SessionBuilder; import org.whispersystems.libaxolotl.SessionBuilder;
import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage; import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage;
import org.whispersystems.libaxolotl.state.DeviceKeyStore; import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.libaxolotl.state.IdentityKeyStore; import org.whispersystems.libaxolotl.state.IdentityKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyStore; import org.whispersystems.libaxolotl.state.PreKeyStore;
import org.whispersystems.libaxolotl.state.SessionRecord; import org.whispersystems.libaxolotl.state.SessionRecord;
@ -61,14 +61,14 @@ public class KeyExchangeInitiator {
} }
private static void initiateKeyExchange(Context context, MasterSecret masterSecret, Recipient recipient) { private static void initiateKeyExchange(Context context, MasterSecret masterSecret, Recipient recipient) {
SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret); SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret);
PreKeyStore preKeyStore = new TextSecurePreKeyStore(context, masterSecret); PreKeyStore preKeyStore = new TextSecurePreKeyStore(context, masterSecret);
DeviceKeyStore deviceKeyStore = new TextSecurePreKeyStore(context, masterSecret); SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context, masterSecret);
IdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(context, masterSecret); IdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(context, masterSecret);
SessionBuilder sessionBuilder = new SessionBuilder(sessionStore, preKeyStore, deviceKeyStore, SessionBuilder sessionBuilder = new SessionBuilder(sessionStore, preKeyStore, signedPreKeyStore,
identityKeyStore, recipient.getRecipientId(), identityKeyStore, recipient.getRecipientId(),
RecipientDevice.DEFAULT_DEVICE_ID); RecipientDevice.DEFAULT_DEVICE_ID);
KeyExchangeMessage keyExchangeMessage = sessionBuilder.process(); KeyExchangeMessage keyExchangeMessage = sessionBuilder.process();
String serializedMessage = Base64.encodeBytesWithoutPadding(keyExchangeMessage.serialize()); String serializedMessage = Base64.encodeBytesWithoutPadding(keyExchangeMessage.serialize());

View File

@ -15,13 +15,12 @@ import org.whispersystems.libaxolotl.StaleKeyExchangeException;
import org.whispersystems.libaxolotl.UntrustedIdentityException; import org.whispersystems.libaxolotl.UntrustedIdentityException;
import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage; import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage;
import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage; import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage;
import org.whispersystems.libaxolotl.state.DeviceKeyStore; import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.libaxolotl.state.IdentityKeyStore; import org.whispersystems.libaxolotl.state.IdentityKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyBundle; import org.whispersystems.libaxolotl.state.PreKeyBundle;
import org.whispersystems.libaxolotl.state.PreKeyStore; import org.whispersystems.libaxolotl.state.PreKeyStore;
import org.whispersystems.libaxolotl.state.SessionStore; import org.whispersystems.libaxolotl.state.SessionStore;
import org.whispersystems.textsecure.crypto.MasterSecret; import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.push.PreKeyEntity;
import org.whispersystems.textsecure.storage.RecipientDevice; import org.whispersystems.textsecure.storage.RecipientDevice;
import org.whispersystems.textsecure.storage.TextSecurePreKeyStore; import org.whispersystems.textsecure.storage.TextSecurePreKeyStore;
import org.whispersystems.textsecure.storage.TextSecureSessionStore; import org.whispersystems.textsecure.storage.TextSecureSessionStore;
@ -48,12 +47,12 @@ public class KeyExchangeProcessor {
this.recipientDevice = recipientDevice; this.recipientDevice = recipientDevice;
this.masterSecret = masterSecret; this.masterSecret = masterSecret;
IdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(context, masterSecret); IdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(context, masterSecret);
PreKeyStore preKeyStore = new TextSecurePreKeyStore(context, masterSecret); PreKeyStore preKeyStore = new TextSecurePreKeyStore(context, masterSecret);
DeviceKeyStore deviceKeyStore = new TextSecurePreKeyStore(context, masterSecret); SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context, masterSecret);
SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret); SessionStore sessionStore = new TextSecureSessionStore(context, masterSecret);
this.sessionBuilder = new SessionBuilder(sessionStore, preKeyStore, deviceKeyStore, this.sessionBuilder = new SessionBuilder(sessionStore, preKeyStore, signedPreKeyStore,
identityKeyStore, recipientDevice.getRecipientId(), identityKeyStore, recipientDevice.getRecipientId(),
recipientDevice.getDeviceId()); recipientDevice.getDeviceId());
} }

View File

@ -9,10 +9,9 @@ import android.util.Log;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.push.PushServiceSocketFactory; import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libaxolotl.IdentityKey;
import org.whispersystems.libaxolotl.IdentityKeyPair; import org.whispersystems.libaxolotl.IdentityKeyPair;
import org.whispersystems.libaxolotl.state.DeviceKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.DeviceKeyStore; import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
import org.whispersystems.textsecure.crypto.MasterSecret; import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.crypto.PreKeyUtil; import org.whispersystems.textsecure.crypto.PreKeyUtil;
@ -69,7 +68,7 @@ public class PreKeyService extends Service {
} }
public void run() { public void run() {
DeviceKeyRecord deviceKeyRecord = null; SignedPreKeyRecord signedPreKeyRecord = null;
try { try {
if (!TextSecurePreferences.isPushRegistered(context)) return; if (!TextSecurePreferences.isPushRegistered(context)) return;
@ -86,38 +85,38 @@ public class PreKeyService extends Service {
PreKeyRecord lastResortKeyRecord = PreKeyUtil.generateLastResortKey(context, masterSecret); PreKeyRecord lastResortKeyRecord = PreKeyUtil.generateLastResortKey(context, masterSecret);
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret); IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret);
deviceKeyRecord = PreKeyUtil.generateDeviceKey(context, masterSecret, identityKey); signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, masterSecret, identityKey);
Log.w(TAG, "Registering new prekeys..."); Log.w(TAG, "Registering new prekeys...");
socket.registerPreKeys(identityKey.getPublicKey(), lastResortKeyRecord, socket.registerPreKeys(identityKey.getPublicKey(), lastResortKeyRecord,
deviceKeyRecord, preKeyRecords); signedPreKeyRecord, preKeyRecords);
removeOldDeviceKeysIfNecessary(deviceKeyRecord); removeOldSignedPreKeysIfNecessary(signedPreKeyRecord);
} catch (IOException e) { } catch (IOException e) {
Log.w(TAG, e); Log.w(TAG, e);
if (deviceKeyRecord != null) { if (signedPreKeyRecord != null) {
Log.w(TAG, "Remote store failed, removing generated device key: " + deviceKeyRecord.getId()); Log.w(TAG, "Remote store failed, removing generated device key: " + signedPreKeyRecord.getId());
new TextSecurePreKeyStore(context, masterSecret).removeDeviceKey(deviceKeyRecord.getId()); new TextSecurePreKeyStore(context, masterSecret).removeSignedPreKey(signedPreKeyRecord.getId());
} }
} }
} }
private void removeOldDeviceKeysIfNecessary(DeviceKeyRecord currentDeviceKey) { private void removeOldSignedPreKeysIfNecessary(SignedPreKeyRecord currentSignedPreKey) {
DeviceKeyStore deviceKeyStore = new TextSecurePreKeyStore(context, masterSecret); SignedPreKeyStore signedPreKeyStore = new TextSecurePreKeyStore(context, masterSecret);
List<DeviceKeyRecord> records = deviceKeyStore.loadDeviceKeys(); List<SignedPreKeyRecord> records = signedPreKeyStore.loadSignedPreKeys();
Iterator<DeviceKeyRecord> iterator = records.iterator(); Iterator<SignedPreKeyRecord> iterator = records.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
if (iterator.next().getId() == currentDeviceKey.getId()) { if (iterator.next().getId() == currentSignedPreKey.getId()) {
iterator.remove(); iterator.remove();
} }
} }
DeviceKeyRecord[] recordsArray = (DeviceKeyRecord[])records.toArray(); SignedPreKeyRecord[] recordsArray = (SignedPreKeyRecord[])records.toArray();
Arrays.sort(recordsArray, new Comparator<DeviceKeyRecord>() { Arrays.sort(recordsArray, new Comparator<SignedPreKeyRecord>() {
@Override @Override
public int compare(DeviceKeyRecord lhs, DeviceKeyRecord rhs) { public int compare(SignedPreKeyRecord lhs, SignedPreKeyRecord rhs) {
if (lhs.getTimestamp() < rhs.getTimestamp()) return -1; if (lhs.getTimestamp() < rhs.getTimestamp()) return -1;
else if (lhs.getTimestamp() > rhs.getTimestamp()) return 1; else if (lhs.getTimestamp() > rhs.getTimestamp()) return 1;
else return 0; else return 0;
@ -127,15 +126,15 @@ public class PreKeyService extends Service {
Log.w(TAG, "Existing device key record count: " + recordsArray.length); Log.w(TAG, "Existing device key record count: " + recordsArray.length);
if (recordsArray.length > 3) { if (recordsArray.length > 3) {
long oldTimestamp = System.currentTimeMillis() - (14 * 24 * 60 * 60 * 1000); long oldTimestamp = System.currentTimeMillis() - (14 * 24 * 60 * 60 * 1000);
DeviceKeyRecord[] oldRecords = Arrays.copyOf(recordsArray, recordsArray.length - 1); SignedPreKeyRecord[] oldRecords = Arrays.copyOf(recordsArray, recordsArray.length - 1);
for (DeviceKeyRecord oldRecord : oldRecords) { for (SignedPreKeyRecord oldRecord : oldRecords) {
Log.w(TAG, "Old device key record timestamp: " + oldRecord.getTimestamp()); Log.w(TAG, "Old device key record timestamp: " + oldRecord.getTimestamp());
if (oldRecord.getTimestamp() <= oldTimestamp) { if (oldRecord.getTimestamp() <= oldTimestamp) {
Log.w(TAG, "Remove device key record: " + oldRecord.getId()); Log.w(TAG, "Remove device key record: " + oldRecord.getId());
deviceKeyStore.removeDeviceKey(oldRecord.getId()); signedPreKeyStore.removeSignedPreKey(oldRecord.getId());
} }
} }
} }

View File

@ -18,7 +18,7 @@ import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
import org.thoughtcrime.securesms.util.DirectoryHelper; import org.thoughtcrime.securesms.util.DirectoryHelper;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libaxolotl.IdentityKeyPair; import org.whispersystems.libaxolotl.IdentityKeyPair;
import org.whispersystems.libaxolotl.state.DeviceKeyRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.PreKeyRecord;
import org.whispersystems.libaxolotl.util.KeyHelper; import org.whispersystems.libaxolotl.util.KeyHelper;
import org.whispersystems.textsecure.crypto.MasterSecret; import org.whispersystems.textsecure.crypto.MasterSecret;
@ -228,11 +228,11 @@ public class RegistrationService extends Service {
throws IOException throws IOException
{ {
setState(new RegistrationState(RegistrationState.STATE_GENERATING_KEYS, number)); setState(new RegistrationState(RegistrationState.STATE_GENERATING_KEYS, number));
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(this, masterSecret); IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(this, masterSecret);
List<PreKeyRecord> records = PreKeyUtil.generatePreKeys(this, masterSecret); List<PreKeyRecord> records = PreKeyUtil.generatePreKeys(this, masterSecret);
PreKeyRecord lastResort = PreKeyUtil.generateLastResortKey(this, masterSecret); PreKeyRecord lastResort = PreKeyUtil.generateLastResortKey(this, masterSecret);
DeviceKeyRecord deviceKey = PreKeyUtil.generateDeviceKey(this, masterSecret, identityKey); SignedPreKeyRecord signedPreKey = PreKeyUtil.generateSignedPreKey(this, masterSecret, identityKey);
socket.registerPreKeys(identityKey.getPublicKey(), lastResort, deviceKey, records); socket.registerPreKeys(identityKey.getPublicKey(), lastResort, signedPreKey, records);
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number)); setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));