1d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller/*
2d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * Copyright 2014 Square Inc.
3d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller *
4d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
5d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * you may not use this file except in compliance with the License.
6d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * You may obtain a copy of the License at
7d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller *
8d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * http://www.apache.org/licenses/LICENSE-2.0
9d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller *
10d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * Unless required by applicable law or agreed to in writing, software
11d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
12d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * See the License for the specific language governing permissions and
14d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller * limitations under the License.
15d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller */
16d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerpackage com.squareup.okhttp;
17d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller
18d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerimport java.io.IOException;
19d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerimport java.net.InetAddress;
20d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerimport java.net.Socket;
21d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerimport java.util.ArrayList;
22d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerimport java.util.List;
23d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerimport javax.net.ssl.SSLSocket;
24d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerimport javax.net.ssl.SSLSocketFactory;
25d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller
26d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller/**
27e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * An SSLSocketFactory that delegates calls. Sockets created by the delegate are wrapped with ones
28e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * that will not accept the {@link #TLS_FALLBACK_SCSV} cipher, thus bypassing server-side fallback
29e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * checks on platforms that support it. Unfortunately this wrapping will disable any
30e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller * reflection-based calls to SSLSocket from Platform.
31d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller */
32d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fullerpublic class FallbackTestClientSocketFactory extends DelegatingSSLSocketFactory {
33d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller  /**
34d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller   * The cipher suite used during TLS connection fallback to indicate a fallback.
35d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller   * See https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
36d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller   */
37d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller  public static final String TLS_FALLBACK_SCSV = "TLS_FALLBACK_SCSV";
38d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller
39e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  public FallbackTestClientSocketFactory(SSLSocketFactory delegate) {
40d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller    super(delegate);
41d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller  }
42d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller
4371b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller  @Override protected SSLSocket configureSocket(SSLSocket sslSocket) throws IOException {
4471b9f47b26fb57ac3e436a19519c6e3ec70e86ebNeil Fuller    return new TlsFallbackScsvDisabledSSLSocket(sslSocket);
45d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller  }
46d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller
47e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller  private static class TlsFallbackScsvDisabledSSLSocket extends DelegatingSSLSocket {
48d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller
49e78f117bcbd6b57d783737107f445ef75ecb474aNeil Fuller    public TlsFallbackScsvDisabledSSLSocket(SSLSocket socket) {
50d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller      super(socket);
51d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller    }
52d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller
53d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller    @Override public void setEnabledCipherSuites(String[] suites) {
54d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller      List<String> enabledCipherSuites = new ArrayList<String>(suites.length);
55d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller      for (String suite : suites) {
56d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller        if (!suite.equals(TLS_FALLBACK_SCSV)) {
57d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller          enabledCipherSuites.add(suite);
58d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller        }
59d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller      }
60d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller      delegate.setEnabledCipherSuites(
61d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller          enabledCipherSuites.toArray(new String[enabledCipherSuites.size()]));
62d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller    }
63d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller  }
64d7254e38efa2f20db6cac1a5cb5ac4548edc3d46Neil Fuller}
65