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