Search in sources :

Example 1 with ProtoStruct

use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.

the class AuthKeyActor method onMessage.

private void onMessage(int connectionId, byte[] data, int offset, int len) {
    if (connectionId != this.connectionId) {
        Log.d(TAG, "Too old: ignoring");
        return;
    }
    ProtoStruct protoStruct;
    try {
        DataInput dataInput = new DataInput(data, offset, len);
        ProtoPackage protoPackage = new ProtoPackage(dataInput);
        if (protoPackage.getAuthId() != 0) {
            throw new IOException("AuthId != 0");
        }
        if (protoPackage.getSessionId() != 0) {
            throw new IOException("Session != 0");
        }
        if (protoPackage.getPayload().getMessageId() != 0) {
            throw new IOException("MessageId != 0");
        }
        protoStruct = ProtoSerializer.readMessagePayload(protoPackage.getPayload().getPayload());
    } catch (IOException e) {
        e.printStackTrace();
        crashConnection();
        return;
    }
    try {
        if (currentState == null) {
            throw new IOException();
        }
        currentState.onMessage(protoStruct);
    } catch (Exception e) {
        e.printStackTrace();
        crashConnection();
    }
}
Also used : DataInput(im.actor.runtime.bser.DataInput) ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) ProtoPackage(im.actor.core.network.mtp.entity.ProtoPackage) IOException(java.io.IOException) IOException(java.io.IOException)

Example 2 with ProtoStruct

use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.

the class AuthKeyActor method gotoDHState.

private void gotoDHState(final long keyId, final byte[] key, final byte[] serverNonce) {
    final byte[] clientNonce = new byte[32];
    Crypto.nextBytes(clientNonce);
    byte[] keyMaterial = new byte[32];
    Crypto.nextBytes(keyMaterial);
    final Curve25519KeyPair clientKeyPair = Curve25519.keyGen(keyMaterial);
    goToState(new ActorState() {

        @Override
        public ProtoStruct sendStartMessage() throws IOException {
            Log.d(TAG, "Sending RequestDH");
            return new RequestDH(randomId, keyId, clientNonce, clientKeyPair.getPublicKey());
        }

        @Override
        public void onMessage(ProtoStruct struct) throws IOException {
            if (struct instanceof ResponseDoDH) {
                Log.d(TAG, "Received ResponseDoDH");
                ResponseDoDH r = (ResponseDoDH) struct;
                if (r.getRandomId() != randomId) {
                    throw new IOException("Incorrect RandomId");
                }
                PRF combinedPrf = Cryptos.PRF_SHA_STREEBOG_256();
                byte[] nonce = ByteStrings.merge(clientNonce, serverNonce);
                byte[] pre_master_secret = Curve25519.calculateAgreement(clientKeyPair.getPrivateKey(), key);
                byte[] master_secret = combinedPrf.calculate(pre_master_secret, "master secret", nonce, 256);
                byte[] verify = combinedPrf.calculate(master_secret, "client finished", nonce, 256);
                if (!Curve25519.verifySignature(key, verify, r.getVerifySign())) {
                    throw new IOException("Incorrect Signature");
                }
                Digest sha256 = Crypto.createSHA256();
                sha256.update(master_secret, 0, master_secret.length);
                byte[] authIdHash = new byte[32];
                sha256.doFinal(authIdHash, 0);
                long authId = ByteStrings.bytesToLong(authIdHash);
                Log.d(TAG, "Key successfully created #" + authId);
                gotoSuccess(master_secret, authId);
            } else {
                throw new IOException("Expected: ResponseGetServerKey, got: " + struct.getClass().getName());
            }
        }
    });
}
Also used : ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) PRF(im.actor.runtime.crypto.primitives.prf.PRF) Digest(im.actor.runtime.crypto.Digest) Curve25519KeyPair(im.actor.runtime.crypto.Curve25519KeyPair) IOException(java.io.IOException) ResponseDoDH(im.actor.core.network.mtp.entity.ResponseDoDH) RequestDH(im.actor.core.network.mtp.entity.RequestDH)

Example 3 with ProtoStruct

use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.

the class ReceiverActor method onReceive.

