summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-06-27 21:25:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2013-06-27 21:25:24 +0000
commita5a2de55082b1f2a9ec0b99962a88063ac6d1bbf (patch)
treedcd95573abf31de14a855f9e4aa52754ad4f0805
parent12c4c0e45b12be18005f0ad2af2433e34dcb1a9f (diff)
parent100d7290264338c6536739abd59879aaaa812537 (diff)
downloadbase-a5a2de55082b1f2a9ec0b99962a88063ac6d1bbf.tar.gz
Merge "Add ALPN support to SSL socket factory"
-rw-r--r--core/java/android/net/SSLCertificateSocketFactory.java56
-rw-r--r--core/tests/coretests/src/android/net/SSLTest.java16
2 files changed, 58 insertions, 14 deletions
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 37f04d308773..31c8edb6ebb5 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -89,6 +89,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
private TrustManager[] mTrustManagers = null;
private KeyManager[] mKeyManagers = null;
private byte[] mNpnProtocols = null;
+ private byte[] mAlpnProtocols = null;
private PrivateKey mChannelIdPrivateKey = null;
private final int mHandshakeTimeoutMillis;
@@ -268,19 +269,42 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
* must be non-empty and of length less than 256.
*/
public void setNpnProtocols(byte[][] npnProtocols) {
- this.mNpnProtocols = toNpnProtocolsList(npnProtocols);
+ this.mNpnProtocols = toLengthPrefixedList(npnProtocols);
+ }
+
+ /**
+ * Sets the
+ * <a href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-01">
+ * Application Layer Protocol Negotiation (ALPN)</a> protocols that this peer
+ * is interested in.
+ *
+ * <p>For servers this is the sequence of protocols to advertise as
+ * supported, in order of preference. This list is sent unencrypted to
+ * all clients that support ALPN.
+ *
+ * <p>For clients this is a list of supported protocols to match against the
+ * server's list. If there is no protocol supported by both client and
+ * server then the first protocol in the client's list will be selected.
+ * The order of the client's protocols is otherwise insignificant.
+ *
+ * @param protocols a non-empty list of protocol byte arrays. All arrays
+ * must be non-empty and of length less than 256.
+ * @hide
+ */
+ public void setAlpnProtocols(byte[][] protocols) {
+ this.mAlpnProtocols = toLengthPrefixedList(protocols);
}
/**
* Returns an array containing the concatenation of length-prefixed byte
* strings.
*/
- static byte[] toNpnProtocolsList(byte[]... npnProtocols) {
- if (npnProtocols.length == 0) {
- throw new IllegalArgumentException("npnProtocols.length == 0");
+ static byte[] toLengthPrefixedList(byte[]... items) {
+ if (items.length == 0) {
+ throw new IllegalArgumentException("items.length == 0");
}
int totalLength = 0;
- for (byte[] s : npnProtocols) {
+ for (byte[] s : items) {
if (s.length == 0 || s.length > 255) {
throw new IllegalArgumentException("s.length == 0 || s.length > 255: " + s.length);
}
@@ -288,7 +312,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
}
byte[] result = new byte[totalLength];
int pos = 0;
- for (byte[] s : npnProtocols) {
+ for (byte[] s : items) {
result[pos++] = (byte) s.length;
for (byte b : s) {
result[pos++] = b;
@@ -310,6 +334,20 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
}
/**
+ * Returns the
+ * <a href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-01">Application
+ * Layer Protocol Negotiation (ALPN)</a> protocol selected by client and server, or null
+ * if no protocol was negotiated.
+ *
+ * @param socket a socket created by this factory.
+ * @throws IllegalArgumentException if the socket was not created by this factory.
+ * @hide
+ */
+ public byte[] getAlpnSelectedProtocol(Socket socket) {
+ return castToOpenSSLSocket(socket).getAlpnSelectedProtocol();
+ }
+
+ /**
* Sets the {@link KeyManager}s to be used for connections made by this factory.
*/
public void setKeyManagers(KeyManager[] keyManagers) {
@@ -393,6 +431,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
public Socket createSocket(Socket k, String host, int port, boolean close) throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close);
s.setNpnProtocols(mNpnProtocols);
+ s.setAlpnProtocols(mAlpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
s.setChannelIdPrivateKey(mChannelIdPrivateKey);
if (mSecure) {
@@ -413,6 +452,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
public Socket createSocket() throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket();
s.setNpnProtocols(mNpnProtocols);
+ s.setAlpnProtocols(mAlpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
s.setChannelIdPrivateKey(mChannelIdPrivateKey);
return s;
@@ -431,6 +471,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
addr, port, localAddr, localPort);
s.setNpnProtocols(mNpnProtocols);
+ s.setAlpnProtocols(mAlpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
s.setChannelIdPrivateKey(mChannelIdPrivateKey);
return s;
@@ -447,6 +488,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
public Socket createSocket(InetAddress addr, int port) throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port);
s.setNpnProtocols(mNpnProtocols);
+ s.setAlpnProtocols(mAlpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
s.setChannelIdPrivateKey(mChannelIdPrivateKey);
return s;
@@ -464,6 +506,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
host, port, localAddr, localPort);
s.setNpnProtocols(mNpnProtocols);
+ s.setAlpnProtocols(mAlpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
s.setChannelIdPrivateKey(mChannelIdPrivateKey);
if (mSecure) {
@@ -482,6 +525,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
public Socket createSocket(String host, int port) throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port);
s.setNpnProtocols(mNpnProtocols);
+ s.setAlpnProtocols(mAlpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
s.setChannelIdPrivateKey(mChannelIdPrivateKey);
if (mSecure) {
diff --git a/core/tests/coretests/src/android/net/SSLTest.java b/core/tests/coretests/src/android/net/SSLTest.java
index 27b699d805e4..45d28aef7974 100644
--- a/core/tests/coretests/src/android/net/SSLTest.java
+++ b/core/tests/coretests/src/android/net/SSLTest.java
@@ -49,35 +49,35 @@ public class SSLTest extends TestCase {
// System.out.println(new String(b));
}
- public void testStringsToNpnBytes() {
+ public void testStringsToLengthPrefixedBytes() {
byte[] expected = {
6, 's', 'p', 'd', 'y', '/', '2',
8, 'h', 't', 't', 'p', '/', '1', '.', '1',
};
- assertTrue(Arrays.equals(expected, SSLCertificateSocketFactory.toNpnProtocolsList(
+ assertTrue(Arrays.equals(expected, SSLCertificateSocketFactory.toLengthPrefixedList(
new byte[] { 's', 'p', 'd', 'y', '/', '2' },
new byte[] { 'h', 't', 't', 'p', '/', '1', '.', '1' })));
}
- public void testStringsToNpnBytesEmptyArray() {
+ public void testStringsToLengthPrefixedBytesEmptyArray() {
try {
- SSLCertificateSocketFactory.toNpnProtocolsList();
+ SSLCertificateSocketFactory.toLengthPrefixedList();
fail();
} catch (IllegalArgumentException expected) {
}
}
- public void testStringsToNpnBytesEmptyByteArray() {
+ public void testStringsToLengthPrefixedBytesEmptyByteArray() {
try {
- SSLCertificateSocketFactory.toNpnProtocolsList(new byte[0]);
+ SSLCertificateSocketFactory.toLengthPrefixedList(new byte[0]);
fail();
} catch (IllegalArgumentException expected) {
}
}
- public void testStringsToNpnBytesOversizedInput() {
+ public void testStringsToLengthPrefixedBytesOversizedInput() {
try {
- SSLCertificateSocketFactory.toNpnProtocolsList(new byte[256]);
+ SSLCertificateSocketFactory.toLengthPrefixedList(new byte[256]);
fail();
} catch (IllegalArgumentException expected) {
}