mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Add V3 support for KeyExchangeMessage case.
1) V3 KeyExchangeMessages can now contain signatures and verification tags.
This commit is contained in:
parent
77ff9cece8
commit
64b40df15b
@ -21,8 +21,10 @@ message PreKeyWhisperMessage {
|
||||
}
|
||||
|
||||
message KeyExchangeMessage {
|
||||
optional uint32 id = 1;
|
||||
optional bytes baseKey = 2;
|
||||
optional bytes ephemeralKey = 3;
|
||||
optional bytes identityKey = 4;
|
||||
optional uint32 id = 1;
|
||||
optional bytes baseKey = 2;
|
||||
optional bytes ephemeralKey = 3;
|
||||
optional bytes identityKey = 4;
|
||||
optional bytes baseKeySignature = 5;
|
||||
optional bytes verification = 6;
|
||||
}
|
@ -501,7 +501,7 @@ public class SessionBuilderTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
|
||||
public void testBasicKeyExchange() throws InvalidKeyException, LegacyMessageException, InvalidMessageException, DuplicateMessageException, UntrustedIdentityException, StaleKeyExchangeException {
|
||||
public void testBasicKeyExchange() throws InvalidKeyException, LegacyMessageException, InvalidMessageException, DuplicateMessageException, UntrustedIdentityException, StaleKeyExchangeException, InvalidVersionException {
|
||||
SessionStore aliceSessionStore = new InMemorySessionStore();
|
||||
PreKeyStore alicePreKeyStore = new InMemoryPreKeyStore();
|
||||
DeviceKeyStore aliceDeviceKeyStore = new InMemoryDeviceKeyStore();
|
||||
@ -520,13 +520,16 @@ public class SessionBuilderTest extends AndroidTestCase {
|
||||
bobIdentityKeyStore,
|
||||
ALICE_RECIPIENT_ID, 1);
|
||||
|
||||
KeyExchangeMessage aliceKeyExchangeMessage = aliceSessionBuilder.process();
|
||||
KeyExchangeMessage bobKeyExchangeMessage = bobSessionBuilder.process(aliceKeyExchangeMessage);
|
||||
|
||||
assertTrue(bobKeyExchangeMessage != null);
|
||||
KeyExchangeMessage aliceKeyExchangeMessage = aliceSessionBuilder.process();
|
||||
assertTrue(aliceKeyExchangeMessage != null);
|
||||
|
||||
KeyExchangeMessage response = aliceSessionBuilder.process(bobKeyExchangeMessage);
|
||||
byte[] aliceKeyExchangeMessageBytes = aliceKeyExchangeMessage.serialize();
|
||||
KeyExchangeMessage bobKeyExchangeMessage = bobSessionBuilder.process(new KeyExchangeMessage(aliceKeyExchangeMessageBytes));
|
||||
|
||||
assertTrue(bobKeyExchangeMessage != null);
|
||||
|
||||
byte[] bobKeyExchangeMessageBytes = bobKeyExchangeMessage.serialize();
|
||||
KeyExchangeMessage response = aliceSessionBuilder.process(new KeyExchangeMessage(bobKeyExchangeMessageBytes));
|
||||
|
||||
assertTrue(response == null);
|
||||
assertTrue(aliceSessionStore.containsSession(BOB_RECIPIENT_ID, 1));
|
||||
|
@ -5,10 +5,10 @@ import android.util.Log;
|
||||
import org.whispersystems.libaxolotl.ecc.Curve;
|
||||
import org.whispersystems.libaxolotl.ecc.ECKeyPair;
|
||||
import org.whispersystems.libaxolotl.ecc.ECPublicKey;
|
||||
import org.whispersystems.libaxolotl.protocol.CiphertextMessage;
|
||||
import org.whispersystems.libaxolotl.protocol.KeyExchangeMessage;
|
||||
import org.whispersystems.libaxolotl.protocol.PreKeyWhisperMessage;
|
||||
import org.whispersystems.libaxolotl.ratchet.RatchetingSession;
|
||||
import org.whispersystems.libaxolotl.state.DeviceKeyRecord;
|
||||
import org.whispersystems.libaxolotl.state.DeviceKeyStore;
|
||||
import org.whispersystems.libaxolotl.state.IdentityKeyStore;
|
||||
import org.whispersystems.libaxolotl.state.PreKeyBundle;
|
||||
@ -149,7 +149,6 @@ public class SessionBuilder {
|
||||
sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId());
|
||||
sessionRecord.getSessionState().setRemoteRegistrationId(message.getRegistrationId());
|
||||
sessionRecord.getSessionState().setAliceBaseKey(theirBaseKey.serialize());
|
||||
sessionRecord.getSessionState().setSessionVersion(message.getMessageVersion());
|
||||
|
||||
if (simultaneousInitiate) sessionRecord.getSessionState().setNeedsRefresh(true);
|
||||
|
||||
@ -197,7 +196,6 @@ public class SessionBuilder {
|
||||
|
||||
sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId());
|
||||
sessionRecord.getSessionState().setRemoteRegistrationId(message.getRegistrationId());
|
||||
sessionRecord.getSessionState().setSessionVersion(message.getMessageVersion());
|
||||
|
||||
if (simultaneousInitiate) sessionRecord.getSessionState().setNeedsRefresh(true);
|
||||
|
||||
@ -277,31 +275,71 @@ public class SessionBuilder {
|
||||
}
|
||||
|
||||
KeyExchangeMessage responseMessage = null;
|
||||
SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId);
|
||||
|
||||
Log.w(TAG, "Received key exchange with sequence: " + message.getSequence());
|
||||
if (message.isInitiate()) responseMessage = processInitiate(message);
|
||||
else processResponse(message);
|
||||
|
||||
if (message.isInitiate()) {
|
||||
Log.w(TAG, "KeyExchange is an initiate.");
|
||||
responseMessage = processInitiate(sessionRecord, message);
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private KeyExchangeMessage processInitiate(KeyExchangeMessage message) throws InvalidKeyException {
|
||||
ECKeyPair ourBaseKey, ourEphemeralKey;
|
||||
IdentityKeyPair ourIdentityKey;
|
||||
|
||||
int flags = KeyExchangeMessage.RESPONSE_FLAG;
|
||||
SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId);
|
||||
|
||||
if (message.getVersion() >= 3 &&
|
||||
!Curve.verifySignature(message.getIdentityKey().getPublicKey(),
|
||||
message.getBaseKey().serialize(),
|
||||
message.getBaseKeySignature()))
|
||||
{
|
||||
throw new InvalidKeyException("Bad signature!");
|
||||
}
|
||||
|
||||
if (message.isResponse()) {
|
||||
SessionState sessionState = sessionRecord.getSessionState();
|
||||
boolean hasPendingKeyExchange = sessionState.hasPendingKeyExchange();
|
||||
boolean isSimultaneousInitiateResponse = message.isResponseForSimultaneousInitiate();
|
||||
|
||||
if ((!hasPendingKeyExchange || sessionState.getPendingKeyExchangeSequence() != message.getSequence()) &&
|
||||
!isSimultaneousInitiateResponse)
|
||||
{
|
||||
throw new StaleKeyExchangeException();
|
||||
}
|
||||
if (!sessionRecord.getSessionState().hasPendingKeyExchange()) {
|
||||
Log.w(TAG, "We don't have a pending initiate...");
|
||||
ourBaseKey = Curve.generateKeyPair(true);
|
||||
ourEphemeralKey = Curve.generateKeyPair(true);
|
||||
ourIdentityKey = identityKeyStore.getIdentityKeyPair();
|
||||
} else {
|
||||
Log.w(TAG, "We already have a pending initiate, responding as simultaneous initiate...");
|
||||
ourBaseKey = sessionRecord.getSessionState().getPendingKeyExchangeBaseKey();
|
||||
ourEphemeralKey = sessionRecord.getSessionState().getPendingKeyExchangeEphemeralKey();
|
||||
ourIdentityKey = sessionRecord.getSessionState().getPendingKeyExchangeIdentityKey();
|
||||
flags |= KeyExchangeMessage.SIMULTAENOUS_INITIATE_FLAG;
|
||||
}
|
||||
|
||||
if (message.getSequence() != sessionRecord.getSessionState().getPendingKeyExchangeSequence()) {
|
||||
Log.w("KeyExchangeProcessor", "No matching sequence for response. " +
|
||||
"Is simultaneous initiate response: " + message.isResponseForSimultaneousInitiate());
|
||||
return responseMessage;
|
||||
sessionRecord.reset();
|
||||
|
||||
RatchetingSession.initializeSession(sessionRecord.getSessionState(),
|
||||
Math.min(message.getMaxVersion(), CiphertextMessage.CURRENT_VERSION),
|
||||
ourBaseKey, message.getBaseKey(),
|
||||
ourEphemeralKey, message.getEphemeralKey(),
|
||||
ourBaseKey, message.getBaseKey(),
|
||||
ourIdentityKey, message.getIdentityKey());
|
||||
|
||||
sessionStore.storeSession(recipientId, deviceId, sessionRecord);
|
||||
identityKeyStore.saveIdentity(recipientId, message.getIdentityKey());
|
||||
|
||||
return new KeyExchangeMessage(sessionRecord.getSessionState().getSessionVersion(),
|
||||
message.getSequence(), flags, ourBaseKey.getPublicKey(), null,
|
||||
ourEphemeralKey.getPublicKey(), ourIdentityKey.getPublicKey(),
|
||||
sessionRecord.getSessionState().getVerification());
|
||||
}
|
||||
|
||||
private void processResponse(KeyExchangeMessage message)
|
||||
throws StaleKeyExchangeException, InvalidKeyException
|
||||
{
|
||||
SessionRecord sessionRecord = sessionStore.loadSession(recipientId, deviceId);
|
||||
SessionState sessionState = sessionRecord.getSessionState();
|
||||
boolean hasPendingKeyExchange = sessionState.hasPendingKeyExchange();
|
||||
boolean isSimultaneousInitiateResponse = message.isResponseForSimultaneousInitiate();
|
||||
|
||||
if (!hasPendingKeyExchange || sessionState.getPendingKeyExchangeSequence() != message.getSequence()) {
|
||||
Log.w(TAG, "No matching sequence for response. Is simultaneous initiate response: " + isSimultaneousInitiateResponse);
|
||||
if (!isSimultaneousInitiateResponse) throw new StaleKeyExchangeException();
|
||||
else return;
|
||||
}
|
||||
|
||||
ECKeyPair ourBaseKey = sessionRecord.getSessionState().getPendingKeyExchangeBaseKey();
|
||||
@ -311,51 +349,22 @@ public class SessionBuilder {
|
||||
sessionRecord.reset();
|
||||
|
||||
RatchetingSession.initializeSession(sessionRecord.getSessionState(),
|
||||
2,
|
||||
Math.min(message.getMaxVersion(), CiphertextMessage.CURRENT_VERSION),
|
||||
ourBaseKey, message.getBaseKey(),
|
||||
ourEphemeralKey, message.getEphemeralKey(),
|
||||
null, null,
|
||||
ourBaseKey, message.getBaseKey(),
|
||||
ourIdentityKey, message.getIdentityKey());
|
||||
|
||||
sessionRecord.getSessionState().setSessionVersion(message.getVersion());
|
||||
sessionStore.storeSession(recipientId, deviceId, sessionRecord);
|
||||
|
||||
identityKeyStore.saveIdentity(recipientId, message.getIdentityKey());
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private KeyExchangeMessage processInitiate(SessionRecord sessionRecord, KeyExchangeMessage message)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
ECKeyPair ourBaseKey, ourEphemeralKey;
|
||||
IdentityKeyPair ourIdentityKey;
|
||||
|
||||
int flags = KeyExchangeMessage.RESPONSE_FLAG;
|
||||
|
||||
if (!sessionRecord.getSessionState().hasPendingKeyExchange()) {
|
||||
Log.w(TAG, "We don't have a pending initiate...");
|
||||
ourBaseKey = Curve.generateKeyPair(true);
|
||||
ourEphemeralKey = Curve.generateKeyPair(true);
|
||||
ourIdentityKey = identityKeyStore.getIdentityKeyPair();
|
||||
|
||||
sessionRecord.getSessionState().setPendingKeyExchange(message.getSequence(), ourBaseKey,
|
||||
ourEphemeralKey, ourIdentityKey);
|
||||
} else {
|
||||
Log.w(TAG, "We already have a pending initiate, responding as simultaneous initiate...");
|
||||
ourBaseKey = sessionRecord.getSessionState().getPendingKeyExchangeBaseKey();
|
||||
ourEphemeralKey = sessionRecord.getSessionState().getPendingKeyExchangeEphemeralKey();
|
||||
ourIdentityKey = sessionRecord.getSessionState().getPendingKeyExchangeIdentityKey();
|
||||
flags |= KeyExchangeMessage.SIMULTAENOUS_INITIATE_FLAG;
|
||||
|
||||
sessionRecord.getSessionState().setPendingKeyExchange(message.getSequence(), ourBaseKey,
|
||||
ourEphemeralKey, ourIdentityKey);
|
||||
if (sessionRecord.getSessionState().getSessionVersion() >= 3 &&
|
||||
!MessageDigest.isEqual(message.getVerificationTag(),
|
||||
sessionRecord.getSessionState().getVerification()))
|
||||
{
|
||||
throw new InvalidKeyException("Verification tag doesn't match!");
|
||||
}
|
||||
|
||||
return new KeyExchangeMessage(message.getSequence(),
|
||||
flags, ourBaseKey.getPublicKey(),
|
||||
ourEphemeralKey.getPublicKey(),
|
||||
ourIdentityKey.getPublicKey());
|
||||
sessionStore.storeSession(recipientId, deviceId, sessionRecord);
|
||||
identityKeyStore.saveIdentity(recipientId, message.getIdentityKey());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -374,10 +383,10 @@ public class SessionBuilder {
|
||||
sessionRecord.getSessionState().setPendingKeyExchange(sequence, baseKey, ephemeralKey, identityKey);
|
||||
sessionStore.storeSession(recipientId, deviceId, sessionRecord);
|
||||
|
||||
return new KeyExchangeMessage(sequence, flags,
|
||||
baseKey.getPublicKey(),
|
||||
return new KeyExchangeMessage(2, sequence, flags,
|
||||
baseKey.getPublicKey(), null,
|
||||
ephemeralKey.getPublicKey(),
|
||||
identityKey.getPublicKey());
|
||||
identityKey.getPublicKey(), null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,8 @@ import org.whispersystems.libaxolotl.util.ByteUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.whispersystems.libaxolotl.protocol.WhisperProtos.KeyExchangeMessage.Builder;
|
||||
|
||||
public class KeyExchangeMessage {
|
||||
|
||||
public static final int INITIATE_FLAG = 0x01;
|
||||
@ -26,31 +28,43 @@ public class KeyExchangeMessage {
|
||||
private final int flags;
|
||||
|
||||
private final ECPublicKey baseKey;
|
||||
private final byte[] baseKeySignature;
|
||||
private final ECPublicKey ephemeralKey;
|
||||
private final IdentityKey identityKey;
|
||||
private final byte[] verificationTag;
|
||||
private final byte[] serialized;
|
||||
|
||||
public KeyExchangeMessage(int sequence, int flags,
|
||||
ECPublicKey baseKey, ECPublicKey ephemeralKey,
|
||||
IdentityKey identityKey)
|
||||
public KeyExchangeMessage(int messageVersion, int sequence, int flags,
|
||||
ECPublicKey baseKey, byte[] baseKeySignature,
|
||||
ECPublicKey ephemeralKey,
|
||||
IdentityKey identityKey, byte[] verificationTag)
|
||||
{
|
||||
this.supportedVersion = 2;
|
||||
this.version = 2;
|
||||
this.supportedVersion = CiphertextMessage.CURRENT_VERSION;
|
||||
this.version = messageVersion;
|
||||
this.sequence = sequence;
|
||||
this.flags = flags;
|
||||
this.baseKey = baseKey;
|
||||
this.baseKeySignature = baseKeySignature;
|
||||
this.ephemeralKey = ephemeralKey;
|
||||
this.identityKey = identityKey;
|
||||
this.verificationTag = verificationTag;
|
||||
|
||||
byte[] version = {ByteUtil.intsToByteHighAndLow(this.version, this.supportedVersion)};
|
||||
byte[] message = WhisperProtos.KeyExchangeMessage.newBuilder()
|
||||
.setId((sequence << 5) | flags)
|
||||
.setBaseKey(ByteString.copyFrom(baseKey.serialize()))
|
||||
.setEphemeralKey(ByteString.copyFrom(ephemeralKey.serialize()))
|
||||
.setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
|
||||
.build().toByteArray();
|
||||
byte[] version = {ByteUtil.intsToByteHighAndLow(this.version, this.supportedVersion)};
|
||||
Builder builder = WhisperProtos.KeyExchangeMessage.newBuilder()
|
||||
.setId((sequence << 5) | flags)
|
||||
.setBaseKey(ByteString.copyFrom(baseKey.serialize()))
|
||||
.setEphemeralKey(ByteString.copyFrom(ephemeralKey.serialize()))
|
||||
.setIdentityKey(ByteString.copyFrom(identityKey.serialize()));
|
||||
|
||||
this.serialized = ByteUtil.combine(version, message);
|
||||
if (messageVersion >= 3 && baseKeySignature != null) {
|
||||
builder.setBaseKeySignature(ByteString.copyFrom(baseKeySignature));
|
||||
}
|
||||
|
||||
if (messageVersion >=3 && verificationTag != null) {
|
||||
builder.setVerification(ByteString.copyFrom(verificationTag));
|
||||
}
|
||||
|
||||
this.serialized = ByteUtil.combine(version, builder.build().toByteArray());
|
||||
}
|
||||
|
||||
public KeyExchangeMessage(byte[] serialized)
|
||||
@ -71,18 +85,22 @@ public class KeyExchangeMessage {
|
||||
|
||||
WhisperProtos.KeyExchangeMessage message = WhisperProtos.KeyExchangeMessage.parseFrom(parts[1]);
|
||||
|
||||
if (!message.hasId() || !message.hasBaseKey() ||
|
||||
!message.hasEphemeralKey() || !message.hasIdentityKey())
|
||||
if (!message.hasId() || !message.hasBaseKey() ||
|
||||
!message.hasEphemeralKey() || !message.hasIdentityKey() ||
|
||||
(this.version >=3 && (((message.getId() & 0x1f) & INITIATE_FLAG) != 0) && !message.hasBaseKeySignature()) ||
|
||||
(this.version >=3 && (((message.getId() & 0x1f) & RESPONSE_FLAG) != 0) && !message.hasVerification()))
|
||||
{
|
||||
throw new InvalidMessageException("Some required fields missing!");
|
||||
}
|
||||
|
||||
this.sequence = message.getId() >> 5;
|
||||
this.flags = message.getId() & 0x1f;
|
||||
this.serialized = serialized;
|
||||
this.baseKey = Curve.decodePoint(message.getBaseKey().toByteArray(), 0);
|
||||
this.ephemeralKey = Curve.decodePoint(message.getEphemeralKey().toByteArray(), 0);
|
||||
this.identityKey = new IdentityKey(message.getIdentityKey().toByteArray(), 0);
|
||||
this.sequence = message.getId() >> 5;
|
||||
this.flags = message.getId() & 0x1f;
|
||||
this.serialized = serialized;
|
||||
this.baseKey = Curve.decodePoint(message.getBaseKey().toByteArray(), 0);
|
||||
this.baseKeySignature = message.getBaseKeySignature().toByteArray();
|
||||
this.verificationTag = message.getVerification().toByteArray();
|
||||
this.ephemeralKey = Curve.decodePoint(message.getEphemeralKey().toByteArray(), 0);
|
||||
this.identityKey = new IdentityKey(message.getIdentityKey().toByteArray(), 0);
|
||||
} catch (InvalidKeyException | IOException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
}
|
||||
@ -96,6 +114,14 @@ public class KeyExchangeMessage {
|
||||
return baseKey;
|
||||
}
|
||||
|
||||
public byte[] getBaseKeySignature() {
|
||||
return baseKeySignature;
|
||||
}
|
||||
|
||||
public byte[] getVerificationTag() {
|
||||
return verificationTag;
|
||||
}
|
||||
|
||||
public ECPublicKey getEphemeralKey() {
|
||||
return ephemeralKey;
|
||||
}
|
||||
|
@ -1621,6 +1621,26 @@ public final class WhisperProtos {
|
||||
* <code>optional bytes identityKey = 4;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString getIdentityKey();
|
||||
|
||||
// optional bytes baseKeySignature = 5;
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
boolean hasBaseKeySignature();
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString getBaseKeySignature();
|
||||
|
||||
// optional bytes verification = 6;
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
boolean hasVerification();
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString getVerification();
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code textsecure.KeyExchangeMessage}
|
||||
@ -1693,6 +1713,16 @@ public final class WhisperProtos {
|
||||
identityKey_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 42: {
|
||||
bitField0_ |= 0x00000010;
|
||||
baseKeySignature_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 50: {
|
||||
bitField0_ |= 0x00000020;
|
||||
verification_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
@ -1797,11 +1827,45 @@ public final class WhisperProtos {
|
||||
return identityKey_;
|
||||
}
|
||||
|
||||
// optional bytes baseKeySignature = 5;
|
||||
public static final int BASEKEYSIGNATURE_FIELD_NUMBER = 5;
|
||||
private com.google.protobuf.ByteString baseKeySignature_;
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
public boolean hasBaseKeySignature() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getBaseKeySignature() {
|
||||
return baseKeySignature_;
|
||||
}
|
||||
|
||||
// optional bytes verification = 6;
|
||||
public static final int VERIFICATION_FIELD_NUMBER = 6;
|
||||
private com.google.protobuf.ByteString verification_;
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
public boolean hasVerification() {
|
||||
return ((bitField0_ & 0x00000020) == 0x00000020);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getVerification() {
|
||||
return verification_;
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
id_ = 0;
|
||||
baseKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
ephemeralKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
baseKeySignature_ = com.google.protobuf.ByteString.EMPTY;
|
||||
verification_ = com.google.protobuf.ByteString.EMPTY;
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
@ -1827,6 +1891,12 @@ public final class WhisperProtos {
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
output.writeBytes(4, identityKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
output.writeBytes(5, baseKeySignature_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
output.writeBytes(6, verification_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
@ -1852,6 +1922,14 @@ public final class WhisperProtos {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(4, identityKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(5, baseKeySignature_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(6, verification_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
@ -1976,6 +2054,10 @@ public final class WhisperProtos {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
baseKeySignature_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
verification_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000020);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -2020,6 +2102,14 @@ public final class WhisperProtos {
|
||||
to_bitField0_ |= 0x00000008;
|
||||
}
|
||||
result.identityKey_ = identityKey_;
|
||||
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
to_bitField0_ |= 0x00000010;
|
||||
}
|
||||
result.baseKeySignature_ = baseKeySignature_;
|
||||
if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
|
||||
to_bitField0_ |= 0x00000020;
|
||||
}
|
||||
result.verification_ = verification_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
return result;
|
||||
@ -2048,6 +2138,12 @@ public final class WhisperProtos {
|
||||
if (other.hasIdentityKey()) {
|
||||
setIdentityKey(other.getIdentityKey());
|
||||
}
|
||||
if (other.hasBaseKeySignature()) {
|
||||
setBaseKeySignature(other.getBaseKeySignature());
|
||||
}
|
||||
if (other.hasVerification()) {
|
||||
setVerification(other.getVerification());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
}
|
||||
@ -2216,6 +2312,78 @@ public final class WhisperProtos {
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional bytes baseKeySignature = 5;
|
||||
private com.google.protobuf.ByteString baseKeySignature_ = com.google.protobuf.ByteString.EMPTY;
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
public boolean hasBaseKeySignature() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getBaseKeySignature() {
|
||||
return baseKeySignature_;
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
public Builder setBaseKeySignature(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000010;
|
||||
baseKeySignature_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes baseKeySignature = 5;</code>
|
||||
*/
|
||||
public Builder clearBaseKeySignature() {
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
baseKeySignature_ = getDefaultInstance().getBaseKeySignature();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional bytes verification = 6;
|
||||
private com.google.protobuf.ByteString verification_ = com.google.protobuf.ByteString.EMPTY;
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
public boolean hasVerification() {
|
||||
return ((bitField0_ & 0x00000020) == 0x00000020);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getVerification() {
|
||||
return verification_;
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
public Builder setVerification(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000020;
|
||||
verification_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes verification = 6;</code>
|
||||
*/
|
||||
public Builder clearVerification() {
|
||||
bitField0_ = (bitField0_ & ~0x00000020);
|
||||
verification_ = getDefaultInstance().getVerification();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:textsecure.KeyExchangeMessage)
|
||||
}
|
||||
|
||||
@ -2258,11 +2426,12 @@ public final class WhisperProtos {
|
||||
"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" +
|
||||
"\030\002 \001(\014\022\023\n\013identityKey\030\003 \001(\014\022\024\n\014verificat" +
|
||||
"ion\030\007 \001(\014\022\017\n\007message\030\004 \001(\014\"\\\n\022KeyExchang" +
|
||||
"eMessage\022\n\n\002id\030\001 \001(\r\022\017\n\007baseKey\030\002 \001(\014\022\024\n" +
|
||||
"\014ephemeralKey\030\003 \001(\014\022\023\n\013identityKey\030\004 \001(\014",
|
||||
"B7\n&org.whispersystems.libaxolotl.protoc" +
|
||||
"olB\rWhisperProtos"
|
||||
"ion\030\007 \001(\014\022\017\n\007message\030\004 \001(\014\"\214\001\n\022KeyExchan" +
|
||||
"geMessage\022\n\n\002id\030\001 \001(\r\022\017\n\007baseKey\030\002 \001(\014\022\024" +
|
||||
"\n\014ephemeralKey\030\003 \001(\014\022\023\n\013identityKey\030\004 \001(",
|
||||
"\014\022\030\n\020baseKeySignature\030\005 \001(\014\022\024\n\014verificat" +
|
||||
"ion\030\006 \001(\014B7\n&org.whispersystems.libaxolo" +
|
||||
"tl.protocolB\rWhisperProtos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@ -2286,7 +2455,7 @@ public final class WhisperProtos {
|
||||
internal_static_textsecure_KeyExchangeMessage_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_textsecure_KeyExchangeMessage_descriptor,
|
||||
new java.lang.String[] { "Id", "BaseKey", "EphemeralKey", "IdentityKey", });
|
||||
new java.lang.String[] { "Id", "BaseKey", "EphemeralKey", "IdentityKey", "BaseKeySignature", "Verification", });
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user