下面列出了javax.net.ssl.SSLEngineResult#Status ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Test for <code>bytesConsumed()</code> method
*/
public void test_bytesConsumed() {
int[] pos = { 0, 1, 1000, Integer.MAX_VALUE, (Integer.MAX_VALUE - 1) };
SSLEngineResult.Status [] enS =
SSLEngineResult.Status.values();
SSLEngineResult.HandshakeStatus [] enHS =
SSLEngineResult.HandshakeStatus.values();
for (int i = 0; i < enS.length; i++) {
for (int j = 0; j < enHS.length; j++) {
for (int n = 0; n < pos.length; n++) {
for (int l = 0; l < pos.length; l++) {
SSLEngineResult res = new SSLEngineResult(enS[i],
enHS[j], pos[n], pos[l]);
assertEquals("Incorrect bytesConsumed", pos[n],
res.bytesConsumed());
}
}
}
}
}
private SSLEngineResult handshakeWrap(SSLEngine engine, CodecCallback callback)
throws IOException {
SSLEngineResult result;
SSLEngineResult.Status status;
ByteBuffer output = allocate();
while (true) {
result = engineWrap(engine, allocate(0), output);
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;
}
}
return result;
}
/**
* Test for <code>bytesProduced()</code> method
*/
public void test_bytesProduced() {
int[] pos = { 0, 1, 1000, Integer.MAX_VALUE, (Integer.MAX_VALUE - 1) };
SSLEngineResult.Status [] enS =
SSLEngineResult.Status.values();
SSLEngineResult.HandshakeStatus [] enHS =
SSLEngineResult.HandshakeStatus.values();
for (int i = 0; i < enS.length; i++) {
for (int j = 0; j < enHS.length; j++) {
for (int n = 0; n < pos.length; n++) {
for (int l = 0; l < pos.length; ++l) {
SSLEngineResult res = new SSLEngineResult(enS[i],
enHS[j], pos[n], pos[l]);
assertEquals("Incorrect bytesProduced", pos[l],
res.bytesProduced());
}
}
}
}
}
/**
* Test for <code>getStatus()</code> method
*/
public void test_getStatus() {
int[] pos = { 0, 1, 1000, Integer.MAX_VALUE, (Integer.MAX_VALUE - 1) };
SSLEngineResult.Status [] enS =
SSLEngineResult.Status.values();
SSLEngineResult.HandshakeStatus [] enHS =
SSLEngineResult.HandshakeStatus.values();
for (int i = 0; i < enS.length; i++) {
for (int j = 0; j < enHS.length; j++) {
for (int n = 0; n < pos.length; n++) {
for (int l = 0; l < pos.length; ++l) {
SSLEngineResult res = new SSLEngineResult(enS[i],
enHS[j], pos[n], pos[l]);
assertEquals("Incorrect Status", enS[i],
res.getStatus());
}
}
}
}
}
/**
* @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.BUFFER_OVERFLOW) {
throw new SSLException("SSLEngine error during decrypt: " + status + " inNetBuffer: " + inNetBuffer
+ "appBuffer: " + appBuffer);
}
}
private SSLEngineResult handshakeUnwrap(SSLEngine engine, ByteBuffer input,
CodecCallback callback) throws IOException {
SSLEngineResult result;
SSLEngineResult.Status status;
ByteBuffer output = allocate();
while (true) {
result = engineUnwrap(engine, input, output);
status = result.getStatus();
output.flip();
int producedSize = output.remaining();
if (producedSize > 0) {
callback.onDecrypt(output);
}
if (status == SSLEngineResult.Status.BUFFER_OVERFLOW) {
int bufferSize = engine.getSession().getApplicationBufferSize() - producedSize;
if (bufferSize < 0) {
bufferSize = engine.getSession().getApplicationBufferSize();
}
output = allocate(bufferSize);
} else if (status == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
// Store the remaining packet and wait next encrypted buffer.
if (input.hasRemaining()) {
callback.onPending(ByteBuffer.wrap(input.array(), input.position(),
input.remaining()));
// Clear all data.
input.position(0);
input.limit(0);
}
break;
} else if (status == SSLEngineResult.Status.CLOSED) {
mEngineClosed = true;
break;
} else {
// It is status OK.
break;
}
}
return result;
}
/**
* DTLS encrypt byte buffer
*/
boolean diameterDTLSEncryptBuffer(SSLEngine engine, ByteBuffer source, ByteBuffer appNet) throws Exception {
//printHex("Received application data for Encrypt", source);
List<DatagramPacket> packets = new ArrayList<>();
SSLEngineResult r = engine.wrap(source, appNet);
appNet.flip();
SSLEngineResult.Status rs = r.getStatus();
if (rs == SSLEngineResult.Status.BUFFER_OVERFLOW) {
// the client maximum fragment size config does not work?
logger.warn("Buffer overflow: " + "incorrect server maximum fragment size");
return false;
} else if (rs == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
// unlikely
logger.warn("Buffer underflow during wraping");
return false;
} else if (rs == SSLEngineResult.Status.CLOSED) {
logger.warn("SSLEngine has closed");
return false;
} else if (rs == SSLEngineResult.Status.OK) {
// OK
} else {
logger.warn("Can't reach here, result is " + rs);
return false;
}
// SSLEngineResult.Status.OK:
// printHex("Produced application data by Encrypt", appNet);
return true;
}
/**
* @param res SSL engine result.
* @throws SSLException If status is not acceptable.
*/
private void checkStatus(SSLEngineResult res)
throws SSLException {
SSLEngineResult.Status status = res.getStatus();
if (status != Status.OK && status != CLOSED && status != BUFFER_UNDERFLOW)
throw new SSLException("Failed to unwrap incoming data (SSL engine error) [ses" + ses + ", status=" +
status + ']');
}
/**
* Checks that status of result {@code r} is {@code wantedStatus}.
*
* @param r - Result.
* @param wantedStatus - Wanted status of the result.
* @throws AssertionError - if status or {@code r} is not
* {@code wantedStatus}.
*/
public static void checkResult(SSLEngineResult r,
SSLEngineResult.Status wantedStatus) {
SSLEngineResult.Status rs = r.getStatus();
if (!rs.equals(wantedStatus)) {
throw new AssertionError("Unexpected status " + rs.name()
+ ", should be " + wantedStatus.name());
}
}
private SSLEngineResult.Status getEngineStatus() {
return engineClosed ? SSLEngineResult.Status.CLOSED : SSLEngineResult.Status.OK;
}
private SSLEngineResult newResultMayFinishHandshake(SSLEngineResult.Status status,
SSLEngineResult.HandshakeStatus hs,
int bytesConsumed, int bytesProduced) throws SSLException {
return newResult(status, mayFinishHandshake(hs != FINISHED ? getHandshakeStatus() : FINISHED),
bytesConsumed, bytesProduced);
}
private void unwrap(SSLEngine engine, ByteBuffer input, CodecCallback callback)
throws IOException {
ByteBuffer output = null;
while (true) {
if (output == null) {
output = allocate();
}
SSLEngineResult result = engineUnwrap(engine, input, output);
SSLEngineResult.Status status = result.getStatus();
output.flip();
int producedSize = output.remaining();
if (producedSize > 0) {
callback.onDecrypt(output);
output = null;
}
if (status == SSLEngineResult.Status.BUFFER_OVERFLOW) {
int bufferSize = engine.getSession().getApplicationBufferSize() - producedSize;
if (bufferSize < 0) {
bufferSize = engine.getSession().getApplicationBufferSize();
}
output = allocate(bufferSize);
} else if (status == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
// Store the remaining packet and wait next encrypted buffer.
if (input.hasRemaining()) {
callback.onPending(ByteBuffer.wrap(input.array(), input.position(),
input.remaining()));
// Clear all data.
input.position(0);
input.limit(0);
}
break;
} else if (status == SSLEngineResult.Status.CLOSED) {
mEngineClosed = true;
break;
} else {
if (!input.hasRemaining()) {
break;
}
}
}
}
/**
* DTLS produce handshake packets
*/
boolean dtls_produceHandshakePackets(SSLEngine engine, /*SocketAddress socketAddr,*/ String peer_realm,
String side, List<DatagramOverDiameterPacket> packets) throws Exception {
long _t = System.currentTimeMillis();
long _end = _t + DTLS_MAX_HANDSHAKE_DURATION*1000;
boolean endLoops = false;
int loops = DTLS_MAX_HANDSHAKE_LOOPS / 2;
while (!endLoops && System.currentTimeMillis() < _end/*&&
(dtls_serverException == null) && (dtls_clientException == null)*/) {
if (--loops < 0) {
throw new RuntimeException(
"Too much loops to produce handshake packets");
}
ByteBuffer oNet = ByteBuffer.allocate(DTLS_BUFFER_SIZE);
ByteBuffer oApp = ByteBuffer.allocate(0);
SSLEngineResult r = engine.wrap(oApp, oNet);
oNet.flip();
SSLEngineResult.Status rs = r.getStatus();
SSLEngineResult.HandshakeStatus hs = r.getHandshakeStatus();
logger.debug("DTLS " + side + ": " + "----produce handshake packet(" +
loops + ", " + rs + ", " + hs + ")----");
if (rs == SSLEngineResult.Status.BUFFER_OVERFLOW) {
// the client maximum fragment size config does not work?
throw new Exception("Buffer overflow: " +
"incorrect server maximum fragment size");
} else if (rs == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
logger.debug("DTLS " + side + ": " +
"Produce handshake packets: BUFFER_UNDERFLOW occured");
logger.debug("DTLS " + side + ": " +
"Produce handshake packets: Handshake status: " + hs);
// bad packet, or the client maximum fragment size
// config does not work?
if (hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
throw new Exception("Buffer underflow: " +
"incorrect server maximum fragment size");
} // otherwise, ignore this packet
} else if (rs == SSLEngineResult.Status.CLOSED) {
throw new Exception("SSLEngine has closed");
} else if (rs == SSLEngineResult.Status.OK) {
// OK
} else {
throw new Exception("Can't reach here, result is " + rs);
}
// SSLEngineResult.Status.OK:
if (oNet.hasRemaining()) {
byte[] ba = new byte[oNet.remaining()];
oNet.get(ba);
DatagramOverDiameterPacket packet = createHandshakePacket(ba, peer_realm);
packets.add(packet);
}
if (hs == SSLEngineResult.HandshakeStatus.FINISHED) {
logger.debug("DTLS " + side + ": " + "Produce handshake packets: "
+ "Handshake status is FINISHED, finish the loop");
return true;
}
boolean endInnerLoop = false;
SSLEngineResult.HandshakeStatus nhs = hs;
while (!endInnerLoop) {
if (nhs == SSLEngineResult.HandshakeStatus.NEED_TASK) {
dtls_runDelegatedTasks(engine);
} else if (nhs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP ||
nhs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN ||
nhs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
endInnerLoop = true;
endLoops = true;
} else if (nhs == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
endInnerLoop = true;
} else if (nhs == SSLEngineResult.HandshakeStatus.FINISHED) {
throw new Exception(
"Unexpected status, SSLEngine.getHandshakeStatus() "
+ "shouldn't return FINISHED");
} else {
throw new Exception("Can't reach here, handshake status is "
+ nhs);
}
nhs = engine.getHandshakeStatus();
}
}
return false;
}
/**
* Perform any handshaking processing.
*/
/* no qualifier */void handshake(NextFilter nextFilter) throws SSLException {
for (;;) {
switch (handshakeStatus) {
case FINISHED:
case NOT_HANDSHAKING:
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} processing the FINISHED state", sslFilter.getSessionInfo(session));
}
session.setAttribute(SslFilter.SSL_SESSION, sslEngine.getSession());
handshakeComplete = true;
// Send the SECURE message only if it's the first SSL handshake
if (firstSSLNegociation && session.containsAttribute(SslFilter.USE_NOTIFICATION)) {
// SESSION_SECURED is fired only when it's the first handshake
firstSSLNegociation = false;
scheduleMessageReceived(nextFilter, SslFilter.SESSION_SECURED);
}
if (LOGGER.isDebugEnabled()) {
if (!isOutboundDone()) {
LOGGER.debug("{} is now secured", sslFilter.getSessionInfo(session));
} else {
LOGGER.debug("{} is not secured yet", sslFilter.getSessionInfo(session));
}
}
return;
case NEED_TASK:
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} processing the NEED_TASK state", sslFilter.getSessionInfo(session));
}
handshakeStatus = doTasks();
break;
case NEED_UNWRAP:
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} processing the NEED_UNWRAP state", sslFilter.getSessionInfo(session));
}
// 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:
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("{} processing the NEED_WRAP state", sslFilter.getSessionInfo(session));
}
// 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:
String msg = "Invalid Handshaking State" + handshakeStatus
+ " while processing the Handshake for session " + session.getId();
LOGGER.error(msg);
throw new IllegalStateException(msg);
}
}
}
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 = unwrap();
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 = unwrap();
// 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 SSLEngineResult.Status getEngineStatus() {
return engineClosed? CLOSED : OK;
}
private void handshake0() throws SSLException {
for (;;) {
switch (handshakeStatus) {
case FINISHED:
case NOT_HANDSHAKING:
handshakeComplete = true;
return;
case NEED_TASK:
handshakeStatus = doTasks();
break;
case NEED_UNWRAP:
SSLEngineResult.Status status = unwrapHandshake();
if (status == SSLEngineResult.Status.BUFFER_UNDERFLOW && handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED || isInboundDone()) {
// Need more data
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();
break;
default:
String msg = "Invalid handshaking state" + handshakeStatus + " while processing the Handshake for session.";
throw new IllegalStateException(msg);
}
}
}
private SSLEngineResult.Status unwrapHandshake() 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 = unwrap();
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 = unwrap();
// prepare to be written again
if (inNetBuffer.hasRemaining()) {
inNetBuffer.compact();
} else {
inNetBuffer = null;
}
renegotiateIfNeeded(res);
} else {
// prepare to be written again
if (inNetBuffer.hasRemaining()) {
inNetBuffer.compact();
} else {
inNetBuffer = null;
}
}
return res.getStatus();
}
/**
* Wraps data with the specified engine.
*
* @param engine - SSLEngine that wraps data.
* @param wrapper - Set wrapper id, e.g. "server" of "client".
* Used for logging only.
* @param maxPacketSize - Max packet size to check that MFLN extension
* works or zero for no check.
* @param app - Buffer with data to wrap.
* @param wantedStatus - Specifies expected result status of wrapping.
* @return - Buffer with wrapped data.
* @throws SSLException - thrown on engine errors.
*/
public static ByteBuffer doWrap(SSLEngine engine, String wrapper,
int maxPacketSize, ByteBuffer app,
SSLEngineResult.Status wantedStatus)
throws SSLException {
return doWrap(engine, wrapper, maxPacketSize,
app, wantedStatus, null);
}
/**
* Unwraps data with the specified engine.
*
* @param engine - SSLEngine that unwraps data.
* @param unwrapper - Set unwrapper id, e.g. "server" of "client".
* Used for logging only.
* @param net - Buffer with data to unwrap.
* @param wantedStatus - Specifies expected result status of wrapping.
* @return - Buffer with unwrapped data.
* @throws SSLException - thrown on engine errors.
*/
public static ByteBuffer doUnWrap(SSLEngine engine, String unwrapper,
ByteBuffer net,
SSLEngineResult.Status wantedStatus) throws SSLException {
return doUnWrap(engine, unwrapper, net, wantedStatus, null);
}