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 com.squareup.okhttp.internal;
19
20import com.android.org.conscrypt.OpenSSLSocketImpl;
21import com.squareup.okhttp.Protocol;
22
23import org.junit.Test;
24
25import java.io.IOException;
26import java.util.Arrays;
27import java.util.List;
28import javax.net.ssl.HandshakeCompletedListener;
29import javax.net.ssl.SSLSession;
30import javax.net.ssl.SSLSocket;
31
32import okio.ByteString;
33
34import static org.junit.Assert.assertEquals;
35import static org.junit.Assert.assertNotNull;
36import static org.junit.Assert.assertNull;
37import static org.junit.Assert.assertTrue;
38
39/**
40 * Tests for {@link Platform}.
41 */
42public class PlatformTest {
43
44  @Test
45  public void enableTlsExtensionOptionalMethods() throws Exception {
46    Platform platform = new Platform();
47
48    // Expect no error
49    TestSSLSocketImpl arbitrarySocketImpl = new TestSSLSocketImpl();
50    platform.enableTlsExtensions(arbitrarySocketImpl, "host");
51
52    FullOpenSSLSocketImpl openSslSocket = new FullOpenSSLSocketImpl();
53    platform.enableTlsExtensions(openSslSocket, "host");
54    assertTrue(openSslSocket.useSessionTickets);
55    assertEquals("host", openSslSocket.hostname);
56  }
57
58  @Test
59  public void getNpnSelectedProtocol() throws Exception {
60    Platform platform = new Platform();
61    byte[] npnBytes = "npn".getBytes();
62    byte[] alpnBytes = "alpn".getBytes();
63
64    TestSSLSocketImpl arbitrarySocketImpl = new TestSSLSocketImpl();
65    assertNull(platform.getNpnSelectedProtocol(arbitrarySocketImpl));
66
67    NpnOnlySSLSocketImpl npnOnlySSLSocketImpl = new NpnOnlySSLSocketImpl();
68    npnOnlySSLSocketImpl.npnProtocols = npnBytes;
69    assertEquals(ByteString.of(npnBytes), platform.getNpnSelectedProtocol(npnOnlySSLSocketImpl));
70
71    FullOpenSSLSocketImpl openSslSocket = new FullOpenSSLSocketImpl();
72    openSslSocket.npnProtocols = npnBytes;
73    openSslSocket.alpnProtocols = alpnBytes;
74    assertEquals(ByteString.of(alpnBytes), platform.getNpnSelectedProtocol(openSslSocket));
75  }
76
77  @Test
78  public void setNpnProtocols() throws Exception {
79    Platform platform = new Platform();
80    List<Protocol> protocols = Arrays.asList(Protocol.SPDY_3);
81
82    // No error
83    TestSSLSocketImpl arbitrarySocketImpl = new TestSSLSocketImpl();
84    platform.setNpnProtocols(arbitrarySocketImpl, protocols);
85
86    NpnOnlySSLSocketImpl npnOnlySSLSocketImpl = new NpnOnlySSLSocketImpl();
87    platform.setNpnProtocols(npnOnlySSLSocketImpl, protocols);
88    assertNotNull(npnOnlySSLSocketImpl.npnProtocols);
89
90    FullOpenSSLSocketImpl openSslSocket = new FullOpenSSLSocketImpl();
91    platform.setNpnProtocols(openSslSocket, protocols);
92    assertNotNull(openSslSocket.npnProtocols);
93    assertNotNull(openSslSocket.alpnProtocols);
94  }
95
96  private static class FullOpenSSLSocketImpl extends OpenSSLSocketImpl {
97    private boolean useSessionTickets;
98    private String hostname;
99    private byte[] npnProtocols;
100    private byte[] alpnProtocols;
101
102    public FullOpenSSLSocketImpl() throws IOException {
103      super(null);
104    }
105
106    @Override
107    public void setUseSessionTickets(boolean useSessionTickets) {
108      this.useSessionTickets = useSessionTickets;
109    }
110
111    @Override
112    public void setHostname(String hostname) {
113      this.hostname = hostname;
114    }
115
116    @Override
117    public void setNpnProtocols(byte[] npnProtocols) {
118      this.npnProtocols = npnProtocols;
119    }
120
121    @Override
122    public byte[] getNpnSelectedProtocol() {
123      return npnProtocols;
124    }
125
126    @Override
127    public void setAlpnProtocols(byte[] alpnProtocols) {
128      this.alpnProtocols = alpnProtocols;
129    }
130
131    @Override
132    public byte[] getAlpnSelectedProtocol() {
133      return alpnProtocols;
134    }
135  }
136
137  // Legacy case
138  private static class NpnOnlySSLSocketImpl extends TestSSLSocketImpl {
139
140    private byte[] npnProtocols;
141
142    public void setNpnProtocols(byte[] npnProtocols) {
143      this.npnProtocols = npnProtocols;
144    }
145
146    public byte[] getNpnSelectedProtocol() {
147      return npnProtocols;
148    }
149  }
150
151  private static class TestSSLSocketImpl extends SSLSocket {
152
153    @Override
154    public String[] getSupportedCipherSuites() {
155      return new String[0];
156    }
157
158    @Override
159    public String[] getEnabledCipherSuites() {
160      return new String[0];
161    }
162
163    @Override
164    public void setEnabledCipherSuites(String[] suites) {
165    }
166
167    @Override
168    public String[] getSupportedProtocols() {
169      return new String[0];
170    }
171
172    @Override
173    public String[] getEnabledProtocols() {
174      return new String[0];
175    }
176
177    @Override
178    public void setEnabledProtocols(String[] protocols) {
179    }
180
181    @Override
182    public SSLSession getSession() {
183      return null;
184    }
185
186    @Override
187    public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {
188    }
189
190    @Override
191    public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {
192    }
193
194    @Override
195    public void startHandshake() throws IOException {
196    }
197
198    @Override
199    public void setUseClientMode(boolean mode) {
200    }
201
202    @Override
203    public boolean getUseClientMode() {
204      return false;
205    }
206
207    @Override
208    public void setNeedClientAuth(boolean need) {
209    }
210
211    @Override
212    public void setWantClientAuth(boolean want) {
213    }
214
215    @Override
216    public boolean getNeedClientAuth() {
217      return false;
218    }
219
220    @Override
221    public boolean getWantClientAuth() {
222      return false;
223    }
224
225    @Override
226    public void setEnableSessionCreation(boolean flag) {
227    }
228
229    @Override
230    public boolean getEnableSessionCreation() {
231      return false;
232    }
233  }
234}
235