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

📄 sslhandler.java

📁 mina是以Java实现的一个开源的网络程序框架
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        // Loop until there is no more data in src        while (src.hasRemaining()) {            SSLEngineResult result = sslEngine.wrap(src, outNetBuffer.buf());            if (result.getStatus() == SSLEngineResult.Status.OK) {                if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {                    doTasks();                }            } else if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {                outNetBuffer.capacity(outNetBuffer.capacity() << 1);                outNetBuffer.limit(outNetBuffer.capacity());            } else {                throw new SSLException("SSLEngine error during encrypt: "                        + result.getStatus() + " src: " + src                        + "outNetBuffer: " + outNetBuffer);            }        }        outNetBuffer.flip();    }    /**     * 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();        createOutNetBuffer(0);        SSLEngineResult result;        for (;;) {            result = sslEngine.wrap(emptyBuffer.buf(), outNetBuffer.buf());            if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {                outNetBuffer.capacity(outNetBuffer.capacity() << 1);                outNetBuffer.limit(outNetBuffer.capacity());            } else {                break;            }        }        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(NextFilter nextFilter) throws SSLException {        if (!handshakeComplete) {            throw new IllegalStateException();        }        unwrap(nextFilter);    }    /**     * @param res     * @throws SSLException     */    private void checkStatus(SSLEngineResult res)            throws SSLException {        SSLEngineResult.Status status = res.getStatus();        /*        * 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.        */        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);        }    }    /**     * Perform any handshaking processing.     */    public void handshake(NextFilter nextFilter) throws SSLException {        for (;;) {            switch (handshakeStatus) {                case FINISHED :                    session.setAttribute(                            SslFilter.SSL_SESSION, sslEngine.getSession());                    handshakeComplete = true;                                        if (!initialHandshakeComplete                            && session.containsAttribute(SslFilter.USE_NOTIFICATION)) {                        // SESSION_SECURED is fired only when it's the first handshake.                        // (i.e. renegotiation shouldn't trigger SESSION_SECURED.)                        initialHandshakeComplete = true;                        scheduleMessageReceived(nextFilter,                                SslFilter.SESSION_SECURED);                    }                                        return;                                    case NEED_TASK :                    handshakeStatus = doTasks();                    break;                                    case NEED_UNWRAP :                    // we need more data read                    SSLEngineResult.Status status = unwrapHandshake(nextFilter);                                        if (status == SSLEngineResult.Status.BUFFER_UNDERFLOW &&                            handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED ||                            isInboundDone()) {                        // We need more data or the session is closed                        return;                    }                                        break;                case 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 != null && outNetBuffer.hasRemaining()) {                        return;                    }                    SSLEngineResult result;                    createOutNetBuffer(0);                                        for (;;) {                        result = sslEngine.wrap(emptyBuffer.buf(), outNetBuffer.buf());                        if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {                            outNetBuffer.capacity(outNetBuffer.capacity() << 1);                            outNetBuffer.limit(outNetBuffer.capacity());                        } else {                            break;                        }                    }                    outNetBuffer.flip();                    handshakeStatus = result.getHandshakeStatus();                    writeNetBuffer(nextFilter);                    break;                            default :                    throw new IllegalStateException("Invalid Handshaking State"                            + handshakeStatus);            }        }    }    private void createOutNetBuffer(int expectedRemaining) {        // SSLEngine requires us to allocate unnecessarily big buffer        // even for small data.  *Shrug*        int capacity = Math.max(                expectedRemaining,                sslEngine.getSession().getPacketBufferSize());        if (outNetBuffer != null) {            outNetBuffer.capacity(capacity);        } else {            outNetBuffer = IoBuffer.allocate(capacity).minimumCapacity(0);        }    }    public WriteFuture writeNetBuffer(NextFilter nextFilter)            throws SSLException {        // Check if any net data needed to be writen        if (outNetBuffer == null || !outNetBuffer.hasRemaining()) {            // no; bail out            return null;        }        // set flag that we are writing encrypted data        // (used in SSLFilter.filterWrite())        writingEncryptedData = true;        // write net data        WriteFuture writeFuture = null;        try {            IoBuffer writeBuffer = fetchOutNetBuffer();            writeFuture = new DefaultWriteFuture(session);            parent.filterWrite(nextFilter, session, new DefaultWriteRequest(                    writeBuffer, writeFuture));            // loop while more writes required to complete handshake            while (needToCompleteHandshake()) {                try {                    handshake(nextFilter);                } catch (SSLException ssle) {                    SSLException newSsle = new SSLHandshakeException(                            "SSL handshake failed.");                    newSsle.initCause(ssle);                    throw newSsle;                }                IoBuffer outNetBuffer = fetchOutNetBuffer();                if (outNetBuffer != null && outNetBuffer.hasRemaining()) {                    writeFuture = new DefaultWriteFuture(session);                    parent.filterWrite(nextFilter, session,                            new DefaultWriteRequest(outNetBuffer, writeFuture));                }            }        } finally {            writingEncryptedData = false;        }        return writeFuture;    }    private void unwrap(NextFilter nextFilter) throws SSLException {        // Prepare the net data for reading.        if (inNetBuffer != null) {            inNetBuffer.flip();        }        if (inNetBuffer == null || !inNetBuffer.hasRemaining()) {            return;        }        SSLEngineResult res = unwrap0();        // prepare to be written again        if (inNetBuffer.hasRemaining()) {            inNetBuffer.compact();        } else {            inNetBuffer = null;        }        checkStatus(res);        renegotiateIfNeeded(nextFilter, res);    }    private SSLEngineResult.Status unwrapHandshake(NextFilter nextFilter) throws SSLException {        // Prepare the net data for reading.        if (inNetBuffer != null) {            inNetBuffer.flip();        }        if (inNetBuffer == null || !inNetBuffer.hasRemaining()) {            // Need more data.            return SSLEngineResult.Status.BUFFER_UNDERFLOW;        }        SSLEngineResult res = unwrap0();        handshakeStatus = res.getHandshakeStatus();        checkStatus(res);        // If handshake finished, no data was produced, and the status is still ok,        // try to unwrap more        if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED                && res.getStatus() == SSLEngineResult.Status.OK                && inNetBuffer.hasRemaining()) {            res = unwrap0();            // prepare to be written again            if (inNetBuffer.hasRemaining()) {                inNetBuffer.compact();            } else {                inNetBuffer = null;            }            renegotiateIfNeeded(nextFilter, res);        } else {            // prepare to be written again            if (inNetBuffer.hasRemaining()) {                inNetBuffer.compact();            } else {                inNetBuffer = null;            }        }        return res.getStatus();    }    private void renegotiateIfNeeded(NextFilter nextFilter, SSLEngineResult res)            throws SSLException {        if (res.getStatus() != SSLEngineResult.Status.CLOSED                && res.getStatus() != SSLEngineResult.Status.BUFFER_UNDERFLOW                && res.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {            // Renegotiation required.            handshakeComplete = false;            handshakeStatus = res.getHandshakeStatus();            handshake(nextFilter);        }    }    private SSLEngineResult unwrap0() throws SSLException {        if (appBuffer == null) {            appBuffer = IoBuffer.allocate(inNetBuffer.remaining());        } else {            appBuffer.expand(inNetBuffer.remaining());        }        SSLEngineResult res;        do {            res = sslEngine.unwrap(inNetBuffer.buf(), appBuffer.buf());            if (res.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {                appBuffer.capacity(appBuffer.capacity() << 1);                appBuffer.limit(appBuffer.capacity());                continue;            }        } while ((res.getStatus() == SSLEngineResult.Status.OK || res.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) &&                 (handshakeComplete && res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING ||                  res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP));        return res;    }    /**     * Do all the outstanding handshake tasks in the current Thread.     */    private SSLEngineResult.HandshakeStatus 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) {            // TODO : we may have to use a thread pool here to improve the performances            runnable.run();        }        return sslEngine.getHandshakeStatus();    }    /**     * Creates a new MINA 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 IoBuffer copy(ByteBuffer src) {        IoBuffer copy = IoBuffer.allocate(src.remaining());        copy.put(src);        copy.flip();        return copy;    }}

⌨️ 快捷键说明

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