@Override public boolean isNeedRead() { return inData.hasRemaining() || ( inCrypt.hasRemaining() && readEngineResult.getStatus() != Status.BUFFER_UNDERFLOW && readEngineResult.getStatus() != Status.CLOSED ); }
/** * Performs the WRAP function * @param doWrite boolean * @return SSLEngineResult * @throws IOException */ private SSLEngineResult handshakeWrap(boolean doWrite) throws IOException { log.trace("SSLHandshake handshakeWrap {}", channelId); if (netWriteBuffer.hasRemaining()) throw new IllegalStateException("handshakeWrap called with netWriteBuffer not empty"); //this should never be called with a network buffer that contains data //so we can clear it here. netWriteBuffer.clear(); SSLEngineResult result = sslEngine.wrap(emptyBuf, netWriteBuffer); //prepare the results to be written netWriteBuffer.flip(); handshakeStatus = result.getHandshakeStatus(); if (result.getStatus() == SSLEngineResult.Status.OK && result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { handshakeStatus = runDelegatedTasks(); } if (doWrite) flush(netWriteBuffer); return result; }
/** * performs the unwrap operation by unwrapping from {@link #inCrypt} to {@link #inData} **/ private synchronized ByteBuffer unwrap() throws SSLException { int rem; //There are some ssl test suites, which get around the selector.select() call, which cause an infinite unwrap and 100% cpu usage (see #459 and #458) if(readEngineResult.getStatus() == SSLEngineResult.Status.CLOSED && sslEngine.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING){ try { close(); } catch (IOException e) { //Not really interesting } } do { rem = inData.remaining(); readEngineResult = sslEngine.unwrap( inCrypt, inData ); } while ( readEngineResult.getStatus() == SSLEngineResult.Status.OK && ( rem != inData.remaining() || sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP ) ); inData.flip(); return inData; }
assert ! Thread.holdsLock(getUnwrapLock()); log.logf(FQCN, Logger.Level.TRACE, null, "Wrap result is %s", result); switch (result.getStatus()) { case BUFFER_UNDERFLOW: { assert result.bytesConsumed() == 0; assert result.bytesProduced() == 0; assert result.bytesProduced() == 0; final ByteBuffer buffer = sendBuffer.getResource(); if (buffer.position() == 0) { } else { buffer.flip(); try { while (buffer.hasRemaining()) { final int res = sinkConduit.write(buffer); if (res == 0) { if (result.bytesProduced() > 0) { if (! doFlush()) { return false; throw msg.unexpectedWrapResult(result.getStatus());
private boolean unwrap(ByteBuffer dst) throws IOException { while (inBuf.hasRemaining()) { SSLEngineResult.Status status = engine.unwrap(inBuf, dst).getStatus(); switch (status) { case BUFFER_UNDERFLOW: inBuf.compact(); socketChannel.read(inBuf); inBuf.flip(); break; case BUFFER_OVERFLOW: return false; case OK: break; case CLOSED: throw new IOException("Did not expect CLOSED"); default: break; } } return true; } }
/** * {@link #read(ByteBuffer)} may not be to leave all buffers(inData, inCrypt) **/ private int readRemaining( ByteBuffer dst ) throws SSLException { if( inData.hasRemaining() ) { return transfereTo( inData, dst ); } if( !inData.hasRemaining() ) inData.clear(); // test if some bytes left from last read (e.g. BUFFER_UNDERFLOW) if( inCrypt.hasRemaining() ) { unwrap(); int amount = transfereTo( inData, dst ); if (readEngineResult.getStatus() == SSLEngineResult.Status.CLOSED) { return -1; } if( amount > 0 ) return amount; } return 0; }
netReadBuffer.flip(); result = sslEngine.unwrap(netReadBuffer, appReadBuffer); netReadBuffer.compact(); handshakeStatus = result.getHandshakeStatus(); if (result.getStatus() == SSLEngineResult.Status.OK && result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) { handshakeStatus = runDelegatedTasks(); cont = (result.getStatus() == SSLEngineResult.Status.OK && handshakeStatus == HandshakeStatus.NEED_UNWRAP) || (ignoreHandshakeStatus && netReadBuffer.position() != position); log.trace("SSLHandshake handshakeUnwrap: handshakeStatus {} status {}", handshakeStatus, result.getStatus()); } while (netReadBuffer.position() != 0 && cont);
assert Thread.holdsLock(getUnwrapLock()); log.logf(FQCN, Logger.Level.TRACE, null, "Unwrap result is %s", result); switch (result.getStatus()) { case BUFFER_OVERFLOW: { assert result.bytesConsumed() == 0; assert result.bytesProduced() == 0; assert result.bytesProduced() == 0; return sourceConduit.read(buffer); } finally { buffer.flip(); throw msg.unexpectedUnwrapResult(result.getStatus());
final SSLEngineResult handshakeResult = engine.wrap(appDataOut, outboundBuffer); if (handshakeResult.getStatus() != Status.CLOSED) { throw new IOException("Invalid close state - will not send network data"); int bytesDiscarded = channel.read(discardBuffer); while (bytesDiscarded > 0) { discardBuffer.clear(); bytesDiscarded = channel.read(discardBuffer);
synchronized (getUnwrapLock()) { if (! Buffers.hasRemaining(dsts, offset, length)) { if (unwrappedBuffer.hasRemaining() && sourceConduit.isReadResumed()) { sourceConduit.wakeupReads(); try { synchronized (getWrapLock()) { engine.wrap(EMPTY_BUFFER, sendBuffer.getResource()); doFlush(); if(res == 0 && result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) { int old; do {
/** * Convert a {@link SSLEngineResult} into a {@link String}, this is needed * because the supplied method includes a log-breaking newline. */ public static String resultToString(final SSLEngineResult result) { return String.format("status=%s,handshakeStatus=%s,bytesConsumed=%d,bytesConsumed=%d", result.getStatus(), result.getHandshakeStatus(), result.bytesProduced(), result.bytesConsumed()); }
/** * Performs raw unwrap from network read buffer. * * @return Result. * @throws SSLException If SSL exception occurs. */ private SSLEngineResult unwrap0() throws SSLException { SSLEngineResult res; do { res = sslEngine.unwrap(inNetBuf, appBuf); if (log.isDebugEnabled()) log.debug("Unwrapped raw data [status=" + res.getStatus() + ", handshakeStatus=" + res.getHandshakeStatus() + ", ses=" + ses + ']'); if (res.getStatus() == Status.BUFFER_OVERFLOW) appBuf = expandBuffer(appBuf, appBuf.capacity() * 2); } while ((res.getStatus() == Status.OK || res.getStatus() == Status.BUFFER_OVERFLOW) && (handshakeFinished && res.getHandshakeStatus() == NOT_HANDSHAKING || res.getHandshakeStatus() == NEED_UNWRAP)); return res; }
SSLEngineResult result = engine.wrap(in0, out0); in.skipBytes(result.bytesConsumed()); out.writerIndex(out.writerIndex() + result.bytesProduced()); switch (result.getStatus()) { case BUFFER_OVERFLOW: out.ensureWritable(engine.getSession().getPacketBufferSize());
private Status encryptAndWriteFully(final BufferStateManager src) throws IOException { SSLEngineResult result = null; final ByteBuffer buff = src.prepareForRead(0); final ByteBuffer outBuff = streamOutManager.prepareForWrite(engine.getSession().getApplicationBufferSize()); logger.trace("{} Encrypting {} bytes", this, buff.remaining()); while (buff.remaining() > 0) { result = engine.wrap(buff, outBuff); if (result.getStatus() == Status.OK) { final ByteBuffer readableOutBuff = streamOutManager.prepareForRead(0); writeFully(readableOutBuff); streamOutManager.clear(); } else { return result.getStatus(); } } return result.getStatus(); }
private boolean handshakeUnwrap() throws IOException { SSLEngineResult result = sslEngineUnwrap(handshakeDummyBuffer); switch (result.getStatus()) { case OK: if (result.bytesProduced() > 0) throw new SSLException("Got application data in handshake unwrap"); return true; case BUFFER_UNDERFLOW: return false; default: throw unexpectedStatusException(result.getStatus()); } }
@Override public synchronized int write( ByteBuffer output ) throws IOException { int num = 0; while( output.hasRemaining() ) { // The loop has a meaning for (outgoing) messages larger than 16KB. // Every wrap call will remove 16KB from the original message and send it to the remote peer. myNetData.clear(); SSLEngineResult result = engine.wrap( output, myNetData ); switch(result.getStatus()) { case OK: myNetData.flip(); while( myNetData.hasRemaining() ) { num += socketChannel.write( myNetData ); } break; case BUFFER_OVERFLOW: myNetData = enlargePacketBuffer( myNetData ); break; case BUFFER_UNDERFLOW: throw new SSLException( "Buffer underflow occured after a wrap. I don't think we should ever get here." ); case CLOSED: closeConnection(); return 0; default: throw new IllegalStateException( "Invalid SSL status: " + result.getStatus() ); } } return num; }
throw e; if (userBuffers != null) { result = engine.unwrap(this.dataToUnwrap.getBuffer(), userBuffers, off, len); if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) { unwrapBufferUsed = true; bytesProduced = result.bytesProduced() > 0; && result.getStatus() != SSLEngineResult.Status.BUFFER_UNDERFLOW && dataToUnwrap.getBuffer().remaining() != dataToUnwrapLength) { state |= FLAG_DATA_TO_UNWRAP; if (result.getStatus() == SSLEngineResult.Status.CLOSED) { if(dataToUnwrap != null) { dataToUnwrap.close(); return -1; if (result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) { state &= ~FLAG_DATA_TO_UNWRAP; } else if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) { UndertowLogger.REQUEST_LOGGER.sslBufferOverflow(this); IoUtils.safeClose(delegate);
private void wrap(SSLEngine engine, ByteBuffer input, CodecCallback callback) throws IOException { ByteBuffer output = allocate(); while (true) { SSLEngineResult result = engineWrap(engine, input, output); SSLEngineResult.Status status = result.getStatus(); output.flip(); if (output.hasRemaining()) { callback.onEncrypt(output); } if (status == SSLEngineResult.Status.BUFFER_OVERFLOW) { output = allocate(engine.getSession().getApplicationBufferSize()); } else { if (status == SSLEngineResult.Status.CLOSED) { mEngineClosed = true; } break; } } }