Skip to content

Commit edc0c2b

Browse files
committed
Add regression tests
1 parent 9b87e53 commit edc0c2b

2 files changed

Lines changed: 392 additions & 0 deletions

File tree

src/test/com/wolfssl/provider/jsse/test/WolfSSLEngineTest.java

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,4 +3253,231 @@ public void testBufferOverflowSmallOutput()
32533253

32543254
pass("\t\t... passed");
32553255
}
3256+
3257+
@Test
3258+
public void testCloseOutboundBeforeHandshake()
3259+
throws NoSuchProviderException, NoSuchAlgorithmException,
3260+
KeyManagementException, KeyStoreException,
3261+
CertificateException, IOException,
3262+
UnrecoverableKeyException {
3263+
3264+
/* Regression: closeOutbound() before handshake started must
3265+
* also close inbound, otherwise isInboundDone() never returns
3266+
* true and callers loop forever. */
3267+
System.out.print("\tcloseOutbound() pre-handshake");
3268+
3269+
this.ctx = tf.createSSLContext("TLS", engineProvider);
3270+
SSLEngine engine = this.ctx.createSSLEngine();
3271+
engine.setUseClientMode(true);
3272+
3273+
/* Do not call beginHandshake() — needInit stays true. */
3274+
engine.closeOutbound();
3275+
3276+
if (!engine.isOutboundDone()) {
3277+
error("\t\t... failed");
3278+
fail("isOutboundDone() should be true after closeOutbound()");
3279+
}
3280+
3281+
if (!engine.isInboundDone()) {
3282+
error("\t\t... failed");
3283+
fail("isInboundDone() should be true after closeOutbound() " +
3284+
"before handshake (was leaving inBound open)");
3285+
}
3286+
3287+
pass("\t\t... passed");
3288+
}
3289+
3290+
@Test
3291+
public void testWrapWithBufferArrayOffset()
3292+
throws NoSuchProviderException, NoSuchAlgorithmException,
3293+
KeyManagementException, KeyStoreException,
3294+
CertificateException, IOException,
3295+
UnrecoverableKeyException {
3296+
3297+
/* Regression for wrap(ByteBuffer[], ofst, len, out) and
3298+
* SendAppData() when ofst > 0. Previously triggered AIOOBE
3299+
* because pos[]/limit[] were sized [len] but indexed by i
3300+
* starting at ofst, and the null-check loop iterated
3301+
* i < len instead of i < ofst + len. */
3302+
System.out.print("\twrap() with ofst > 0");
3303+
3304+
this.ctx = tf.createSSLContext("TLS", engineProvider);
3305+
SSLEngine server = this.ctx.createSSLEngine();
3306+
SSLEngine client = this.ctx.createSSLEngine("wolfSSL test", 11111);
3307+
3308+
server.setUseClientMode(false);
3309+
server.setNeedClientAuth(false);
3310+
client.setUseClientMode(true);
3311+
3312+
server.beginHandshake();
3313+
client.beginHandshake();
3314+
3315+
int ret = tf.testConnection(server, client, null, null,
3316+
"wrap ofst test");
3317+
if (ret != 0) {
3318+
error("\t\t... failed");
3319+
fail("failed to create connection");
3320+
}
3321+
3322+
/* Build a 2-element ByteBuffer[] and wrap with ofst=1, len=1
3323+
* so the null check, pos/limit recording, and gather loops
3324+
* all index past the [len] boundary. The buffer at index 0
3325+
* intentionally contains data that must NOT be sent. */
3326+
byte[] decoy = "DECOY-MUST-NOT-BE-SENT".getBytes();
3327+
byte[] payload = "real-payload-bytes".getBytes();
3328+
3329+
ByteBuffer[] inBufs = new ByteBuffer[2];
3330+
inBufs[0] = ByteBuffer.wrap(decoy);
3331+
inBufs[1] = ByteBuffer.wrap(payload);
3332+
3333+
ByteBuffer netOut = ByteBuffer.allocateDirect(
3334+
client.getSession().getPacketBufferSize());
3335+
3336+
SSLEngineResult result = client.wrap(inBufs, 1, 1, netOut);
3337+
if (result.getStatus() != SSLEngineResult.Status.OK) {
3338+
error("\t\t... failed");
3339+
fail("wrap with ofst=1 failed: " + result.getStatus());
3340+
}
3341+
3342+
/* Decoy must be untouched, payload fully consumed. */
3343+
if (inBufs[0].position() != 0) {
3344+
error("\t\t... failed");
3345+
fail("decoy buffer at index 0 was advanced: pos=" +
3346+
inBufs[0].position());
3347+
}
3348+
if (inBufs[1].position() != payload.length) {
3349+
error("\t\t... failed");
3350+
fail("payload buffer not fully consumed: pos=" +
3351+
inBufs[1].position());
3352+
}
3353+
3354+
/* Decrypt on server side and verify content is the payload. */
3355+
netOut.flip();
3356+
ByteBuffer plain = ByteBuffer.allocate(
3357+
server.getSession().getApplicationBufferSize());
3358+
result = server.unwrap(netOut, plain);
3359+
if (result.getStatus() != SSLEngineResult.Status.OK) {
3360+
error("\t\t... failed");
3361+
fail("server unwrap failed: " + result.getStatus());
3362+
}
3363+
3364+
plain.flip();
3365+
byte[] received = new byte[plain.remaining()];
3366+
plain.get(received);
3367+
if (!java.util.Arrays.equals(received, payload)) {
3368+
error("\t\t... failed");
3369+
fail("received data does not match payload");
3370+
}
3371+
3372+
pass("\t\t... passed");
3373+
}
3374+
3375+
@Test
3376+
public void testUnwrapWithBufferArrayOffset()
3377+
throws NoSuchProviderException, NoSuchAlgorithmException,
3378+
KeyManagementException, KeyStoreException,
3379+
CertificateException, IOException,
3380+
UnrecoverableKeyException {
3381+
3382+
/* Regression for unwrap(in, ByteBuffer[], ofst, length) with
3383+
* ofst > 0. Previously the null/readOnly-check loop iterated
3384+
* i < length instead of i < ofst + length, skipping the
3385+
* actually-targeted output buffers. */
3386+
System.out.print("\tunwrap() with ofst > 0");
3387+
3388+
this.ctx = tf.createSSLContext("TLS", engineProvider);
3389+
SSLEngine server = this.ctx.createSSLEngine();
3390+
SSLEngine client = this.ctx.createSSLEngine("wolfSSL test", 11111);
3391+
3392+
server.setUseClientMode(false);
3393+
server.setNeedClientAuth(false);
3394+
client.setUseClientMode(true);
3395+
3396+
server.beginHandshake();
3397+
client.beginHandshake();
3398+
3399+
int ret = tf.testConnection(server, client, null, null,
3400+
"unwrap ofst test");
3401+
if (ret != 0) {
3402+
error("\t\t... failed");
3403+
fail("failed to create connection");
3404+
}
3405+
3406+
byte[] payload = "unwrap-target-bytes".getBytes();
3407+
3408+
/* Client wraps payload, server will unwrap into ByteBuffer[]
3409+
* at ofst=1. */
3410+
ByteBuffer appBuf = ByteBuffer.wrap(payload);
3411+
ByteBuffer netBuf = ByteBuffer.allocateDirect(
3412+
client.getSession().getPacketBufferSize());
3413+
3414+
SSLEngineResult result = client.wrap(appBuf, netBuf);
3415+
if (result.getStatus() != SSLEngineResult.Status.OK) {
3416+
error("\t\t... failed");
3417+
fail("client wrap failed: " + result.getStatus());
3418+
}
3419+
netBuf.flip();
3420+
3421+
/* Build 2-element output array, ofst=1 so index 0 must stay
3422+
* untouched and decrypted bytes land at index 1. */
3423+
int appBufSize = server.getSession().getApplicationBufferSize();
3424+
ByteBuffer[] outBufs = new ByteBuffer[2];
3425+
outBufs[0] = ByteBuffer.allocate(appBufSize);
3426+
outBufs[1] = ByteBuffer.allocate(appBufSize);
3427+
3428+
result = server.unwrap(netBuf, outBufs, 1, 1);
3429+
if (result.getStatus() != SSLEngineResult.Status.OK) {
3430+
error("\t\t... failed");
3431+
fail("server unwrap with ofst=1 failed: " + result.getStatus());
3432+
}
3433+
3434+
if (outBufs[0].position() != 0) {
3435+
error("\t\t... failed");
3436+
fail("output buffer at index 0 was written: pos=" +
3437+
outBufs[0].position());
3438+
}
3439+
3440+
outBufs[1].flip();
3441+
byte[] received = new byte[outBufs[1].remaining()];
3442+
outBufs[1].get(received);
3443+
if (!java.util.Arrays.equals(received, payload)) {
3444+
error("\t\t... failed");
3445+
fail("received data does not match payload");
3446+
}
3447+
3448+
pass("\t\t... passed");
3449+
}
3450+
3451+
@Test
3452+
public void testWrapRejectsNullAtOffset() throws Exception {
3453+
System.out.print("\twrap() rejects null at ofst+len-1");
3454+
this.ctx = tf.createSSLContext("TLS", engineProvider);
3455+
SSLEngine c = this.ctx.createSSLEngine("wolfSSL test", 11111);
3456+
c.setUseClientMode(true);
3457+
ByteBuffer[] in = {ByteBuffer.wrap("x".getBytes()), null};
3458+
ByteBuffer out = ByteBuffer.allocateDirect(
3459+
c.getSession().getPacketBufferSize());
3460+
try {
3461+
c.wrap(in, 1, 1, out);
3462+
fail("expected SSLException for null at ofst=1");
3463+
} catch (SSLException e) { /* expected */ }
3464+
pass("\t... passed");
3465+
}
3466+
3467+
@Test
3468+
public void testUnwrapRejectsReadOnlyAtOffset() throws Exception {
3469+
System.out.print("\tunwrap() rejects readOnly at ofst+length-1");
3470+
this.ctx = tf.createSSLContext("TLS", engineProvider);
3471+
SSLEngine s = this.ctx.createSSLEngine();
3472+
s.setUseClientMode(false);
3473+
ByteBuffer in = ByteBuffer.allocateDirect(
3474+
s.getSession().getPacketBufferSize());
3475+
ByteBuffer[] out = {ByteBuffer.allocate(64),
3476+
ByteBuffer.allocate(64).asReadOnlyBuffer()};
3477+
try {
3478+
s.unwrap(in, out, 1, 1);
3479+
fail("expected ReadOnlyBufferException at ofst=1");
3480+
} catch (java.nio.ReadOnlyBufferException e) { /* expected */ }
3481+
pass("\t... passed");
3482+
}
32563483
}

0 commit comments

Comments
 (0)