Skip to content

Commit

Permalink
Merge f94875e into 8acb92d
Browse files Browse the repository at this point in the history
  • Loading branch information
MatkovIvan authored Dec 21, 2018
2 parents 8acb92d + f94875e commit 80b9e5a
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 14 deletions.
6 changes: 5 additions & 1 deletion sdk/appcenter/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@

-keepclasseswithmembers class * implements com.microsoft.appcenter.AppCenterService {
public static ** getInstance();
}
}

-keepclassmembers class * implements javax.net.ssl.SSLSocketFactory {
private javax.net.ssl.SSLSocketFactory delegate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ private String doHttpCall() throws Exception {
* Don't hardcode TLS version when enabled by default to avoid unnecessary wrapping and
* to support future versions of TLS such as say 1.3 without having to patch this code.
*/
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT_WATCH) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
urlConnection.setSSLSocketFactory(new TLS1_2SocketFactory());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

Expand All @@ -14,10 +17,35 @@
*/
class TLS1_2SocketFactory extends SSLSocketFactory {

/**
* TLS 1.2 protocol name.
*/
private static final String TLS1_2_PROTOCOL = "TLSv1.2";

/**
* Protocols that we allow.
*/
private static final String[] ENABLED_PROTOCOLS = {"TLSv1.2"};
private static final String[] ENABLED_PROTOCOLS = { TLS1_2_PROTOCOL };

/**
* Socket factory.
*
* DO NOT RENAME IT! See https://github.com/square/okhttp/issues/2323
*/
private SSLSocketFactory delegate;

TLS1_2SocketFactory() {
try {
SSLContext sc = SSLContext.getInstance(TLS1_2_PROTOCOL);
sc.init(null, null, null);
delegate = sc.getSocketFactory();
} catch (KeyManagementException ignored) {
} catch (NoSuchAlgorithmException ignored) {
}
if (delegate == null) {
delegate = getDefaultSSLSocketFactory();
}
}

/**
* Force TLS 1.2 protocol on a socket.
Expand All @@ -33,41 +61,41 @@ private SSLSocket forceTLS1_2(Socket socket) {

@Override
public String[] getDefaultCipherSuites() {
return getDefaultSSLSocketFactory().getDefaultCipherSuites();
return delegate.getDefaultCipherSuites();
}

@Override
public String[] getSupportedCipherSuites() {
return getDefaultSSLSocketFactory().getSupportedCipherSuites();
return delegate.getSupportedCipherSuites();
}

@Override
public SSLSocket createSocket() throws IOException {
return forceTLS1_2(getDefaultSSLSocketFactory().createSocket());
return forceTLS1_2(delegate.createSocket());
}

@Override
public SSLSocket createSocket(String host, int port) throws IOException {
return forceTLS1_2(getDefaultSSLSocketFactory().createSocket(host, port));
return forceTLS1_2(delegate.createSocket(host, port));
}

@Override
public SSLSocket createSocket(InetAddress host, int port) throws IOException {
return forceTLS1_2(getDefaultSSLSocketFactory().createSocket(host, port));
return forceTLS1_2(delegate.createSocket(host, port));
}

@Override
public SSLSocket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
return forceTLS1_2(getDefaultSSLSocketFactory().createSocket(host, port, localHost, localPort));
return forceTLS1_2(delegate.createSocket(host, port, localHost, localPort));
}

@Override
public SSLSocket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return forceTLS1_2(getDefaultSSLSocketFactory().createSocket(address, port, localAddress, localPort));
return forceTLS1_2(delegate.createSocket(address, port, localAddress, localPort));
}

@Override
public SSLSocket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return forceTLS1_2(getDefaultSSLSocketFactory().createSocket(socket, host, port, autoClose));
return forceTLS1_2(delegate.createSocket(socket, host, port, autoClose));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ public void tls1_2Enforcement() throws Exception {

/* Configure mock HTTP. */
mockCall();
for (int apiLevel = Build.VERSION_CODES.JELLY_BEAN; apiLevel < Build.VERSION_CODES.KITKAT_WATCH; apiLevel++) {
for (int apiLevel = Build.VERSION_CODES.JELLY_BEAN; apiLevel <= Build.VERSION_CODES.LOLLIPOP; apiLevel++) {
testTls1_2Setting(apiLevel, 1);
}
for (int apiLevel = Build.VERSION_CODES.KITKAT_WATCH; apiLevel <= Build.VERSION_CODES.O_MR1; apiLevel++) {
for (int apiLevel = Build.VERSION_CODES.LOLLIPOP_MR1; apiLevel <= Build.VERSION_CODES.O_MR1; apiLevel++) {
testTls1_2Setting(apiLevel, 0);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,34 @@
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;
import static org.powermock.api.mockito.PowerMockito.when;

@SuppressWarnings("unused")
@PrepareForTest(HttpsURLConnection.class)
@PrepareForTest({ HttpsURLConnection.class, SSLContext.class })
@RunWith(PowerMockRunner.class)
public class Tls1_2SocketFactoryTest {

Expand Down Expand Up @@ -52,6 +63,42 @@ private void checkProtocol(SSLSocket socket) {
verify(socket).setEnabledProtocols(new String[]{"TLSv1.2"});
}

@SuppressWarnings("ObviousNullCheck")
@Test
public void createFactory() throws Exception {
SSLContext sslContext = mock(SSLContext.class);
doNothing().doThrow(new KeyManagementException())
.when(sslContext).init(any(KeyManager[].class), any(TrustManager[].class), any(SecureRandom.class));
SSLSocketFactory sslSocketFactory = mock(SSLSocketFactory.class);
when(sslContext.getSocketFactory())
.thenReturn(sslSocketFactory);
mockStatic(SSLContext.class);
when(SSLContext.getInstance("TLSv1.2"))
.thenReturn(sslContext)
.thenReturn(sslContext)
.thenThrow(new NoSuchAlgorithmException());

// Mock default factory.
mockStatic(HttpsURLConnection.class);
when(HttpsURLConnection.getDefaultSSLSocketFactory())
.thenReturn(sslSocketFactory);

// Get factory from context.
assertNotNull(new TLS1_2SocketFactory());
verifyStatic(never());
HttpsURLConnection.getDefaultSSLSocketFactory();

// KeyManagementException
assertNotNull(new TLS1_2SocketFactory());
verifyStatic(times(1));
HttpsURLConnection.getDefaultSSLSocketFactory();

// NoSuchAlgorithmException
assertNotNull(new TLS1_2SocketFactory());
verifyStatic(times(2));
HttpsURLConnection.getDefaultSSLSocketFactory();
}

@Test
public void createSocket() throws Exception {
checkProtocol(getFactory().createSocket());
Expand Down

0 comments on commit 80b9e5a

Please sign in to comment.