1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.unit_tests; 18 19 import android.content.ContentResolver; 20 import android.database.Cursor; 21 import android.database.sqlite.SQLiteOpenHelper; 22 import android.provider.Settings; 23 import android.test.AndroidTestCase; 24 import android.test.suitebuilder.annotation.LargeTest; 25 import android.test.suitebuilder.annotation.Suppress; 26 27 import com.google.android.net.GoogleHttpClient; 28 29 import com.android.internal.net.DbSSLSessionCache; 30 import com.android.internal.net.DbSSLSessionCache.DatabaseHelper; 31 32 import org.apache.http.HttpResponse; 33 import org.apache.http.client.methods.HttpGet; 34 35 import java.io.IOException; 36 import java.security.Principal; 37 import java.security.cert.Certificate; 38 39 import javax.net.ssl.SSLPeerUnverifiedException; 40 import javax.net.ssl.SSLSession; 41 import javax.net.ssl.SSLSessionContext; 42 import javax.security.cert.X509Certificate; 43 44 /** Unit test for SSL session caching with {@link GoogleHttpClient}. 45 * Uses network resources. 46 */ 47 @Suppress 48 public class DbSSLSessionCacheTest extends AndroidTestCase { 49 setUp()50 protected void setUp() throws Exception { 51 } 52 tearDown()53 protected void tearDown() throws Exception { 54 } 55 56 /** 57 * We want to test the actual database write - the actual hooking into 58 * low-level SSL is tested. 59 */ 60 @LargeTest testSslCacheAdd()61 public void testSslCacheAdd() throws Exception { 62 // Let's verify the database has the rows. 63 // Use internal details of the implementation - could make the field 64 // visible for testing, but it's same. 65 66 // Use default database 67 DbSSLSessionCache cache = DbSSLSessionCache.getInstanceForPackage(getContext()); 68 cache.clear(); 69 70 71 makeRequestInNewContext("https://www.google.com"); 72 73 // Verify the key was inserted 74 SQLiteOpenHelper helper = new DatabaseHelper(getContext()); 75 Cursor query = null; 76 try { 77 query = helper.getReadableDatabase().query(DbSSLSessionCache.SSL_CACHE_TABLE, 78 new String[] {"hostport"}, null, 79 null, null, null, null); 80 81 assertTrue(query.moveToFirst()); // one row inserted 82 String hostPort = query.getString(0); 83 assertEquals(hostPort, "www.google.com:443"); 84 } finally { 85 query.close(); 86 } 87 } 88 89 @LargeTest testExpire()90 public void testExpire() throws Exception { 91 DatabaseHelper helper = new DatabaseHelper(getContext()); 92 // clean up 93 DbSSLSessionCache cache = new DbSSLSessionCache(helper); 94 cache.clear(); 95 96 long t0 = System.currentTimeMillis(); 97 for (int i = 0; i < DbSSLSessionCache.MAX_CACHE_SIZE + 2; i++) { 98 final int port = i; 99 cache.putSessionData(new MockSession() { 100 101 public String getPeerHost() { 102 return "test.host.com"; 103 } 104 105 public int getPeerPort() { 106 return port; 107 } 108 }, new byte[256]); 109 } 110 long t1 = System.currentTimeMillis(); 111 112 System.err.println("Time to insert " + 113 (DbSSLSessionCache.MAX_CACHE_SIZE + 2) + " " + (t1 - t0)); 114 115 // first entry should have port 1. 116 Cursor query = helper.getReadableDatabase().query(DbSSLSessionCache.SSL_CACHE_TABLE, 117 new String[] {"hostport", "session"}, null, 118 null, null, null, null); 119 120 int cnt = query.getCount(); 121 122 assertTrue(query.moveToFirst()); // one row inserted 123 String hostPort = query.getString(0); 124 assertEquals("test.host.com:2", hostPort); 125 while (query.moveToNext()) { 126 hostPort = query.getString(0); 127 String session = query.getString(1); 128 } 129 long t2 = System.currentTimeMillis(); 130 System.err.println("Time to load " + cnt + " " + (t2 - t1)); 131 132 query.close(); 133 } 134 makeRequestInNewContext(String url)135 private void makeRequestInNewContext(String url) throws IOException { 136 GoogleHttpClient client = new GoogleHttpClient(getContext(), "Test", 137 false /* no gzip */); 138 139 try { 140 // Note: we must test against a real server, because the connection 141 // gets established before the interceptor can crash the request. 142 HttpGet method = new HttpGet(url); 143 HttpResponse response = client.execute(method); 144 } finally { 145 client.close(); 146 } 147 } 148 149 private static class MockSession implements SSLSession { 150 getPeerHost()151 public String getPeerHost() { 152 throw new UnsupportedOperationException(); 153 } 154 155 getPeerPort()156 public int getPeerPort() { 157 throw new UnsupportedOperationException(); 158 } 159 160 161 getApplicationBufferSize()162 public int getApplicationBufferSize() { 163 throw new UnsupportedOperationException(); 164 } 165 166 getCipherSuite()167 public String getCipherSuite() { 168 throw new UnsupportedOperationException(); 169 } 170 171 getCreationTime()172 public long getCreationTime() { 173 throw new UnsupportedOperationException(); 174 } 175 176 getId()177 public byte[] getId() { 178 throw new UnsupportedOperationException(); 179 } 180 181 getLastAccessedTime()182 public long getLastAccessedTime() { 183 throw new UnsupportedOperationException(); 184 } 185 186 getLocalCertificates()187 public Certificate[] getLocalCertificates() { 188 throw new UnsupportedOperationException(); 189 } 190 191 getLocalPrincipal()192 public Principal getLocalPrincipal() { 193 throw new UnsupportedOperationException(); 194 } 195 196 getPacketBufferSize()197 public int getPacketBufferSize() { 198 throw new UnsupportedOperationException(); 199 } 200 201 getPeerCertificateChain()202 public X509Certificate[] getPeerCertificateChain() 203 throws SSLPeerUnverifiedException { 204 throw new UnsupportedOperationException(); 205 } 206 207 getPeerCertificates()208 public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { 209 throw new UnsupportedOperationException(); 210 } 211 212 getPeerPrincipal()213 public Principal getPeerPrincipal() throws SSLPeerUnverifiedException { 214 throw new UnsupportedOperationException(); 215 } 216 217 getProtocol()218 public String getProtocol() { 219 throw new UnsupportedOperationException(); 220 } 221 222 getSessionContext()223 public SSLSessionContext getSessionContext() { 224 throw new UnsupportedOperationException(); 225 } 226 227 getValue(String name)228 public Object getValue(String name) { 229 throw new UnsupportedOperationException(); 230 } 231 232 getValueNames()233 public String[] getValueNames() { 234 throw new UnsupportedOperationException(); 235 } 236 237 invalidate()238 public void invalidate() { 239 throw new UnsupportedOperationException(); 240 } 241 242 isValid()243 public boolean isValid() { 244 throw new UnsupportedOperationException(); 245 } 246 247 putValue(String name, Object value)248 public void putValue(String name, Object value) { 249 throw new UnsupportedOperationException(); 250 } 251 252 removeValue(String name)253 public void removeValue(String name) { 254 throw new UnsupportedOperationException(); 255 } 256 } 257 258 259 } 260