@Override public synchronized SSLEngineResult wrap( ByteBuffer[] srcs, int offset, int length, ByteBuffer dst) throws SSLException { if (dst.position() > 0) { return logWrap( new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0)); } final HandshakeStatus status; final int currentActionIndex; synchronized (this) { status = getHandshakeStatus(); currentActionIndex = actionIndex; } final SSLEngineResult result; switch (status) { case FINISHED: { actionAccountedFor(HandshakeAction.FINISH, currentActionIndex); result = new SSLEngineResult( SSLEngineResult.Status.OK, SSLEngineResult.HandshakeStatus.FINISHED, 0, 0); break; } case NEED_TASK: result = new SSLEngineResult( SSLEngineResult.Status.OK, SSLEngineResult.HandshakeStatus.NEED_TASK, 0, 0); break; case NEED_UNWRAP: result = new SSLEngineResult( closed ? SSLEngineResult.Status.CLOSED : SSLEngineResult.Status.OK, SSLEngineResult.HandshakeStatus.NEED_UNWRAP, 0, 0); break; case NEED_WRAP: result = wrapper.wrap(dst, srcs, offset, length, true, currentActionIndex); break; case NOT_HANDSHAKING: { if (closed) { return new SSLEngineResult( SSLEngineResult.Status.CLOSED, SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0); } actionAccountedFor(HandshakeAction.PERFORM_REQUESTED_ACTION, currentActionIndex); result = wrapper.wrap(dst, srcs, offset, length, false, currentActionIndex); break; } default: throw new IllegalStateException("Unexpected handshake status: " + getHandshakeStatus()); } logWrap(result); return result; }
@Override public synchronized SSLEngineResult unwrap( ByteBuffer src, ByteBuffer[] dsts, int offset, int length) throws SSLException { for (int i = offset; i < length; i++) { if (dsts[i].hasRemaining()) { break; } else if (i == length - 1) { return logUnwrap( new SSLEngineResult( SSLEngineResult.Status.BUFFER_OVERFLOW, getHandshakeStatus(), 0, 0)); } } if (closed && closeMessageUnwrapped) { return logUnwrap(new SSLEngineResult(Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING, 0, 0)); } final HandshakeStatus status; final int currentActionIndex; synchronized (this) { status = getHandshakeStatus(); currentActionIndex = actionIndex; } final SSLEngineResult result; switch (status) { case FINISHED: actionAccountedFor(HandshakeAction.FINISH, currentActionIndex); result = new SSLEngineResult(Status.OK, HandshakeStatus.FINISHED, 30, 0); break; case NEED_TASK: result = new SSLEngineResult(Status.OK, HandshakeStatus.NEED_TASK, 0, 0); break; case NEED_UNWRAP: result = wrapper.unwrap(dsts, offset, length, src, true, currentActionIndex); break; case NEED_WRAP: if (closed) { result = new SSLEngineResult(Status.CLOSED, SSLEngineResult.HandshakeStatus.NEED_WRAP, 0, 0); } else { result = new SSLEngineResult(Status.OK, SSLEngineResult.HandshakeStatus.NEED_WRAP, 0, 0); } break; case NOT_HANDSHAKING: actionAccountedFor(HandshakeAction.PERFORM_REQUESTED_ACTION, currentActionIndex); result = wrapper.unwrap(dsts, offset, length, src, false, currentActionIndex); break; default: throw new IllegalStateException("Unexpected handshake status: " + getHandshakeStatus()); } logUnwrap(result); return result; }
/** * A wrap entry is a pair of texts representing an unwrapped data and its wrapped equivalent. Once * this wrap entry is added to this mock, this mock will start writing {@code wrappedData} * whenever it is requested to wrap {@code unwrappedData}, and it will write {@code unwrappedData} * whenever requested to unwrap {@code wrappedData}. * * @param unwrappedData unwrapped data * @param wrappedData the wrapped equivalent of {@code unwrappedData} */ public void addWrapEntry(String unwrappedData, String wrappedData) { wrapper.put(unwrappedData, wrappedData); }