private void onReceive(ProtoMessage message) {
    sender.send(new PusherActor.ReadPackageFromConnection());
    boolean disableConfirm = false;
    try {
        if (receivedMessages.size() >= MAX_RECEIVED_BUFFER) {
            receivedMessages.remove(0);
        }
        receivedMessages.add(message.getMessageId());
        ProtoStruct obj;
        try {
            obj = ProtoSerializer.readMessagePayload(message.getPayload());
        } catch (IOException e) {
            Log.w(TAG, "Unable to parse message: ignoring");
            e.printStackTrace();
            return;
        }
        if (obj instanceof NewSessionCreated) {
            NewSessionCreated newSessionCreated = (NewSessionCreated) obj;
            sender.send(new PusherActor.NewSession(newSessionCreated.getMessageId()));
            proto.getCallback().onSessionCreated();
        } else if (obj instanceof Container) {
            Container container = (Container) obj;
            for (ProtoMessage m : container.getMessages()) {
                self().send(m, sender());
            }
        } else if (obj instanceof SessionLost) {
            sender.send(new PusherActor.SessionLost());
        } else if (obj instanceof MTRpcResponse) {
            MTRpcResponse responseBox = (MTRpcResponse) obj;
            // Forget messages
            sender.send(new PusherActor.ForgetMessage(responseBox.getMessageId(), true));
            proto.getCallback().onRpcResponse(responseBox.getMessageId(), responseBox.getPayload());
        } else if (obj instanceof MessageAck) {
            MessageAck ack = (MessageAck) obj;
            for (long ackMsgId : ack.messagesIds) {
                sender.send(new PusherActor.ForgetMessage(ackMsgId, false));
            }
        } else if (obj instanceof MTPush) {
            MTPush box = (MTPush) obj;
            proto.getCallback().onUpdate(box.getPayload());
        } else if (obj instanceof UnsentResponse) {
            UnsentResponse unsent = (UnsentResponse) obj;
            if (!receivedMessages.contains(unsent.getResponseMessageId())) {
                disableConfirm = true;
                sender.send(new PusherActor.SendMessage(MTUids.nextId(), new RequestResend(unsent.getMessageId()).toByteArray(), true));
            }
        } else if (obj instanceof UnsentMessage) {
            UnsentMessage unsent = (UnsentMessage) obj;
            if (!receivedMessages.contains(unsent.getMessageId())) {
                disableConfirm = true;
                sender.send(new PusherActor.SendMessage(MTUids.nextId(), new RequestResend(unsent.getMessageId()).toByteArray(), false));
            }
        } else if (obj instanceof AuthIdInvalid) {
            proto.getCallback().onAuthKeyInvalidated(proto.getAuthId());
            proto.stopProto();
        } else {
            Log.w(TAG, "Unsupported package " + obj);
        }
    } catch (Exception e) {
        Log.w(TAG, "Parsing error");
    } finally {
        if (!disableConfirm) {
            sender.send(new PusherActor.ConfirmMessage(message.getMessageId()));
        }
    }
}
Also used : MTRpcResponse(im.actor.core.network.mtp.entity.MTRpcResponse) MTPush(im.actor.core.network.mtp.entity.MTPush) NewSessionCreated(im.actor.core.network.mtp.entity.NewSessionCreated) Container(im.actor.core.network.mtp.entity.Container) ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) AuthIdInvalid(im.actor.core.network.mtp.entity.AuthIdInvalid) ProtoMessage(im.actor.core.network.mtp.entity.ProtoMessage) UnsentResponse(im.actor.core.network.mtp.entity.UnsentResponse) MessageAck(im.actor.core.network.mtp.entity.MessageAck) UnsentMessage(im.actor.core.network.mtp.entity.UnsentMessage) IOException(java.io.IOException) IOException(java.io.IOException) RequestResend(im.actor.core.network.mtp.entity.RequestResend) SessionLost(im.actor.core.network.mtp.entity.SessionLost)

Example 4 with ProtoStruct

use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.

the class ApiBroker method processUpdate.

private void processUpdate(long authId, byte[] content) {
    if (authId != currentAuthId) {
        return;
    }
    ProtoStruct protoStruct;
    try {
        protoStruct = ProtoSerializer.readUpdate(content);
    } catch (IOException e) {
        e.printStackTrace();
        Log.w(TAG, "Broken mt update");
        return;
    }
    int type = ((Push) protoStruct).updateType;
    byte[] body = ((Push) protoStruct).body;
    RpcScope updateBox;
    try {
        updateBox = parserConfig.parseRpc(type, body);
    } catch (IOException e) {
        e.printStackTrace();
        Log.w(TAG, "Broken update box");
        return;
    }
    // Log.w(TAG, "Box: " + updateBox + "");
    callback.onUpdateReceived(updateBox);
}
Also used : ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) RpcScope(im.actor.core.network.parser.RpcScope) IOException(java.io.IOException) Push(im.actor.core.network.mtp.entity.rpc.Push)

Example 5 with ProtoStruct

use of im.actor.core.network.mtp.entity.ProtoStruct in project actor-platform by actorapp.

the class ApiBroker method processResponse.

