AbstractSessionContext.java revision 860d2707ce126ef8f66e3eac7ceeab6d24218cd8
108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project/* 208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * you may not use this file except in compliance with the License. 608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * You may obtain a copy of the License at 708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 1008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * See the License for the specific language governing permissions and 1408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * limitations under the License. 1508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 1608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt; 1808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 194a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.io.ByteArrayInputStream; 204a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.io.ByteArrayOutputStream; 214a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.io.DataInputStream; 224a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.io.DataOutputStream; 234a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.io.IOException; 24e247367fbd5d5b0451c3b3e61e6dba37f27d49e1Brian Carlstromimport java.security.cert.Certificate; 25e247367fbd5d5b0451c3b3e61e6dba37f27d49e1Brian Carlstromimport java.security.cert.CertificateEncodingException; 26860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootimport java.security.cert.X509Certificate; 274a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.util.Arrays; 284a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.util.Enumeration; 294a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.util.Iterator; 3061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstromimport java.util.LinkedHashMap; 3161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstromimport java.util.Map; 324a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstromimport java.util.NoSuchElementException; 33860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root 3408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport javax.net.ssl.SSLSession; 3508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectimport javax.net.ssl.SSLSessionContext; 3608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 3708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project/** 3808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Supports SSL session caches. 3908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 4008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Projectabstract class AbstractSessionContext implements SSLSessionContext { 4108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 4208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project volatile int maximumSize; 4308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project volatile int timeout; 4408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 4538c70d393f14cf0963a289caefb72e6ac14e23d3Joel Dice final long sslCtxNativePointer = NativeCrypto.SSL_CTX_new(); 4608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 4708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** Identifies OpenSSL sessions. */ 4808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project static final int OPEN_SSL = 1; 4908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 5061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom private final Map<ByteArray, SSLSession> sessions 5161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom = new LinkedHashMap<ByteArray, SSLSession>() { 5261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom @Override 5361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom protected boolean removeEldestEntry( 5461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom Map.Entry<ByteArray, SSLSession> eldest) { 55a5c365c0867e66e6b5ad8e3e9a1cbd306f35226bBrian Carlstrom boolean remove = maximumSize > 0 && size() > maximumSize; 56a5c365c0867e66e6b5ad8e3e9a1cbd306f35226bBrian Carlstrom if (remove) { 57a5c365c0867e66e6b5ad8e3e9a1cbd306f35226bBrian Carlstrom remove(eldest.getKey()); 58a5c365c0867e66e6b5ad8e3e9a1cbd306f35226bBrian Carlstrom sessionRemoved(eldest.getValue()); 59a5c365c0867e66e6b5ad8e3e9a1cbd306f35226bBrian Carlstrom } 60a5c365c0867e66e6b5ad8e3e9a1cbd306f35226bBrian Carlstrom return false; 6161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 6261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom }; 6361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom 6408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 6508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Constructs a new session context. 6608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 6708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param maximumSize of cache 6808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @param timeout for cache entries 6908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 702785b7f916644f939b599cf6b01a3df6fae1eca5Brian Carlstrom AbstractSessionContext(int maximumSize, int timeout) { 7108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project this.maximumSize = maximumSize; 7208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project this.timeout = timeout; 7308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 7408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 7508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 7661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom * Returns the collection of sessions ordered from oldest to newest 7708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 7861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom private Iterator<SSLSession> sessionIterator() { 7961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom synchronized (sessions) { 8061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom SSLSession[] array = sessions.values().toArray( 8161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom new SSLSession[sessions.size()]); 8261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return Arrays.asList(array).iterator(); 8361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 8461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 8508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 8608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public final Enumeration getIds() { 874a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom final Iterator<SSLSession> i = sessionIterator(); 8808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return new Enumeration<byte[]>() { 894a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom private SSLSession next; 9008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public boolean hasMoreElements() { 914a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom if (next != null) { 924a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom return true; 934a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom } 944a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom while (i.hasNext()) { 954a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom SSLSession session = i.next(); 964a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom if (session.isValid()) { 974a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom next = session; 984a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom return true; 994a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom } 1004a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom } 1014a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom next = null; 1024a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom return false; 10308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 10408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public byte[] nextElement() { 1054a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom if (hasMoreElements()) { 1064a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom byte[] id = next.getId(); 1074a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom next = null; 1084a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom return id; 1094a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom } 1104a91f8a9c955b7cd64fbdf36233295ac3dd515d3Brian Carlstrom throw new NoSuchElementException(); 11108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 11208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project }; 11308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 11408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 11508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public final int getSessionCacheSize() { 11608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return maximumSize; 11708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 11808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 11908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public final int getSessionTimeout() { 12008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return timeout; 12108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 12208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 12308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 12408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Makes sure cache size is < maximumSize. 12508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 12661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom protected void trimToSize() { 12761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom synchronized (sessions) { 12861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom int size = sessions.size(); 12961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (size > maximumSize) { 13061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom int removals = size - maximumSize; 13161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom Iterator<SSLSession> i = sessions.values().iterator(); 13261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom do { 13361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom SSLSession session = i.next(); 13461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom i.remove(); 13561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom sessionRemoved(session); 13661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } while (--removals > 0); 13761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 13861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 13961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 14061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom 14161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom public void setSessionTimeout(int seconds) 14261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom throws IllegalArgumentException { 14361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (seconds < 0) { 14461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom throw new IllegalArgumentException("seconds < 0"); 14561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 14661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom timeout = seconds; 14761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom 14861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom synchronized (sessions) { 14961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom Iterator<SSLSession> i = sessions.values().iterator(); 15061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom while (i.hasNext()) { 15161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom SSLSession session = i.next(); 15261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom // SSLSession's know their context and consult the 15361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom // timeout as part of their validity condition. 15461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (!session.isValid()) { 15561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom i.remove(); 15661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom sessionRemoved(session); 15761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 15861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 15961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 16061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 16161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom 1621f42e0a4d7d28b8fc20833e0be05ad17dcfa8ea0Brian Carlstrom /** 16361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom * Called when a session is removed. Used by ClientSessionContext 16461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom * to update its host-and-port based cache. 16561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom */ 166ff69e28cd239217f33fe96a9c8e7c40b658c19f9Jesse Wilson protected abstract void sessionRemoved(SSLSession session); 16708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 16808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project public final void setSessionCacheSize(int size) 16908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throws IllegalArgumentException { 17008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (size < 0) { 17108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project throw new IllegalArgumentException("size < 0"); 17208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 17308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 17408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project int oldMaximum = maximumSize; 17508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project maximumSize = size; 17608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 17708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // Trim cache to size if necessary. 17808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (size < oldMaximum) { 17908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project trimToSize(); 18008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 18108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 18208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 18308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 18408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Converts the given session to bytes. 18508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 18608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return session data as bytes or null if the session can't be converted 18708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 18808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project byte[] toBytes(SSLSession session) { 18908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // TODO: Support SSLSessionImpl, too. 19008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (!(session instanceof OpenSSLSessionImpl)) { 19108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return null; 19208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 19308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 19408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project OpenSSLSessionImpl sslSession = (OpenSSLSessionImpl) session; 19508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project try { 19608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project ByteArrayOutputStream baos = new ByteArrayOutputStream(); 19708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project DataOutputStream daos = new DataOutputStream(baos); 19808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 19908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project daos.writeInt(OPEN_SSL); // session type ID 20008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 20108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // Session data. 20208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project byte[] data = sslSession.getEncoded(); 20308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project daos.writeInt(data.length); 20408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project daos.write(data); 20508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 20608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project // Certificates. 207e247367fbd5d5b0451c3b3e61e6dba37f27d49e1Brian Carlstrom Certificate[] certs = session.getPeerCertificates(); 20808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project daos.writeInt(certs.length); 20908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 210e247367fbd5d5b0451c3b3e61e6dba37f27d49e1Brian Carlstrom for (Certificate cert : certs) { 21108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project data = cert.getEncoded(); 21208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project daos.writeInt(data.length); 21308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project daos.write(data); 21408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 2152828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom // TODO: local certificates? 21608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 21708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return baos.toByteArray(); 21808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } catch (IOException e) { 21908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project log(e); 22008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return null; 22108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } catch (CertificateEncodingException e) { 22208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project log(e); 22308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return null; 22408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 22508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 22608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 22708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project /** 22808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * Creates a session from the given bytes. 22908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * 23008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project * @return a session or null if the session can't be converted 23108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project */ 23208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project SSLSession toSession(byte[] data, String host, int port) { 23308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project ByteArrayInputStream bais = new ByteArrayInputStream(data); 23408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project DataInputStream dais = new DataInputStream(bais); 23508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project try { 23608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project int type = dais.readInt(); 23708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project if (type != OPEN_SSL) { 23808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project log(new AssertionError("Unexpected type ID: " + type)); 23908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return null; 24008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 24108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 24208ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project int length = dais.readInt(); 24308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project byte[] sessionData = new byte[length]; 24408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project dais.readFully(sessionData); 24508ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 24608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project int count = dais.readInt(); 247860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root X509Certificate[] certs = new X509Certificate[count]; 24808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project for (int i = 0; i < count; i++) { 24908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project length = dais.readInt(); 25008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project byte[] certData = new byte[length]; 25108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project dais.readFully(certData); 252860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Root certs[i] = OpenSSLX509Certificate.fromX509Der(certData); 25308ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 25408ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 2552828ed800862c0ed2cf2116cb986d6bf209e4f58Brian Carlstrom return new OpenSSLSessionImpl(sessionData, host, port, certs, this); 25608ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } catch (IOException e) { 25708ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project log(e); 25808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project return null; 25908ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 26008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 26108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 26261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom public SSLSession getSession(byte[] sessionId) { 26361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (sessionId == null) { 26461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom throw new NullPointerException("sessionId == null"); 26561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 26661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom ByteArray key = new ByteArray(sessionId); 26761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom SSLSession session; 26861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom synchronized (sessions) { 26961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom session = sessions.get(key); 27061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 27161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (session != null && session.isValid()) { 27261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return session; 27361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 27461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return null; 27561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 27661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom 27761b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom void putSession(SSLSession session) { 27861b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom byte[] id = session.getId(); 27961b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom if (id.length == 0) { 28061b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom return; 28161b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 28261b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom ByteArray key = new ByteArray(id); 28361b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom synchronized (sessions) { 28461b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom sessions.put(key, session); 28561b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 28661b2ada13329b7d1698f6c706b31077a67fbac2dBrian Carlstrom } 287f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom 28808ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project static void log(Throwable t) { 2895006f3bedbfd19dc905416bbf28bb0e95807f845Jesse Wilson System.logW("Error converting session.", t); 29008ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project } 29108ecc8c0f00f1a7f2258c569187e36606ed73045The Android Open Source Project 2921990574e420184f3ad43400171f624dad44700d8Brian Carlstrom @Override protected void finalize() throws Throwable { 2931990574e420184f3ad43400171f624dad44700d8Brian Carlstrom try { 2941990574e420184f3ad43400171f624dad44700d8Brian Carlstrom NativeCrypto.SSL_CTX_free(sslCtxNativePointer); 2951990574e420184f3ad43400171f624dad44700d8Brian Carlstrom } finally { 2961990574e420184f3ad43400171f624dad44700d8Brian Carlstrom super.finalize(); 2971990574e420184f3ad43400171f624dad44700d8Brian Carlstrom } 298f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom } 299f0c622f8ceb1fa261b67e3b8654f58254a12729cBrian Carlstrom} 300