Skip to content

Commit c012eab

Browse files
author
Pete Bentley
committed
Tests for SSLEngine unwrap preconditions.
Mirrors the tests for wrap preconditions in #1420. Does not contain any tests or fixes for bug #1372. They will follow in a smaller, focussed PR.
1 parent 827d29f commit c012eab

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

common/src/test/java/org/conscrypt/javax/net/ssl/SSLEngineTest.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,116 @@ private void assertWrapSucceeds(ByteBuffer[] buffers, int offset, int length) th
10581058
}
10591059
}
10601060

1061+
/*
1062+
* The preconditions for the unwrap() methods of SSLEngine have a relatively
1063+
* complex mapping from precondition to the exception thrown on failure. This method
1064+
* checks that all the failure cases throw the correct exception and that
1065+
* corner cases which should not throw are also handled correctly.
1066+
*/
1067+
@Test
1068+
public void unwrapPreconditions() throws Exception {
1069+
int bufferSize = 128;
1070+
int arrayLength = 5;
1071+
ByteBuffer srcBuffer = BufferType.HEAP.newRandomBuffer(bufferSize);
1072+
ByteBuffer dstBuffer = ByteBuffer.allocate(bufferSize);
1073+
ByteBuffer readOnlyDestBuffer = dstBuffer.asReadOnlyBuffer();
1074+
1075+
ByteBuffer[] dsts = BufferType.HEAP.newBufferArray(arrayLength, bufferSize);
1076+
ByteBuffer[] dstsWithNullEntry = Arrays.copyOf(dsts, dsts.length);
1077+
int nullBufferIndex = 2;
1078+
dstsWithNullEntry[nullBufferIndex] = null;
1079+
ByteBuffer[] dstsWithReadOnlyEntry = Arrays.copyOf(dsts, dsts.length);
1080+
int readOnlyBufferIndex = 2;
1081+
dstsWithReadOnlyEntry[readOnlyBufferIndex] =
1082+
dstsWithReadOnlyEntry[readOnlyBufferIndex].asReadOnlyBuffer();
1083+
1084+
// Failure cases
1085+
// Client/server mode not set => IllegalStateException
1086+
assertThrows(IllegalStateException.class,
1087+
() -> newUnconnectedEngine().unwrap(srcBuffer, dstBuffer));
1088+
assertThrows(IllegalStateException.class,
1089+
() -> newUnconnectedEngine().unwrap(srcBuffer, dsts));
1090+
assertThrows(IllegalStateException.class,
1091+
() -> newUnconnectedEngine().unwrap(srcBuffer, dsts, 0, 1));
1092+
1093+
// Read-only destination => ReadOnlyBufferException
1094+
assertThrows(ReadOnlyBufferException.class,
1095+
() -> newConnectedEngine().unwrap(srcBuffer, readOnlyDestBuffer));
1096+
assertThrows(ReadOnlyBufferException.class,
1097+
() -> newConnectedEngine().unwrap(srcBuffer, dstsWithReadOnlyEntry));
1098+
assertThrows(ReadOnlyBufferException.class,
1099+
() -> newConnectedEngine().unwrap(
1100+
srcBuffer, dstsWithReadOnlyEntry, 0, arrayLength));
1101+
1102+
// Null destination => IllegalArgumentException
1103+
assertThrows(IllegalArgumentException.class,
1104+
() -> newConnectedEngine().unwrap(srcBuffer, (ByteBuffer) null));
1105+
assertThrows(IllegalArgumentException.class,
1106+
() -> newConnectedEngine().unwrap(srcBuffer, (ByteBuffer[]) null));
1107+
assertThrows(IllegalArgumentException.class,
1108+
() -> newConnectedEngine().unwrap(srcBuffer, null, 0, 1));
1109+
1110+
// Null source => IllegalArgumentException
1111+
assertThrows(IllegalArgumentException.class,
1112+
() -> newConnectedEngine().unwrap(null, dstBuffer));
1113+
assertThrows(IllegalArgumentException.class,
1114+
() -> newConnectedEngine().unwrap(null, dsts));
1115+
assertThrows(IllegalArgumentException.class,
1116+
() -> newConnectedEngine().unwrap(null, dsts, 0, 1));
1117+
1118+
// Null entries in destination buffer array => IllegalArgumentException
1119+
assertThrows(IllegalArgumentException.class,
1120+
() -> newConnectedEngine().unwrap(srcBuffer, dstsWithNullEntry));
1121+
assertThrows(IllegalArgumentException.class,
1122+
() -> newConnectedEngine().unwrap(
1123+
srcBuffer, dstsWithNullEntry, 0, arrayLength));
1124+
1125+
// Bad offset or length => IndexOutOfBoundsException
1126+
assertThrows(IndexOutOfBoundsException.class,
1127+
() -> newConnectedEngine().unwrap(srcBuffer, dsts, 0, arrayLength + 1));
1128+
assertThrows(IndexOutOfBoundsException.class,
1129+
() -> newConnectedEngine().unwrap(srcBuffer, dsts, arrayLength, 1));
1130+
assertThrows(IndexOutOfBoundsException.class,
1131+
() -> newConnectedEngine().unwrap(srcBuffer, dsts, arrayLength - 1, 2));
1132+
1133+
// Corner cases which should not throw
1134+
// Zero length arrays of output buffers should never throw
1135+
assertUnwrapDoesNotThrow(dsts, 0, 0);
1136+
assertUnwrapDoesNotThrow(dsts, arrayLength, 0);
1137+
1138+
// TODO(prb): Add tests for null/read-only entries outside the selected offset and length
1139+
// after https://github.com/google/conscrypt/issues/1372 is fixed.
1140+
}
1141+
1142+
// Asserts that an unwrap call with the given arguments does not throw a precondition
1143+
// exception. Note that the unwrap call itself may not produce plaintext if the selected
1144+
// destination buffers don't have enough capacity, but this is purely a precondition test
1145+
// and actual unwrap functionality is tested elsewhere.
1146+
private void assertUnwrapDoesNotThrow(ByteBuffer[] dsts, int offset, int length) throws Exception {
1147+
try (TestSSLEnginePair pair = TestSSLEnginePair.create()) {
1148+
assertConnected(pair);
1149+
1150+
// Wrap some plaintext to get TLS ciphertext to unwrap.
1151+
ByteBuffer plaintext = BufferType.HEAP.newRandomBuffer(128);
1152+
ByteBuffer ciphertext =
1153+
ByteBuffer.allocate(pair.client.getSession().getPacketBufferSize());
1154+
SSLEngineResult wrapResult = pair.client.wrap(plaintext, ciphertext);
1155+
assertEquals(Status.OK, wrapResult.getStatus());
1156+
ciphertext.flip();
1157+
1158+
// Reset the selected destination buffers to their initial (empty) state.
1159+
for (int i = offset; i < offset + length; i++) {
1160+
dsts[i].clear();
1161+
}
1162+
1163+
// Unwrap: may return BUFFER_OVERFLOW if the selected buffers don't have enough capacity but that's
1164+
// fine for this *precondition* test.
1165+
SSLEngineResult result = pair.server.unwrap(ciphertext, dsts, offset, length);
1166+
assertTrue(result.getStatus() == Status.OK
1167+
|| result.getStatus() == Status.BUFFER_OVERFLOW);
1168+
}
1169+
}
1170+
10611171
@Test
10621172
public void bufferArrayOffsets() throws Exception {
10631173
TestSSLEnginePair pair = TestSSLEnginePair.create();

testing/src/main/java/org/conscrypt/TestUtils.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ ByteBuffer newBuffer(int size) {
109109
private static final Random random = new Random(System.currentTimeMillis());
110110
abstract ByteBuffer newBuffer(int size);
111111

112+
public ByteBuffer[] newBufferArray(int arrayLength, int bufferSize) {
113+
ByteBuffer[] result = new ByteBuffer[arrayLength];
114+
for (int i = 0; i < arrayLength; i++) {
115+
result[i] = newBuffer(bufferSize);
116+
}
117+
return result;
118+
}
119+
112120
public ByteBuffer[] newRandomBuffers(int... sizes) {
113121
int numBuffers = sizes.length;
114122
ByteBuffer[] result = new ByteBuffer[numBuffers];

0 commit comments

Comments
 (0)