Remove unnecessary classes, up prekey limit to 100

This commit is contained in:
Moxie Marlinspike 2013-11-27 17:50:38 -08:00
parent 1ab4e7e9de
commit 327ee4ff62
11 changed files with 546 additions and 164 deletions

View File

@ -51,4 +51,10 @@ message SessionStructure {
optional PendingKeyExchange pendingKeyExchange = 8; optional PendingKeyExchange pendingKeyExchange = 8;
optional PendingPreKey pendingPreKey = 9; optional PendingPreKey pendingPreKey = 9;
}
message PreKeyRecordStructure {
optional uint32 id = 1;
optional bytes publicKey = 2;
optional bytes privateKey = 3;
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View File

@ -23,6 +23,7 @@ import android.util.Log;
import com.google.thoughtcrimegson.Gson; import com.google.thoughtcrimegson.Gson;
import org.whispersystems.textsecure.crypto.ecc.Curve25519; 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.InvalidKeyIdException;
import org.whispersystems.textsecure.storage.PreKeyRecord; import org.whispersystems.textsecure.storage.PreKeyRecord;
import org.whispersystems.textsecure.util.Medium; import org.whispersystems.textsecure.util.Medium;
@ -40,7 +41,7 @@ import java.util.List;
public class PreKeyUtil { public class PreKeyUtil {
public static final int BATCH_SIZE = 20; public static final int BATCH_SIZE = 100;
public static List<PreKeyRecord> generatePreKeys(Context context, MasterSecret masterSecret) { public static List<PreKeyRecord> generatePreKeys(Context context, MasterSecret masterSecret) {
List<PreKeyRecord> records = new LinkedList<PreKeyRecord>(); List<PreKeyRecord> records = new LinkedList<PreKeyRecord>();
@ -48,7 +49,7 @@ public class PreKeyUtil {
for (int i=0;i<BATCH_SIZE;i++) { for (int i=0;i<BATCH_SIZE;i++) {
int preKeyId = (preKeyIdOffset + i) % Medium.MAX_VALUE; int preKeyId = (preKeyIdOffset + i) % Medium.MAX_VALUE;
PreKeyPair keyPair = new PreKeyPair(masterSecret, Curve25519.generateKeyPair()); ECKeyPair keyPair = Curve25519.generateKeyPair();
PreKeyRecord record = new PreKeyRecord(context, masterSecret, preKeyId, keyPair); PreKeyRecord record = new PreKeyRecord(context, masterSecret, preKeyId, keyPair);
record.save(); record.save();
@ -69,7 +70,7 @@ public class PreKeyUtil {
} }
} }
PreKeyPair keyPair = new PreKeyPair(masterSecret, Curve25519.generateKeyPair()); ECKeyPair keyPair = Curve25519.generateKeyPair();
PreKeyRecord record = new PreKeyRecord(context, masterSecret, Medium.MAX_VALUE, keyPair); PreKeyRecord record = new PreKeyRecord(context, masterSecret, Medium.MAX_VALUE, keyPair);
record.save(); record.save();

View File

@ -47,11 +47,6 @@ public class PublicKey {
this.id = id; this.id = id;
} }
public PublicKey(int preKeyId, PreKeyPublic publicKey) {
this.id = preKeyId;
this.publicKey = publicKey.getPublicKey();
}
public PublicKey(byte[] bytes, int offset) throws InvalidKeyException { public PublicKey(byte[] bytes, int offset) throws InvalidKeyException {
Log.w("PublicKey", "PublicKey Length: " + (bytes.length - offset)); Log.w("PublicKey", "PublicKey Length: " + (bytes.length - offset));

View File

@ -8,9 +8,11 @@ import com.google.thoughtcrimegson.JsonParseException;
import com.google.thoughtcrimegson.JsonPrimitive; import com.google.thoughtcrimegson.JsonPrimitive;
import com.google.thoughtcrimegson.JsonSerializationContext; import com.google.thoughtcrimegson.JsonSerializationContext;
import com.google.thoughtcrimegson.JsonSerializer; import com.google.thoughtcrimegson.JsonSerializer;
import org.whispersystems.textsecure.crypto.IdentityKey; import org.whispersystems.textsecure.crypto.IdentityKey;
import org.whispersystems.textsecure.crypto.InvalidKeyException; import org.whispersystems.textsecure.crypto.InvalidKeyException;
import org.whispersystems.textsecure.crypto.PreKeyPublic; import org.whispersystems.textsecure.crypto.ecc.Curve;
import org.whispersystems.textsecure.crypto.ecc.ECPublicKey;
import org.whispersystems.textsecure.util.Base64; import org.whispersystems.textsecure.util.Base64;
import java.io.IOException; import java.io.IOException;
@ -18,11 +20,11 @@ import java.lang.reflect.Type;
public class PreKeyEntity { public class PreKeyEntity {
private int keyId; private int keyId;
private PreKeyPublic publicKey; private ECPublicKey publicKey;
private IdentityKey identityKey; private IdentityKey identityKey;
public PreKeyEntity(int keyId, PreKeyPublic publicKey, IdentityKey identityKey) { public PreKeyEntity(int keyId, ECPublicKey publicKey, IdentityKey identityKey) {
this.keyId = keyId; this.keyId = keyId;
this.publicKey = publicKey; this.publicKey = publicKey;
this.identityKey = identityKey; this.identityKey = identityKey;
@ -32,7 +34,7 @@ public class PreKeyEntity {
return keyId; return keyId;
} }
public PreKeyPublic getPublicKey() { public ECPublicKey getPublicKey() {
return publicKey; return publicKey;
} }
@ -50,29 +52,29 @@ public class PreKeyEntity {
public static GsonBuilder getBuilder() { public static GsonBuilder getBuilder() {
GsonBuilder builder = new GsonBuilder(); GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(PreKeyPublic.class, new PreKeyPublicJsonAdapter()); builder.registerTypeAdapter(ECPublicKey.class, new ECPublicKeyJsonAdapter());
builder.registerTypeAdapter(IdentityKey.class, new IdentityKeyJsonAdapter()); builder.registerTypeAdapter(IdentityKey.class, new IdentityKeyJsonAdapter());
return builder; return builder;
} }
private static class PreKeyPublicJsonAdapter private static class ECPublicKeyJsonAdapter
implements JsonSerializer<PreKeyPublic>, JsonDeserializer<PreKeyPublic> implements JsonSerializer<ECPublicKey>, JsonDeserializer<ECPublicKey>
{ {
@Override @Override
public JsonElement serialize(PreKeyPublic preKeyPublic, Type type, public JsonElement serialize(ECPublicKey preKeyPublic, Type type,
JsonSerializationContext jsonSerializationContext) JsonSerializationContext jsonSerializationContext)
{ {
return new JsonPrimitive(Base64.encodeBytesWithoutPadding(preKeyPublic.serialize())); return new JsonPrimitive(Base64.encodeBytesWithoutPadding(preKeyPublic.serialize()));
} }
@Override @Override
public PreKeyPublic deserialize(JsonElement jsonElement, Type type, public ECPublicKey deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) JsonDeserializationContext jsonDeserializationContext)
throws JsonParseException throws JsonParseException
{ {
try { try {
return new PreKeyPublic(Base64.decodeWithoutPadding(jsonElement.getAsJsonPrimitive().getAsString()), 0); return Curve.decodePoint(Base64.decodeWithoutPadding(jsonElement.getAsJsonPrimitive().getAsString()), 0);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
throw new JsonParseException(e); throw new JsonParseException(e);
} catch (IOException e) { } catch (IOException e) {

View File

@ -20,6 +20,10 @@ public class PreKeyList {
return PreKeyEntity.getBuilder().create().toJson(entity); return PreKeyEntity.getBuilder().create().toJson(entity);
} }
public static PreKeyList fromJson(String serialized) {
return PreKeyEntity.getBuilder().create().fromJson(serialized, PreKeyList.class);
}
public PreKeyEntity getLastResortKey() { public PreKeyEntity getLastResortKey() {
return lastResortKey; return lastResortKey;
} }

View File

@ -3,9 +3,16 @@ package org.whispersystems.textsecure.storage;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import com.google.protobuf.ByteString;
import org.whispersystems.textsecure.crypto.InvalidKeyException; 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.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.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -19,36 +26,46 @@ public class PreKeyRecord extends Record {
private static final int CURRENT_VERSION_MARKER = 1; private static final int CURRENT_VERSION_MARKER = 1;
private final MasterSecret masterSecret; private final MasterSecret masterSecret;
private StorageProtos.PreKeyRecordStructure structure;
private PreKeyPair keyPair;
private int id;
public PreKeyRecord(Context context, MasterSecret masterSecret, int id) public PreKeyRecord(Context context, MasterSecret masterSecret, int id)
throws InvalidKeyIdException throws InvalidKeyIdException
{ {
super(context, PREKEY_DIRECTORY, id+""); super(context, PREKEY_DIRECTORY, id+"");
this.id = id; this.structure = StorageProtos.PreKeyRecordStructure.newBuilder().setId(id).build();
this.masterSecret = masterSecret; this.masterSecret = masterSecret;
loadData(); loadData();
} }
public PreKeyRecord(Context context, MasterSecret masterSecret, public PreKeyRecord(Context context, MasterSecret masterSecret,
int id, PreKeyPair keyPair) int id, ECKeyPair keyPair)
{ {
super(context, PREKEY_DIRECTORY, id+""); super(context, PREKEY_DIRECTORY, id+"");
this.id = id;
this.keyPair = keyPair;
this.masterSecret = masterSecret; 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() { public int getId() {
return id; return this.structure.getId();
} }
public PreKeyPair getKeyPair() { public ECKeyPair getKeyPair() {
return keyPair; 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) { public static boolean hasRecord(Context context, long id) {
@ -67,8 +84,10 @@ public class PreKeyRecord extends Record {
FileChannel out = file.getChannel(); FileChannel out = file.getChannel();
out.position(0); out.position(0);
MasterCipher masterCipher = new MasterCipher(masterSecret);
writeInteger(CURRENT_VERSION_MARKER, out); writeInteger(CURRENT_VERSION_MARKER, out);
writeKeyPair(keyPair, out); writeBlob(masterCipher.encryptBytes(structure.toByteArray()), out);
out.force(true); out.force(true);
out.truncate(out.position()); out.truncate(out.position());
@ -83,15 +102,18 @@ public class PreKeyRecord extends Record {
private void loadData() throws InvalidKeyIdException { private void loadData() throws InvalidKeyIdException {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
try { try {
FileInputStream in = this.openInputStream(); MasterCipher masterCipher = new MasterCipher(masterSecret);
int recordVersion = readInteger(in); FileInputStream in = this.openInputStream();
int recordVersion = readInteger(in);
if (recordVersion != CURRENT_VERSION_MARKER) { if (recordVersion != CURRENT_VERSION_MARKER) {
Log.w("PreKeyRecord", "Invalid version: " + recordVersion); Log.w("PreKeyRecord", "Invalid version: " + recordVersion);
return; return;
} }
keyPair = readKeyPair(in); this.structure =
StorageProtos.PreKeyRecordStructure.parseFrom(masterCipher.decryptBytes(readBlob(in)));
in.close(); in.close();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Log.w("PreKeyRecord", e); Log.w("PreKeyRecord", e);
@ -99,23 +121,10 @@ public class PreKeyRecord extends Record {
} catch (IOException ioe) { } catch (IOException ioe) {
Log.w("PreKeyRecord", ioe); Log.w("PreKeyRecord", ioe);
throw new InvalidKeyIdException(ioe); throw new InvalidKeyIdException(ioe);
} catch (InvalidKeyException ike) { } catch (InvalidMessageException ime) {
Log.w("LocalKeyRecord", ike); Log.w("PreKeyRecord", ime);
throw new InvalidKeyIdException(ike); 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);
}
} }

View File

@ -4054,6 +4054,464 @@ public final class StorageProtos {
// @@protoc_insertion_point(class_scope:textsecure.SessionStructure) // @@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<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 private static com.google.protobuf.Descriptors.Descriptor
internal_static_textsecure_SessionStructure_descriptor; internal_static_textsecure_SessionStructure_descriptor;
private static private static
@ -4084,6 +4542,11 @@ public final class StorageProtos {
private static private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_textsecure_SessionStructure_PendingPreKey_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 public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() { getDescriptor() {
@ -4118,8 +4581,10 @@ public final class StorageProtos {
"emeralKeyPrivate\030\005 \001(\014\022\030\n\020localIdentityK" + "emeralKeyPrivate\030\005 \001(\014\022\030\n\020localIdentityK" +
"ey\030\007 \001(\014\022\037\n\027localIdentityKeyPrivate\030\010 \001(" + "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" + "\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" + "baseKey\030\002 \001(\014\"J\n\025PreKeyRecordStructure\022\n" +
"secure.storageB\rStorageProtos" "\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 = com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@ -4174,6 +4639,14 @@ public final class StorageProtos {
new java.lang.String[] { "PreKeyId", "BaseKey", }, new java.lang.String[] { "PreKeyId", "BaseKey", },
org.whispersystems.textsecure.storage.StorageProtos.SessionStructure.PendingPreKey.class, org.whispersystems.textsecure.storage.StorageProtos.SessionStructure.PendingPreKey.class,
org.whispersystems.textsecure.storage.StorageProtos.SessionStructure.PendingPreKey.Builder.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; return null;
} }
}; };

View File

@ -3,7 +3,6 @@ package org.thoughtcrime.securesms;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.recipients.RecipientFactory; 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.recipients.Recipients;
import org.thoughtcrime.securesms.service.ApplicationMigrationService; import org.thoughtcrime.securesms.service.ApplicationMigrationService;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.crypto.MasterSecret;
public class RoutingActivity extends PassphraseRequiredSherlockActivity { public class RoutingActivity extends PassphraseRequiredSherlockActivity {

View File

@ -89,7 +89,7 @@ public class KeyExchangeProcessorV2 extends KeyExchangeProcessor {
throw new InvalidKeyIdException("No such prekey: " + preKeyId); throw new InvalidKeyIdException("No such prekey: " + preKeyId);
PreKeyRecord preKeyRecord = new PreKeyRecord(context, masterSecret, preKeyId); PreKeyRecord preKeyRecord = new PreKeyRecord(context, masterSecret, preKeyId);
ECKeyPair ourBaseKey = preKeyRecord.getKeyPair().getKeyPair(); ECKeyPair ourBaseKey = preKeyRecord.getKeyPair();
ECKeyPair ourEphemeralKey = ourBaseKey; ECKeyPair ourEphemeralKey = ourBaseKey;
IdentityKeyPair ourIdentityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret, ourBaseKey.getPublicKey().getType()); IdentityKeyPair ourIdentityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret, ourBaseKey.getPublicKey().getType());
@ -113,7 +113,7 @@ public class KeyExchangeProcessorV2 extends KeyExchangeProcessor {
{ {
ECKeyPair ourBaseKey = Curve.generateKeyPairForSession(2); ECKeyPair ourBaseKey = Curve.generateKeyPairForSession(2);
ECKeyPair ourEphemeralKey = Curve.generateKeyPairForSession(2); ECKeyPair ourEphemeralKey = Curve.generateKeyPairForSession(2);
ECPublicKey theirBaseKey = message.getPublicKey().getPublicKey(); ECPublicKey theirBaseKey = message.getPublicKey();
ECPublicKey theirEphemeralKey = theirBaseKey; ECPublicKey theirEphemeralKey = theirBaseKey;
IdentityKey theirIdentityKey = message.getIdentityKey(); IdentityKey theirIdentityKey = message.getIdentityKey();
IdentityKeyPair ourIdentityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret, IdentityKeyPair ourIdentityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret,