⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslhandler.java

📁 apache 的一个socket框架
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    /**     * Start SSL shutdown process.     *     * @return <tt>true</tt> if shutdown process is started.     *         <tt>false</tt> if shutdown process is already finished.     *     * @throws SSLException on errors     */    public boolean closeOutbound() throws SSLException {        if (sslEngine == null || sslEngine.isOutboundDone()) {            return false;        }        sslEngine.closeOutbound();        // By RFC 2616, we can "fire and forget" our close_notify        // message, so that's what we'll do here.        outNetBuffer.clear();        SSLEngineResult result = sslEngine.wrap(hsBB, outNetBuffer);        if (result.getStatus() != SSLEngineResult.Status.CLOSED) {            throw new SSLException("Improper close state: " + result);        }        outNetBuffer.flip();        return true;    }    /**     * Decrypt in net buffer. Result is stored in app buffer.     *     * @throws SSLException     */    private void decrypt() throws SSLException {        if (!initialHandshakeComplete) {            throw new IllegalStateException();        }        if (appBuffer.hasRemaining()) {            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, " Error: appBuffer not empty!");            }            //still app data in buffer!?            throw new IllegalStateException();        }        unwrap();    }    /**     * @param status     * @throws SSLException     */    private SSLEngineResult.Status checkStatus(SSLEngineResult.Status status)            throws SSLException {        if (status != SSLEngineResult.Status.OK                && status != SSLEngineResult.Status.CLOSED                && status != SSLEngineResult.Status.BUFFER_UNDERFLOW) {            throw new SSLException("SSLEngine error during decrypt: " + status                    + " inNetBuffer: " + inNetBuffer + "appBuffer: "                    + appBuffer);        }        return status;    }    /**     * Perform any handshaking processing.     */    public void handshake(NextFilter nextFilter) throws SSLException {        if (SessionLog.isDebugEnabled(session)) {            SessionLog.debug(session, " doHandshake()");        }        while (!initialHandshakeComplete) {            if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED) {                session.setAttribute(SSLFilter.SSL_SESSION, sslEngine                        .getSession());                if (SessionLog.isDebugEnabled(session)) {                    SSLSession sslSession = sslEngine.getSession();                    SessionLog.debug(session,                            "  initialHandshakeStatus=FINISHED");                    SessionLog.debug(session, "  sslSession CipherSuite used "                            + sslSession.getCipherSuite());                }                initialHandshakeComplete = true;                if (session.containsAttribute(SSLFilter.USE_NOTIFICATION)) {                    scheduleMessageReceived(nextFilter,                            SSLFilter.SESSION_SECURED);                }                break;            } else if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) {                if (SessionLog.isDebugEnabled(session)) {                    SessionLog.debug(session,                            "  initialHandshakeStatus=NEED_TASK");                }                initialHandshakeStatus = doTasks();            } else if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {                // we need more data read                if (SessionLog.isDebugEnabled(session)) {                    SessionLog.debug(session,                            "  initialHandshakeStatus=NEED_UNWRAP");                }                SSLEngineResult.Status status = unwrapHandshake();                if ((initialHandshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED && status == SSLEngineResult.Status.BUFFER_UNDERFLOW)                        || isInboundDone()) {                    // We need more data or the session is closed                    break;                }            } else if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP) {                if (SessionLog.isDebugEnabled(session)) {                    SessionLog.debug(session,                            "  initialHandshakeStatus=NEED_WRAP");                }                // First make sure that the out buffer is completely empty. Since we                // cannot call wrap with data left on the buffer                if (outNetBuffer.hasRemaining()) {                    if (SessionLog.isDebugEnabled(session)) {                        SessionLog                                .debug(session, "  Still data in out buffer!");                    }                    break;                }                outNetBuffer.clear();                SSLEngineResult result = sslEngine.wrap(hsBB, outNetBuffer);                if (SessionLog.isDebugEnabled(session)) {                    SessionLog.debug(session, " Wrap res:" + result);                }                outNetBuffer.flip();                initialHandshakeStatus = result.getHandshakeStatus();                writeNetBuffer(nextFilter);            } else {                throw new IllegalStateException("Invalid Handshaking State"                        + initialHandshakeStatus);            }        }    }    public WriteFuture writeNetBuffer(NextFilter nextFilter)            throws SSLException {        // Check if any net data needed to be writen        if (!getOutNetBuffer().hasRemaining()) {            // no; bail out            return DefaultWriteFuture.newNotWrittenFuture(session);        }        // set flag that we are writing encrypted data        // (used in SSLFilter.filterWrite())        writingEncryptedData = true;        // write net data        WriteFuture writeFuture = null;        try {            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, " write outNetBuffer: "                        + getOutNetBuffer());            }            org.apache.mina.common.ByteBuffer writeBuffer = copy(getOutNetBuffer());            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, " session write: " + writeBuffer);            }            //debug("outNetBuffer (after copy): {0}", sslHandler.getOutNetBuffer());            writeFuture = new DefaultWriteFuture(session);            parent.filterWrite(nextFilter, session, new WriteRequest(                    writeBuffer, writeFuture));            // loop while more writes required to complete handshake            while (needToCompleteInitialHandshake()) {                try {                    handshake(nextFilter);                } catch (SSLException ssle) {                    SSLException newSSLE = new SSLHandshakeException(                            "Initial SSL handshake failed.");                    newSSLE.initCause(ssle);                    throw newSSLE;                }                if (getOutNetBuffer().hasRemaining()) {                    if (SessionLog.isDebugEnabled(session)) {                        SessionLog.debug(session, " write outNetBuffer2: "                                + getOutNetBuffer());                    }                    org.apache.mina.common.ByteBuffer writeBuffer2 = copy(getOutNetBuffer());                    writeFuture = new DefaultWriteFuture(session);                    parent.filterWrite(nextFilter, session, new WriteRequest(                            writeBuffer2, writeFuture));                }            }        } finally {            writingEncryptedData = false;        }        return writeFuture;    }    private SSLEngineResult.Status unwrap() throws SSLException {        if (SessionLog.isDebugEnabled(session)) {            SessionLog.debug(session, " unwrap()");        }        // Prepare the application buffer to receive decrypted data        appBuffer.clear();        // Prepare the net data for reading.        inNetBuffer.flip();        SSLEngineResult res;        do {            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, "   inNetBuffer: " + inNetBuffer);                SessionLog.debug(session, "   appBuffer: " + appBuffer);            }            res = sslEngine.unwrap(inNetBuffer, appBuffer);            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, " Unwrap res:" + res);            }        } while (res.getStatus() == SSLEngineResult.Status.OK);        // prepare to be written again        inNetBuffer.compact();        // prepare app data to be read        appBuffer.flip();        /*         * The status may be:         * OK - Normal operation         * OVERFLOW - Should never happen since the application buffer is         *      sized to hold the maximum packet size.         * UNDERFLOW - Need to read more data from the socket. It's normal.         * CLOSED - The other peer closed the socket. Also normal.         */        return checkStatus(res.getStatus());    }    private SSLEngineResult.Status unwrapHandshake() throws SSLException {        if (SessionLog.isDebugEnabled(session)) {            SessionLog.debug(session, " unwrapHandshake()");        }        // Prepare the application buffer to receive decrypted data        appBuffer.clear();        // Prepare the net data for reading.        inNetBuffer.flip();        SSLEngineResult res;        do {            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, "   inNetBuffer: " + inNetBuffer);                SessionLog.debug(session, "   appBuffer: " + appBuffer);            }            res = sslEngine.unwrap(inNetBuffer, appBuffer);            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, " Unwrap res:" + res);            }        } while (res.getStatus() == SSLEngineResult.Status.OK                && res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP);        initialHandshakeStatus = res.getHandshakeStatus();        // If handshake finished, no data was produced, and the status is still ok,        // try to unwrap more        if (initialHandshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED                && appBuffer.position() == 0                && res.getStatus() == SSLEngineResult.Status.OK                && inNetBuffer.hasRemaining()) {            do {                if (SessionLog.isDebugEnabled(session)) {                    SessionLog.debug(session, "  extra handshake unwrap");                    SessionLog.debug(session, "   inNetBuffer: " + inNetBuffer);                    SessionLog.debug(session, "   appBuffer: " + appBuffer);                }                res = sslEngine.unwrap(inNetBuffer, appBuffer);                if (SessionLog.isDebugEnabled(session)) {                    SessionLog.debug(session, " Unwrap res:" + res);                }            } while (res.getStatus() == SSLEngineResult.Status.OK);        }        // prepare to be written again        inNetBuffer.compact();        // prepare app data to be read        appBuffer.flip();        /*         * The status may be:         * OK - Normal operation         * OVERFLOW - Should never happen since the application buffer is         *      sized to hold the maximum packet size.         * UNDERFLOW - Need to read more data from the socket. It's normal.         * CLOSED - The other peer closed the socket. Also normal.         */        //initialHandshakeStatus = res.getHandshakeStatus();        return checkStatus(res.getStatus());    }    /**     * Do all the outstanding handshake tasks in the current Thread.     */    private SSLEngineResult.HandshakeStatus doTasks() {        if (SessionLog.isDebugEnabled(session)) {            SessionLog.debug(session, "   doTasks()");        }        /*         * We could run this in a separate thread, but I don't see the need         * for this when used from SSLFilter. Use thread filters in MINA instead?         */        Runnable runnable;        while ((runnable = sslEngine.getDelegatedTask()) != null) {            if (SessionLog.isDebugEnabled(session)) {                SessionLog.debug(session, "    doTask: " + runnable);            }            runnable.run();        }        if (SessionLog.isDebugEnabled(session)) {            SessionLog.debug(session, "   doTasks(): "                    + sslEngine.getHandshakeStatus());        }        return sslEngine.getHandshakeStatus();    }    /**     * Creates a new Mina byte buffer that is a deep copy of the remaining bytes     * in the given buffer (between index buf.position() and buf.limit())     *     * @param src the buffer to copy     * @return the new buffer, ready to read from     */    public static org.apache.mina.common.ByteBuffer copy(java.nio.ByteBuffer src) {        org.apache.mina.common.ByteBuffer copy = org.apache.mina.common.ByteBuffer                .allocate(src.remaining());        copy.put(src);        copy.flip();        return copy;    }    private static class EventType {        public static final EventType RECEIVED = new EventType("RECEIVED");        public static final EventType FILTER_WRITE = new EventType(                "FILTER_WRITE");        private final String value;        private EventType(String value) {            this.value = value;        }        public String toString() {            return value;        }    }    private static class Event {        private final EventType type;        private final NextFilter nextFilter;        private final Object data;        Event(EventType type, NextFilter nextFilter, Object data) {            this.type = type;            this.nextFilter = nextFilter;            this.data = data;        }        public Object getData() {            return data;        }        public NextFilter getNextFilter() {            return nextFilter;        }        public EventType getType() {            return type;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -