List of usage examples for javax.crypto Cipher update
public final byte[] update(byte[] input)
From source file:org.red5.server.net.rtmpe.RTMPEIoFilter.java
@Override public void messageReceived(NextFilter nextFilter, IoSession session, Object obj) throws Exception { log.trace("messageReceived nextFilter: {} session: {} message: {}", nextFilter, session, obj); String sessionId = (String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID); if (sessionId != null) { log.trace("Session id: {}", sessionId); RTMPMinaConnection conn = (RTMPMinaConnection) RTMPConnManager.getInstance() .getConnectionBySessionId(sessionId); // filter based on current connection state RTMP rtmp = conn.getState();// w ww.j a v a 2 s.c o m final byte connectionState = conn.getStateCode(); // assume message is an IoBuffer IoBuffer message = (IoBuffer) obj; // client handshake handling InboundHandshake handshake = null; int remaining = 0; switch (connectionState) { case RTMP.STATE_CONNECT: // we're expecting C0+C1 here //log.trace("C0C1 byte order: {}", message.order()); // get the handshake from the session handshake = (InboundHandshake) session.getAttribute(RTMPConnection.RTMP_HANDSHAKE); // set handshake to match client requested type message.mark(); handshake.setHandshakeType(message.get()); message.reset(); log.debug("decodeHandshakeC0C1 - buffer: {}", message); // we want 1537 bytes for C0C1 remaining = message.remaining(); log.trace("Incoming C0C1 size: {}", remaining); if (remaining >= (Constants.HANDSHAKE_SIZE + 1)) { // get the connection type byte, may want to set this on the conn in the future byte connectionType = message.get(); log.trace("Incoming C0 connection type: {}", connectionType); // create array for decode byte[] dst = new byte[Constants.HANDSHAKE_SIZE]; // copy out 1536 bytes message.get(dst); //log.debug("C1 - buffer: {}", Hex.encodeHexString(dst)); // set state to indicate we're waiting for C2 rtmp.setState(RTMP.STATE_HANDSHAKE); // buffer any extra bytes remaining = message.remaining(); if (log.isTraceEnabled()) { log.trace("Incoming C1 remaining size: {}", remaining); } if (remaining > 0) { // store the remaining bytes in a thread local for use by C2 decoding byte[] remainder = new byte[remaining]; message.get(remainder); session.setAttribute("handshake.buffer", remainder); log.trace("Stored {} bytes for later decoding", remaining); } IoBuffer s1 = handshake.decodeClientRequest1(IoBuffer.wrap(dst)); if (s1 != null) { //log.trace("S1 byte order: {}", s1.order()); session.write(s1); } else { log.warn("Client was rejected due to invalid handshake"); conn.close(); } } break; case RTMP.STATE_HANDSHAKE: // we're expecting C2 here //log.trace("C2 byte order: {}", message.order()); // get the handshake from the session handshake = (InboundHandshake) session.getAttribute(RTMPConnection.RTMP_HANDSHAKE); log.debug("decodeHandshakeC2 - buffer: {}", message); remaining = message.remaining(); // check for remaining stored bytes left over from C0C1 byte[] remainder = null; if (session.containsAttribute("handshake.buffer")) { remainder = (byte[]) session.getAttribute("handshake.buffer"); remaining += remainder.length; log.trace("Remainder: {}", Hex.encodeHexString(remainder)); } // no connection type byte is supposed to be in C2 data log.trace("Incoming C2 size: {}", remaining); if (remaining >= Constants.HANDSHAKE_SIZE) { // create array for decode byte[] dst = new byte[Constants.HANDSHAKE_SIZE]; // check for remaining stored bytes left over from C0C1 and prepend to the dst array if (remainder != null) { // copy into dst System.arraycopy(remainder, 0, dst, 0, remainder.length); log.trace("Copied {} from buffer {}", remainder.length, Hex.encodeHexString(dst)); // copy message.get(dst, remainder.length, (Constants.HANDSHAKE_SIZE - remainder.length)); log.trace("Copied {} from message {}", (Constants.HANDSHAKE_SIZE - remainder.length), Hex.encodeHexString(dst)); // remove buffer session.removeAttribute("handshake.buffer"); } else { // copy message.get(dst); log.trace("Copied {}", Hex.encodeHexString(dst)); } //if (log.isTraceEnabled()) { // log.trace("C2 - buffer: {}", Hex.encodeHexString(dst)); //} if (handshake.decodeClientRequest2(IoBuffer.wrap(dst))) { log.debug("Connected, removing handshake data and adding rtmp protocol filter"); // set state to indicate we're connected rtmp.setState(RTMP.STATE_CONNECTED); // set encryption flag the rtmp state if (handshake.useEncryption()) { log.debug("Using encrypted communications, adding ciphers to the session"); rtmp.setEncrypted(true); session.setAttribute(RTMPConnection.RTMPE_CIPHER_IN, handshake.getCipherIn()); session.setAttribute(RTMPConnection.RTMPE_CIPHER_OUT, handshake.getCipherOut()); } // remove handshake from session now that we are connected session.removeAttribute(RTMPConnection.RTMP_HANDSHAKE); // add protocol filter as the last one in the chain log.debug("Adding RTMP protocol filter"); session.getFilterChain().addAfter("rtmpeFilter", "protocolFilter", new ProtocolCodecFilter(new RTMPMinaCodecFactory())); } else { log.warn("Client was rejected due to invalid handshake"); conn.close(); break; } } // no break here if there are still message bytes if (!message.hasRemaining()) { break; } case RTMP.STATE_CONNECTED: // assuming majority of connections will not be encrypted if (!rtmp.isEncrypted()) { log.trace("Receiving message: {}", message); nextFilter.messageReceived(session, message); } else { Cipher cipher = (Cipher) session.getAttribute(RTMPConnection.RTMPE_CIPHER_IN); if (cipher != null) { if (log.isDebugEnabled()) { log.debug("Decrypting message: {}", message); } byte[] encrypted = new byte[message.remaining()]; message.get(encrypted); message.clear(); message.free(); byte[] plain = cipher.update(encrypted); IoBuffer messageDecrypted = IoBuffer.wrap(plain); if (log.isDebugEnabled()) { log.debug("Receiving decrypted message: {}", messageDecrypted); } nextFilter.messageReceived(session, messageDecrypted); } } break; case RTMP.STATE_ERROR: case RTMP.STATE_DISCONNECTING: case RTMP.STATE_DISCONNECTED: // do nothing, really log.debug("Nothing to do, connection state: {}", RTMP.states[connectionState]); break; default: throw new IllegalStateException("Invalid RTMP state: " + connectionState); } } }
From source file:org.red5.server.net.rtmpe.RTMPEIoFilter.java
@Override public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest request) throws Exception { log.trace("filterWrite nextFilter: {} session: {} request: {}", nextFilter, session, request); RTMPMinaConnection conn = (RTMPMinaConnection) RTMPConnManager.getInstance() .getConnectionBySessionId((String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID)); if (conn.getState().isEncrypted()) { Cipher cipher = (Cipher) session.getAttribute(RTMPConnection.RTMPE_CIPHER_OUT); IoBuffer message = (IoBuffer) request.getMessage(); if (!message.hasRemaining()) { if (log.isTraceEnabled()) { log.trace("Ignoring empty message"); }//from www. j a v a 2 s . co m } else { if (log.isDebugEnabled()) { log.debug("Encrypting message: {}", message); } byte[] plain = new byte[message.remaining()]; message.get(plain); message.clear(); message.free(); //encrypt and write byte[] encrypted = cipher.update(plain); IoBuffer messageEncrypted = IoBuffer.wrap(encrypted); if (log.isDebugEnabled()) { log.debug("Writing encrypted message: {}", messageEncrypted); } nextFilter.filterWrite(session, new EncryptedWriteRequest(request, messageEncrypted)); } } else { log.trace("Writing message"); nextFilter.filterWrite(session, request); } }