mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Move prekey jsonifcation into the push code, add identity key.
This commit is contained in:
parent
b8f663b69c
commit
499de2d2bf
@ -5,5 +5,6 @@ option java_outer_classname = "PreKeyProtos";
|
||||
|
||||
message PreKeyEntity {
|
||||
optional uint64 id = 1;
|
||||
optional bytes key = 2;
|
||||
optional bytes public_key = 2;
|
||||
optional bytes identity_key = 3;
|
||||
}
|
||||
|
@ -65,22 +65,6 @@ public class PreKeyUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static PreKeyList toJson(List<PreKeyRecord> records) {
|
||||
List<String> encoded = new LinkedList<String>();
|
||||
|
||||
for (PreKeyRecord record : records) {
|
||||
PreKeyEntity entity = PreKeyEntity.newBuilder().setId(record.getId())
|
||||
.setKey(ByteString.copyFrom(KeyUtil.encodePoint(record.getKeyPair().getPublicKey().getQ())))
|
||||
.build();
|
||||
|
||||
String encodedEntity = Base64.encodeBytesWithoutPadding(entity.toByteArray());
|
||||
|
||||
encoded.add(encodedEntity);
|
||||
}
|
||||
|
||||
return new PreKeyList(encoded);
|
||||
}
|
||||
|
||||
private static long getNextPreKeyId(Context context) {
|
||||
try {
|
||||
File directory = getPreKeysDirectory(context);
|
||||
|
@ -22,7 +22,7 @@ import android.util.Log;
|
||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.spongycastle.crypto.agreement.ECDHBasicAgreement;
|
||||
import org.spongycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.whispersystems.textsecure.protocol.Message;
|
||||
import org.whispersystems.textsecure.crypto.protocol.Message;
|
||||
import org.whispersystems.textsecure.storage.CanonicalRecipientAddress;
|
||||
import org.whispersystems.textsecure.storage.InvalidKeyIdException;
|
||||
import org.whispersystems.textsecure.storage.LocalKeyRecord;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* 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.protocol;
|
||||
package org.whispersystems.textsecure.crypto.protocol;
|
||||
|
||||
import android.util.Log;
|
||||
|
@ -15,9 +15,13 @@ public final class PreKeyProtos {
|
||||
boolean hasId();
|
||||
long getId();
|
||||
|
||||
// optional bytes key = 2;
|
||||
boolean hasKey();
|
||||
com.google.protobuf.ByteString getKey();
|
||||
// optional bytes public_key = 2;
|
||||
boolean hasPublicKey();
|
||||
com.google.protobuf.ByteString getPublicKey();
|
||||
|
||||
// optional bytes identity_key = 3;
|
||||
boolean hasIdentityKey();
|
||||
com.google.protobuf.ByteString getIdentityKey();
|
||||
}
|
||||
public static final class PreKeyEntity extends
|
||||
com.google.protobuf.GeneratedMessage
|
||||
@ -58,19 +62,30 @@ public final class PreKeyProtos {
|
||||
return id_;
|
||||
}
|
||||
|
||||
// optional bytes key = 2;
|
||||
public static final int KEY_FIELD_NUMBER = 2;
|
||||
private com.google.protobuf.ByteString key_;
|
||||
public boolean hasKey() {
|
||||
// optional bytes public_key = 2;
|
||||
public static final int PUBLIC_KEY_FIELD_NUMBER = 2;
|
||||
private com.google.protobuf.ByteString publicKey_;
|
||||
public boolean hasPublicKey() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
public com.google.protobuf.ByteString getKey() {
|
||||
return key_;
|
||||
public com.google.protobuf.ByteString getPublicKey() {
|
||||
return publicKey_;
|
||||
}
|
||||
|
||||
// optional bytes identity_key = 3;
|
||||
public static final int IDENTITY_KEY_FIELD_NUMBER = 3;
|
||||
private com.google.protobuf.ByteString identityKey_;
|
||||
public boolean hasIdentityKey() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public com.google.protobuf.ByteString getIdentityKey() {
|
||||
return identityKey_;
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
id_ = 0L;
|
||||
key_ = com.google.protobuf.ByteString.EMPTY;
|
||||
publicKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
@ -88,7 +103,10 @@ public final class PreKeyProtos {
|
||||
output.writeUInt64(1, id_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeBytes(2, key_);
|
||||
output.writeBytes(2, publicKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
output.writeBytes(3, identityKey_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
@ -105,7 +123,11 @@ public final class PreKeyProtos {
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(2, key_);
|
||||
.computeBytesSize(2, publicKey_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(3, identityKey_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
@ -233,8 +255,10 @@ public final class PreKeyProtos {
|
||||
super.clear();
|
||||
id_ = 0L;
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
key_ = com.google.protobuf.ByteString.EMPTY;
|
||||
publicKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -280,7 +304,11 @@ public final class PreKeyProtos {
|
||||
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
to_bitField0_ |= 0x00000002;
|
||||
}
|
||||
result.key_ = key_;
|
||||
result.publicKey_ = publicKey_;
|
||||
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
to_bitField0_ |= 0x00000004;
|
||||
}
|
||||
result.identityKey_ = identityKey_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
return result;
|
||||
@ -300,8 +328,11 @@ public final class PreKeyProtos {
|
||||
if (other.hasId()) {
|
||||
setId(other.getId());
|
||||
}
|
||||
if (other.hasKey()) {
|
||||
setKey(other.getKey());
|
||||
if (other.hasPublicKey()) {
|
||||
setPublicKey(other.getPublicKey());
|
||||
}
|
||||
if (other.hasIdentityKey()) {
|
||||
setIdentityKey(other.getIdentityKey());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
@ -341,7 +372,12 @@ public final class PreKeyProtos {
|
||||
}
|
||||
case 18: {
|
||||
bitField0_ |= 0x00000002;
|
||||
key_ = input.readBytes();
|
||||
publicKey_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
bitField0_ |= 0x00000004;
|
||||
identityKey_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -371,26 +407,50 @@ public final class PreKeyProtos {
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional bytes key = 2;
|
||||
private com.google.protobuf.ByteString key_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasKey() {
|
||||
// optional bytes public_key = 2;
|
||||
private com.google.protobuf.ByteString publicKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasPublicKey() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
public com.google.protobuf.ByteString getKey() {
|
||||
return key_;
|
||||
public com.google.protobuf.ByteString getPublicKey() {
|
||||
return publicKey_;
|
||||
}
|
||||
public Builder setKey(com.google.protobuf.ByteString value) {
|
||||
public Builder setPublicKey(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000002;
|
||||
key_ = value;
|
||||
publicKey_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearKey() {
|
||||
public Builder clearPublicKey() {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
key_ = getDefaultInstance().getKey();
|
||||
publicKey_ = getDefaultInstance().getPublicKey();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional bytes identity_key = 3;
|
||||
private com.google.protobuf.ByteString identityKey_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasIdentityKey() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public com.google.protobuf.ByteString getIdentityKey() {
|
||||
return identityKey_;
|
||||
}
|
||||
public Builder setIdentityKey(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000004;
|
||||
identityKey_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearIdentityKey() {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
identityKey_ = getDefaultInstance().getIdentityKey();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
@ -420,10 +480,10 @@ public final class PreKeyProtos {
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\022PreKeyEntity.proto\022\ntextsecure\"\'\n\014PreK" +
|
||||
"eyEntity\022\n\n\002id\030\001 \001(\004\022\013\n\003key\030\002 \001(\014B5\n%org" +
|
||||
".whispersystems.textsecure.encodedB\014PreK" +
|
||||
"eyProtos"
|
||||
"\n\022PreKeyEntity.proto\022\ntextsecure\"D\n\014PreK" +
|
||||
"eyEntity\022\n\n\002id\030\001 \001(\004\022\022\n\npublic_key\030\002 \001(\014" +
|
||||
"\022\024\n\014identity_key\030\003 \001(\014B5\n%org.whispersys" +
|
||||
"tems.textsecure.encodedB\014PreKeyProtos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@ -435,7 +495,7 @@ public final class PreKeyProtos {
|
||||
internal_static_textsecure_PreKeyEntity_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_textsecure_PreKeyEntity_descriptor,
|
||||
new java.lang.String[] { "Id", "Key", },
|
||||
new java.lang.String[] { "Id", "PublicKey", "IdentityKey", },
|
||||
org.whispersystems.textsecure.encoded.PreKeyProtos.PreKeyEntity.class,
|
||||
org.whispersystems.textsecure.encoded.PreKeyProtos.PreKeyEntity.Builder.class);
|
||||
return null;
|
||||
|
@ -1,15 +1,18 @@
|
||||
package org.whispersystems.textsecure.push;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.thoughtcrimegson.Gson;
|
||||
import org.whispersystems.textsecure.R;
|
||||
import org.whispersystems.textsecure.Release;
|
||||
import org.whispersystems.textsecure.crypto.IdentityKey;
|
||||
import org.whispersystems.textsecure.directory.DirectoryDescriptor;
|
||||
import org.whispersystems.textsecure.directory.NumberFilter;
|
||||
import org.whispersystems.textsecure.encoded.PreKeyProtos.PreKeyEntity;
|
||||
import org.whispersystems.textsecure.storage.PreKeyRecord;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
import org.whispersystems.textsecure.util.Util;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
@ -31,7 +34,6 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class PushServiceSocket {
|
||||
|
||||
@ -57,16 +59,16 @@ public class PushServiceSocket {
|
||||
this.trustManagerFactory = initializeTrustManagerFactory(context);
|
||||
}
|
||||
|
||||
public void createAccount(boolean voice) throws IOException, RateLimitException {
|
||||
public void createAccount(boolean voice) throws IOException {
|
||||
String path = voice ? CREATE_ACCOUNT_VOICE_PATH : CREATE_ACCOUNT_SMS_PATH;
|
||||
makeRequest(String.format(path, localNumber), "POST", null);
|
||||
}
|
||||
|
||||
public void verifyAccount(String verificationCode) throws IOException, RateLimitException {
|
||||
public void verifyAccount(String verificationCode) throws IOException {
|
||||
makeRequest(String.format(VERIFY_ACCOUNT_PATH, verificationCode), "PUT", null);
|
||||
}
|
||||
|
||||
public void registerGcmId(String gcmRegistrationId) throws IOException, RateLimitException {
|
||||
public void registerGcmId(String gcmRegistrationId) throws IOException {
|
||||
GcmRegistrationId registration = new GcmRegistrationId(gcmRegistrationId);
|
||||
makeRequest(REGISTER_GCM_PATH, "PUT", new Gson().toJson(registration));
|
||||
}
|
||||
@ -106,8 +108,23 @@ public class PushServiceSocket {
|
||||
throw new IOException("Got send failure: " + response.getFailure().get(0));
|
||||
}
|
||||
|
||||
public void registerPreKeys(PreKeyList keys) throws IOException {
|
||||
makeRequest(PREKEY_PATH, "PUT", new Gson().toJson(keys));
|
||||
public void registerPreKeys(IdentityKey identityKey, List<PreKeyRecord> records)
|
||||
throws IOException
|
||||
{
|
||||
List<String> encoded = new LinkedList<String>();
|
||||
|
||||
for (PreKeyRecord record : records) {
|
||||
PreKeyEntity entity = PreKeyEntity.newBuilder().setId(record.getId())
|
||||
.setPublicKey(ByteString.copyFrom(record.getEncodedPublicKey()))
|
||||
.setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
|
||||
.build();
|
||||
|
||||
String encodedEntity = Base64.encodeBytesWithoutPadding(entity.toByteArray());
|
||||
|
||||
encoded.add(encodedEntity);
|
||||
}
|
||||
|
||||
makeRequest(PREKEY_PATH, "PUT", new Gson().toJson(new PreKeyList(encoded)));
|
||||
}
|
||||
|
||||
|
||||
@ -317,7 +334,7 @@ public class PushServiceSocket {
|
||||
|
||||
private String getAuthorizationHeader() {
|
||||
try {
|
||||
return "Basic " + new String(Base64.encode((localNumber + ":" + password).getBytes("UTF-8"), Base64.NO_WRAP));
|
||||
return "Basic " + Base64.encodeBytes((localNumber + ":" + password).getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.whispersystems.textsecure.crypto.InvalidKeyException;
|
||||
import org.whispersystems.textsecure.crypto.KeyUtil;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.PreKeyPair;
|
||||
|
||||
@ -51,6 +52,10 @@ public class PreKeyRecord extends Record {
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
public byte[] getEncodedPublicKey() {
|
||||
return KeyUtil.encodePoint(keyPair.getPublicKey().getQ());
|
||||
}
|
||||
|
||||
public static boolean hasRecord(Context context, long id) {
|
||||
Log.w("PreKeyRecord", "Checking: " + id);
|
||||
return Record.hasRecord(context, PREKEY_DIRECTORY, id+"");
|
||||
|
@ -22,7 +22,6 @@ import android.content.SharedPreferences.Editor;
|
||||
import android.util.Log;
|
||||
|
||||
import org.spongycastle.asn1.ASN1Encoding;
|
||||
import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.DERInteger;
|
||||
|
@ -24,7 +24,7 @@ import org.whispersystems.textsecure.crypto.InvalidKeyException;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.PublicKey;
|
||||
import org.whispersystems.textsecure.storage.LocalKeyRecord;
|
||||
import org.whispersystems.textsecure.protocol.Message;
|
||||
import org.whispersystems.textsecure.crypto.protocol.Message;
|
||||
import org.whispersystems.textsecure.util.Base64;
|
||||
import org.whispersystems.textsecure.util.Conversions;
|
||||
|
||||
|
@ -26,7 +26,7 @@ import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.storage.LocalKeyRecord;
|
||||
import org.whispersystems.textsecure.storage.RemoteKeyRecord;
|
||||
import org.whispersystems.textsecure.storage.SessionRecord;
|
||||
import org.whispersystems.textsecure.protocol.Message;
|
||||
import org.whispersystems.textsecure.crypto.protocol.Message;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
|
@ -13,6 +13,8 @@ import android.util.Pair;
|
||||
|
||||
import com.google.android.gcm.GCMRegistrar;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||
import org.whispersystems.textsecure.crypto.IdentityKey;
|
||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.crypto.PreKeyUtil;
|
||||
import org.whispersystems.textsecure.storage.PreKeyRecord;
|
||||
@ -268,8 +270,9 @@ public class RegistrationService extends Service {
|
||||
throws GcmRegistrationTimeoutException, IOException
|
||||
{
|
||||
setState(new RegistrationState(RegistrationState.STATE_GENERATING_KEYS, number));
|
||||
IdentityKey identityKey = IdentityKeyUtil.getIdentityKey(this);
|
||||
List<PreKeyRecord> records = waitForPreKeys(masterSecret);
|
||||
socket.registerPreKeys(PreKeyUtil.toJson(records));
|
||||
socket.registerPreKeys(identityKey, records);
|
||||
|
||||
setState(new RegistrationState(RegistrationState.STATE_GCM_REGISTERING, number));
|
||||
GCMRegistrar.register(this, GcmIntentService.GCM_SENDER_ID);
|
||||
|
Loading…
Reference in New Issue
Block a user