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.provider.jsse;
19
20import java.io.IOException;
21import java.net.Socket;
22import java.net.InetSocketAddress;
23import javax.net.ssl.SSLServerSocket;
24
25import junit.framework.Test;
26import junit.framework.TestCase;
27import junit.framework.TestSuite;
28
29/**
30 * SSLServerSocketImplTest test
31 */
32public class SSLServerSocketImplTest extends TestCase {
33
34    private static boolean doLog = false;
35
36    /**
37     * Sets up the test case.
38     */
39    @Override
40    public void setUp() {
41        if (doLog) {
42            System.out.println("");
43            System.out.println("========================");
44            System.out.println("====== Running the test: " + getName());
45        }
46    }
47
48    private SSLServerSocket createSSLServerSocket() throws Exception {
49        return new SSLServerSocketImpl(JSSETestData.getSSLParameters());
50    }
51
52    /**
53     * SSLServerSocketImpl(SSLParameters sslParameters) method testing.
54     */
55    public void testSSLServerSocketImpl1() throws Exception {
56        Client client = null;
57        SSLServerSocket ssocket = null;
58        try {
59            ssocket = new SSLServerSocketImpl(JSSETestData.getSSLParameters());
60            ssocket.bind(null);
61            ssocket.setUseClientMode(true);
62
63            final SSLServerSocket s = ssocket;
64            Thread thread = new Thread() {
65                @Override
66                public void run() {
67                    try {
68                        s.accept().close();
69                    } catch (Exception e) {
70                    }
71                }
72            };
73
74            thread.start();
75
76            client = new Client(ssocket.getLocalPort());
77            client.start();
78
79            int timeout = 10; // wait no more than 5 seconds for handshake
80            while (!client.handshakeStarted()) {
81                // wait for handshake start
82                try {
83                    Thread.sleep(500);
84                } catch (Exception e) {
85                }
86                timeout--;
87                if (timeout < 0) {
88                    try {
89                        client.close();
90                    } catch (IOException ex) {
91                    }
92                    try {
93                        ssocket.close();
94                    } catch (IOException ex) {
95                    }
96                    fail("Handshake was not started");
97                }
98            }
99        } finally {
100            if (client != null) {
101                try {
102                    client.close();
103                } catch (IOException ex) {
104                }
105            }
106            if (ssocket != null) {
107                try {
108                    ssocket.close();
109                } catch (IOException ex) {
110                }
111            }
112        }
113    }
114
115    /**
116     * SSLServerSocketImpl(int port, SSLParameters sslParameters) method
117     * testing.
118     */
119    public void testSSLServerSocketImpl2() throws Exception {
120        Client client = null;
121        SSLServerSocket ssocket = null;
122        try {
123            ssocket = new SSLServerSocketImpl(0,
124                    JSSETestData.getSSLParameters());
125            ssocket.setUseClientMode(true);
126
127            final SSLServerSocket s = ssocket;
128            Thread thread = new Thread() {
129                @Override
130                public void run() {
131                    try {
132                        s.accept().close();
133                    } catch (Exception e) {
134                    }
135                }
136            };
137
138            thread.start();
139
140            client = new Client(ssocket.getLocalPort());
141            client.start();
142
143            int timeout = 10; // wait no more than 5 seconds for handshake
144            while (!client.handshakeStarted()) {
145                // wait for handshake start
146                try {
147                    Thread.sleep(500);
148                } catch (Exception e) {
149                }
150                timeout--;
151                if (timeout < 0) {
152                    try {
153                        client.close();
154                    } catch (IOException ex) {
155                    }
156                    try {
157                        ssocket.close();
158                    } catch (IOException ex) {
159                    }
160                    fail("Handshake was not started");
161                }
162            }
163        } finally {
164            if (client != null) {
165                try {
166                    client.close();
167                } catch (IOException ex) {
168                }
169            }
170            if (ssocket != null) {
171                try {
172                    ssocket.close();
173                } catch (IOException ex) {
174                }
175            }
176        }
177    }
178
179    /**
180     * SSLServerSocketImpl(int port, int backlog,
181     * SSLParameters sslParameters) method testing.
182     */
183    public void testSSLServerSocketImpl3() throws Exception {
184        Client client = null;
185        SSLServerSocket ssocket = null;
186        try {
187            ssocket = new SSLServerSocketImpl(0, 1,
188                    JSSETestData.getSSLParameters());
189            ssocket.setUseClientMode(true);
190
191            final SSLServerSocket s = ssocket;
192            Thread thread = new Thread() {
193                @Override
194                public void run() {
195                    try {
196                        s.accept().close();
197                    } catch (Exception e) {
198                    }
199                }
200            };
201
202            thread.start();
203
204            client = new Client(ssocket.getLocalPort());
205            client.start();
206
207            int timeout = 10; // wait no more than 5 seconds for handshake
208            while (!client.handshakeStarted()) {
209                // wait for handshake start
210                try {
211                    Thread.sleep(500);
212                } catch (Exception e) {
213                }
214                timeout--;
215                if (timeout < 0) {
216                    try {
217                        client.close();
218                    } catch (IOException ex) {
219                    }
220                    try {
221                        ssocket.close();
222                    } catch (IOException ex) {
223                    }
224                    fail("Handshake was not started");
225                }
226            }
227        } finally {
228            if (client != null) {
229                try {
230                    client.close();
231                } catch (IOException ex) {
232                }
233            }
234            if (ssocket != null) {
235                try {
236                    ssocket.close();
237                } catch (IOException ex) {
238                }
239            }
240        }
241    }
242
243    /**
244     * SSLServerSocketImpl(int port, int backlog, InetAddress iAddress,
245     * SSLParameters sslParameters) method testing.
246     */
247    public void testSSLServerSocketImpl4() throws Exception {
248        Client client = null;
249        SSLServerSocket ssocket = null;
250        try {
251            ssocket = new SSLServerSocketImpl(0, 1, null,
252                    JSSETestData.getSSLParameters());
253            ssocket.setUseClientMode(true);
254
255            final SSLServerSocket s = ssocket;
256            Thread thread = new Thread() {
257                @Override
258                public void run() {
259                    try {
260                        s.accept().close();
261                    } catch (Exception e) {
262                    }
263                }
264            };
265
266            thread.start();
267
268            client = new Client(ssocket.getLocalPort());
269            client.start();
270
271            int timeout = 10; // wait no more than 5 seconds for handshake
272            while (!client.handshakeStarted()) {
273                // wait for handshake start
274                try {
275                    Thread.sleep(500);
276                } catch (Exception e) {
277                }
278                timeout--;
279                if (timeout < 0) {
280                    try {
281                        client.close();
282                    } catch (IOException ex) {
283                    }
284                    try {
285                        ssocket.close();
286                    } catch (IOException ex) {
287                    }
288                    fail("Handshake was not started");
289                }
290            }
291        } finally {
292            if (client != null) {
293                try {
294                    client.close();
295                } catch (IOException ex) {
296                }
297            }
298            if (ssocket != null) {
299                try {
300                    ssocket.close();
301                } catch (IOException ex) {
302                }
303            }
304        }
305    }
306
307    /**
308     * getSupportedCipherSuites() method testing.
309     */
310    public void testGetSupportedCipherSuites() throws Exception {
311        SSLServerSocket ssocket = createSSLServerSocket();
312        String[] supported = ssocket.getSupportedCipherSuites();
313        assertNotNull(supported);
314        supported[0] = "NOT_SUPPORTED_CIPHER_SUITE";
315        supported = ssocket.getEnabledCipherSuites();
316        for (int i = 0; i < supported.length; i++) {
317            if ("NOT_SUPPORTED_CIPHER_SUITE".equals(supported[i])) {
318                fail("Modification of the returned result "
319                        + "causes the modification of the internal state");
320            }
321        }
322    }
323
324    /**
325     * getEnabledCipherSuites() method testing.
326     */
327    public void testGetEnabledCipherSuites() throws Exception {
328        SSLServerSocket ssocket = createSSLServerSocket();
329        String[] enabled = ssocket.getEnabledCipherSuites();
330        assertNotNull(enabled);
331        String[] supported = ssocket.getSupportedCipherSuites();
332        for (int i = 0; i < enabled.length; i++) {
333            //System.out.println("Checking of "+enabled[i]);
334            found:
335            {
336                for (int j = 0; j < supported.length; j++) {
337                    if (enabled[i].equals(supported[j])) {
338                        break found;
339                    }
340                }
341                fail("Enabled suite does not belong to the set "
342                        + "of supported cipher suites: " + enabled[i]);
343            }
344        }
345        ssocket.setEnabledCipherSuites(supported);
346        for (int i = 0; i < supported.length; i++) {
347            enabled = new String[supported.length - i];
348            System.arraycopy(supported, 0,
349                    enabled, 0, supported.length - i);
350            ssocket.setEnabledCipherSuites(enabled);
351            String[] result = ssocket.getEnabledCipherSuites();
352            if (result.length != enabled.length) {
353                fail("Returned result does not correspond to expected.");
354            }
355            for (int k = 0; k < result.length; k++) {
356                found:
357                {
358                    for (int n = 0; n < enabled.length; n++) {
359                        if (result[k].equals(enabled[n])) {
360                            break found;
361                        }
362                    }
363                    if (result.length != enabled.length) {
364                        fail("Returned result does not correspond "
365                                + "to expected.");
366                    }
367                }
368            }
369        }
370    }
371
372    /**
373     * setEnabledCipherSuites(String[] suites) method testing.
374     */
375    public void testSetEnabledCipherSuites() throws Exception {
376        SSLServerSocket ssocket = createSSLServerSocket();
377        String[] enabled = ssocket.getEnabledCipherSuites();
378        assertNotNull(enabled);
379        String[] supported = ssocket.getSupportedCipherSuites();
380        for (int i = 0; i < enabled.length; i++) {
381            //System.out.println("Checking of "+enabled[i]);
382            found:
383            {
384                for (int j = 0; j < supported.length; j++) {
385                    if (enabled[i].equals(supported[j])) {
386                        break found;
387                    }
388                }
389                fail("Enabled suite does not belong to the set "
390                        + "of supported cipher suites: " + enabled[i]);
391            }
392        }
393        ssocket.setEnabledCipherSuites(supported);
394        ssocket.setEnabledCipherSuites(enabled);
395        ssocket.setEnabledCipherSuites(supported);
396        String[] more_than_supported = new String[supported.length + 1];
397        for (int i = 0; i < supported.length + 1; i++) {
398            more_than_supported[i]
399                    = "NOT_SUPPORTED_CIPHER_SUITE";
400            System.arraycopy(supported, 0,
401                    more_than_supported, 0, i);
402            System.arraycopy(supported, i,
403                    more_than_supported, i + 1, supported.length - i);
404            try {
405                ssocket.setEnabledCipherSuites(more_than_supported);
406                fail("Expected IllegalArgumentException was not thrown");
407            } catch (IllegalArgumentException e) {
408            }
409        }
410        enabled = ssocket.getEnabledCipherSuites();
411        enabled[0] = "NOT_SUPPORTED_CIPHER_SUITE";
412        enabled = ssocket.getEnabledCipherSuites();
413        for (int i = 0; i < enabled.length; i++) {
414            if ("NOT_SUPPORTED_CIPHER_SUITE".equals(enabled[i])) {
415                fail("Modification of the returned result "
416                        + "causes the modification of the internal state");
417            }
418        }
419    }
420
421    /**
422     * getSupportedProtocols() method testing.
423     */
424    public void testGetSupportedProtocols() throws Exception {
425        SSLServerSocket ssocket = createSSLServerSocket();
426        String[] supported = ssocket.getSupportedProtocols();
427        assertNotNull(supported);
428        assertFalse(supported.length == 0);
429        supported[0] = "NOT_SUPPORTED_PROTOCOL";
430        supported = ssocket.getSupportedProtocols();
431        for (int i = 0; i < supported.length; i++) {
432            if ("NOT_SUPPORTED_PROTOCOL".equals(supported[i])) {
433                fail("Modification of the returned result "
434                        + "causes the modification of the internal state");
435            }
436        }
437    }
438
439    /**
440     * getEnabledProtocols() method testing.
441     */
442    public void testGetEnabledProtocols() throws Exception {
443        SSLServerSocket ssocket = createSSLServerSocket();
444        String[] enabled = ssocket.getEnabledProtocols();
445        assertNotNull(enabled);
446        String[] supported = ssocket.getSupportedProtocols();
447        for (int i = 0; i < enabled.length; i++) {
448            //System.out.println("Checking of "+enabled[i]);
449            found:
450            {
451                for (int j = 0; j < supported.length; j++) {
452                    if (enabled[i].equals(supported[j])) {
453                        break found;
454                    }
455                }
456                fail("Enabled protocol does not belong to the set "
457                        + "of supported protocols: " + enabled[i]);
458            }
459        }
460        ssocket.setEnabledProtocols(supported);
461        for (int i = 0; i < supported.length; i++) {
462            enabled = new String[supported.length - i];
463            System.arraycopy(supported, i,
464                    enabled, 0, supported.length - i);
465            //System.out.println("");
466            //for (int k=0; k<supported.length - i; k++) {
467            //    System.out.println("---- "+enabled[k]);
468            //}
469            ssocket.setEnabledProtocols(enabled);
470            String[] result = ssocket.getEnabledProtocols();
471            if (result.length != enabled.length) {
472                fail("Returned result does not correspond to expected.");
473            }
474            for (int k = 0; k < result.length; k++) {
475                found:
476                {
477                    for (int n = 0; n < enabled.length; n++) {
478                        if (result[k].equals(enabled[n])) {
479                            break found;
480                        }
481                    }
482                    if (result.length != enabled.length) {
483                        fail("Returned result does not correspond "
484                                + "to expected.");
485                    }
486                }
487            }
488        }
489    }
490
491    /**
492     * setEnabledProtocols(String[] protocols) method testing.
493     */
494    public void testSetEnabledProtocols() throws Exception {
495        SSLServerSocket ssocket = createSSLServerSocket();
496        String[] enabled = ssocket.getEnabledProtocols();
497        assertNotNull(enabled);
498        String[] supported = ssocket.getSupportedProtocols();
499        for (int i = 0; i < enabled.length; i++) {
500            //System.out.println("Checking of "+enabled[i]);
501            found:
502            {
503                for (int j = 0; j < supported.length; j++) {
504                    if (enabled[i].equals(supported[j])) {
505                        break found;
506                    }
507                }
508                fail("Enabled suite does not belong to the set "
509                        + "of supported cipher suites: " + enabled[i]);
510            }
511        }
512        ssocket.setEnabledProtocols(supported);
513        ssocket.setEnabledProtocols(enabled);
514        ssocket.setEnabledProtocols(supported);
515        String[] more_than_supported = new String[supported.length + 1];
516        for (int i = 0; i < supported.length + 1; i++) {
517            more_than_supported[i]
518                    = "NOT_SUPPORTED_PROTOCOL";
519            System.arraycopy(supported, 0,
520                    more_than_supported, 0, i);
521            System.arraycopy(supported, i,
522                    more_than_supported, i + 1, supported.length - i);
523            try {
524                ssocket.setEnabledProtocols(more_than_supported);
525                fail("Expected IllegalArgumentException was not thrown");
526            } catch (IllegalArgumentException e) {
527            }
528        }
529        enabled = ssocket.getEnabledProtocols();
530        enabled[0] = "NOT_SUPPORTED_PROTOCOL";
531        enabled = ssocket.getEnabledProtocols();
532        for (int i = 0; i < enabled.length; i++) {
533            if ("NOT_SUPPORTED_PROTOCOL".equals(enabled[i])) {
534                fail("Modification of the returned result "
535                        + "causes the modification of the internal state");
536            }
537        }
538    }
539
540    /**
541     * setUseClientMode(boolean mode) method testing.
542     * getUseClientMode() method testing.
543     */
544    public void testSetGetUseClientMode() throws Exception {
545        SSLServerSocket ssocket = createSSLServerSocket();
546
547        ssocket.setUseClientMode(false);
548        assertFalse("Result does not correspond to expected",
549                ssocket.getUseClientMode());
550        ssocket.setUseClientMode(true);
551        assertTrue("Result does not correspond to expected",
552                ssocket.getUseClientMode());
553    }
554
555    /**
556     * setNeedClientAuth(boolean need) method testing.
557     * getNeedClientAuth() method testing.
558     */
559    public void testSetGetNeedClientAuth() throws Exception {
560        SSLServerSocket ssocket = createSSLServerSocket();
561
562        ssocket.setWantClientAuth(true);
563        ssocket.setNeedClientAuth(false);
564        assertFalse("Result does not correspond to expected",
565                ssocket.getNeedClientAuth());
566        assertFalse("Socket did not reset its want client auth state",
567                ssocket.getWantClientAuth());
568        ssocket.setWantClientAuth(true);
569        ssocket.setNeedClientAuth(true);
570        assertTrue("Result does not correspond to expected",
571                ssocket.getNeedClientAuth());
572        assertFalse("Socket did not reset its want client auth state",
573                ssocket.getWantClientAuth());
574    }
575
576    /**
577     * setWantClientAuth(boolean want) method testing.
578     * getWantClientAuth() method testing.
579     */
580    public void testSetGetWantClientAuth() throws Exception {
581        SSLServerSocket ssocket = createSSLServerSocket();
582
583        ssocket.setNeedClientAuth(true);
584        ssocket.setWantClientAuth(false);
585        assertFalse("Result does not correspond to expected",
586                ssocket.getWantClientAuth());
587        assertFalse("Socket did not reset its want client auth state",
588                ssocket.getNeedClientAuth());
589        ssocket.setNeedClientAuth(true);
590        ssocket.setWantClientAuth(true);
591        assertTrue("Result does not correspond to expected",
592                ssocket.getWantClientAuth());
593        assertFalse("Socket did not reset its want client auth state",
594                ssocket.getNeedClientAuth());
595    }
596
597    /**
598     * setEnableSessionCreation(boolean flag) method testing.
599     * getEnableSessionCreation() method testing.
600     */
601    public void testSetGetEnableSessionCreation() throws Exception {
602        SSLServerSocket ssocket = createSSLServerSocket();
603
604        ssocket.setEnableSessionCreation(false);
605        assertFalse("Result does not correspond to expected",
606                ssocket.getEnableSessionCreation());
607        ssocket.setEnableSessionCreation(true);
608        assertTrue("Result does not correspond to expected",
609                ssocket.getEnableSessionCreation());
610    }
611
612    /**
613     * toString() method testing.
614     */
615    public void testToString() throws Exception {
616        SSLServerSocket ssocket = createSSLServerSocket();
617        assertNotNull("String representation is null", ssocket.toString());
618    }
619
620    private static class Client extends Thread {
621
622        private boolean closed;
623        private boolean handshake_started = false;
624        private Socket client = null;
625        private int port;
626
627        public Client(int port) throws IOException {
628            super();
629            this.port = port;
630            client = new Socket();
631            client.setSoTimeout(10000);
632        }
633
634        public int getPort() {
635            return client.getLocalPort();
636        }
637
638        @Override
639        public void run() {
640            while (!closed) {
641                try {
642                    if (doLog) {
643                        System.out.print(".");
644                    }
645                    if (!handshake_started) {
646                        client.connect(
647                                new InetSocketAddress("localhost", port));
648                        client.getInputStream().read();
649                        handshake_started = true;
650                    }
651                    Thread.sleep(1000);
652                } catch (Exception e) {
653                    e.printStackTrace();
654                }
655            }
656            if (client != null) {
657                try {
658                    client.close();
659                } catch (IOException e) {
660                }
661            }
662            //System.out.println("===== client has been stopped");
663        }
664
665        public boolean handshakeStarted() {
666            return handshake_started;
667        }
668
669        public void close() throws IOException {
670            closed = true;
671            client.close();
672        }
673
674    }
675
676    ;
677
678    public static Test suite() {
679        return new TestSuite(SSLServerSocketImplTest.class);
680    }
681
682}
683