use of im.actor.core.entity.encryption.PeerSession 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.core.entity.encryption.PeerSession in project actor-platform by actorapp.
the class SessionManagerActor method spawnSession.
/**
* Spawn new session
*
* @param uid user's id
* @param ownKeyGroup own key group id
* @param theirKeyGroup their key group Id
* @param ownIdentity own identity private key
* @param theirIdentity their identity public key
* @param ownPreKey own pre key
* @param theirPreKey their pre key
* @return spawned session
*/
private PeerSession spawnSession(int uid, int ownKeyGroup, int theirKeyGroup, PrivateKey ownIdentity, PublicKey theirIdentity, PrivateKey ownPreKey, PublicKey theirPreKey) {
//
// Calculating Master Secret
//
byte[] masterSecret = RatchetMasterSecret.calculateMasterSecret(new RatchetPrivateKey(ownIdentity.getKey()), new RatchetPrivateKey(ownPreKey.getKey()), new RatchetPublicKey(theirIdentity.getPublicKey()), new RatchetPublicKey(theirPreKey.getPublicKey()));
//
// Building Session
//
PeerSession peerSession = new PeerSession(RandomUtils.nextRid(), uid, ownKeyGroup, theirKeyGroup, ownPreKey.getKeyId(), theirPreKey.getKeyId(), masterSecret);
//
// Saving session in sessions storage
//
PeerSessionsStorage sessionsStorage = peerSessions.getValue(uid);
if (sessionsStorage == null) {
sessionsStorage = new PeerSessionsStorage(uid, new ArrayList<PeerSession>());
}
sessionsStorage = sessionsStorage.addSession(peerSession);
peerSessions.addOrUpdateItem(sessionsStorage);
return peerSession;
}
use of im.actor.core.entity.encryption.PeerSession in project actor-platform by actorapp.
the class EncryptedPeerActor method doEncrypt.
private Promise<EncryptBoxResponse> doEncrypt(final byte[] data) {
if (!isReady) {
stash();
return null;
}
//
// Stage 1: Loading User Key Groups
// Stage 2: Pick sessions for encryption
// Stage 3: Encrypt box_key int session
// Stage 4: Encrypt box
//
final byte[] encKey = Crypto.randomBytes(32);
final byte[] encKeyExtended = keyPrf.calculate(encKey, "ActorPackage", 128);
Log.d(TAG, "doEncrypt");
final long start = Runtime.getActorTime();
return PromisesArray.of(theirKeys.getUserKeysGroups()).filter(new Predicate<UserKeysGroup>() {
@Override
public boolean apply(UserKeysGroup keysGroup) {
return !ignoredKeyGroups.contains(keysGroup.getKeyGroupId());
}
}).mapOptional(new Function<UserKeysGroup, Promise<SessionActor>>() {
@Override
public Promise<SessionActor> apply(final UserKeysGroup keysGroup) {
if (activeSessions.containsKey(keysGroup.getKeyGroupId())) {
return success(activeSessions.get(keysGroup.getKeyGroupId()).getSessions().get(0));
}
return context().getEncryption().getSessionManagerInt().pickSession(uid, keysGroup.getKeyGroupId()).failure(new Consumer<Exception>() {
@Override
public void apply(Exception e) {
ignoredKeyGroups.add(keysGroup.getKeyGroupId());
}
}).map(new Function<PeerSession, SessionActor>() {
@Override
public SessionActor apply(PeerSession src) {
return spawnSession(src);
}
});
}
}).mapOptional(encrypt(encKeyExtended)).zip().map(new Function<List<EncryptedSessionActor.EncryptedPackageRes>, EncryptBoxResponse>() {
@Override
public EncryptBoxResponse apply(List<EncryptedSessionActor.EncryptedPackageRes> src) {
if (src.size() == 0) {
throw new RuntimeException("No sessions available");
}
Log.d(TAG, "Keys Encrypted in " + (Runtime.getActorTime() - start) + " ms");
ArrayList<EncryptedBoxKey> encryptedKeys = new ArrayList<>();
for (EncryptedSessionActor.EncryptedPackageRes r : src) {
Log.d(TAG, "Keys: " + r.getKeyGroupId());
encryptedKeys.add(new EncryptedBoxKey(uid, r.getKeyGroupId(), "curve25519", r.getData()));
}
byte[] encData;
try {
encData = ActorBox.closeBox(ByteStrings.intToBytes(ownKeyGroupId), data, Crypto.randomBytes(32), new ActorBoxKey(encKeyExtended));
} catch (IntegrityException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
Log.d(TAG, "All Encrypted in " + (Runtime.getActorTime() - start) + " ms");
return new EncryptBoxResponse(new EncryptedBox(encryptedKeys.toArray(new EncryptedBoxKey[encryptedKeys.size()]), ByteStrings.merge(ByteStrings.intToBytes(ownKeyGroupId), encData)));
}
});
}
use of im.actor.core.entity.encryption.PeerSession in project actor-platform by actorapp.
the class UserSessions method parse.
@Override
public void parse(BserValues values) throws IOException {
uid = values.getInt(1);
sessionDescriptors = new ArrayList<>();
List<byte[]> desc = values.getRepeatedBytes(2);
for (byte[] b : desc) {
sessionDescriptors.add(new PeerSession(b));
}
}
Aggregations