1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.xnet.tests.javax.net.ssl;
19
20import java.nio.ByteBuffer;
21import java.nio.ReadOnlyBufferException;
22
23import javax.net.ssl.SSLEngine;
24import javax.net.ssl.SSLException;
25import javax.net.ssl.SSLParameters;
26import javax.net.ssl.SSLEngineResult.HandshakeStatus;
27import javax.net.ssl.SSLSession;
28import javax.net.ssl.SSLEngineResult;
29
30import junit.framework.TestCase;
31
32/**
33 * Tests for SSLEngine class
34 */
35
36public class SSLEngineTest extends TestCase {
37
38    /**
39     * Test for <code>SSLEngine()</code> constructor Assertion: creates
40     * SSLEngine object with null host and -1 port
41     */
42    public void test01() {
43        SSLEngine e = new mySSLEngine();
44        assertNull(e.getPeerHost());
45        assertEquals(-1, e.getPeerPort());
46        String[] suites = { "a", "b", "c" };
47        e.setEnabledCipherSuites(suites);
48        assertEquals(e.getEnabledCipherSuites().length, suites.length);
49    }
50
51    /**
52     * Test for <code>SSLEngine(String host, int port)</code> constructor
53     */
54    public void test02() throws SSLException {
55        int port = 1010;
56        SSLEngine e = new mySSLEngine(null, port);
57        assertNull(e.getPeerHost());
58        assertEquals(e.getPeerPort(), port);
59        try {
60            e.beginHandshake();
61        } catch (SSLException ex) {
62        }
63    }
64
65    /**
66     * Test for <code>SSLEngine(String host, int port)</code> constructor
67     */
68    public void test03() {
69        String host = "new host";
70        int port = 8080;
71        SSLEngine e = new mySSLEngine(host, port);
72        assertEquals(e.getPeerHost(), host);
73        assertEquals(e.getPeerPort(), port);
74        String[] suites = { "a", "b", "c" };
75        e.setEnabledCipherSuites(suites);
76        assertEquals(e.getEnabledCipherSuites().length, suites.length);
77        e.setUseClientMode(true);
78        assertTrue(e.getUseClientMode());
79    }
80
81    /**
82     * Test for <code>wrap(ByteBuffer src, ByteBuffer dst)</code> method
83     * Assertions:
84     * throws IllegalArgumentException when src or dst is null
85     * throws ReadOnlyBufferException when dst is ReadOnly byte buffer
86     * <p/>
87     * Check that implementation behavior follows RI:
88     * jdk 1.5 does not throw IllegalArgumentException when parameters are null
89     * and does not throw ReadOnlyBufferException if dst is read only byte buffer
90     */
91    public void testWrap01() throws SSLException {
92        String host = "new host";
93        int port = 8080;
94        ByteBuffer bbN = null;
95        ByteBuffer bb = ByteBuffer.allocate(10);
96        SSLEngine e = new mySSLEngine(host, port);
97
98        e.wrap(bbN, bb);
99        e.wrap(bb, bbN);
100
101        ByteBuffer roBb = bb.asReadOnlyBuffer();
102        assertTrue("Not read only byte buffer", roBb.isReadOnly());
103        e.wrap(bb, roBb);
104
105    }
106
107    /**
108     * Test for <code>wrap(ByteBuffer[] srcs, ByteBuffer dst)</code> method
109     * <p/>
110     * Assertions: throws IllegalArgumentException when srcs or dst is null or
111     * srcs contains null byte buffer; throws ReadOnlyBufferException when dst
112     * is read only byte buffer
113     * <p/>
114     * Check that implementation behavior follows RI:
115     * jdk 1.5 does not throw IllegalArgumentException when dst is null or
116     * if srcs contains null elements It does not throw ReadOnlyBufferException
117     * for read only dst
118     */
119    public void testWrap02() throws SSLException {
120        String host = "new host";
121        int port = 8080;
122        ByteBuffer[] bbNA = null;
123        ByteBuffer[] bbA = { null, ByteBuffer.allocate(10), null };
124
125        ByteBuffer bb = ByteBuffer.allocate(10);
126        ByteBuffer bbN = null;
127        SSLEngine e = new mySSLEngine(host, port);
128        try {
129            e.wrap(bbNA, bb);
130            fail("IllegalArgumentException must be thrown for null srcs byte buffer array");
131        } catch (IllegalArgumentException ex) {
132        }
133
134        e.wrap(bbA, bb);
135        e.wrap(bbA, bbN);
136
137        ByteBuffer roBb = bb.asReadOnlyBuffer();
138        bbA[0] = ByteBuffer.allocate(100);
139        bbA[2] = ByteBuffer.allocate(20);
140        assertTrue("Not read only byte buffer", roBb.isReadOnly());
141
142        e.wrap(bbA, roBb);
143
144    }
145
146    /**
147     * Test for <code>wrap(ByteBuffer src, ByteBuffer dst)</code> and
148     * <code>wrap(ByteBuffer[] srcs, ByteBuffer dst)</code> methods
149     * <p/>
150     * Assertion: these methods throw SSLException
151     */
152    public void testWrap03() throws SSLException {
153        String host = "new host";
154        int port = 8080;
155        ByteBuffer bbs = ByteBuffer.allocate(100);
156        ByteBuffer bbd = ByteBuffer.allocate(10);
157        SSLEngine e = new mySSLEngine1(host, port);
158        try {
159            e.wrap(bbs, bbd);
160            fail("SSLException must be thrown");
161        } catch (SSLException ex) {
162        }
163        SSLEngineResult res = e.wrap(bbd, bbs);
164        assertEquals(10, res.bytesConsumed());
165        assertEquals(20, res.bytesProduced());
166
167        try {
168            e.wrap(new ByteBuffer[] { bbs }, bbd);
169            fail("SSLException must be thrown");
170        } catch (SSLException ex) {
171        }
172        res = e.wrap(new ByteBuffer[] { bbd }, bbs);
173        assertEquals(10, res.bytesConsumed());
174        assertEquals(20, res.bytesProduced());
175    }
176
177    /**
178     * Test for <code>wrap(ByteBuffer src, ByteBuffer dst)</code> method
179     * <p/>
180     * Assertion: encodes a buffer data into network data.
181     */
182    public void testWrap04() throws SSLException {
183        String host = "new host";
184        int port = 8080;
185        ByteBuffer bb = ByteBuffer.allocate(10);
186        SSLEngine e = new mySSLEngine(host, port);
187
188        SSLEngineResult res = e.wrap(bb, ByteBuffer.allocate(10));
189        assertEquals(10, res.bytesConsumed());
190        assertEquals(20, res.bytesProduced());
191    }
192
193    /**
194     * Test for <code>wrap(ByteBuffer[] srcs, ByteBuffer dst)</code> method
195     * <p/>
196     * Assertion: encodes datas from buffers into network data.
197     */
198    public void testWrap05() throws SSLException {
199        String host = "new host";
200        int port = 8080;
201
202        ByteBuffer bb = ByteBuffer.allocate(10);
203        ByteBuffer[] bbA = { ByteBuffer.allocate(5), ByteBuffer.allocate(10), ByteBuffer.allocate(5) };
204
205        SSLEngine e = new mySSLEngine(host, port);
206
207        SSLEngineResult res = e.wrap(bbA, bb);
208        assertEquals(10, res.bytesConsumed());
209        assertEquals(20, res.bytesProduced());
210    }
211
212    /**
213     * Test for <code>unwrap(ByteBuffer src, ByteBuffer dst)</code> method
214     * <p/>
215     * Assertions:
216     * throws IllegalArgumentException when src or dst is null
217     * throws ReadOnlyBufferException when dst is read only byte buffer
218     * <p/>
219     * Check that implementation behavior follows RI:
220     * jdk 1.5 does not throw IllegalArgumentException when parameters are null
221     * and does not throw ReadOnlyBufferException if dst is read only byte buffer
222     */
223    public void testUnwrap01() throws SSLException {
224        String host = "new host";
225        int port = 8080;
226        ByteBuffer bbN = null;
227        ByteBuffer bb = ByteBuffer.allocate(10);
228        SSLEngine e = new mySSLEngine(host, port);
229
230        e.unwrap(bbN, bb);
231        e.unwrap(bb, bbN);
232
233        ByteBuffer roBb = bb.asReadOnlyBuffer();
234        assertTrue("Not read only byte buffer", roBb.isReadOnly());
235
236        e.unwrap(bb, roBb);
237    }
238
239    /**
240     * Test for <code>unwrap(ByteBuffer src, ByteBuffer[] dsts)</code> method
241     * <p/>
242     * Assertions: throws IllegalArgumentException if parameters are null or
243     * when dsts contains null elements throws ReadOnlyBufferException when dsts
244     * contains read only elements
245     * <p/>
246     * Check that implementation behavior follows RI:
247     * jdk 1.5 does not throw IllegalArgumentException when src is null or
248     * if dsts contains null elements It does not throw ReadOnlyBufferException
249     * when dsts contains read only elements
250     */
251    public void testUnwrap02() throws SSLException {
252        String host = "new host";
253        int port = 8080;
254        ByteBuffer[] bbNA = null;
255        ByteBuffer[] bbA = { null, ByteBuffer.allocate(10), null };
256
257        ByteBuffer bb = ByteBuffer.allocate(10);
258        ByteBuffer bbN = null;
259        SSLEngine e = new mySSLEngine(host, port);
260        try {
261            e.unwrap(bb, bbNA);
262            fail("IllegalArgumentException must be thrown for null dsts byte buffer array");
263        } catch (IllegalArgumentException ex) {
264        }
265
266        e.unwrap(bb, bbA);
267        e.unwrap(bbN, bbA);
268
269        ByteBuffer bb1 = ByteBuffer.allocate(100);
270        ByteBuffer roBb = bb1.asReadOnlyBuffer();
271        bbA[0] = bb1;
272        bbA[2] = roBb;
273        assertTrue("Not read only byte buffer", bbA[2].isReadOnly());
274
275        e.unwrap(bb, bbA);
276
277    }
278
279    /**
280     * Test for <code>unwrap(ByteBuffersrc, ByteBuffer dst)</code> and
281     * <code>unwrap(ByteBuffer src, ByteBuffer[] dsts)</code> methods
282     * <p/>
283     * Assertion: these methods throw SSLException
284     */
285    public void testUnwrap03() throws SSLException {
286        ByteBuffer bbs = ByteBuffer.allocate(100);
287        ByteBuffer bbd = ByteBuffer.allocate(10);
288        SSLEngine e = new mySSLEngine1();
289        try {
290            e.unwrap(bbs, bbd);
291            fail("SSLException must be thrown");
292        } catch (SSLException ex) {
293        }
294        SSLEngineResult res = e.unwrap(bbd, bbs);
295        assertEquals(1, res.bytesConsumed());
296        assertEquals(2, res.bytesProduced());
297
298        try {
299            e.unwrap(bbs, new ByteBuffer[] { bbd });
300            fail("SSLException must be thrown");
301        } catch (SSLException ex) {
302        }
303        res = e.unwrap(bbd, new ByteBuffer[] { bbs });
304        assertEquals(1, res.bytesConsumed());
305        assertEquals(2, res.bytesProduced());
306    }
307
308    /**
309     * Test for <code>unwrap(ByteBuffer src, ByteBuffer dst)</code> method
310     * <p/>
311     * Assertion: decodes  network data into a data buffer.
312     */
313    public void testUnwrap04() throws SSLException {
314        String host = "new host";
315        int port = 8080;
316        ByteBuffer bb = ByteBuffer.allocate(10);
317        SSLEngine e = new mySSLEngine(host, port);
318        SSLEngineResult res = e.unwrap(bb, ByteBuffer.allocate(10));
319
320        assertEquals(1, res.bytesConsumed());
321        assertEquals(2, res.bytesProduced());
322    }
323
324    /**
325     * Test for <code>unwrap(ByteBuffer src, ByteBuffer[] dsts)</code> method
326     * <p/>
327     * Assertion:
328     * decode network data into data buffers.
329     */
330    public void testUnwrap05() throws SSLException {
331        String host = "new host";
332        int port = 8080;
333        ByteBuffer[] bbA = { ByteBuffer.allocate(100), ByteBuffer.allocate(10), ByteBuffer.allocate(100) };
334
335        ByteBuffer bb = ByteBuffer.allocate(10);
336        SSLEngine e = new mySSLEngine(host, port);
337
338        SSLEngineResult res = e.unwrap(bb, bbA);
339        assertEquals(1, res.bytesConsumed());
340        assertEquals(2, res.bytesProduced());
341    }
342}
343
344/*
345 * Additional class for verification SSLEngine constructors
346 */
347
348class mySSLEngine extends SSLEngine {
349
350    private boolean useClientMode;
351
352    private boolean needClientAuth;
353
354    private boolean enableSessionCreation;
355
356    private boolean wantClientAuth;
357
358    private String[] enabledProtocols;
359
360    private String[] enabledCipherSuites;
361
362    public mySSLEngine() {
363        super();
364    }
365
366    protected mySSLEngine(String host, int port) {
367        super(host, port);
368    }
369
370    @Override
371    public void beginHandshake() throws SSLException {
372        String host = super.getPeerHost();
373        if ((host == null) || (host.length() == 0)) {
374            throw new SSLException("");
375        }
376    }
377
378    @Override
379    public void closeInbound() throws SSLException {
380    }
381
382    @Override
383    public void closeOutbound() {
384    }
385
386    @Override
387    public Runnable getDelegatedTask() {
388        return null;
389    }
390
391    @Override
392    public String[] getEnabledCipherSuites() {
393        return enabledCipherSuites;
394    }
395
396    @Override
397    public String[] getEnabledProtocols() {
398        return enabledProtocols;
399    }
400
401    @Override
402    public boolean getEnableSessionCreation() {
403        return enableSessionCreation;
404    }
405
406    @Override
407    public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
408        return SSLEngineResult.HandshakeStatus.FINISHED;
409    }
410
411    @Override
412    public boolean getNeedClientAuth() {
413        return needClientAuth;
414    }
415
416    @Override
417    public SSLSession getSession() {
418        return null;
419    }
420
421    @Override
422    public String[] getSupportedCipherSuites() {
423        return new String[0];
424    }
425
426    @Override
427    public String[] getSupportedProtocols() {
428        return new String[0];
429    }
430
431    @Override
432    public boolean getUseClientMode() {
433        return useClientMode;
434    }
435
436    @Override
437    public boolean getWantClientAuth() {
438        return wantClientAuth;
439    }
440
441    @Override
442    public boolean isInboundDone() {
443        return false;
444    }
445
446    @Override
447    public boolean isOutboundDone() {
448        return false;
449    }
450
451    @Override
452    public void setEnabledCipherSuites(String[] suites) {
453        enabledCipherSuites = suites;
454    }
455
456    @Override
457    public void setEnabledProtocols(String[] protocols) {
458        enabledProtocols = protocols;
459    }
460
461    @Override
462    public void setEnableSessionCreation(boolean flag) {
463        enableSessionCreation = flag;
464    }
465
466    @Override
467    public void setNeedClientAuth(boolean need) {
468        needClientAuth = need;
469    }
470
471    @Override
472    public void setUseClientMode(boolean mode) {
473        useClientMode = mode;
474    }
475
476    @Override
477    public void setWantClientAuth(boolean want) {
478        wantClientAuth = want;
479    }
480
481    @Override
482    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts,
483            int offset, int length) throws SSLException {
484        return new SSLEngineResult(SSLEngineResult.Status.OK,
485                SSLEngineResult.HandshakeStatus.FINISHED, 1, 2);
486    }
487
488    @Override
489    public SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length,
490            ByteBuffer dst) throws SSLException {
491        return new SSLEngineResult(SSLEngineResult.Status.OK,
492                SSLEngineResult.HandshakeStatus.FINISHED, 10, 20);
493    }
494
495    @Override
496    public SSLParameters getSSLParameters() {
497        // TODO Auto-generated method stub
498        return null;
499    }
500
501    @Override
502    public void setSSLParameters(SSLParameters sslP) {
503        // TODO Auto-generated method stub
504
505    }
506}
507
508class mySSLEngine1 extends mySSLEngine {
509
510    public mySSLEngine1() {
511    }
512
513    public mySSLEngine1(String host, int port) {
514        super(host, port);
515    }
516
517    @Override
518    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst)
519            throws SSLException {
520        if (src.limit() > dst.limit()) {
521            throw new SSLException("incorrect limits");
522        }
523        return super.unwrap(src, dst);
524    }
525
526    @Override
527    public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts)
528            throws SSLException {
529        if (src.limit() > dsts[0].limit()) {
530            throw new SSLException("incorrect limits");
531        }
532        return super.unwrap(src, dsts);
533    }
534
535    @Override
536    public SSLEngineResult wrap(ByteBuffer[] srcs, ByteBuffer dst)
537            throws SSLException {
538        if (srcs[0].limit() > dst.limit()) {
539            throw new SSLException("incorrect limits");
540        }
541        return super.wrap(srcs, dst);
542    }
543
544    @Override
545    public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst)
546            throws SSLException {
547        if (src.limit() > dst.limit()) {
548            throw new SSLException("incorrect limits");
549        }
550        return super.wrap(src, dst);
551    }
552
553}
554