diff --git a/library/protobuf/LocalStorageProtocol.proto b/library/protobuf/LocalStorageProtocol.proto
index 22378423d8..ff8f8c0b2b 100644
--- a/library/protobuf/LocalStorageProtocol.proto
+++ b/library/protobuf/LocalStorageProtocol.proto
@@ -51,4 +51,10 @@ message SessionStructure {
optional PendingKeyExchange pendingKeyExchange = 8;
optional PendingPreKey pendingPreKey = 9;
+}
+
+message PreKeyRecordStructure {
+ optional uint32 id = 1;
+ optional bytes publicKey = 2;
+ optional bytes privateKey = 3;
}
\ No newline at end of file
diff --git a/library/src/org/whispersystems/textsecure/crypto/PreKeyPair.java b/library/src/org/whispersystems/textsecure/crypto/PreKeyPair.java
deleted file mode 100644
index e4429b584d..0000000000
--- a/library/src/org/whispersystems/textsecure/crypto/PreKeyPair.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Copyright (C) 2013 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.whispersystems.textsecure.crypto;
-
-import org.whispersystems.textsecure.crypto.ecc.ECKeyPair;
-import org.whispersystems.textsecure.crypto.ecc.ECPrivateKey;
-import org.whispersystems.textsecure.util.Util;
-
-public class PreKeyPair {
-
- private final MasterCipher masterCipher;
- private final PreKeyPublic publicKey;
- private final ECPrivateKey privateKey;
-
- public PreKeyPair(MasterSecret masterSecret, ECKeyPair keyPair) {
- this.masterCipher = new MasterCipher(masterSecret);
- this.publicKey = new PreKeyPublic(keyPair.getPublicKey());
- this.privateKey = keyPair.getPrivateKey();
- }
-
- public PreKeyPair(MasterSecret masterSecret, byte[] serialized) throws InvalidKeyException {
- byte[] privateKeyBytes = new byte[serialized.length - PreKeyPublic.KEY_SIZE];
- System.arraycopy(serialized, PreKeyPublic.KEY_SIZE, privateKeyBytes, 0, privateKeyBytes.length);
-
- this.masterCipher = new MasterCipher(masterSecret);
- this.publicKey = new PreKeyPublic(serialized, 0);
- this.privateKey = masterCipher.decryptKey(this.publicKey.getType(), privateKeyBytes);
- }
-
- public PreKeyPublic getPublicKey() {
- return publicKey;
- }
-
- public ECKeyPair getKeyPair() {
- return new ECKeyPair(publicKey.getPublicKey(), privateKey);
- }
-
- public byte[] serialize() {
- byte[] publicKeyBytes = publicKey.serialize();
- byte[] privateKeyBytes = masterCipher.encryptKey(privateKey);
-
- return Util.combine(publicKeyBytes, privateKeyBytes);
- }
-}
diff --git a/library/src/org/whispersystems/textsecure/crypto/PreKeyPublic.java b/library/src/org/whispersystems/textsecure/crypto/PreKeyPublic.java
deleted file mode 100644
index 8b889b317d..0000000000
--- a/library/src/org/whispersystems/textsecure/crypto/PreKeyPublic.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Copyright (C) 2013 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package org.whispersystems.textsecure.crypto;
-
-import org.whispersystems.textsecure.crypto.ecc.Curve;
-import org.whispersystems.textsecure.crypto.ecc.ECPublicKey;
-import org.whispersystems.textsecure.util.Util;
-
-public class PreKeyPublic {
-
- public static final int KEY_SIZE = ECPublicKey.KEY_SIZE;
-
- private final ECPublicKey publicKey;
-
- public PreKeyPublic(ECPublicKey publicKey) {
- this.publicKey = publicKey;
- }
-
- public PreKeyPublic(byte[] serialized, int offset) throws InvalidKeyException {
- this.publicKey = Curve.decodePoint(serialized, offset);
- }
-
- public byte[] serialize() {
- return publicKey.serialize();
- }
-
- public ECPublicKey getPublicKey() {
- return publicKey;
- }
-
- public int getType() {
- return this.publicKey.getType();
- }
-}
diff --git a/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java b/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java
index 9c97a155db..b0f9abc53c 100644
--- a/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java
+++ b/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java
@@ -23,6 +23,7 @@ import android.util.Log;
import com.google.thoughtcrimegson.Gson;
import org.whispersystems.textsecure.crypto.ecc.Curve25519;
+import org.whispersystems.textsecure.crypto.ecc.ECKeyPair;
import org.whispersystems.textsecure.storage.InvalidKeyIdException;
import org.whispersystems.textsecure.storage.PreKeyRecord;
import org.whispersystems.textsecure.util.Medium;
@@ -40,7 +41,7 @@ import java.util.List;
public class PreKeyUtil {
- public static final int BATCH_SIZE = 20;
+ public static final int BATCH_SIZE = 100;
public static List generatePreKeys(Context context, MasterSecret masterSecret) {
List records = new LinkedList();
@@ -48,7 +49,7 @@ public class PreKeyUtil {
for (int i=0;i, JsonDeserializer
+ private static class ECPublicKeyJsonAdapter
+ implements JsonSerializer, JsonDeserializer
{
@Override
- public JsonElement serialize(PreKeyPublic preKeyPublic, Type type,
+ public JsonElement serialize(ECPublicKey preKeyPublic, Type type,
JsonSerializationContext jsonSerializationContext)
{
return new JsonPrimitive(Base64.encodeBytesWithoutPadding(preKeyPublic.serialize()));
}
@Override
- public PreKeyPublic deserialize(JsonElement jsonElement, Type type,
+ public ECPublicKey deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext)
throws JsonParseException
{
try {
- return new PreKeyPublic(Base64.decodeWithoutPadding(jsonElement.getAsJsonPrimitive().getAsString()), 0);
+ return Curve.decodePoint(Base64.decodeWithoutPadding(jsonElement.getAsJsonPrimitive().getAsString()), 0);
} catch (InvalidKeyException e) {
throw new JsonParseException(e);
} catch (IOException e) {
diff --git a/library/src/org/whispersystems/textsecure/push/PreKeyList.java b/library/src/org/whispersystems/textsecure/push/PreKeyList.java
index b47c32babb..6571fc4118 100644
--- a/library/src/org/whispersystems/textsecure/push/PreKeyList.java
+++ b/library/src/org/whispersystems/textsecure/push/PreKeyList.java
@@ -20,6 +20,10 @@ public class PreKeyList {
return PreKeyEntity.getBuilder().create().toJson(entity);
}
+ public static PreKeyList fromJson(String serialized) {
+ return PreKeyEntity.getBuilder().create().fromJson(serialized, PreKeyList.class);
+ }
+
public PreKeyEntity getLastResortKey() {
return lastResortKey;
}
diff --git a/library/src/org/whispersystems/textsecure/storage/PreKeyRecord.java b/library/src/org/whispersystems/textsecure/storage/PreKeyRecord.java
index dd67468eee..d5796c054d 100644
--- a/library/src/org/whispersystems/textsecure/storage/PreKeyRecord.java
+++ b/library/src/org/whispersystems/textsecure/storage/PreKeyRecord.java
@@ -3,9 +3,16 @@ package org.whispersystems.textsecure.storage;
import android.content.Context;
import android.util.Log;
+import com.google.protobuf.ByteString;
+
import org.whispersystems.textsecure.crypto.InvalidKeyException;
+import org.whispersystems.textsecure.crypto.InvalidMessageException;
+import org.whispersystems.textsecure.crypto.MasterCipher;
import org.whispersystems.textsecure.crypto.MasterSecret;
-import org.whispersystems.textsecure.crypto.PreKeyPair;
+import org.whispersystems.textsecure.crypto.ecc.Curve;
+import org.whispersystems.textsecure.crypto.ecc.ECKeyPair;
+import org.whispersystems.textsecure.crypto.ecc.ECPrivateKey;
+import org.whispersystems.textsecure.crypto.ecc.ECPublicKey;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -19,36 +26,46 @@ public class PreKeyRecord extends Record {
private static final int CURRENT_VERSION_MARKER = 1;
private final MasterSecret masterSecret;
-
- private PreKeyPair keyPair;
- private int id;
+ private StorageProtos.PreKeyRecordStructure structure;
public PreKeyRecord(Context context, MasterSecret masterSecret, int id)
throws InvalidKeyIdException
{
super(context, PREKEY_DIRECTORY, id+"");
- this.id = id;
+ this.structure = StorageProtos.PreKeyRecordStructure.newBuilder().setId(id).build();
this.masterSecret = masterSecret;
loadData();
}
public PreKeyRecord(Context context, MasterSecret masterSecret,
- int id, PreKeyPair keyPair)
+ int id, ECKeyPair keyPair)
{
super(context, PREKEY_DIRECTORY, id+"");
- this.id = id;
- this.keyPair = keyPair;
this.masterSecret = masterSecret;
+ this.structure = StorageProtos.PreKeyRecordStructure.newBuilder()
+ .setId(id)
+ .setPublicKey(ByteString.copyFrom(keyPair.getPublicKey()
+ .serialize()))
+ .setPrivateKey(ByteString.copyFrom(keyPair.getPrivateKey()
+ .serialize()))
+ .build();
}
public int getId() {
- return id;
+ return this.structure.getId();
}
- public PreKeyPair getKeyPair() {
- return keyPair;
+ public ECKeyPair getKeyPair() {
+ try {
+ ECPublicKey publicKey = Curve.decodePoint(this.structure.getPublicKey().toByteArray(), 0);
+ ECPrivateKey privateKey = Curve.decodePrivatePoint(publicKey.getType(), this.structure.getPrivateKey().toByteArray());
+
+ return new ECKeyPair(publicKey, privateKey);
+ } catch (InvalidKeyException e) {
+ throw new AssertionError(e);
+ }
}
public static boolean hasRecord(Context context, long id) {
@@ -67,8 +84,10 @@ public class PreKeyRecord extends Record {
FileChannel out = file.getChannel();
out.position(0);
+ MasterCipher masterCipher = new MasterCipher(masterSecret);
+
writeInteger(CURRENT_VERSION_MARKER, out);
- writeKeyPair(keyPair, out);
+ writeBlob(masterCipher.encryptBytes(structure.toByteArray()), out);
out.force(true);
out.truncate(out.position());
@@ -83,15 +102,18 @@ public class PreKeyRecord extends Record {
private void loadData() throws InvalidKeyIdException {
synchronized (FILE_LOCK) {
try {
- FileInputStream in = this.openInputStream();
- int recordVersion = readInteger(in);
+ MasterCipher masterCipher = new MasterCipher(masterSecret);
+ FileInputStream in = this.openInputStream();
+ int recordVersion = readInteger(in);
if (recordVersion != CURRENT_VERSION_MARKER) {
Log.w("PreKeyRecord", "Invalid version: " + recordVersion);
return;
}
- keyPair = readKeyPair(in);
+ this.structure =
+ StorageProtos.PreKeyRecordStructure.parseFrom(masterCipher.decryptBytes(readBlob(in)));
+
in.close();
} catch (FileNotFoundException e) {
Log.w("PreKeyRecord", e);
@@ -99,23 +121,10 @@ public class PreKeyRecord extends Record {
} catch (IOException ioe) {
Log.w("PreKeyRecord", ioe);
throw new InvalidKeyIdException(ioe);
- } catch (InvalidKeyException ike) {
- Log.w("LocalKeyRecord", ike);
- throw new InvalidKeyIdException(ike);
+ } catch (InvalidMessageException ime) {
+ Log.w("PreKeyRecord", ime);
+ throw new InvalidKeyIdException(ime);
}
}
}
-
- private void writeKeyPair(PreKeyPair keyPair, FileChannel out) throws IOException {
- byte[] serialized = keyPair.serialize();
- writeBlob(serialized, out);
- }
-
- private PreKeyPair readKeyPair(FileInputStream in)
- throws IOException, InvalidKeyException
- {
- byte[] keyPairBytes = readBlob(in);
- return new PreKeyPair(masterSecret, keyPairBytes);
- }
-
}
diff --git a/library/src/org/whispersystems/textsecure/storage/StorageProtos.java b/library/src/org/whispersystems/textsecure/storage/StorageProtos.java
index 7f51de31f8..0afdf31eb3 100644
--- a/library/src/org/whispersystems/textsecure/storage/StorageProtos.java
+++ b/library/src/org/whispersystems/textsecure/storage/StorageProtos.java
@@ -4054,6 +4054,464 @@ public final class StorageProtos {
// @@protoc_insertion_point(class_scope:textsecure.SessionStructure)
}
+ public interface PreKeyRecordStructureOrBuilder
+ extends com.google.protobuf.MessageOrBuilder {
+
+ // optional uint32 id = 1;
+ boolean hasId();
+ int getId();
+
+ // optional bytes publicKey = 2;
+ boolean hasPublicKey();
+ com.google.protobuf.ByteString getPublicKey();
+
+ // optional bytes privateKey = 3;
+ boolean hasPrivateKey();
+ com.google.protobuf.ByteString getPrivateKey();
+ }
+ public static final class PreKeyRecordStructure extends
+ com.google.protobuf.GeneratedMessage
+ implements PreKeyRecordStructureOrBuilder {
+ // Use PreKeyRecordStructure.newBuilder() to construct.
+ private PreKeyRecordStructure(Builder builder) {
+ super(builder);
+ }
+ private PreKeyRecordStructure(boolean noInit) {}
+
+ private static final PreKeyRecordStructure defaultInstance;
+ public static PreKeyRecordStructure getDefaultInstance() {
+ return defaultInstance;
+ }
+
+ public PreKeyRecordStructure getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return org.whispersystems.textsecure.storage.StorageProtos.internal_static_textsecure_PreKeyRecordStructure_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return org.whispersystems.textsecure.storage.StorageProtos.internal_static_textsecure_PreKeyRecordStructure_fieldAccessorTable;
+ }
+
+ private int bitField0_;
+ // optional uint32 id = 1;
+ public static final int ID_FIELD_NUMBER = 1;
+ private int id_;
+ public boolean hasId() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ public int getId() {
+ return id_;
+ }
+
+ // optional bytes publicKey = 2;
+ public static final int PUBLICKEY_FIELD_NUMBER = 2;
+ private com.google.protobuf.ByteString publicKey_;
+ public boolean hasPublicKey() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ public com.google.protobuf.ByteString getPublicKey() {
+ return publicKey_;
+ }
+
+ // optional bytes privateKey = 3;
+ public static final int PRIVATEKEY_FIELD_NUMBER = 3;
+ private com.google.protobuf.ByteString privateKey_;
+ public boolean hasPrivateKey() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ public com.google.protobuf.ByteString getPrivateKey() {
+ return privateKey_;
+ }
+
+ private void initFields() {
+ id_ = 0;
+ publicKey_ = com.google.protobuf.ByteString.EMPTY;
+ privateKey_ = com.google.protobuf.ByteString.EMPTY;
+ }
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized != -1) return isInitialized == 1;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ output.writeUInt32(1, id_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ output.writeBytes(2, publicKey_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ output.writeBytes(3, privateKey_);
+ }
+ getUnknownFields().writeTo(output);
+ }
+
+ private int memoizedSerializedSize = -1;
+ public int getSerializedSize() {
+ int size = memoizedSerializedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (((bitField0_ & 0x00000001) == 0x00000001)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeUInt32Size(1, id_);
+ }
+ if (((bitField0_ & 0x00000002) == 0x00000002)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(2, publicKey_);
+ }
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBytesSize(3, privateKey_);
+ }
+ size += getUnknownFields().getSerializedSize();
+ memoizedSerializedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ @java.lang.Override
+ protected java.lang.Object writeReplace()
+ throws java.io.ObjectStreamException {
+ return super.writeReplace();
+ }
+
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry)
+ .buildParsed();
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).buildParsed();
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data, extensionRegistry)
+ .buildParsed();
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry)
+ .buildParsed();
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ Builder builder = newBuilder();
+ if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
+ return builder.buildParsed();
+ } else {
+ return null;
+ }
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input).buildParsed();
+ }
+ public static org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return newBuilder().mergeFrom(input, extensionRegistry)
+ .buildParsed();
+ }
+
+ public static Builder newBuilder() { return Builder.create(); }
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder(org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure prototype) {
+ return newBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() { return newBuilder(this); }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder
+ implements org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructureOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return org.whispersystems.textsecure.storage.StorageProtos.internal_static_textsecure_PreKeyRecordStructure_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return org.whispersystems.textsecure.storage.StorageProtos.internal_static_textsecure_PreKeyRecordStructure_fieldAccessorTable;
+ }
+
+ // Construct using org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ private static Builder create() {
+ return new Builder();
+ }
+
+ public Builder clear() {
+ super.clear();
+ id_ = 0;
+ bitField0_ = (bitField0_ & ~0x00000001);
+ publicKey_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000002);
+ privateKey_ = com.google.protobuf.ByteString.EMPTY;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ return this;
+ }
+
+ public Builder clone() {
+ return create().mergeFrom(buildPartial());
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure.getDescriptor();
+ }
+
+ public org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure getDefaultInstanceForType() {
+ return org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure.getDefaultInstance();
+ }
+
+ public org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure build() {
+ org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ private org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure buildParsed()
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(
+ result).asInvalidProtocolBufferException();
+ }
+ return result;
+ }
+
+ public org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure buildPartial() {
+ org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure result = new org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+ to_bitField0_ |= 0x00000001;
+ }
+ result.id_ = id_;
+ if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+ to_bitField0_ |= 0x00000002;
+ }
+ result.publicKey_ = publicKey_;
+ if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+ to_bitField0_ |= 0x00000004;
+ }
+ result.privateKey_ = privateKey_;
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure) {
+ return mergeFrom((org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure other) {
+ if (other == org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure.getDefaultInstance()) return this;
+ if (other.hasId()) {
+ setId(other.getId());
+ }
+ if (other.hasPublicKey()) {
+ setPublicKey(other.getPublicKey());
+ }
+ if (other.hasPrivateKey()) {
+ setPrivateKey(other.getPrivateKey());
+ }
+ this.mergeUnknownFields(other.getUnknownFields());
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+ com.google.protobuf.UnknownFieldSet.newBuilder(
+ this.getUnknownFields());
+ while (true) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ this.setUnknownFields(unknownFields.build());
+ onChanged();
+ return this;
+ default: {
+ if (!parseUnknownField(input, unknownFields,
+ extensionRegistry, tag)) {
+ this.setUnknownFields(unknownFields.build());
+ onChanged();
+ return this;
+ }
+ break;
+ }
+ case 8: {
+ bitField0_ |= 0x00000001;
+ id_ = input.readUInt32();
+ break;
+ }
+ case 18: {
+ bitField0_ |= 0x00000002;
+ publicKey_ = input.readBytes();
+ break;
+ }
+ case 26: {
+ bitField0_ |= 0x00000004;
+ privateKey_ = input.readBytes();
+ break;
+ }
+ }
+ }
+ }
+
+ private int bitField0_;
+
+ // optional uint32 id = 1;
+ private int id_ ;
+ public boolean hasId() {
+ return ((bitField0_ & 0x00000001) == 0x00000001);
+ }
+ public int getId() {
+ return id_;
+ }
+ public Builder setId(int value) {
+ bitField0_ |= 0x00000001;
+ id_ = value;
+ onChanged();
+ return this;
+ }
+ public Builder clearId() {
+ bitField0_ = (bitField0_ & ~0x00000001);
+ id_ = 0;
+ onChanged();
+ return this;
+ }
+
+ // optional bytes publicKey = 2;
+ private com.google.protobuf.ByteString publicKey_ = com.google.protobuf.ByteString.EMPTY;
+ public boolean hasPublicKey() {
+ return ((bitField0_ & 0x00000002) == 0x00000002);
+ }
+ public com.google.protobuf.ByteString getPublicKey() {
+ return publicKey_;
+ }
+ public Builder setPublicKey(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000002;
+ publicKey_ = value;
+ onChanged();
+ return this;
+ }
+ public Builder clearPublicKey() {
+ bitField0_ = (bitField0_ & ~0x00000002);
+ publicKey_ = getDefaultInstance().getPublicKey();
+ onChanged();
+ return this;
+ }
+
+ // optional bytes privateKey = 3;
+ private com.google.protobuf.ByteString privateKey_ = com.google.protobuf.ByteString.EMPTY;
+ public boolean hasPrivateKey() {
+ return ((bitField0_ & 0x00000004) == 0x00000004);
+ }
+ public com.google.protobuf.ByteString getPrivateKey() {
+ return privateKey_;
+ }
+ public Builder setPrivateKey(com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ bitField0_ |= 0x00000004;
+ privateKey_ = value;
+ onChanged();
+ return this;
+ }
+ public Builder clearPrivateKey() {
+ bitField0_ = (bitField0_ & ~0x00000004);
+ privateKey_ = getDefaultInstance().getPrivateKey();
+ onChanged();
+ return this;
+ }
+
+ // @@protoc_insertion_point(builder_scope:textsecure.PreKeyRecordStructure)
+ }
+
+ static {
+ defaultInstance = new PreKeyRecordStructure(true);
+ defaultInstance.initFields();
+ }
+
+ // @@protoc_insertion_point(class_scope:textsecure.PreKeyRecordStructure)
+ }
+
private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_SessionStructure_descriptor;
private static
@@ -4084,6 +4542,11 @@ public final class StorageProtos {
private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_textsecure_SessionStructure_PendingPreKey_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_textsecure_PreKeyRecordStructure_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_textsecure_PreKeyRecordStructure_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
@@ -4118,8 +4581,10 @@ public final class StorageProtos {
"emeralKeyPrivate\030\005 \001(\014\022\030\n\020localIdentityK" +
"ey\030\007 \001(\014\022\037\n\027localIdentityKeyPrivate\030\010 \001(" +
"\014\0322\n\rPendingPreKey\022\020\n\010preKeyId\030\001 \001(\r\022\017\n\007" +
- "baseKey\030\002 \001(\014B6\n%org.whispersystems.text" +
- "secure.storageB\rStorageProtos"
+ "baseKey\030\002 \001(\014\"J\n\025PreKeyRecordStructure\022\n" +
+ "\n\002id\030\001 \001(\r\022\021\n\tpublicKey\030\002 \001(\014\022\022\n\nprivate" +
+ "Key\030\003 \001(\014B6\n%org.whispersystems.textsecu" +
+ "re.storageB\rStorageProtos"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -4174,6 +4639,14 @@ public final class StorageProtos {
new java.lang.String[] { "PreKeyId", "BaseKey", },
org.whispersystems.textsecure.storage.StorageProtos.SessionStructure.PendingPreKey.class,
org.whispersystems.textsecure.storage.StorageProtos.SessionStructure.PendingPreKey.Builder.class);
+ internal_static_textsecure_PreKeyRecordStructure_descriptor =
+ getDescriptor().getMessageTypes().get(1);
+ internal_static_textsecure_PreKeyRecordStructure_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_textsecure_PreKeyRecordStructure_descriptor,
+ new java.lang.String[] { "Id", "PublicKey", "PrivateKey", },
+ org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure.class,
+ org.whispersystems.textsecure.storage.StorageProtos.PreKeyRecordStructure.Builder.class);
return null;
}
};
diff --git a/src/org/thoughtcrime/securesms/RoutingActivity.java b/src/org/thoughtcrime/securesms/RoutingActivity.java
index 958a1dbe76..536ac9e981 100644
--- a/src/org/thoughtcrime/securesms/RoutingActivity.java
+++ b/src/org/thoughtcrime/securesms/RoutingActivity.java
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms;
import android.content.Intent;
import android.net.Uri;
-import org.whispersystems.textsecure.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.recipients.RecipientFactory;
@@ -11,6 +10,7 @@ import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.ApplicationMigrationService;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
+import org.whispersystems.textsecure.crypto.MasterSecret;
public class RoutingActivity extends PassphraseRequiredSherlockActivity {
diff --git a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java
index 8d4326699e..b0190e4df8 100644
--- a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java
+++ b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java
@@ -89,7 +89,7 @@ public class KeyExchangeProcessorV2 extends KeyExchangeProcessor {
throw new InvalidKeyIdException("No such prekey: " + preKeyId);
PreKeyRecord preKeyRecord = new PreKeyRecord(context, masterSecret, preKeyId);
- ECKeyPair ourBaseKey = preKeyRecord.getKeyPair().getKeyPair();
+ ECKeyPair ourBaseKey = preKeyRecord.getKeyPair();
ECKeyPair ourEphemeralKey = ourBaseKey;
IdentityKeyPair ourIdentityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret, ourBaseKey.getPublicKey().getType());
@@ -113,7 +113,7 @@ public class KeyExchangeProcessorV2 extends KeyExchangeProcessor {
{
ECKeyPair ourBaseKey = Curve.generateKeyPairForSession(2);
ECKeyPair ourEphemeralKey = Curve.generateKeyPairForSession(2);
- ECPublicKey theirBaseKey = message.getPublicKey().getPublicKey();
+ ECPublicKey theirBaseKey = message.getPublicKey();
ECPublicKey theirEphemeralKey = theirBaseKey;
IdentityKey theirIdentityKey = message.getIdentityKey();
IdentityKeyPair ourIdentityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret,