use of im.actor.runtime.function.Tuple2 in project actor-platform by actorapp.
the class EncryptedPeerActor method doDecrypt.
private Promise<DecryptBoxResponse> doDecrypt(final EncryptedBox data) {
if (!isReady) {
stash();
return null;
}
final int senderKeyGroup = ByteStrings.bytesToInt(ByteStrings.substring(data.getEncryptedPackage(), 0, 4));
final byte[] encPackage = ByteStrings.substring(data.getEncryptedPackage(), 4, data.getEncryptedPackage().length - 4);
if (ignoredKeyGroups.contains(senderKeyGroup)) {
throw new RuntimeException("This key group is ignored");
}
return PromisesArray.of(data.getKeys()).filter(EncryptedBoxKey.FILTER(myUid(), ownKeyGroupId)).first().flatMap(new Function<EncryptedBoxKey, Promise<Tuple2<SessionActor, EncryptedBoxKey>>>() {
@Override
public Promise<Tuple2<SessionActor, EncryptedBoxKey>> apply(final EncryptedBoxKey boxKey) {
final long senderPreKeyId = ByteStrings.bytesToLong(boxKey.getEncryptedKey(), 4);
final long receiverPreKeyId = ByteStrings.bytesToLong(boxKey.getEncryptedKey(), 12);
if (activeSessions.containsKey(boxKey.getKeyGroupId())) {
for (SessionActor s : activeSessions.get(senderKeyGroup).getSessions()) {
if (s.getSession().getOwnPreKeyId() == receiverPreKeyId && s.getSession().getTheirPreKeyId() == senderPreKeyId) {
return success(new Tuple2<>(s, boxKey));
}
}
}
return context().getEncryption().getSessionManagerInt().pickSession(uid, senderKeyGroup, receiverPreKeyId, senderPreKeyId).map(new Function<PeerSession, Tuple2<SessionActor, EncryptedBoxKey>>() {
@Override
public Tuple2<SessionActor, EncryptedBoxKey> apply(PeerSession src) {
return new Tuple2<>(spawnSession(src), boxKey);
}
});
}
}).flatMap(new Function<Tuple2<SessionActor, EncryptedBoxKey>, Promise<EncryptedSessionActor.DecryptedPackage>>() {
@Override
public Promise<EncryptedSessionActor.DecryptedPackage> apply(Tuple2<SessionActor, EncryptedBoxKey> src) {
Log.d(TAG, "Key size:" + src.getT2().getEncryptedKey().length);
// TODO: Implement
return null;
}
}).map(new Function<EncryptedSessionActor.DecryptedPackage, DecryptBoxResponse>() {
@Override
public DecryptBoxResponse apply(EncryptedSessionActor.DecryptedPackage decryptedPackage) {
byte[] encData;
try {
byte[] encKeyExtended = decryptedPackage.getData().length >= 128 ? decryptedPackage.getData() : keyPrf.calculate(decryptedPackage.getData(), "ActorPackage", 128);
encData = ActorBox.openBox(ByteStrings.intToBytes(senderKeyGroup), encPackage, new ActorBoxKey(encKeyExtended));
Log.d(TAG, "Box size: " + encData.length);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return new DecryptBoxResponse(encData);
}
});
}
use of im.actor.runtime.function.Tuple2 in project actor-platform by actorapp.
the class KeyManagerActor method fetchUserPreKey.
/**
* Fetching user's random pre key
*
* @param uid User's id
* @param keyGroupId User's key group id
*/
private Promise<PublicKey> fetchUserPreKey(final int uid, final int keyGroupId) {
return pickUserGroup(uid, keyGroupId).flatMap(new Function<Tuple2<UserKeysGroup, UserKeys>, Promise<PublicKey>>() {
@Override
public Promise<PublicKey> apply(final Tuple2<UserKeysGroup, UserKeys> keyGroups) {
return api(new RequestLoadPrePublicKeys(new ApiUserOutPeer(uid, getUser(uid).getAccessHash()), keyGroupId)).map(new Function<ResponsePublicKeys, PublicKey>() {
@Override
public PublicKey apply(ResponsePublicKeys response) {
if (response.getPublicKey().size() == 0) {
throw new RuntimeException("User doesn't have pre keys");
}
ApiEncryptionKey key = response.getPublicKey().get(0);
ApiEncryptionKeySignature sig = null;
for (ApiEncryptionKeySignature s : response.getSignatures()) {
if (s.getKeyId() == key.getKeyId() && "Ed25519".equals(s.getSignatureAlg())) {
sig = s;
break;
}
}
if (sig == null) {
throw new RuntimeException("Unable to find public key on server");
}
byte[] keyHash = RatchetKeySignature.hashForSignature(key.getKeyId(), key.getKeyAlg(), key.getKeyMaterial());
if (!Curve25519.verifySignature(keyGroups.getT1().getIdentityKey().getPublicKey(), keyHash, sig.getSignature())) {
throw new RuntimeException("Key signature does not isMatch");
}
return new PublicKey(key.getKeyId(), key.getKeyAlg(), key.getKeyMaterial());
}
});
}
});
}
use of im.actor.runtime.function.Tuple2 in project actor-platform by actorapp.
the class KeyManagerActor method fetchUserPreKey.
/**
* Fetching user's pre key by key id
*
* @param uid User's id
* @param keyGroupId User's key group id
* @param keyId Key id
*/
private Promise<PublicKey> fetchUserPreKey(final int uid, final int keyGroupId, final long keyId) {
User user = users().getValue(uid);
if (user == null) {
throw new RuntimeException("Unable to find user #" + uid);
}
return pickUserGroup(uid, keyGroupId).flatMap(new Function<Tuple2<UserKeysGroup, UserKeys>, Promise<PublicKey>>() {
@Override
public Promise<PublicKey> apply(final Tuple2<UserKeysGroup, UserKeys> keysGroup) {
for (PublicKey p : keysGroup.getT1().getEphemeralKeys()) {
if (p.getKeyId() == keyId) {
return Promise.success(p);
}
}
//
// Downloading pre key
//
ArrayList<Long> ids = new ArrayList<Long>();
ids.add(keyId);
final UserKeysGroup finalKeysGroup = keysGroup.getT1();
return api(new RequestLoadPublicKey(new ApiUserOutPeer(uid, getUser(uid).getAccessHash()), keyGroupId, ids)).map(new Function<ResponsePublicKeys, PublicKey>() {
@Override
public PublicKey apply(ResponsePublicKeys responsePublicKeys) {
if (responsePublicKeys.getPublicKey().size() == 0) {
throw new RuntimeException("Unable to find public key on server");
}
ApiEncryptionKeySignature sig = null;
for (ApiEncryptionKeySignature s : responsePublicKeys.getSignatures()) {
if (s.getKeyId() == keyId && "Ed25519".equals(s.getSignatureAlg())) {
sig = s;
break;
}
}
if (sig == null) {
throw new RuntimeException("Unable to find public key on server");
}
ApiEncryptionKey key = responsePublicKeys.getPublicKey().get(0);
byte[] keyHash = RatchetKeySignature.hashForSignature(key.getKeyId(), key.getKeyAlg(), key.getKeyMaterial());
if (!Curve25519.verifySignature(keysGroup.getT1().getIdentityKey().getPublicKey(), keyHash, sig.getSignature())) {
throw new RuntimeException("Key signature does not isMatch");
}
PublicKey pkey = new PublicKey(keyId, key.getKeyAlg(), key.getKeyMaterial());
UserKeysGroup userKeysGroup = finalKeysGroup.addPublicKey(pkey);
cacheUserKeys(keysGroup.getT2().removeUserKeyGroup(userKeysGroup.getKeyGroupId()).addUserKeyGroup(userKeysGroup));
return pkey;
}
});
}
});
}
use of im.actor.runtime.function.Tuple2 in project actor-platform by actorapp.
the class UserRouter method onLoadFullUser.
//
// Users changed
//
@Verified
private void onLoadFullUser(int uid) {
if (requestedFullUsers.contains(uid)) {
return;
}
requestedFullUsers.add(uid);
freeze();
users().getValueAsync(uid).flatMap((Function<User, Promise<Tuple2<ResponseLoadFullUsers, User>>>) u -> {
if (!u.isHaveExtension()) {
ArrayList<ApiUserOutPeer> users = new ArrayList<>();
users.add(new ApiUserOutPeer(u.getUid(), u.getAccessHash()));
return api(new RequestLoadFullUsers(users)).map(responseLoadFullUsers -> new Tuple2<>(responseLoadFullUsers, u));
} else {
if (!getUserVM(uid).isInPhoneBook().get()) {
return checkIsInPhoneBook(u).flatMap(new Function<Void, Promise<Tuple2<ResponseLoadFullUsers, User>>>() {
@Override
public Promise<Tuple2<ResponseLoadFullUsers, User>> apply(Void aVoid) {
return Promise.failure(new RuntimeException("Already loaded"));
}
});
} else {
return Promise.failure(new RuntimeException("Already loaded"));
}
}
}).then(r -> {
User upd = r.getT2().updateExt(r.getT1().getFullUsers().get(0));
users().addOrUpdateItem(upd);
}).chain(r -> checkIsInPhoneBook(r.getT2().updateExt(r.getT1().getFullUsers().get(0)))).after((r, e) -> unfreeze());
}
Aggregations