@Override public void fire() { IoSession session = getSession(); NextFilter nextFilter = getNextFilter(); IoEventType type = getType(); if (DEBUG) { LOGGER.debug("Firing a {} event for session {}", type, session.getId()); } switch (type) { case MESSAGE_RECEIVED: Object parameter = getParameter(); nextFilter.messageReceived(session, parameter); break; case MESSAGE_SENT: WriteRequest writeRequest = (WriteRequest) getParameter(); nextFilter.messageSent(session, writeRequest); break; case WRITE: writeRequest = (WriteRequest) getParameter(); nextFilter.filterWrite(session, writeRequest); break; case CLOSE: nextFilter.filterClose(session); break; case EXCEPTION_CAUGHT: Throwable throwable = (Throwable) getParameter(); nextFilter.exceptionCaught(session, throwable); break; case SESSION_IDLE: nextFilter.sessionIdle(session, (IdleStatus) getParameter()); break; case SESSION_OPENED: nextFilter.sessionOpened(session); break; case SESSION_CREATED: nextFilter.sessionCreated(session); break; case SESSION_CLOSED: nextFilter.sessionClosed(session); break; default: throw new IllegalArgumentException("Unknown event type: " + type); } if (DEBUG) { LOGGER.debug("Event {} has been fired for session {}", type, session.getId()); } }
public void unwrap(NextFilter nextFilter, IoBuffer buf) { try { int len = buf.remaining(); if (len == 0) throw new AuthException("Decryption failed"); byte[] encryptedMsg = new byte[len - 6]; byte[] msgType = new byte[2]; byte[] seqNum = new byte[4]; // Get cipherMsg; msgType; sequenceNum buf.get(encryptedMsg); buf.get(msgType); buf.get(seqNum); // Decrypt message - CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg}[0..9])}) byte[] decryptedMsg; try { // Do CBC (chaining) across packets decryptedMsg = decCipher.update(encryptedMsg); // update() can return null if (decryptedMsg == null) throw new IllegalBlockSizeException("" + encryptedMsg.length); } catch (IllegalBlockSizeException e) { throw new AuthException("Illegal block sizes used with chosen cipher", e); } byte[] msgWithPadding = new byte[decryptedMsg.length - 10]; byte[] mac = new byte[10]; System.arraycopy(decryptedMsg, 0, msgWithPadding, 0, msgWithPadding.length); System.arraycopy(decryptedMsg, msgWithPadding.length, mac, 0, 10); int msgLength = msgWithPadding.length; int blockSize = decCipher.getBlockSize(); if (blockSize > 1) { // get value of last octet of the byte array msgLength -= (int) msgWithPadding[msgWithPadding.length - 1]; if (msgLength < 0) // Discard message and do not increment sequence number throw new AuthException("Decryption failed"); } byte[] msg = new byte[msgLength]; System.arraycopy(msgWithPadding, 0, msg, 0, msgLength); // Re-calculate MAC to ensure integrity byte[] expectedMac = AuthDigestMD5IoFilter.computeMACBlock(session, msg, true); byte[] fullMac = new byte[16]; System.arraycopy(mac, 0, fullMac, 0, 10); System.arraycopy(msgType, 0, fullMac, 10, 2); System.arraycopy(seqNum, 0, fullMac, 12, 4); if (isValidMAC(fullMac, expectedMac)) { IoBuffer out = IoBuffer.allocate(msgLength + LINE_TERMINATOR.length); out.put(msg); out.put(LINE_TERMINATOR); out.flip(); nextFilter.messageReceived(session, out); } } catch (Exception ex) { log.debug(ex.getMessage()); nextFilter.messageReceived(session, "\r\n"); } if (session instanceof AbstractIoSession) ((AbstractIoSession) session).increaseReadMessages(System.currentTimeMillis()); }