1/* 2 * Copyright (C) 2009 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 17package org.conscrypt; 18 19import static org.mockito.Mockito.any; 20import static org.mockito.Mockito.eq; 21import static org.mockito.Mockito.mock; 22import static org.mockito.Mockito.verify; 23import static org.mockito.Mockito.when; 24 25import java.security.cert.Certificate; 26import java.util.Collections; 27import java.util.Enumeration; 28import java.util.HashSet; 29import java.util.Set; 30import javax.net.ssl.SSLSession; 31import junit.framework.TestCase; 32import libcore.javax.net.ssl.FakeSSLSession; 33 34public final class ClientSessionContextTest extends TestCase { 35 36 public void testSimpleAddition() { 37 ClientSessionContext context = new ClientSessionContext(); 38 SSLSession a = new ValidSSLSession("a"); 39 SSLSession b = new ValidSSLSession("b"); 40 41 context.putSession(a); 42 assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b }); 43 44 context.putSession(b); 45 assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[0]); 46 } 47 48 public void testTrimToSize() { 49 ClientSessionContext context = new ClientSessionContext(); 50 ValidSSLSession a = new ValidSSLSession("a"); 51 ValidSSLSession b = new ValidSSLSession("b"); 52 ValidSSLSession c = new ValidSSLSession("c"); 53 ValidSSLSession d = new ValidSSLSession("d"); 54 55 context.putSession(a); 56 assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b, c, d }); 57 58 context.putSession(b); 59 assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[] { c, d }); 60 61 context.putSession(c); 62 assertSessionContextContents(context, new SSLSession[] { a, b, c }, new SSLSession[] { d }); 63 64 context.putSession(d); 65 assertSessionContextContents(context, new SSLSession[] { a, b, c, d }, new SSLSession[0]); 66 67 context.setSessionCacheSize(2); 68 assertSessionContextContents(context, new SSLSession[] { c, d }, new SSLSession[] { a, b }); 69 } 70 71 public void testImplicitRemovalOfOldest() { 72 ClientSessionContext context = new ClientSessionContext(); 73 context.setSessionCacheSize(2); 74 ValidSSLSession a = new ValidSSLSession("a"); 75 ValidSSLSession b = new ValidSSLSession("b"); 76 ValidSSLSession c = new ValidSSLSession("c"); 77 ValidSSLSession d = new ValidSSLSession("d"); 78 79 context.putSession(a); 80 assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b, c, d }); 81 82 context.putSession(b); 83 assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[] { c, d }); 84 85 context.putSession(c); 86 assertSessionContextContents(context, new SSLSession[] { b, c }, new SSLSession[] { a, d }); 87 88 context.putSession(d); 89 assertSessionContextContents(context, new SSLSession[] { c, d }, new SSLSession[] { a, b }); 90 } 91 92 public void testSerializeSession_NoStatusResponses() throws Exception { 93 OpenSSLSessionImpl mockSession = mock(OpenSSLSessionImpl.class); 94 when(mockSession.getId()).thenReturn(new byte[] { 0x11, 0x09, 0x03, 0x20 }); 95 when(mockSession.getPeerHost()).thenReturn("ssl.example.com"); 96 when(mockSession.getPeerPort()).thenReturn(443); 97 when(mockSession.getEncoded()).thenReturn(new byte[] { 0x01, 0x02, 0x03 }); 98 when(mockSession.getStatusResponses()).thenReturn(Collections.<byte[]>emptyList()); 99 100 Certificate mockCert = mock(Certificate.class); 101 when(mockCert.getEncoded()).thenReturn(new byte[] { 0x05, 0x06, 0x07, 0x10 }); 102 103 when(mockSession.getPeerCertificates()).thenReturn(new Certificate[] { mockCert }); 104 105 SSLClientSessionCache mockCache = mock(SSLClientSessionCache.class); 106 ClientSessionContext context = new ClientSessionContext(); 107 context.setPersistentCache(mockCache); 108 109 context.putSession(mockSession); 110 verify(mockCache).putSessionData(eq(mockSession), any(byte[].class)); 111 } 112 113 114 private static void assertSessionContextContents(ClientSessionContext context, 115 SSLSession[] contains, 116 SSLSession[] exludes) { 117 assertEquals(contains.length, context.size()); 118 119 for (SSLSession s : contains) { 120 assertSame(s.getPeerHost(), s, context.getSession(s.getId())); 121 assertSame(s.getPeerHost(), s, context.getSession(s.getPeerHost(), 443)); 122 } 123 for (SSLSession s : exludes) { 124 assertNull(s.getPeerHost(), context.getSession(s.getId())); 125 assertNull(s.getPeerHost(), context.getSession(s.getPeerHost(), 443)); 126 } 127 128 Set<SSLSession> sessions = new HashSet<SSLSession>(); 129 Enumeration<byte[]> ids = context.getIds(); 130 while (ids.hasMoreElements()) { 131 byte[] id = ids.nextElement(); 132 sessions.add(context.getSession(id)); 133 } 134 135 Set<SSLSession> expected = new HashSet<SSLSession>(); 136 for (SSLSession s : sessions) { 137 expected.add(s); 138 } 139 assertEquals(expected, sessions); 140 } 141 142 static class ValidSSLSession extends FakeSSLSession { 143 ValidSSLSession(String host) { 144 super(host); 145 } 146 @Override public boolean isValid() { 147 return true; 148 } 149 } 150} 151