private void processResponse(long authId, long mid, byte[] content) {
    if (authId != currentAuthId) {
        return;
    }
    ProtoStruct protoStruct;
    try {
        protoStruct = ProtoSerializer.readRpcResponsePayload(content);
    } catch (IOException e) {
        e.printStackTrace();
        Log.w(TAG, "Broken response mid#" + mid);
        return;
    }
    // Log.w(TAG, protoStruct + " mid#" + mid);
    long rid;
    if (idMap.containsKey(mid)) {
        rid = idMap.get(mid);
    } else {
        return;
    }
    CommonTimer timer = timeouts.get(rid);
    if (timer != null) {
        timer.cancel();
        timeouts.remove(rid);
    }
    RequestHolder holder;
    if (requests.containsKey(rid)) {
        holder = requests.get(rid);
    } else {
        return;
    }
    if (protoStruct instanceof RpcOk) {
        RpcOk ok = (RpcOk) protoStruct;
        requests.remove(rid);
        if (holder.protoId != 0) {
            idMap.remove(holder.protoId);
        }
        Response response;
        try {
            response = (Response) parserConfig.parseRpc(ok.responseType, ok.payload);
        } catch (IOException e) {
            e.printStackTrace();
            requests.remove(rid);
            if (holder.protoId != 0) {
                idMap.remove(holder.protoId);
            }
            holder.callback.onError(new RpcInternalException());
            return;
        }
        Log.d(TAG, "<- response#" + holder.publicId + ": " + response + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
        holder.callback.onResult(response);
    } else if (protoStruct instanceof RpcError) {
        RpcError e = (RpcError) protoStruct;
        requests.remove(rid);
        if (holder.protoId != 0) {
            idMap.remove(holder.protoId);
        }
        Log.w(TAG, "<- error#" + holder.publicId + ": " + e.errorTag + " " + e.errorCode + " " + e.userMessage + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
        holder.callback.onError(new RpcException(e.errorTag, e.errorCode, e.userMessage, e.canTryAgain, e.relatedData));
    } else if (protoStruct instanceof RpcInternalError) {
        RpcInternalError e = ((RpcInternalError) protoStruct);
        Log.d(TAG, "<- internal_error#" + holder.publicId + " " + e.getTryAgainDelay() + " sec" + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
        if (e.isCanTryAgain()) {
            schedule(new ForceResend(rid), e.getTryAgainDelay() * 1000L);
        } else {
            requests.remove(rid);
            if (holder.protoId != 0) {
                idMap.remove(holder.protoId);
            }
            holder.callback.onError(new RpcInternalException());
        }
    } else if (protoStruct instanceof RpcFloodWait) {
        RpcFloodWait f = (RpcFloodWait) protoStruct;
        Log.d(TAG, "<- flood_wait#" + holder.publicId + " " + f.getDelay() + " sec" + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
        schedule(new ForceResend(rid), f.getDelay() * 1000L);
    } else {
        Log.d(TAG, "<- unknown_package#" + holder.publicId + " in " + (Runtime.getCurrentTime() - holder.requestTime) + " ms");
    }
}
Also used : RpcError(im.actor.core.network.mtp.entity.rpc.RpcError) CommonTimer(im.actor.runtime.threading.CommonTimer) IOException(java.io.IOException) RpcInternalError(im.actor.core.network.mtp.entity.rpc.RpcInternalError) Response(im.actor.core.network.parser.Response) ProtoStruct(im.actor.core.network.mtp.entity.ProtoStruct) RpcOk(im.actor.core.network.mtp.entity.rpc.RpcOk) RpcFloodWait(im.actor.core.network.mtp.entity.rpc.RpcFloodWait)

Aggregations

ProtoStruct (im.actor.core.network.mtp.entity.ProtoStruct)7 IOException (java.io.IOException)7 ProtoMessage (im.actor.core.network.mtp.entity.ProtoMessage)3 ProtoPackage (im.actor.core.network.mtp.entity.ProtoPackage)3 AuthIdInvalid (im.actor.core.network.mtp.entity.AuthIdInvalid)1 Container (im.actor.core.network.mtp.entity.Container)1 MTPush (im.actor.core.network.mtp.entity.MTPush)1 MTRpcResponse (im.actor.core.network.mtp.entity.MTRpcResponse)1 MessageAck (im.actor.core.network.mtp.entity.MessageAck)1 NewSessionCreated (im.actor.core.network.mtp.entity.NewSessionCreated)1 RequestDH (im.actor.core.network.mtp.entity.RequestDH)1 RequestResend (im.actor.core.network.mtp.entity.RequestResend)1 ResponseDoDH (im.actor.core.network.mtp.entity.ResponseDoDH)1 SessionLost (im.actor.core.network.mtp.entity.SessionLost)1 UnsentMessage (im.actor.core.network.mtp.entity.UnsentMessage)1 UnsentResponse (im.actor.core.network.mtp.entity.UnsentResponse)1 Push (im.actor.core.network.mtp.entity.rpc.Push)1 RpcError (im.actor.core.network.mtp.entity.rpc.RpcError)1 RpcFloodWait (im.actor.core.network.mtp.entity.rpc.RpcFloodWait)1 RpcInternalError (im.actor.core.network.mtp.entity.rpc.RpcInternalError)1